-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Remove :globaldecl and :global lowered forms; add Core.declare_global #58279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
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
We accept `global` in a few more cases where we previously would reject it,
possibly complicating some macros:
julia> global v1
julia> begin
global v2
global v3
end
ERROR: syntax: misplaced "global" declaration
Stacktrace:
[1] top-level scope
@ REPL[2]:1
A new ephemeral form in lowering, `unused-only` (analogous to `toplevel-only`),
can be used to mark expressions that should not be assigned to variables, used
as call arguments, etc. It is more permissive than global's prior behaviour,
failing only when the value is used in non-tail position.
While converting assignments to globals, do not generate calls to declare_global if we are in a context where definition effects are not allowed (@generated function bodies). Previously, jl_declare_global would fail when performing the definition effects for a @generated function body: julia> @generated function foo(x) :(global bar = x) end foo (generic function with 1 method) julia> foo(1) ERROR: new strong globals cannot be created in a generated function. Declare them outside using `global x::Any`. Stacktrace: [1] top-level scope @ REPL[2]:1 Now, they fail when the assignment is performed and no global was previously declared: julia> @generated function foo(x) :(global bar = x) end foo (generic function with 1 method) julia> foo(1) ERROR: Global Main.bar does not exist and cannot be assigned. Note: Julia 1.9 and 1.10 inadvertently omitted this error check (JuliaLang#56933). Hint: Declare it using `global bar` inside `Main` before attempting assignment. Stacktrace: [1] macro expansion @ ./REPL[1]:1 [inlined] [2] foo(x::Int64) @ Main ./REPL[1]:1 [3] top-level scope @ REPL[2]:1
This succeeded by bypassing lowering previously.
Member
Author
|
TODOs:
|
Member
|
I implemented something similar to the Specifically, "global decls are not allowed in value position, except in tail position in a top level thunk". Which is a fairly minor but IMO safe relaxation to the current rules. If another decision gets made here I'm happy to adjust things, though. |
vtjnash
reviewed
Sep 16, 2025
vtjnash
added a commit
to vtjnash/LoweredCodeUtils.jl
that referenced
this pull request
Sep 16, 2025
Missed in f111efe, caught in trying to test JuliaLang/julia#58279.
vtjnash
added a commit
to vtjnash/LoweredCodeUtils.jl
that referenced
this pull request
Sep 17, 2025
Ensures all tests pass before and after JuliaLang/julia#58279 based on change from `Expr(:globaldecl, GlobalRef(M, S))` to `Core.declare_global(M, S, true)`, while still ignoring `Expr(:global, S)` from `struct` expanding to `strong=false`.
timholy
pushed a commit
to JuliaDebug/LoweredCodeUtils.jl
that referenced
this pull request
Sep 17, 2025
Missed in f111efe, caught in trying to test JuliaLang/julia#58279.
aviatesk
added a commit
to JuliaDebug/LoweredCodeUtils.jl
that referenced
this pull request
Sep 29, 2025
* handle new declare_global intrinsic Ensures all tests pass before and after JuliaLang/julia#58279 based on change from `Expr(:globaldecl, GlobalRef(M, S))` to `Core.declare_global(M, S, true)`, while still ignoring `Expr(:global, S)` from `struct` expanding to `strong=false`. * Update src/codeedges.jl --------- Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>
e05165a to
45729e7
Compare
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.
Overview
In the spirit of #58187 and #57965, this PR lowers more surface syntax to calls,
eliminating the lowered
:globaland:globaldecloperations in favour of asingle
Core.declare_globalbuiltin.Core.declare_globalhas the signature:strong = false, it has the effect ofglobal nameat the top level(see the description for
PARTITION_KIND_DECLARED).strong = true:typrovided: if no global exists, creates a strong global with typeAny. Has no effect if one already exists. This form is generated byglobal assignments with no type declaration.
typrovided: always creates a new global with the given type, failing ifone already exists with a different declared type.
Definition effects
One of the purposes of this change is to remove the definitions effects for
:globaland:globaldecl:julia/src/method.c
Lines 95 to 105 in d46b665
The eventual goal is to make all the definition effects for a method explicit
after lowering, simplifying interpreters for lowered IR.
Minor lowering changes
globalpermitted in more placesAdds a new ephemeral syntax head,
unused-only, to wrap expressions whoseresult should not be used. It generates the
misplaced "global" declarationerror, and is slightly more forgiving than the old restriction. This was
necessary to permit
globalto be lowered in all contexts. Old:New:
globalalways loweredThis change maintains support for some expressions that cannot be produced by
the parser (similar to
Expr(:const, :foo)):julia/test/precompile.jl
Line 2036 in d46b665
This used to work by bypassing lowering but is now lowered to the appropriate
declare_globalcall.Generated functions
After lowering the body AST returned by a
@generatedfunction, the definitioneffects are still performed. Instead of relying on a check in
jl_declare_globalto fail during this process,GeneratedFunctionStubnowwraps the AST in a new Expr head,
Expr(:toplevel_pure, ...), indicatinglowering should not produce toplevel side effects.
Currently, this is used only to omit calls to
declare_globalfor generatedfunctions, but it could also be used to improve the catch-all error message when
lowering returns a thunk (telling the user if it failed because of a closure,
generator, etc), or even to support some closures by making them opaque.
The error message for declaring a global as a side effect of a
@generatedfunction AST has changed, because it now fails when the assignment to an
undeclared global is performed. Old:
New:
Examples of the new lowering
Toplevel weak global:
Toplevel strong global declaration with type:
Toplevel strong global assignment:
Toplevel strong global assignment with type:
Global assignment inside function (call to
declare_globalhoisted to toplevel):