Hi folks, I have a question. How would one test a procedural macro from within the same crate?
A procedural macro takes a proc_macro::TokenStream
parameter. However, doing let foo: proc_macro::TokenStream = quote!{ 1 + 1 }.into()
throws a massive error, as does "1 + 1".parse().unwrap()
:
thread 'tests::basic_test' panicked at 'proc_macro::__internal::with_sess() called before set_parse_sess()!', libproc_macro/lib.rs:1448:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
1: std::sys_common::backtrace::print
2: std::panicking::default_hook::{{closure}}
3: std::panicking::default_hook
4: std::panicking::rust_panic_with_hook
5: std::panicking::begin_panic
6: proc_macro::Span::call_site
7: proc_macro2::imp::nightly_works::{{closure}}
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/unstable.rs:33
8: alloc::raw_vec::alloc_guard
at /Users/travis/build/rust-lang/rust/src/libstd/panicking.rs:310
9: __rust_maybe_catch_panic
10: alloc::raw_vec::alloc_guard
at /Users/travis/build/rust-lang/rust/src/libstd/panicking.rs:289
11: core::ptr::swap_nonoverlapping_bytes
at /Users/travis/build/rust-lang/rust/src/libstd/panic.rs:397
12: <syntax::parse::token::DelimToken as core::clone::Clone>::clone
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/unstable.rs:33
13: proc_macro2::imp::nightly_works::{{closure}}
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/unstable.rs:44
14: proc_macro2::TokenStream::_new_stable
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/lib.rs:107
15: jsx_macro::tests::basic_test
at jsx_macro/src/lib.rs:40
16: jsx_macro::__test::TESTS::{{closure}}
at jsx_macro/src/lib.rs:38
17: core::ops::function::FnOnce::call_once
at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
18: <F as alloc::boxed::FnBox<A>>::call_box
19: __rust_maybe_catch_panic
thread 'tests::basic_test' panicked at 'proc_macro::__internal::with_sess() called before set_parse_sess()!', libproc_macro/lib.rs:1448:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
1: std::sys_common::backtrace::print
2: std::panicking::default_hook::{{closure}}
3: std::panicking::default_hook
4: std::panicking::rust_panic_with_hook
5: std::panicking::begin_panic
6: proc_macro::__internal::with_sess
7: <proc_macro::TokenStream as core::str::FromStr>::from_str
8: core::str::<impl str>::chars
at /Users/travis/build/rust-lang/rust/src/libcore/str/mod.rs:3792
9: <proc_macro::TokenStream as core::clone::Clone>::clone
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/unstable.rs:97
10: <syntax::parse::token::DelimToken as core::clone::Clone>::clone
at /Users/travis/build/rust-lang/rust/src/libcore/convert.rs:396
11: <proc_macro::TokenStream as core::clone::Clone>::clone
at /Users/robertbalicki/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.6/src/lib.rs:151
12: <T as core::convert::Into<U>>::into
at /Users/travis/build/rust-lang/rust/src/libcore/convert.rs:396
13: jsx_macro::tests::basic_test
at jsx_macro/src/lib.rs:40
14: jsx_macro::__test::TESTS::{{closure}}
at jsx_macro/src/lib.rs:38
15: core::ops::function::FnOnce::call_once
at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
16: <F as alloc::boxed::FnBox<A>>::call_box
17: __rust_maybe_catch_panic
I can create a TokenStream manually, or test from another crate in the same workspace. The latter seems okay, but then the crate will not be published along with its tests.
What is the best practice here?
Thank you!
-R