Can expressions containing syntax errors be used in macro calls?

I’d like to use an expression like this one in a macro call

struct A(B)
    x::Int
end

which gives a syntax error when called without the macro wrap:

julia> struct A(B)
           x::Int
       end
ERROR: syntax: invalid type signature around REPL[3]:1
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

but it works inside a macro:

julia> macro a(s) end

julia> @a struct A(B)
              x::Int
          end

here I’m using Julia 1.9, can I expect in this case that no syntax error will be thrown in some new Julia 1.x version?

This question came up to my mind since for example this other expression gives a syntax error even when called from a macro:

julia> @a begin
             const x::Int 
          end
ERROR: syntax: expected assignment after "const"
Stacktrace:
 [1] top-level scope
   @ none:1

So, more generally, when is it possible to use expressions with syntax errors in macro calls? Should this be avoided even if the sligthly tweaked syntax seems better?

2 Likes

As macros get parsed expressions, they should work on any syntax that does not raise a parse error:

julia> Meta.parse("""struct A(B)
           x::Int
       end""")
:(struct A(B)
      #= none:2 =#
      x::Int
  end)
julia> Meta.parse("""begin
           const x::Int
       end""")
ERROR: Base.Meta.ParseError("expected assignment after \"const\"")

If you really want to support currently illegal syntax (as defined by the parser), you would need a string macro and do the parsing yourself.

4 Likes

Didn’t expect that the answer was that simple and “well-behaved”, thank you @bertschi

1 Like