JuliaLang / julia

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

Callsite `@inline` doesn't like `val` argument #48910

Open maleadt opened 1 year ago

maleadt commented 1 year ago

MWE:

macro foo()
    quote
        function bar(val)
            @inline identity(nothing)
        end
    end
end
@foo
ERROR: LoadError: syntax: local variable name "#9#val" conflicts with an argument

Using any other variable name than val makes this work. Probably suspect: https://github.com/JuliaLang/julia/blob/7eb961588f204e1866aea0bdee63f5dd91d42ac3/base/expr.jl#L846-L859

TakshDhabalia commented 1 year ago

anyone working on this issue ? would like to talk about this and make changes Thanks!

maleadt commented 1 year ago

The issue isn't assigned, so I don't think anybody is working on this.

simeonschaub commented 1 year ago

This is probably not a great first issue though, since the source is likely a macro hygiene bug

xlxs4 commented 1 year ago

For completeness' sake annotate_meta_def_or_block is also called when @noinline is used, so this error is present if you substitute @inline with @noinline. The problem has to do with annotate_meta_def_or_block itself. The expanded macro will be

quote
    function var"#<x gensym>#<function name>"(var"#<y gensym>#<argument name>")
        begin
            $(Expr(:<meta>, true))
            local var"#<z gensym>#val" = <escaped expression>
            $(Expr(:<meta>, false))
            var"#<z gensym>#val"
        end
    end
end

The gensym for the argument in the case of val is the same inside the begin block

xlxs4 commented 1 year ago

Same issue for @inbounds, defined as:

macro inbounds(blk)
    return Expr(:block,
        Expr(:inbounds, true),
        Expr(:local, Expr(:(=), :val, esc(blk))),
        Expr(:inbounds, :pop),
        :val)
end
xlxs4 commented 1 year ago

I wonder, why use true/false for @(no)inline, but true/:pop for @inbounds?

xlxs4 commented 1 year ago

I think this is unrelated to hygiene, and is intended behavior, as it has to do with what gets escaped and what doesn't. If that's the case, we can leave everything as-is, or prefix val with an underscore? In case we'd do the latter, we should remember to also prefix the respective variable in @noinline and @inbounds.

Pangoraw commented 1 year ago

Probably related to https://github.com/JuliaLang/julia/pull/43151. @foo and @inline share the same gensym for val.