quote
quote copied to clipboard
Unit struct or const cannot be interpolated inside repetition
use proc_macro2::{Ident, Span, TokenStream};
use quote::{ToTokens, quote};
struct Private;
impl ToTokens for Private {
fn to_tokens(&self, tokens: &mut TokenStream) {
Ident::new("private", Span::call_site()).to_tokens(tokens);
}
}
fn main() {
let _ = quote! {
// Okay
... #Private ...
};
let iter = vec!['0', '1', '2'];
let _ = quote! {
// Fail
#(#Private #iter)*
};
}
error[E0530]: let bindings cannot shadow unit structs
--> src/main.rs:21:12
|
4 | struct Private;
| --------------- the unit struct `Private` is defined here
...
21 | #(#Private #iter)*
| ^^^^^^^ cannot be named the same as a unit struct
The non-repetition expands to something like this, which is fine:
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_dot3(&mut _s);
::quote::ToTokens::to_tokens(&Private, &mut _s);
::quote::__private::push_dot3(&mut _s);
_s
}
The repetition expands to:
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::ThereIsNoIteratorInRepetition;
#[allow(unused_mut)]
let (mut Private, i) = Private.quote_into_iter();
let has_iter = has_iter | i;
#[allow(unused_mut)]
let (mut iter, i) = iter.quote_into_iter();
let has_iter = has_iter | i;
let _: ::quote::__private::HasIterator = has_iter;
while true {
let Private = match Private.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
let iter = match iter.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&Private, &mut _s);
::quote::ToTokens::to_tokens(&iter, &mut _s);
}
}
_s
}
where let (mut Private, i) = Private.quote_into_iter() is the source of "let bindings cannot shadow unit structs".
This correct expansion is probably achievable:
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::ThereIsNoIteratorInRepetition;
let (var, i) = Private.quote_into_iter();
let has_iter = has_iter | i;
{
fn Private() {}
#[allow(unused_mut)]
let mut Private = var;
let (var, i) = iter.quote_into_iter();
let has_iter = has_iter | i;
{
fn iter() {}
#[allow(unused_mut)]
let mut iter = var;
let _: ::quote::__private::HasIterator = has_iter;
while true {
let Private = match Private.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
let iter = match iter.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&Private, &mut _s);
::quote::ToTokens::to_tokens(&iter, &mut _s);
}
}
}
}
_s
}