JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.82k stars 5.49k forks source link

Valid const declaration with where on a new line is considered invalid syntax #55898

Open Tortar opened 1 month ago

Tortar commented 1 month ago

I'm updating one package and something strange is happening, I think it should be a bug in Julia. this is the PR in question https://github.com/Tortar/HybridStructs.jl/pull/3, the test code is valid and can be executed, but it actually throws in Julia 1.10 and Julia 1.11

ERROR: LoadError: syntax: unsupported `const` declaration on local variable around /home/runner/work/HybridStructs.jl/HybridStructs.jl/src/HybridStructs.jl:86
Stacktrace:
 [1] top-level scope
   @ ~/work/HybridStructs.jl/HybridStructs.jl/test/runtests.jl:11
 [2] include(fname::String)
   @ Base.MainInclude ./client.jl:489
 [3] top-level scope
   @ none:6
in expression starting at /home/runner/work/HybridStructs.jl/HybridStructs.jl/test/runtests.jl:11
Package HybridStructs errored during testing
Error: Process completed with exit code 1.

and on nightly it constructs an invalid name B = Union{B_Immut{X}, B_Mut{X}}. See https://github.com/Tortar/HybridStructs.jl/actions/runs/11061551686/job/30734388810.

For a reproducer you can dev that branch and execute

using HybridStructs
@hybrid struct B{X} end # this errors

while you can see that this is valid code

julia> @macroexpand @hybrid struct B{X} end
quote
    #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:83 =#
    mutable struct B_Mut{X} <: Any
        #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:49 =#
        #= REPL[6]:1 =#
    end
    #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:84 =#
    struct B_Immut{X} <: Any
        #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:53 =#
        #= REPL[6]:1 =#
    end
    #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:85 =#
    const B = Union{B_Immut{X}, B_Mut{X}} where X
    #= /home/bob/.julia/dev/HybridStructs/src/HybridStructs.jl:86 =#
    nothing
end

Also, this instead works

julia> using HybridStructs
julia> @hybrid struct B end
Tortar commented 1 month ago

I got an MWE:

julia> macro repro()
           e = :(const B = F{X} 
               where {X})
           return esc(quote
               struct F{X} end
               $e 
           end)
       end
@repro (macro with 1 method)

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

julia> macro repro()
           e = :(const B = F{X} where {X})
           return esc(quote
               struct F{X} end
               $e 
           end)
       end
@repro (macro with 1 method)

julia> @repro
F

Seems like the newline character breaks the expression when in a macro somehow

Tortar commented 1 month ago

On nightly this works but it constructs an invalid name

julia> macro repro()
           e = :(const B = F{X} 
               where {X})
           return esc(quote
               struct F{X} end
               $e 
           end)
       end
@repro (macro with 1 method)

julia> @repro
F

julia> B
F{X}