Advance the world at skipped :latestworld statements - #171
Merged
Merged
Conversation
Since Julia 1.12, top-level code advances its world only at `:latestworld` statements, and JuliaInterpreter is going to follow that instead of moving top-level frames to the latest world before every statement. Selective evaluation skips the statements it does not select, `:latestworld` ones included, so later statements could then read bindings in a world prior to their definition, or fail to call methods defined earlier in the thunk. `next_or_nothing!` now advances the world of the frame when it skips a `:latestworld` statement. This covers `selective_eval!` and the callers that skip statements themselves with `next_or_nothing!`, such as Revise. It is compatible with current JuliaInterpreter versions, whose top-level frames are always in the latest world anyway. Selecting the `:latestworld` statements in `lines_required!` instead would grow the slice: a selected statement pulls in its control flow and type definition, so branch conditions, loop iterations, and struct definitions that the slice does not need would get evaluated. Advancing the world while skipping has no effect on the program state, and matches native execution, which advances the world at every `:latestworld` it reaches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 3, 2026
aviatesk
added a commit
to timholy/Revise.jl
that referenced
this pull request
Oct 3, 2026
….2 (#1150) JuliaInterpreter 0.12 interprets the code passed to `Core.eval`, and on Julia 1.12 and later its top-level frames advance their world only at `:latestworld` statements, as native evaluation does. Neither changes what Revise does: - Revise evaluates top-level code with `Compiled()` and handles `Core.eval` itself in `methods_by_execution!`, so the recursive interpretation of `Core.eval` does not apply to it. - Revise skips the statements it does not select with `LoweredCodeUtils.next_or_nothing!`, which advances the world at skipped `:latestworld` statements since LoweredCodeUtils 3.10 (JuliaDebug/LoweredCodeUtils.jl#171), the first version that allows JuliaInterpreter 0.12. The patch release is needed for JET, which requires JuliaInterpreter 0.12 and whose test environment includes Revise: Revise 3.17.1 and earlier cap JuliaInterpreter at 0.11, so JET cannot move to 0.12 until a Revise release allows it.
aviatesk
added a commit
to timholy/Revise.jl
that referenced
this pull request
Oct 3, 2026
#1150 required JuliaInterpreter 0.12, but Revise works with both 0.11 and 0.12 without changes. Requiring 0.12 would hold Revise back at 3.17.1 in every environment that pins JuliaInterpreter to 0.11, e.g. one that also has Debugger.jl, which does not allow 0.12 yet, so those environments would miss later Revise releases. The compat now allows both again, and the LoweredCodeUtils bound goes back to 3.7. With JuliaInterpreter 0.12 the resolver still picks LoweredCodeUtils 3.10 or later, because earlier versions cap JuliaInterpreter at 0.11, and 3.10 advances the world at the `:latestworld` statements that Revise skips (JuliaDebug/LoweredCodeUtils.jl#171). With JuliaInterpreter 0.11, Revise runs with the same packages as 3.17.1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since Julia 1.12, top-level code advances its world only at
:latestworldstatements, and JuliaInterpreter is going to follow that instead of moving top-level frames to the latest world before every statement (JuliaDebug/JuliaInterpreter.jl#783). Selective evaluation skips the statements it does not select,:latestworldones included, so later statements could then read bindings in a world prior to their definition, or fail to call methods defined earlier in the thunk.next_or_nothing!now advances the world of the frame when it skips a:latestworldstatement. This coversselective_eval!and the callers that skip statements themselves withnext_or_nothing!, such as Revise. It is compatible with current JuliaInterpreter versions, whose top-level frames are always in the latest world anyway.Selecting the
:latestworldstatements inlines_required!instead would grow the slice: a selected statement pulls in its control flow and type definition, so branch conditions, loop iterations, and struct definitions that the slice does not need would get evaluated. Advancing the world while skipping has no effect on the program state, and matches native execution, which advances the world at every:latestworldit reaches.