I have a macro in some module that calls a function:
mod a {
mod b {
fn foo(_: u32) {}
macro_rules! bar {
( $x:expr ) => (foo($x))
}
}
}
This does not work from outside module a::b
unless I import foo
. Explicitly naming the module works in this case:
macro_rules! bar {
( $x:expr ) => (crate::a::b::foo($x))
}
However, this wouldn't work from outside the crate for an exported macro. I tried the following but it didn't work either:
#[macro_export]
macro_rules! bar {
( $x:expr ) => (::mycratename::a::b::foo($x))
}
Where mycratename
is the name of the library in Cargo.toml
.
[lib]
name = "mycratename"
crate-type = ["lib", "cdylib", "staticlib"]
At least it doesn't work when I try to use the macro from within the crate, I didn't try using it from outside. Is there a way to make it work from both within and outside the crate?
This is exactly what the reserved $crate
meta variable is for.
It expands to crate
within the defining crate and to ::crate_name
outside of it.
Using $crate in Rust's procedural macros?
::crate_name
even if you rename the crate on import, but it'll still correctly resolve the crate, though manually replacing the macro invocation with the expanded version will fail in this case.