Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error[E0277]: the trait bound `Vec<TokenStream2>: ToTokens` is not satisfied

Tags:

rust

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>?

like image 537
Teymour Aldridge Avatar asked Oct 23 '25 19:10

Teymour Aldridge


1 Answers

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,
    },
]
like image 191
Teymour Aldridge Avatar answered Oct 27 '25 02:10

Teymour Aldridge



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!