@@ -1094,6 +1094,17 @@ precompile_test_harness("invoke") do dir
10941094 f44320(::Any) = 2
10951095 g44320() = invoke(f44320, Tuple{Any}, 0)
10961096 g44320()
1097+ # Issue #57115
1098+ f57115(@nospecialize(::Any)) = error("unimplemented")
1099+ function g57115(@nospecialize(x))
1100+ if @noinline rand(Bool)
1101+ # Add an 'invoke' edge from 'foo' to 'bar'
1102+ Core.invoke(f57115, Tuple{Any}, x)
1103+ else
1104+ # ... and also an identical 'call' edge
1105+ @noinline f57115(x)
1106+ end
1107+ end
10971108
10981109 # Adding new specializations should not invalidate `invoke`s
10991110 function getlast(itr)
@@ -1110,6 +1121,8 @@ precompile_test_harness("invoke") do dir
11101121 """
11111122 module $CallerModule
11121123 using $InvokeModule
1124+ import $InvokeModule : f57115, g57115
1125+
11131126 # involving external modules
11141127 callf(x) = f(x)
11151128 callg(x) = x < 5 ? g(x) : invoke(g, Tuple{Real}, x)
@@ -1130,6 +1143,8 @@ precompile_test_harness("invoke") do dir
11301143
11311144 # Issue #44320
11321145 f44320(::Real) = 3
1146+ # Issue #57115
1147+ f57115(::Int) = 1
11331148
11341149 call_getlast(x) = getlast(x)
11351150
@@ -1150,6 +1165,7 @@ precompile_test_harness("invoke") do dir
11501165 @noinline internalnc(3)
11511166 @noinline call_getlast([1,2,3])
11521167 end
1168+ precompile(g57115, (Any,))
11531169
11541170 # Now that we've precompiled, invalidate with a new method that overrides the `invoke` dispatch
11551171 $InvokeModule .h(x::Integer) = -1
@@ -1217,6 +1233,30 @@ precompile_test_harness("invoke") do dir
12171233 m = only (methods (M. g44320))
12181234 @test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
12191235
1236+ m = only (methods (M. g57115))
1237+ mi = m. specializations:: Core.MethodInstance
1238+
1239+ f_m = get_method_for_type (M. f57115, Any)
1240+ f_mi = f_m. specializations:: Core.MethodInstance
1241+
1242+ # Make sure that f57115(::Any) has a 'call' backedge to 'g57115'
1243+ has_f_call_backedge = false
1244+ i = 1
1245+ while i ≤ length (f_mi. backedges)
1246+ if f_mi. backedges[i] isa DataType
1247+ # invoke edge - skip
1248+ i += 2
1249+ else
1250+ caller = f_mi. backedges[i]:: Core.CodeInstance
1251+ if caller. def === mi
1252+ has_f_call_backedge = true
1253+ break
1254+ end
1255+ i += 1
1256+ end
1257+ end
1258+ @test has_f_call_backedge
1259+
12201260 m = which (MI. getlast, (Any,))
12211261 @test (m. specializations:: Core.MethodInstance ). cache. max_world == typemax (UInt)
12221262
0 commit comments