Just for completeness: while it is true that extern crate
"statements" are not needed in edition 2018 anymore (except for test
, or, for older compiler version, proc_macro
), the #[macro_use] extern crate ...
idiom can still be useful (in that it cannot be replicated by use
"statements"). Indeed, once you #[macro_use] extern crate some_crate
, all the macros exported by ::some_crate
are in scope even inside (sub)modules:
//! Entrypoint: `lib.rs` or `main.rs`
#[macro_use]
extern crate log;
mod something {
// `debug!` can be used here
}
vs.
mod something {
// `::log::debug!` (or `log::debug!` if no (other) `log` item in scope) can be used here
}
// or
mod alternative {
use ::log::debug; // or `log::debug` if no (other) `log` item in scope
// `debug!` can be used here.
}
Basically, with use
"statements", macros behave like any other item (function, type) regarding namespaces and scopes, but it can sometimes be convenient to be able to add something to this "global / ubiquitous scope" (called the prelude). And the only way to do so currently is by using #[macro_use] extern crate ...
.
Ideally, there should be an actual mechanism to customize one's prelude, and once that's available, #[macro_use] extern crate
could definitely be deprecated.
Also, see this other post where I detail how one can "hand-roll a custom prelude": What's the difference between 'extern crate' and write into cargo.toml - #20 by Yandros