Rust: гигиена процедурного макроса, который расширяется до вызова макроса - PullRequest
0 голосов
/ 08 февраля 2019

У меня проблема с процедурной макро гигиеной.Моя реальная задача более сложная, но основная проблема заключается в следующем:

Я пытаюсь написать функциональный процедурный макрос my_macro, который расширяется до вызова макроса lazy_static.Я хочу написать так, чтобы пользователям my_macro не нужно было указывать lazy_static в зависимостях своего ящика и явно использовать его (use lazy_static::lazy_static).

Это минимальный пример кода:

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 (ящик для использования)

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 (ящик для использования)

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

[dependencies]
my_macro = { path = "./my_macro" }
# lazy_static = "1.2.0"

Приведенный выше код приводит кошибка компиляции:

error: cannot find macro `lazy_static!` in this scope
 --> src/lib.rs:6:1
  |
6 | my_macro!();
  | ^^^^^^^^^^^^

error: aborting due to previous error

Я понимаю ошибку, и я знаю, что могу решить ее, позволив клетке usage зависеть от lazy_static и use в lib.rs (см. закомментированные строки).

Проблема в том, что это будет означать, что все ящики, которые используют my_macro, должны будут перечислить lazy_static в своих зависимостях.Это кажется неправильным, и я хотел бы знать, есть ли альтернатива.Я уже попробовал пару вещей, но ничего не решило проблему.

Заранее спасибо!

...