如何编写一个扩展为宏调用的过程宏,而不需要用户导入宏的包?

Fel*_*lix 5 macros rust rust-proc-macros

我正在尝试编写一个类似函数的过程宏my_macro,该宏可扩展为lazy_static宏调用。我想以一种用户不需要my_macrolazy_static其板条箱的依赖项中列出并显式使用它的方式编写它(use lazy_static::lazy_static)。

这是最小的示例代码:

lib.rs(my_macro 箱)

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()
}
Run Code Online (Sandbox Code Playgroud)

Cargo.toml(my_macro 箱)

[package]
name = "my_macro"
version = "0.1.0"
edition = "2018"

[dependencies]
quote = "0.6"
lazy_static = "1.2.0"

[lib]
proc-macro = true
Run Code Online (Sandbox Code Playgroud)

lib.rs(使用包)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Cargo.toml(使用箱)

[package]
name = "import_test"
version = "0.1.0"
edition = "2018"

[dependencies]
my_macro = { path = "./my_macro" }
# lazy_static = "1.2.0"
Run Code Online (Sandbox Code Playgroud)

上面的代码会导致编译错误:

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()
}
Run Code Online (Sandbox Code Playgroud)

我理解这个错误,并且我知道我可以通过让usage板条箱依赖lazy_staticuse来解决它lib.rs(请参阅注释行)。

问题是,这意味着所有使用的板条箱都my_macro必须lazy_static在其依赖项中列出。这似乎不对,我想知道是否有其他选择。我已经尝试了一些方法,但没有解决问题。