How do I use a macro across module files?

user picture user · Nov 4, 2014 · Viewed 40.6k times · Source

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?

Answer

Lukas Kalbertodt picture Lukas Kalbertodt · Jul 31, 2015

Macros within the same crate

#[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 {
        () => ()
    }
}

Macros across crates

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.