简体   繁体   中英

How do I accept syntactically invalid input in a procedural macro?

I thought that procedural macros only had to have lexically-valid input, but it seems like all input must also parse as Rust code, unless I'm doing something wrong.

The RFC says:

By operating on tokens, code passed to procedural macros does not need to satisfy the Rust parser, only the lexer.

As soon as the input involves invalid Rust syntax I get parse errors.

Consider the following procedural macro:

#[proc_macro_attribute]
pub fn my_macro(_: TokenStream, _: TokenStream) -> TokenStream {
    TokenStream::from(quote! {})
}

when run on:

#[my_macro]
fn test() { * } // lexically valid but syntactically invalid

I get the error:

error: expected expression, found `}`
  --> blah.rs:38:2
   |
33 | #[logic] fn omg () { * }
   |                        ^ expected expression

cargo-expand shows that the macro correctly deletes the function. Shouldn't it thus stop any parse error?

What am I doing wrong?

By reading the proc-macro RFC closely, I noticed that this is a documented behavior of attribute-like proc-macros:

The second argument is the tokens for the AST node the attribute is placed on. Note that in order to compute the tokens to pass here, the compiler must be able to parse the code the attribute is applied to.

To work around this it seems like the only choice is to use a function-like macro which does not have this limitation, which changes the syntax slightly, it's too bad but not the end of the world for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM