'Refer to an extern crate in macro expansion
I'm trying to write some macros that work in nostd environment as well as in std environment. In order to do so I have this kind of code in proc macro crate:
#[cfg(not(feature = "alloc"))]
{
quote!(err.message = Some(::std::borrow::Cow::from(#m));)
}
#[cfg(feature = "alloc")]
{
quote!(err.message = Some(::alloc::borrow::Cow::from(#m));)
}
This correctly produces the code that uses alloc when alloc feature is enabled, but the compiler complains
error[E0433]: failed to resolve: could not find `alloc` in the list of imported crates
Of course the reason is that the macro expansion is missing
extern crate alloc;
But adding that is a problem. Since it's a procedural derive macro, the extern crate will be added on each derive call. How can I refer to an extern crate in macro expansion? Using $crate does not seem to work inside quote!.
Solution 1:[1]
You can wrap the expansion in a block, then you can define alloc multiple times.
Another common practice for proc macros that need auxiliary types is to create a crate that provides them, and reexport the macro from it. E.g. create mycrate and mycrate-macros. Then you can get rid of the whole alloc feature if you only need alloc-accessible types, like:
#![no_std]
extern crate alloc;
#[doc(inline)]
pub use mycrate_macros::my_macro;
#[doc(hidden)]
pub use alloc:borrow::Cow;
Then in the macro refer to ::my_crate::Cow.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Chayim Friedman |
