Hi all,
I have a question: am i seeing a bug in the macro expander, or am I misunderstanding its usage?
I’m implementing a macro which delegates (most of) its work to another macro, and I’m running into some issues around escaping. Here is a minimal version which I think should work, based on the discussion in this related issue, but isn’t:
module Retest
using Test
macro retestset1(args...)
:(@testset($((esc(a) for a in args)...))) # should work?
end
macro retestset2(args...)
esc(:($Test.@testset($(args...)))) # works but eww?
end
end
Note that this is a completely generic problem—the fact that @testset
is the macro being delegated to is just a detail, and we should be able to “wrap” any macro we want without changes to that macro’s implementation.
Here’s the error trying to invoke @retesetse1
:
julia> Retest.@retestset1 begin end
ERROR: LoadError: Expected begin/end block or for loop as argument to @testset
Stacktrace:
[1] @testset(::LineNumberNode, ::Module, ::Vararg{Any,N} where N) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1041
in expression starting at /Volumes/GoogleDrive/My Drive/Retest/src/Retest.jl:6
A little investigation indicates that the issue is that the expressions passed to @testset
still contain escape nodes, which it chokes on. Here’s an even simpler example illustrating the phenomenon:
julia> macro foo(arg)
@show arg
end
@foo (macro with 1 method)
julia> macro bar(arg)
:(@foo($(esc(arg))))
end
@bar (macro with 1 method)
julia> @bar 1+1
arg = :($(Expr(:escape, :(1 + 1))))
2
Is this how the macroexpander is supposed to operate? If so, how do I reconcile this with the advice from @Tamas_Papp in Call a macro within a macro - #6 by findmyway?
Invoking @retestset2
on the other hand works fine, including picking up variables from the calling environment:
julia> let x=1
Retest.@retestset2 begin @assert x == 1 end
end
Test Summary: |
test set | No tests
Test.DefaultTestSet("test set", Any[], 0, false)
But it seems like a bit of a kludge. Any help appreciated.