This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
Procedural macro reimplementation of quote!
to resolve longstanding limitations #8
Closed
Description
Originally filed as dtolnay/quote#82 but I would like this to begin its life as a separate library.
The current macro_rules-based quote macro has the limitation that duplicate interpolations inside of a repetition are not allowed. quote! { #a #a }
works but quote! { #(#a #a)* }
does not work. The reason boils down to macro_rules macros having no way to determine that two identifiers are equal.
Some background on the quote macro:
-
quote! { #a #a }
expands to:{ let mut _s = TokenStream::new(); let _span = Span::call_site(); ToTokens::to_tokens(&a, &mut _s); ToTokens::to_tokens(&a, &mut _s); _s }
-
quote! { #(#a)* }
expands to:{ let mut _s = TokenStream::new(); let _span = Span::call_site(); for a in a { ToTokens::to_tokens(&a, &mut _s); } _s }
-
quote! { #(#a #b)* }
expands to:{ let mut _s = TokenStream::new(); let _span = Span::call_site(); for (a, b) in a.into_iter().zip(b) { ToTokens::to_tokens(&a, &mut _s); ToTokens::to_tokens(&b, &mut _s); } _s }
-
quote! { #(#a #a)* }
expands to:{ let mut _s = TokenStream::new(); let _span = Span::call_site(); for (a, a) in a.into_iter().zip(a) { ToTokens::to_tokens(&a, &mut _s); ToTokens::to_tokens(&a, &mut _s); } _s }
That last expansion is illegal so the quote invocation fails.
error[E0416]: identifier `a` is bound more than once in the same pattern
--> src/main.rs:12:17
|
12 | for (a, a) in a.into_iter().zip(a) {
| ^ used in a pattern more than once
In an implementation as a procedural macro we would want that invocation to expand instead as:
{
let mut _s = TokenStream::new();
let _span = Span::call_site();
for a in a {
ToTokens::to_tokens(&a, &mut _s);
ToTokens::to_tokens(&a, &mut _s);
}
_s
}
Metadata
Metadata
Assignees
Labels
No labels