I ran into this error and thought my very hacky workaround might be of use to someone.
Suppose I have some code (playground) which looks like this:
#[macro_use]
extern crate quote;
extern crate syn;
extern crate proc_macro2; // 1.0.24
fn main() {
let x = vec![
quote! {let x = 1;},
quote! {let x = 2;}
];
println!("{:#?}", quote! {
#x
});
}
This doesn't compile.
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Vec<TokenStream2>: ToTokens` is not satisfied
--> src/main.rs:11:23
|
11 | println!("{:#?}", quote! {
| _______________________^
12 | | #x
13 | | });
| |_____^ the trait `ToTokens` is not implemented for `Vec<TokenStream2>`
|
= note: required by `to_tokens`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
How do I use quote! to concatenate a Vec<proc_macro2::TokenStream>?
For some reason, quote::ToTokens isn't implemented for proc_macro2::TokenStream.
New answer
This is achievable using the quote! macro's syntax:
#[macro_use]
extern crate quote;
extern crate syn;
extern crate proc_macro2; // 1.0.24
fn main() {
let x = vec![
quote! {let x = 1;},
quote! {let x = 2;}
];
println!("{:#?}", quote! {
#(#x)*
});
}
Old answer
To fix this, one possible workaround is to use fold (playground link).
#[macro_use]
extern crate quote;
extern crate syn;
extern crate proc_macro2; // 1.0.24
fn main() {
let x = vec![
quote! {let x = 1;},
quote! {let x = 2;}
].iter().fold(quote! {}, |acc, new| quote! {#acc #new});
println!("{:#?}", quote! {
#x
});
}
This now compiles, producing the expected output:
TokenStream [
Ident {
sym: let,
},
Ident {
sym: x,
},
Punct {
char: '=',
spacing: Alone,
},
Literal {
lit: 1,
span: bytes(1..2),
},
Punct {
char: ';',
spacing: Alone,
},
Ident {
sym: let,
},
Ident {
sym: x,
},
Punct {
char: '=',
spacing: Alone,
},
Literal {
lit: 2,
span: bytes(3..4),
},
Punct {
char: ';',
spacing: Alone,
},
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With