@@ -158,25 +158,49 @@ function fixup_macro_name(ctx::MacroExpansionContext, ex::SyntaxTree)
158158 end
159159end
160160
161- function eval_macro_name (ctx:: MacroExpansionContext , mctx:: MacroContext , ex:: SyntaxTree )
162- # `ex1` might contain a nontrivial mix of scope layers so we can't just
163- # `eval()` it, as it's already been partially lowered by this point.
164- # Instead, we repeat the latter parts of `lower()` here.
165- ex1 = expand_forms_1 (ctx, fixup_macro_name (ctx, ex))
166- ctx2, ex2 = expand_forms_2 (ctx, ex1)
167- ctx3, ex3 = resolve_scopes (ctx2, ex2)
168- ctx4, ex4 = convert_closures (ctx3, ex3)
169- ctx5, ex5 = linearize_ir (ctx4, ex4)
161+ function _eval_dot (world:: UInt , mod, ex:: SyntaxTree )
162+ if kind (ex) === K " ."
163+ mod = _eval_dot (world, mod, ex[1 ])
164+ ex = ex[2 ]
165+ end
166+ kind (ex) in KSet " Identifier Symbol" && mod isa Module ?
167+ Base. invoke_in_world (world, getproperty, mod, Symbol (ex. name_val)) :
168+ nothing
169+ end
170+
171+ # If macroexpand(ex[1]) is an identifier or dot-expression, we can simply grab
172+ # it from the scope layer's module in ctx.macro_world. Otherwise, we need to
173+ # eval arbitrary code (which, TODO : does not use the correct world age, and it
174+ # isn't clear the language is meant to support this).
175+ function eval_macro_name (ctx:: MacroExpansionContext , mctx:: MacroContext , ex0:: SyntaxTree )
170176 mod = current_layer (ctx). mod
171- expr_form = to_lowered_expr (ex5 )
177+ ex = fixup_macro_name (ctx, expand_forms_1 (ctx, ex0) )
172178 try
173- # Using Core.eval here fails when precompiling packages since we hit the
174- # user-facing error (in `jl_check_top_level_effect`) that warns that
175- # effects won't persist when eval-ing into a closed module.
176- # `jl_invoke_julia_macro` bypasses this by calling `jl_toplevel_eval` on
177- # the macro name. This is fine assuming the first argument to the
178- # macrocall is effect-free.
179- ccall (:jl_toplevel_eval , Any, (Any, Any), mod, expr_form)
179+ if kind (ex) === K " Value"
180+ ! (ex. value isa GlobalRef) ? ex. value :
181+ Base. invoke_in_world (ctx. macro_world, getglobal,
182+ ex. value. mod, ex. value. name)
183+ elseif kind (ex) === K " Identifier"
184+ layer = get (ex, :scope_layer , nothing )
185+ if ! isnothing (layer)
186+ mod = ctx. scope_layers[layer]. mod
187+ end
188+ Base. invoke_in_world (ctx. macro_world, getproperty,
189+ mod, Symbol (ex. name_val))
190+ elseif kind (ex) === K " ." &&
191+ (ed = _eval_dot (ctx. macro_world, mod, ex); ! isnothing (ed))
192+ ed
193+ else
194+ # `ex` might contain a nontrivial mix of scope layers so we can't
195+ # just `eval()` it, as it's already been partially lowered by this
196+ # point. Instead, we repeat the latter parts of `lower()` here.
197+ ctx2, ex2 = expand_forms_2 (ctx, ex)
198+ ctx3, ex3 = resolve_scopes (ctx2, ex2)
199+ ctx4, ex4 = convert_closures (ctx3, ex3)
200+ ctx5, ex5 = linearize_ir (ctx4, ex4)
201+ expr_form = to_lowered_expr (ex5)
202+ ccall (:jl_toplevel_eval , Any, (Any, Any), mod, expr_form)
203+ end
180204 catch err
181205 throw (MacroExpansionError (mctx, ex, " Macro not found" , :all , err))
182206 end
0 commit comments