@@ -380,7 +380,7 @@ using Base.Experimental: @opaque
380380f_oc_getfield (x) =  (@opaque  ()-> x)()
381381@test  fully_eliminated (f_oc_getfield, Tuple{Int})
382382
383- import  Core. Compiler:  argextype
383+ import  Core. Compiler:  argextype, singleton_type 
384384const  EMPTY_SPTYPES =  Core. Compiler. EMPTY_SLOTTYPES
385385
386386code_typed1 (args... ; kwargs... ) =  first (only (code_typed (args... ; kwargs... ))):: Core.CodeInfo 
@@ -389,7 +389,7 @@ get_code(args...; kwargs...) = code_typed1(args...; kwargs...).code
389389#  check if `x` is a dynamic call of a given function
390390function  iscall ((src, f):: Tuple{Core.CodeInfo,Function} , @nospecialize (x))
391391    return  iscall (x) do  @nospecialize  x
392-         argextype (x, src, EMPTY_SPTYPES) ===  typeof (f) 
392+         singleton_type ( argextype (x, src, EMPTY_SPTYPES))  ===  f 
393393    end 
394394end 
395395iscall (pred, @nospecialize (x)) =  Meta. isexpr (x, :call ) &&  pred (x. args[1 ])
@@ -724,7 +724,7 @@ let f(x) = (x...,)
724724end 
725725
726726#  https://github.com/JuliaLang/julia/issues/42754
727- #  inline union-split constant-prop'ed sources 
727+ #  inline union-split constant-prop'ed results 
728728mutable struct  X42754
729729    #  NOTE in order to confuse `fieldtype_tfunc`, we need to have at least two fields with different types
730730    a:: Union{Nothing, Int} 
745745
746746import  Base:  @constprop 
747747
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+ 
748775#  test single, non-dispatchtuple callsite inlining
749776
750777@constprop  :none  @inline  test_single_nondispatchtuple (@nospecialize (t)) = 
0 commit comments