我认为过程宏只需要有词法上有效的输入,但似乎所有的输入都必须解析作为Rust代码,除非我做错了什么。
RFC说:
通过操作令牌,传递给过程性宏的代码不需要满足Rust解析器,只需要满足词法分析器。
只要输入涉及到无效的Rust语法,我就会得到解析错误。
考虑以下过程宏:
#[proc_macro_attribute]
pub fn my_macro(_: TokenStream, _: TokenStream) -> TokenStream {
TokenStream::from(quote! {})
}
运行时:
#[my_macro]
fn test() { * } // lexically valid but syntactically invalid
我得到错误:
error: expected expression, found `}`
--> blah.rs:38:2
|
33 | #[logic] fn omg () { * }
| ^ expected expression
cargo-expand
显示宏正确删除了函数。难道它不应该停止任何解析错误吗?
我做错了什么?
通过仔细阅读proc-macro RFC,我注意到这是类属性proc-macros的文档行为:
第二个参数是属性所在的AST节点的令牌。请注意,为了计算要在这里传递的令牌,编译器必须能够解析应用该属性的代码。
要解决这个问题,似乎唯一的选择是使用一个类似函数的宏,它没有这个限制,它稍微改变了语法,这太糟糕了,但对我来说并不是世界末日。