snippetrustCritical
How do I use a macro across module files?
Viewed 0 times
howmoduleacrossusemacrofiles
Problem
I have two modules in separate files within the same crate, where the crate has
I currently hit the compiler error "
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?Solution
Macros within the same crate
New method (since Rust 1.32, 2019-01-17)
With the
Old method
If you want to use the macro in the same crate, the module your macro is defined in needs the attribute
Macros across crates
Crate
Crate
Note that with this method, macros always live at the top-level of a crate! So even if
Before Rust 2018, you had to import macro from other crates by adding the attribute
New method (since Rust 1.32, 2019-01-17)
foo::bar!(); // works
mod foo {
macro_rules! bar {
() => ()
}
pub(crate) use bar; // <-- the trick
}
foo::bar!(); // worksWith the
pub use, the macro can be used and imported like any other item. And unlike the older method, this does not rely on source code order, so you can use the macro before (source code order) it has been defined.Old method
bar!(); // Does not work! Relies on source code order!
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
bar!(); // worksIf you want to use the macro in the same crate, the module your macro is defined in needs the attribute
#[macro_use]. Note that macros can only be used after they have been defined!Macros across crates
Crate
util#[macro_export]
macro_rules! foo {
() => ()
}Crate
useruse util::foo;
foo!();Note that with this method, 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;. By using pub use, you can export a macro from a module of your crate (in addition to it being exported at the root).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. This syntax should not be necessary anymore.Code Snippets
foo::bar!(); // works
mod foo {
macro_rules! bar {
() => ()
}
pub(crate) use bar; // <-- the trick
}
foo::bar!(); // worksbar!(); // Does not work! Relies on source code order!
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
bar!(); // works#[macro_export]
macro_rules! foo {
() => ()
}use util::foo;
foo!();Context
Stack Overflow Q#26731243, score: 366
Revisions (0)
No revisions yet.