@@ -380,7 +380,7 @@ using Base.Experimental: @opaque
380
380
f_oc_getfield (x) = (@opaque ()-> x)()
381
381
@test fully_eliminated (f_oc_getfield, Tuple{Int})
382
382
383
- import Core. Compiler: argextype
383
+ import Core. Compiler: argextype, singleton_type
384
384
const EMPTY_SPTYPES = Core. Compiler. EMPTY_SLOTTYPES
385
385
386
386
code_typed1 (args... ; kwargs... ) = first (only (code_typed (args... ; kwargs... ))):: Core.CodeInfo
@@ -389,7 +389,7 @@ get_code(args...; kwargs...) = code_typed1(args...; kwargs...).code
389
389
# check if `x` is a dynamic call of a given function
390
390
function iscall ((src, f):: Tuple{Core.CodeInfo,Function} , @nospecialize (x))
391
391
return iscall (x) do @nospecialize x
392
- argextype (x, src, EMPTY_SPTYPES) === typeof (f)
392
+ singleton_type ( argextype (x, src, EMPTY_SPTYPES)) === f
393
393
end
394
394
end
395
395
iscall (pred, @nospecialize (x)) = Meta. isexpr (x, :call ) && pred (x. args[1 ])
@@ -724,7 +724,7 @@ let f(x) = (x...,)
724
724
end
725
725
726
726
# https://github.com/JuliaLang/julia/issues/42754
727
- # inline union-split constant-prop'ed sources
727
+ # inline union-split constant-prop'ed results
728
728
mutable struct X42754
729
729
# NOTE in order to confuse `fieldtype_tfunc`, we need to have at least two fields with different types
730
730
a:: Union{Nothing, Int}
745
745
746
746
import Base: @constprop
747
747
748
+ # test union-split callsite with successful and unsuccessful constant-prop' results
749
+ @constprop :aggressive @inline f42840 (xs, a:: Int ) = xs[a] # should be successful, and inlined
750
+ @constprop :none @noinline f42840 (xs:: AbstractVector , a:: Int ) = xs[a] # should be unsuccessful, but still statically resolved
751
+ let src = code_typed ((Union{Tuple{Int,Int,Int}, Vector{Int}},)) do xs
752
+ f42840 (xs, 2 )
753
+ end |> only |> first
754
+ @test count (src. code) do @nospecialize x
755
+ iscall ((src, getfield), x) # `(xs::Tuple{Int,Int,Int})[a::Const(2)]` => `getfield(xs, 2)`
756
+ end == 1
757
+ @test count (src. code) do @nospecialize x
758
+ isinvoke (:f42840 , x)
759
+ end == 1
760
+ end
761
+ # a bit weird, but should handle this kind of case as well
762
+ @constprop :aggressive @noinline g42840 (xs, a:: Int ) = xs[a] # should be successful, but only statically resolved
763
+ @constprop :none @inline g42840 (xs:: AbstractVector , a:: Int ) = xs[a] # should be unsuccessful, still inlined
764
+ let src = code_typed ((Union{Tuple{Int,Int,Int}, Vector{Int}},)) do xs
765
+ g42840 (xs, 2 )
766
+ end |> only |> first
767
+ @test count (src. code) do @nospecialize x
768
+ iscall ((src, Base. arrayref), x) # `(xs::Vector{Int})[a::Const(2)]` => `Base.arrayref(true, xs, 2)`
769
+ end == 1
770
+ @test count (src. code) do @nospecialize x
771
+ isinvoke (:g42840 , x)
772
+ end == 1
773
+ end
774
+
748
775
# test single, non-dispatchtuple callsite inlining
749
776
750
777
@constprop :none @inline test_single_nondispatchtuple (@nospecialize (t)) =
0 commit comments