cargo expand in some case deletes nested braces that are syntactically meaningful
Closed this issue · 1 comments
We had a buggy procedural macro that when run on the following enum
enum Data {
A,
}
would try to create a value by generating the expression Data :: A { {} }
, which is syntactically incorrect. The problem is that cargo expand
was displaying the same expression as Data :: A {}
, we guess because of some simplification procedure which, however, in this case, was transforming a syntactically incorrect sequence of tokens into a correct one. Thus, we were seeing errors in the compiler, but the code returned by cargo expand would compile without problem. Printing manually the output of the macro highlighted the problem above.
A minimized example is as follows: consider the following proc macro:
#[proc_macro_derive(Test)]
pub fn test_derive(input: TokenStream) -> TokenStream {
let out = quote!{ fn test() { let _ = Data::A {{}}; } }.into();
eprintln!("out: {}", out);
out
}
and the source code
#[derive(Test)]
enum Data {
A,
}
When one invokes cargo expand, the output is of eprintln!
is
out: fn test() { let _ = Data :: A { {} } ; }
whereas the output of cargo expand is
enum Data { A, }
fn test() { let _ = Data::A {}; }
and the compiler complains with
error: expected identifier, found `{`
|
9 | #[derive(Test)]
| ^^^^
| |
| expected identifier
| while parsing this struct
|
= note: this error originates in the derive macro `Test` (in Nightly builds, run with -Z macro-backtrace for more info)
I don't think this is a cargo-expand issue, since you would get the same output from cargo rustc -- -Zunpretty=expanded
which does not involve cargo-expand.