@@ -1007,6 +1007,17 @@ precompile_test_harness("invoke") do dir
10071007 f44320(::Any) = 2
10081008 g44320() = invoke(f44320, Tuple{Any}, 0)
10091009 g44320()
1010+ # Issue #57115
1011+ f57115(@nospecialize(::Any)) = error("unimplemented")
1012+ function g57115(@nospecialize(x))
1013+ if @noinline rand(Bool)
1014+ # Add an 'invoke' edge from 'foo' to 'bar'
1015+ Core.invoke(f57115, Tuple{Any}, x)
1016+ else
1017+ # ... and also an identical 'call' edge
1018+ @noinline f57115(x)
1019+ end
1020+ end
10101021
10111022 # Adding new specializations should not invalidate `invoke`s
10121023 function getlast(itr)
@@ -1023,6 +1034,8 @@ precompile_test_harness("invoke") do dir
10231034 """
10241035 module $CallerModule
10251036 using $InvokeModule
1037+ import $InvokeModule : f57115, g57115
1038+
10261039 # involving external modules
10271040 callf(x) = f(x)
10281041 callg(x) = x < 5 ? g(x) : invoke(g, Tuple{Real}, x)
@@ -1043,6 +1056,8 @@ precompile_test_harness("invoke") do dir
10431056
10441057 # Issue #44320
10451058 f44320(::Real) = 3
1059+ # Issue #57115
1060+ f57115(::Int) = 1
10461061
10471062 call_getlast(x) = getlast(x)
10481063
@@ -1063,6 +1078,7 @@ precompile_test_harness("invoke") do dir
10631078 internalnc(3)
10641079 call_getlast([1,2,3])
10651080 end
1081+ precompile(g57115, (Any,))
10661082
10671083 # Now that we've precompiled, invalidate with a new method that overrides the `invoke` dispatch
10681084 $InvokeModule .h(x::Integer) = -1
@@ -1083,7 +1099,7 @@ precompile_test_harness("invoke") do dir
10831099 for m in methods (func)
10841100 m. sig. parameters[end ] === T && return m
10851101 end
1086- error (" no ::Real method found for $func " )
1102+ error (" no ::$T method found for $func " )
10871103 end
10881104 function nvalid (mi:: Core.MethodInstance )
10891105 isdefined (mi, :cache ) || return 0
@@ -1129,6 +1145,27 @@ precompile_test_harness("invoke") do dir
11291145 m = only (methods (M. g44320))
11301146 @test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
11311147
1148+ m = only (methods (M. g57115))
1149+ mi = m. specializations:: Core.MethodInstance
1150+
1151+ f_m = get_method_for_type (M. f57115, Any)
1152+ f_mi = f_m. specializations:: Core.MethodInstance
1153+
1154+ # Make sure that f57115(::Any) has a 'call' backedge to 'g57115'
1155+ has_f_call_backedge = false
1156+ it = Core. Compiler. BackedgeIterator (f_mi. backedges)
1157+ # Manually-written iterate(...) protocol, since this is in Core.Compiler
1158+ item = Core. Compiler. iterate (it)
1159+ while item != = nothing
1160+ (; sig, caller) = item[1 ]
1161+ if sig === nothing && caller === mi
1162+ has_f_call_backedge = true
1163+ break
1164+ end
1165+ item = Core. Compiler. iterate (it, item[2 ])
1166+ end
1167+ @test has_f_call_backedge
1168+
11321169 m = which (MI. getlast, (Any,))
11331170 @test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
11341171
0 commit comments