Procedural macro API is used outside of a procedural macro

Any idea why I get the error "procedural macro API is used outside of a procedural macro"?

I have a proc_macro crate, which converts two proc_macro::TokenStream to proc_macro2::TokenStream and passes them to an external library:

use proc_macro2::TokenStream as TokenStream2;

#[proc_macro_attribute]
pub fn requires(attr: TokenStream, item: TokenStream) -> TokenStream {
    PLUGIN.requires(TokenStream2::from(attr), TokenStream2::from(item)).into()
}

The external library (PLUGIN) uses the quote and proc-macro2 crates. The high-level code is the following:

fn requires(attr: TokenStream, item: TokenStream) -> TokenStream {
    add_print_statement(attr, item)
}

fn add_print_statement(attr: TokenStream, item: TokenStream) -> TokenStream {
   let mut item = match syn::parse2::<Item>(item) { /* ... */ }
    // ... mutate `item`
    item.into_token_stream()
} // this is line 45

As far as I know, the proc_macro API mentioned in the error is only used in the first crate, not in the library. However, the stack trace shows that the panic originates from the end of add_print_statement.

The full stack trace of the panic that I get at compile time, when the procedural macro is executed, is this:

thread '<unnamed>' panicked at 'procedural macro API is used outside of a procedural macro', src/libproc_macro/bridge/client.rs:315:17
stack backtrace:
   0:     0x7f03c9050b7b - backtrace::backtrace::libunwind::trace::h5dfa5d4c5feed6dc
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1:     0x7f03c9050b7b - backtrace::backtrace::trace_unsynchronized::hb731fe64f3fa469f
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2:     0x7f03c9050b7b - std::sys_common::backtrace::_print::hf4fd45fe7ae4a250
                               at src/libstd/sys_common/backtrace.rs:47
   3:     0x7f03c9050b7b - std::sys_common::backtrace::print::h31646c3786c57441
                               at src/libstd/sys_common/backtrace.rs:36
   4:     0x7f03c9050b7b - std::panicking::default_hook::{{closure}}::hda785e768c746ae7
                               at src/libstd/panicking.rs:200
   5:     0x7f03c9050857 - std::panicking::default_hook::h0c4b76f338614ef1
                               at src/libstd/panicking.rs:214
   6:     0x7f03c9051280 - std::panicking::rust_panic_with_hook::h096dff2cb12b67ce
                               at src/libstd/panicking.rs:477
   7:     0x7f03c903ea75 - std::panicking::begin_panic::h12426f0200b67cfb
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/panicking.rs:411
   8:     0x7f03c9040948 - proc_macro::bridge::client::<impl proc_macro::bridge::Bridge>::with::{{closure}}::h4b299369b0e0d1d6
                               at src/libproc_macro/bridge/client.rs:315
   9:     0x7f03c9040948 - proc_macro::bridge::client::BridgeState::with::{{closure}}::{{closure}}::h0faec3c7acec189b
                               at src/libproc_macro/bridge/client.rs:285
  10:     0x7f03c90471fb - proc_macro::bridge::scoped_cell::ScopedCell<T>::replace::hb049ca5381ed525f
                               at src/libproc_macro/bridge/scoped_cell.rs:73
  11:     0x7f03c90471fb - proc_macro::bridge::client::BridgeState::with::{{closure}}::h26e5bb87d55e4945
                               at src/libproc_macro/bridge/client.rs:283
  12:     0x7f03c90471fb - std::thread::local::LocalKey<T>::try_with::h1161a758d3a72173
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/thread/local.rs:257
  13:     0x7f03c90471fb - std::thread::local::LocalKey<T>::with::haef9ee928a7104b6
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/thread/local.rs:234
  14:     0x7f03c90471fb - proc_macro::bridge::client::BridgeState::with::hc234b8c9968168a0
                               at src/libproc_macro/bridge/client.rs:282
  15:     0x7f03c90471fb - proc_macro::bridge::client::<impl proc_macro::bridge::Bridge>::with::h039bf0fff6b0f186
                               at src/libproc_macro/bridge/client.rs:313
  16:     0x7f03c90471fb - proc_macro::bridge::client::TokenStream::drop::hbcc65a19f79aec15
                               at src/libproc_macro/bridge/client.rs:229
  17:     0x7f03c90471fb - <proc_macro::bridge::client::TokenStream as core::ops::drop::Drop>::drop::h66606ec2b104ac96
                               at src/libproc_macro/bridge/client.rs:54
  18:     0x7f03c8e7209f - core::ptr::real_drop_in_place::hff9c09fb9051046b
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libcore/ptr/mod.rs:197
  19:     0x7f03c8e6f1ce - core::ptr::real_drop_in_place::h86b8a1e3b93c1133
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libcore/ptr/mod.rs:197
  20:     0x7f03c8e6e447 - core::ptr::real_drop_in_place::h6356fb7fc96d0ecf
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libcore/ptr/mod.rs:197
  21:     0x7f03c8e714ee - core::ptr::real_drop_in_place::hda2abe5be4783d7a
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libcore/ptr/mod.rs:197
  22:     0x7f03c8e76915 - rust_contracts_plugin::add_print_statement::h39e7c80279b2d845
                               at src/lib.rs:45
  23:     0x7f03c8e76cf5 - <rust_contracts_plugin::ExamplePlugin as rust_contracts_common::Plugin>::requires::h73d60a6a60cb4304
                               at src/lib.rs:49
  24:     0x7f03c9349f86 - rust_contracts::requires::h799266dd7002b1fa
                               at src/lib.rs:20
  25:     0x7f03d6be19a3 - proc_macro::bridge::client::__run_expand2::{{closure}}::{{closure}}::hf077f32caced8951
                               at src/libproc_macro/bridge/client.rs:412
  26:     0x7f03d6be19a3 - proc_macro::bridge::scoped_cell::ScopedCell<T>::set::{{closure}}::hbc7e4c36695d230b
                               at src/libproc_macro/bridge/scoped_cell.rs:78
  27:     0x7f03d6be19a3 - proc_macro::bridge::scoped_cell::ScopedCell<T>::replace::h459acdde6526a890
                               at src/libproc_macro/bridge/scoped_cell.rs:73
  28:     0x7f03d6be19a3 - proc_macro::bridge::scoped_cell::ScopedCell<T>::set::h7464173bb05f4fa7
                               at src/libproc_macro/bridge/scoped_cell.rs:78
  29:     0x7f03d6be19a3 - proc_macro::bridge::client::<impl proc_macro::bridge::Bridge>::enter::{{closure}}::h4990c45999841775
                               at src/libproc_macro/bridge/client.rs:309
  30:     0x7f03d6be19a3 - std::thread::local::LocalKey<T>::try_with::h3e4f748e19bf8934
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/thread/local.rs:257
  31:     0x7f03d6be19a3 - std::thread::local::LocalKey<T>::with::hdee77422ac0c39f9
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/thread/local.rs:234
  32:     0x7f03d6be19a3 - proc_macro::bridge::client::<impl proc_macro::bridge::Bridge>::enter::h19dad4334140a57c
                               at src/libproc_macro/bridge/client.rs:309
  33:     0x7f03d6be19a3 - proc_macro::bridge::client::__run_expand2::{{closure}}::h101b520d67a56a06
                               at src/libproc_macro/bridge/client.rs:404
  34:     0x7f03d6be19a3 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::ha7d63e8c014c8be2
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/panic.rs:315
  35:     0x7f03d6be19a3 - std::panicking::try::do_call::hbbcc0953c95f062d
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/panicking.rs:296
  36:     0x7f03db3b74ba - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  37:     0x7f03d6be6915 - std::panicking::try::h50ef1f473aa651a0
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/panicking.rs:275
  38:     0x7f03d6be6915 - std::panic::catch_unwind::h4fc8c49f5a9217bf
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/libstd/panic.rs:394
  39:     0x7f03d6be6915 - proc_macro::bridge::client::__run_expand2::h6ef792b1a8e1d0f3
                               at src/libproc_macro/bridge/client.rs:403
  40:     0x7f03d45e8fac - proc_macro::bridge::server::run_server::h84cff3a875a1a418
  41:     0x7f03d465f2e7 - proc_macro::bridge::server::<impl proc_macro::bridge::client::Client<fn(proc_macro::TokenStream, proc_macro::TokenStream) .> proc_macro::TokenStream>>::run::h89870095f1fe7a03
  42:     0x7f03d464cf45 - <syntax_ext::proc_macro_impl::AttrProcMacro as syntax::ext::base::AttrProcMacro>::expand::h7bd69142c0adeed6
  43:     0x7f03d7cc84dc - syntax::ext::expand::MacroExpander::expand_invoc::he74b02405bf53486
  44:     0x7f03d7cc142b - syntax::ext::expand::MacroExpander::expand_fragment::h4f16b3b70343e996
  45:     0x7f03d7cc061d - syntax::ext::expand::MacroExpander::expand_crate::ha701db54702300e8
  46:     0x7f03da61262b - rustc_interface::passes::configure_and_expand_inner::{{closure}}::ha6aae6e3990db8b3
  47:     0x7f03da60f60f - rustc::util::common::time::h947943e585a025b8
  48:     0x7f03da5c7fad - rustc_interface::passes::configure_and_expand_inner::h0ba510b142cee699
  49:     0x7f03da611b0f - rustc_interface::passes::configure_and_expand::{{closure}}::h423836e7c8496c7b
  50:     0x7f03da5ed292 - rustc_data_structures::box_region::PinnedGenerator<I,A,R>::new::hc32729f799da90bc
  51:     0x7f03da5c5116 - rustc_interface::passes::configure_and_expand::ha8e018f7c718da78
  52:     0x7f03da5acdee - rustc_interface::queries::Query<T>::compute::ha54cc85dcf07a896
  53:     0x7f03da5ac08d - rustc_interface::queries::Query<T>::compute::h7a8cec77f24e2a36
  54:     0x7f03da5ae176 - rustc_interface::queries::Query<T>::compute::hf0422e1045e1f15f
  55:     0x7f03da64c0b4 - rustc_interface::queries::<impl rustc_interface::interface::Compiler>::prepare_outputs::hdc8ce6fc341b40e4
  56:     0x7f03db676337 - rustc_interface::interface::run_compiler_in_existing_thread_pool::h2bc09f246bfd173d
  57:     0x7f03db699022 - std::thread::local::LocalKey<T>::with::hfda3afcdd5a185fa
  58:     0x7f03db6ac861 - scoped_tls::ScopedKey<T>::set::h77e0b01426b8b0ed
  59:     0x7f03db6c4884 - syntax::with_globals::h97c3850fd06678ab
  60:     0x7f03db665bdd - std::sys_common::backtrace::__rust_begin_short_backtrace::h4c55b8b27b493a36
  61:     0x7f03db3b74ba - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  62:     0x7f03db678da9 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h3f9d08d982b4373b
  63:     0x7f03db389e3f - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h55ef432b72ff7a0b
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/liballoc/boxed.rs:746
  64:     0x7f03db3b61a0 - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h9294a5138530eae1
                               at /rustc/61d1607e0f6a18bb4897d6f9b10abeac9e11eb8e/src/liballoc/boxed.rs:746
  65:     0x7f03db3b61a0 - std::sys_common::thread::start_thread::h0d2733dd32c3723c
                               at src/libstd/sys_common/thread.rs:13
  66:     0x7f03db3b61a0 - std::sys::unix::thread::Thread::new::thread_start::hf1005dad6ba8f2b1
                               at src/libstd/sys/unix/thread.rs:79
  67:     0x7f03db1286ba - start_thread
  68:     0x7f03daa5241d - clone
  69:                0x0 - <unknown>
thread panicked while panicking. aborting.

In short, it's not valid for TokenStream to cross dynamic library boundaries as-is (see this).

1 Like