I just ran across this issue while using my first kind-of-useful macro (a helper for parsing AoC input) -- 6 years later, is this still the recommended way to approach this?
Specifically, I had naively placed the use anyhow
within the macro itself, which worked until I decided to try out eyre
and the compiler complained about not being able to find anyhow
. I reviewed the reference on hygiene and made these initial changes. I found surprisingly few relevant SO results and tried to peek at the anyhow!
and eyre!
macro source, but I don't see external crates being referenced there.
Specifically, some of the issues I ran into (and didn't expect since the macro was working fine until I tried to change to eyre
):
- I initially placed
use anyhow
within the macro itself. This worked until I used the macro in a crate that didn't already depend onanyhow
; it tries to resolve this dependency from within the new crate and can't find it. - I then tried place
use anyhow
in the crate containing the macro, in which case the macro can't findanyhow
and the tests fail. (I still find this a little surprising, given that the crate depends on anyhow -- shouldn't the macro within the crate know about it too?)- Additionally, the compiler complained about an unused dependency; changing to
pub use anyhow
took care of that.
- Additionally, the compiler complained about an unused dependency; changing to
- I then tried
pub(crate) use anyhow
; the macro still couldn't find it, so I went back to just planpub
. - I then tried
$crate::anyhow
in the macro, still couldn't find it. - Finally I realized that my macro was in a module, so
pub use anyhow
at the top level, thenuse $crate::files::anyhow
in the macro - I tried going back to
pub(crate) use anyhow
at the top level, thinking that I didn't really want to reexport all of anyhow, but it still won't work that way (which makes sense, the consuming crate needs to know aboutanyhow
if that's the resulting type). - I also had some issues with
Context
trait ambiguity betweeneyre
andanyhow
which required me to use the fully-qualified syntax.
After a few more tweaks and finding this thread, my resulting code follows the pattern:
pub use anyhow;
#[macro_export]
macro_rules! my_macro {
($path:expr, $ty:ty) => {{
use ::std::example::stdlib::Dependency;
use $crate::my::mod::name::anyhow;
do_stuff_with_Dependency_and_anyhow();
}}
}
I know the arch forum would throw a fit about a necrobump like this, but hopefully this will help another noob use external crates in their macro, because I had a hard time figuring this one out.