错误[E0277]:不满足特征绑定`Vec <TokenStream2>:ToTokens`

Tey*_*dge 3 rust

我遇到了这个错误,并认为我的非常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>

Tey*_*dge 6

由于某种原因,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)