Skip to content
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

Fix error message when using const inside a function, require the LHS to be global, and prohibit "const x[] = 1" #57470

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

xal-0
Copy link
Contributor

@xal-0 xal-0 commented Feb 19, 2025

The changes to const resulted in confusing error messages when it was used
inside a function (#57334). On 1.11.3:

julia> function f()
           const x = 1
       end
ERROR: syntax: unsupported `const` declaration on local variable around REPL[1]:2
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

On nightly:

julia> function f()
           const x = 1
       end
ERROR: syntax: World age increment not at top level
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

In prior versions, we also accepted confused expressions like:

x = Ref(1)
const x[] = 1

This change adds a new error messages explicitly prohibiting const where the
left hand side is not declaring variables:

ERROR: syntax: `const` left hand side "x[]" contains non-variables around REPL[2]:1
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

Finally, #54773 made const stop participating in scope resolution (the left
hand side was always taken to be in global scope). Some expressions that were
prohibited started being accepted:

In 1.11.3:

julia> let
           const x = 1
       end
ERROR: syntax: unsupported `const` declaration on local variable around REPL[1]:2
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

Nightly:

julia> let
           const x = 1
       end
1

This change rejects const unless the variable would be in global scope
(global const would be required in the example), so we don't lose the
ability to make const in local scope meaningful later.

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Minor nit with this error though:

julia> const (x{T},) = T
ERROR: syntax: `const` left hand side "SSAValue(81)" contains non-variables around REPL[13]:1

@xal-0 xal-0 added compiler:lowering Syntax lowering (compiler front end, 2nd stage) bugfix This change fixes an existing bug error messages Better, more actionable error messages labels Feb 19, 2025
@xal-0
Copy link
Contributor Author

xal-0 commented Feb 19, 2025

Argh, this is actually a regression.

1.11.3:

julia> const X{T}, Y{U} = [Int, Int]
2-element Vector{DataType}:
 Int64
 Int64

This:

julia> const X{T}, Y{U} = [Int, Int]
ERROR: syntax: `const` left hand side "SSAValue(4)" contains non-variables around REPL[1]:1
Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

I'll need to think of a way to handle this.

Also update some tests that used @test with a quote containing `const`, which
cannot be spliced into a function.
@xal-0 xal-0 marked this pull request as draft February 22, 2025 00:34
Modifies the handling of the 3-argument "lowered const" so `const x = y`
participates in scope resolution again (JuliaLang#56613); we treat (const x y) as an
assignment form, producing the "unsupported `const` declaration on local
variable" error if the usual scope rules would not make x global.

At the top level, these should succeed:

    const x = 1
    begin
        const x = 1
    end
    let
        const global x = 1
    end

Each of the following should fail:

    # ERROR: syntax: unsupported `const` declaration on local variable around REPL[1]:2
    let
        const x = 1
    end

    # ERROR: syntax: unsupported `const` declaration on local variable around REPL[1]:2
    function f()
        const x = 1
    end

This also amkes the use of `const global` inside a function body produce the
original, specific error message rather than a generic "World age increment not
at top level" error (JuliaLang#57334):

    # ERROR: syntax: `global const` declaration not allowed inside function around REPL[1]:2
    function f()
        global const x = 1
    end

Issue JuliaLang#57334 revealed we silently accept `const` expressions writing to
variables.  These now fail with a new error message:

    a = [1, 2]
    # ERROR: syntax: cannot declare "a[1]" `const` around REPL[1]:2
    const a[1] = 3

The bulk of these changes track const-ness through the functions called by
expand-assignment, since each of the three types of LHS is affect differently:
- ordinary variables become `const`, producing error if not global
- `X{T} = ...` forces X to be `const`, rather than the defaulting to being
  implicitly const only if in global scope.
- `f() = ...` ignores `const`.
@xal-0 xal-0 force-pushed the const-function-errors branch from 33184ba to b45c8e0 Compare February 22, 2025 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix This change fixes an existing bug compiler:lowering Syntax lowering (compiler front end, 2nd stage) error messages Better, more actionable error messages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants