Export `macro_rules!` from current module

This seems an old topic but I lose track of its most recent progress. Simply speaking I'd to define macros in a module (not necessarily root module) inside a crate and use it from another crate. Currently the only way to do this seems #[macro_export] which exports the macro at crate root, not the module where it is defined.

This is almost the same question as https://internals.rust-lang.org/t/pub-on-macro-rules/19358 (and similar to https://users.rust-lang.org/t/re-exporting-macro-export-ed-macros-by-module-where-they-are-defined/84130/4). However I'm not sure that topic tracks the most recent work in progress on this issue. Here I'd like to know if any progress has been made so we can write pub macro_rules! ... or similar things to export macros from the module where it's defined and not pollute the crate root namespace. If this hasn't been resolved yet, then I'd like to know which is the GH issue tracker working on it so that I can watch on it.

By the way I've seen several hacks using #[macro_export] with hashed macro identifiers but none of them can avoid the crate root namespace pollution. They make it hard, but not impossible, to access the hashed identifiers.

From the rust reference:

However, if it has the #[macro_export] attribute, then it is declared in the crate root scope and can be referred to normally as such

You can use pub(super) use the_macro_name; right after the macro and then import the macro from the parent like a regular item.

How does this allow you to use the macro from a different crate? You can't pub use a non-macro_export macro. You can pub(crate) use or pub(super) use it, but these don't export the macro to a different crate?

Ultimately there must be something exported at the crate root unless you define the macro in a separate crate and re-export it. You can make it difficult to use and hide it from documentation at the crate root, however.

2 Likes

The only positive way to avoid this is to involve a new external crate, kind of like we already need for proc-macros, only for #[macro_export]ed macro_rules! macros, this time.

Basically in that thread you linked to, my post over

does "summarize" the latest situation w.r.t. these things

After reading several posts it's still unclear to me why #[macro_export] must export at crate root. I think most people would like the export at macro definition module.

In addition, in that post you suggested pub macro_rules! and:

  • the compiler machinery for all this is already available, it's just a matter of switching the knob to enable it;

And I'm wondering why this is still not doable with the latest rust compiler. Ideally we don't need #[macro_export] but control macro visibility solely with pub, pub(crate), etc.

I guess it's solely a backwards compatibility problem.

1 Like