Skip to content

Commit

Permalink
only allow one completion task to infer in repl_eval_ex at a time
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Jan 29, 2025
1 parent 392e085 commit 61d0213
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions stdlib/REPL/src/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,9 @@ function resolve_toplevel_symbols!(src::Core.CodeInfo, mod::Module)
return src
end

# lock so that threaded completions don't run inference on the same expr at the same time
const inference_lock = Base.ReentrantLock()

# lower `ex` and run type inference on the resulting top-level expression
function repl_eval_ex(@nospecialize(ex), context_module::Module; limit_aggressive_inference::Bool=false)
if (isexpr(ex, :toplevel) || isexpr(ex, :tuple)) && !isempty(ex.args)
Expand All @@ -756,9 +759,13 @@ function repl_eval_ex(@nospecialize(ex), context_module::Module; limit_aggressiv
result = CC.InferenceResult(mi)
frame = CC.InferenceState(result, src, #=cache=#:no, interp)

# NOTE Use the fixed world here to make `REPLInterpreter` robust against
# potential invalidations of `Core.Compiler` methods.
Base.invoke_in_world(COMPLETION_WORLD[], CC.typeinf, interp, frame)
# With threaded completions, this inference is often done on the same `src` repeatedly,
# so wait for one to complete rather than multiple tasks doing the same work.
@lock inference_lock begin
# NOTE Use the fixed world here to make `REPLInterpreter` robust against
# potential invalidations of `Core.Compiler` methods.
Base.invoke_in_world(COMPLETION_WORLD[], CC.typeinf, interp, frame)
end

result = frame.result.result
result === Union{} && return nothing # for whatever reason, callers expect this as the Bottom and/or Top type instead
Expand Down

0 comments on commit 61d0213

Please sign in to comment.