I'm trying to write a function-like procedural macro my_macro
that expands to a lazy_static
macro invocation. I want to write it in a way that users of my_macro
don't need to list lazy_static
in their crate's dependencies and explicitly use it (use lazy_static::lazy_static
).
This is the minimal example code:
lib.rs (my_macro crate)
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
#[proc_macro]
pub fn my_macro(_item: TokenStream) -> TokenStream {
quote!(
lazy_static! {
static ref EXAMPLE: u8 = 42;
}
).into()
}
Cargo.toml (my_macro crate)
[package]
name = "my_macro"
version = "0.1.0"
edition = "2018"
[dependencies]
quote = "0.6"
lazy_static = "1.2.0"
[lib]
proc-macro = true
lib.rs (usage crate)
use my_macro::my_macro;
// use lazy_static::lazy_static;
my_macro!();
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(*EXAMPLE, 42);
}
}
Cargo.toml (usage crate)
[package]
name = "import_test"
version = "0.1.0"
edition = "2018"
[dependencies]
my_macro = { path = "./my_macro" }
# lazy_static = "1.2.0"
The code above results in a compile error:
error: cannot find macro `lazy_static!` in this scope
--> src/lib.rs:6:1
|
6 | my_macro!();
| ^^^^^^^^^^^^
I understand the error and I know that I can solve it by letting the usage
crate depend on lazy_static
and use
it in lib.rs
(see commented lines).
The problem is that this would mean that all crates that use my_macro
would have to list lazy_static
in their dependencies. This doesn't seem right and I'd like to know if there's an alternative. I already tried a couple of things but nothing solved the problem.