From the Syn documentation:
Syn operates on the token representation provided by the
proc-macro2crate from crates.io rather than using the compiler's built inproc-macrocrate directly. This enables code usingSynto execute outside of the context of a procedural macro, such as in unit tests orbuild.rs
I am trying to enable unit testing for some Syn functions, however I can't get it to work no matter what I have tried. It does not work with the proc_macro2::TokenStream type, but it won't work with the proc_macro::TokenStream because we are not in a proc-macro context.
use quote::quote;
use syn;
fn test() {
// let stream: syn::export::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
let stream: proc_macro2::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
// let item = parse_macro_input!(stream as Item); // doesn't work
let item = syn::parse(stream).unwrap();
}
fn main() {
test();
}
Any help on how to test syn functions outside of the proc-macro context would be appreciated. I am aware of the trybuild crate, but I would like to be able to unit test the macro's functions first.
Yes, and that's the whole point! Crates that export procedural macros can't export anything else, but
proc_macrocan only be used in crates that export macros. This is the reason whyproc_macro2exists in the first place.You need to use multiple crates in order to write tests for code that uses
synandproc_macro2:#[proc_macro]etc., and does very little except convert aproc_macro::TokenStreaminto aproc_macro2::TokenStreamand vice versa.proc_macro2but notproc_macro. Your tests can go in here.The error you are seeing is because
syn::parseaccepts aproc_macro::TokenStream. You can instead usesyn::parse2, which is identical except that it accepts aproc_macro2::TokenStream.