Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion JuliaLowering/src/macro_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ function expand_macro(ctx, ex)
# method was defined (may be different from `parentmodule(macfunc)`)
mod_for_ast = lookup_method_instance(macfunc, macro_args,
ctx.macro_world).def.module
expanded = fix_toplevel_expansion(ctx, expanded, mod_for_ast, macro_loc)
new_layer = ScopeLayer(length(ctx.scope_layers)+1, mod_for_ast,
current_layer_id(ctx), true)
push_layer!(ctx, mod_for_ast, true)
Expand Down Expand Up @@ -454,6 +453,9 @@ function expand_forms_1(ctx::MacroExpansionContext, ex::SyntaxTree)
end
elseif k == K"macrocall"
expand_macro(ctx, ex)
elseif k == K"toplevel" && length(ctx.scope_layer_stack) > 1
fix_toplevel_expansion(ctx, ex, current_layer(ctx).mod,
source_location(LineNumberNode, ex))
elseif k == K"module" || k == K"toplevel" || k == K"inert"
# Remove scope layer information from any inert syntax which survives
# macro expansion so that it doesn't contaminate lowering passes which
Expand Down
17 changes: 17 additions & 0 deletions JuliaLowering/test/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -483,4 +483,21 @@ end
@test_broken JuliaLowering.eval(test_mod, code) == ("outer x", "inner x")
end

@testset "toplevel macro hygiene" begin
@eval test_mod module MacroMod
macro escaped_toplevel()
esc(Expr(:toplevel, :(@__MODULE__)))
end
macro inner_escaped_toplevel()
Expr(:toplevel, esc(:(@__MODULE__)))
end
macro unescaped_toplevel()
Expr(:toplevel, :(@__MODULE__))
end
end
@test JuliaLowering.include_string(test_mod, "MacroMod.@escaped_toplevel") === test_mod
@test JuliaLowering.include_string(test_mod, "MacroMod.@inner_escaped_toplevel") === test_mod
@test JuliaLowering.include_string(test_mod, "MacroMod.@unescaped_toplevel") === test_mod.MacroMod
end

end