Repository: JuliaLang/julia
File: JuliaLowering/src/syntax_macros.jl (Julia)

Code before:
# extensions":
#
# * They emit syntactic forms with special `Kind`s and semantics known to
#   lowering
# * There is no other Julia surface syntax for these `Kind`s.

# In order to implement these here without getting into bootstrapping problems,
# we just write them as plain old macro-named functions and add the required
# __context__ argument ourselves.
#
# TODO: @inline, @noinline, @inbounds, @simd, @ccall, @assume_effects
#
# TODO: Eventually move these to proper `macro` definitions and use
# `JuliaLowering.include()` or something. Then we'll be in the fun little world
# of bootstrapping but it shouldn't be too painful :)

function _apply_nospecialize(ctx, ex)
    k = kind(ex)
    if k == K"Identifier" || k == K"Placeholder" || k == K"tuple"
        setmeta(ex; nospecialize=true)
    elseif k == K"..." || k == K"::" || k == K"=" || k == K"kw"
        # The @nospecialize macro is responsible for converting K"=" to K"kw".
        # Desugaring uses this helper internally, so we may see K"kw" too.
        if k == K"::" && numchildren(ex) == 1
            ex = @ast ctx ex [K"::" "_"::K"Placeholder" ex[1]]
        elseif k == K"="
            ex = @ast ctx ex [K"kw" ex[1] ex[2]]
        end
        mapchildren(c->_apply_nospecialize(ctx, c), ctx, ex, 1:1)
    else
        throw(LoweringError(ex, "Invalid function argument"))
    end
end

function Base.var"@nospecialize"(__context__::MacroContext, ex, exs...)
    # TODO support multi-arg version properly
    _apply_nospecialize(__context__, ex)
end

function Base.var"@atomic"(__context__::MacroContext, ex)
    @chk kind(ex) == K"Identifier" || kind(ex) == K"::" (ex, "Expected identifier or declaration")
    @ast __context__ __context__.macrocall [K"atomic" ex]
end

function Base.var"@label"(__context__::MacroContext, ex)
    @chk kind(ex) == K"Identifier"
    @ast __context__ ex ex=>K"symbolic_label"
end

function Base.var"@goto"(__context__::MacroContext, ex)
    @chk kind(ex) == K"Identifier"

Review comment (suggestion):
```suggestion
        elseif k == K"=" && numchildren(ex) == 2
```

Code after:
# extensions":
#
# * They emit syntactic forms with special `Kind`s and semantics known to
#   lowering
# * There is no other Julia surface syntax for these `Kind`s.

# In order to implement these here without getting into bootstrapping problems,
# we just write them as plain old macro-named functions and add the required
# __context__ argument ourselves.
#
# TODO: @inline, @noinline, @inbounds, @simd, @ccall, @assume_effects
#
# TODO: Eventually move these to proper `macro` definitions and use
# `JuliaLowering.include()` or something. Then we'll be in the fun little world
# of bootstrapping but it shouldn't be too painful :)

function _apply_nospecialize(ctx, ex)
    k = kind(ex)
    if k == K"Identifier" || k == K"Placeholder" || k == K"tuple"
        setmeta(ex; nospecialize=true)
    elseif k == K"..." || k == K"::" || k == K"=" || k == K"kw"
        # The @nospecialize macro is responsible for converting K"=" to K"kw".
        # Desugaring uses this helper internally, so we may see K"kw" too.
        if k == K"::" && numchildren(ex) == 1
            ex = @ast ctx ex [K"::" "_"::K"Placeholder" ex[1]]
        elseif k == K"=" && numchildren(ex) === 2
            ex = @ast ctx ex [K"kw" ex[1] ex[2]]
        end
        mapchildren(c->_apply_nospecialize(ctx, c), ctx, ex, 1:1)
    else
        throw(LoweringError(ex, "Invalid function argument"))
    end
end

function Base.var"@nospecialize"(__context__::MacroContext, ex, exs...)
    # TODO support multi-arg version properly
    _apply_nospecialize(__context__, ex)
end

# TODO: support all forms that the original supports
# function Base.var"@atomic"(__context__::MacroContext, ex)
#     @chk kind(ex) == K"Identifier" || kind(ex) == K"::" (ex, "Expected identifier or declaration")
#     @ast __context__ __context__.macrocall [K"atomic" ex]
# end

function Base.var"@label"(__context__::MacroContext, ex)
    @chk kind(ex) == K"Identifier"
    @ast __context__ ex ex=>K"symbolic_label"
end

function Base.var"@goto"(__context__::MacroContext, ex)