Using @assert in another macro

I’m attempting to use @assert in the definition of another macro, and I cannot get the message associated with the AssertionError to be formed correctly. Here’s an MWE:

macro my_assert(arg)
    return :(@assert $(esc(arg)))
end

@assert false    # returns ERROR: AssertionError: false
@my_assert false # returns ERROR: AssertionError: $(Expr(:escape, false))

This happens because esc(x) is represented explicitly in the AST (Abstract Syntax Tree) as Expr(:escape, x). In your wrapper macro you pass esc(arg) as an argument to another macro (@assert), so @assert ends up seeing the escape node and prints it in the AssertionError.

Minimal fix: don’t escape the argument, escape the whole returned expression so the expander removes :escape before @assert is processed.

macro my_assert(arg)
    esc(:(@assert $arg))
end

Fully aligned with @assert (supports @assert <cond> <msg>):

macro my_assert(args...)
    esc(:(@assert $(args...)))
end
julia> @my_assert false "🚫🚫🚫"
ERROR: AssertionError: 🚫🚫🚫

That’s perfect. Thank you!