I have two modules in separate files within the same crate, where the crate has macro_rules
enabled. I want to use the macros defined in one module in another module.
// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)
// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?
I currently hit the compiler error "macro undefined: 'my_macro'
"... which makes sense; the macro system runs before the module system. How do I work around that?
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
bar!(); // works
If you want to use the macro in the same crate, the module your macro is defined in needs the attribute #[macro_use]
.
Macros can only be used after they have been defined. This means that this does not work:
bar!(); // ERROR: cannot find macro `bar!` in this scope
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
To use your macro_rules!
macro from other crates, the macro itself needs the attribute #[macro_export]
. The importing crate can then import the macro via use crate_name::macro_name;
.
Crate util
#[macro_export]
macro_rules! foo {
() => ()
}
Crate user
use util::foo;
foo!();
Note that macros always live at the top-level of a crate; so even if foo
would be inside a mod bar {}
, the user
crate would still have to write use util::foo;
and not use util::bar::foo;
.
Before Rust 2018, you had to import macro from other crates by adding the attribute #[macro_use]
to the extern crate util;
statement. That would import all macros from util
. Alternatively, #[macro_use(cat, dog)]
could be used to only import the macros cat
and dog
. This syntax should not be necessary anymore.
More information is available in The Rust Programming Language chapter on macros.