@@ -132,7 +132,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
132
132
# if there's a possibility we could constant-propagate a better result
133
133
# (hopefully without doing too much work), try to do that now
134
134
# TODO : it feels like this could be better integrated into abstract_call_method / typeinf_edge
135
- const_rettype = abstract_call_method_with_const_args (interp, rettype, f, argtypes, applicable[nonbot]:: SimpleVector , sv)
135
+ const_rettype = abstract_call_method_with_const_args (interp, rettype, f, argtypes, applicable[nonbot]:: SimpleVector , sv, edgecycle )
136
136
if const_rettype ⊑ rettype
137
137
# use the better result, if it's a refinement of rettype
138
138
rettype = const_rettype
@@ -185,7 +185,7 @@ function const_prop_profitable(@nospecialize(arg))
185
185
return false
186
186
end
187
187
188
- function abstract_call_method_with_const_args (interp:: AbstractInterpreter , @nospecialize (rettype), @nospecialize (f), argtypes:: Vector{Any} , match:: SimpleVector , sv:: InferenceState )
188
+ function abstract_call_method_with_const_args (interp:: AbstractInterpreter , @nospecialize (rettype), @nospecialize (f), argtypes:: Vector{Any} , match:: SimpleVector , sv:: InferenceState , edgecycle :: Bool )
189
189
method = match[3 ]:: Method
190
190
nargs:: Int = method. nargs
191
191
method. isva && (nargs -= 1 )
@@ -259,6 +259,24 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter, @nosp
259
259
inf_cache = get_inference_cache (interp)
260
260
inf_result = cache_lookup (mi, argtypes, inf_cache)
261
261
if inf_result === nothing
262
+ if edgecycle
263
+ # if there might be a cycle, check to make sure we don't end up
264
+ # calling ourselves here.
265
+ infstate = sv
266
+ cyclei = 0
267
+ while ! (infstate === nothing )
268
+ if method === infstate. linfo. def && any (infstate. result. overridden_by_const)
269
+ return Any
270
+ end
271
+ if cyclei < length (infstate. callers_in_cycle)
272
+ cyclei += 1
273
+ infstate = infstate. callers_in_cycle[cyclei]
274
+ else
275
+ cyclei = 0
276
+ infstate = infstate. parent
277
+ end
278
+ end
279
+ end
262
280
inf_result = InferenceResult (mi, argtypes)
263
281
frame = InferenceState (inf_result, #= cache=# false , interp)
264
282
frame === nothing && return Any # this is probably a bad generated function (unsound), but just ignore it
0 commit comments