From 3a760529314fa68cf6453cc0f8dd5f2c66c10af5 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 29 Apr 2025 16:27:29 +0000 Subject: [PATCH] Prevent type infer hang of "simple" recursive functions Prevent infinite inference when dealing with LimitedAccuracy by declining to cache them. Presence in the cache triggers further compilation to resolve it, so removing infinite work from the cache also prevents infinite work at pre-compile/jit compile time. Fix #57098 Fix #57873 --- Compiler/src/typeinfer.jl | 15 +++++++-------- Compiler/test/inference.jl | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index d2709259c8824..edc80536febab 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -613,18 +613,17 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter, cycleid:: istoplevel = !(me.linfo.def isa Method) istoplevel || compute_edges!(me) # don't add backedges to toplevel method instance - if limited_ret - # a parent may be cached still, but not this intermediate work: - # we can throw everything else away now + if limited_ret || limited_src + # A parent may be cached still, but not this intermediate work: + # we can throw everything else away now. Caching anything can confuse later + # heuristics to consider it worth trying to pursue compiling this further and + # finding infinite work as a result. Avoiding caching helps to ensure there is only + # a finite amount of work that can be discovered later (although potentially still a + # large multiplier on it). result.src = nothing result.tombstone = true me.cache_mode = CACHE_MODE_NULL set_inlineable!(me.src, false) - elseif limited_src - # a type result will be cached still, but not this intermediate work: - # we can throw everything else away now - result.src = nothing - set_inlineable!(me.src, false) else # annotate fulltree with type information, # either because we are the outermost code, or we might use this later diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index c5f44e22d55ed..4545be8bdf8ff 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6445,4 +6445,29 @@ A58257.B58257.get! # Creates binding partition in A.B, N+1:∞ Base.invoke_in_world(UInt(38678), getglobal, A58257, :get!) # Expands binding partition in A through