我遇到了这个错误,并认为我的非常hacky的解决方法可能对某人有用。
假设我有一些代码(游乐场),如下所示:
#[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
});
}
Run Code Online (Sandbox Code Playgroud)
这不能编译。
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
Run Code Online (Sandbox Code Playgroud)
如何使用quote!连接 a Vec<proc_macro2::TokenStream>?
由于某种原因,quote::ToTokens未针对 实现proc_macro2::TokenStream。
新答案
这可以使用quote!宏的语法来实现:
#[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)*
});
}
Run Code Online (Sandbox Code Playgroud)
旧答案
要解决此问题,一种可能的解决方法是使用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;}
];
println!("{:#?}", quote! {
#(#x)*
});
}
Run Code Online (Sandbox Code Playgroud)
现在编译,产生预期的输出:
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,
},
]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2173 次 |
| 最近记录: |