Tracking issue for `pub use` re-export of macros from within submodules without `macro_export`
Opened this issue · 1 comments
Tracking issue for pub use re-export of macros from within submodules without macro_export.
The feature gate for the issue is TBD.
Motivation
I first noticed this during my work on name resolution, and when discussing it with t-lang-docs, @traviscross suggested I open an experiment to address this functionality gap.
Current State
As things stand, there are two ways to expose macro_rules! via the module system.
#[macro_export]: exports the macro with path-based scope from the crate root- use declarations: these can re-export macros from within their textual scope and create path-based scope name entries for them within submodules that can be referenced from outside the macro's original textual scope.
The problem is that use declarations visibility is limited by the underlying visibility of the macro, which is itself controlled by the presence or absence of #[macro_export]. Without #[macro_export] MBE items have an implicit visibility of pub(crate). They only become pub and therefore pub use-able with the presence of a #[macro_export].
This leaves an asymmetry in how much you can control the visibility and organizational structure of library APIs when working with private vs public MBE macros. If it's private, you can re-export the macro within the module where it's defined, then re-export it anywhere else you wish, as visibility permits, which you can restrict via the associated use declarations. If you want to export the macro publicly, you must expose the macro in your crate root. You can also re-export it in a sub-module, but there is currently no way to avoid listing all of your public macros in the crate root.
Experiment proposal
I asked @traviscross for a suggestion on how to address this because I really do not want to get locked inside a syntax bikeshed. He suggested I simply change the default visibility for macro_rules without #[macro_export] to be pub, thus allowing pub re-exports. As far as I know, this should be a straightforward change in the compiler, one line, not counting the additional logic needed to add a new feature flag. As I understand it, changing the default visibility of MBE macros shouldn't affect their practical visibility in any existing scenario, since they don't have path-based scope by default. The only way to gain path-based scope is to use a re-export1. However, the language currently restricts greater visibility re-exports via an error, so all existing re-exports would still restrict visibility to less than the new default.
Note: @ehuss was able to find this previous discussion on a similar proposal to allow visibility markers on macro_rules definitions: https://internals.rust-lang.org/t/pub-on-macro-rules/19358. This post does a good job highlighting some of the problems that arise from the current state of MBE macros and claims that this was not possible due to, presumably, name-resolution issues, but should be possible now. I can't speak to historical problems with name resolution. Still, I'd like to verify the claim that it is possible now, or, if it is not, use this experiment to understand why, which I hope will support my work on name resolution in the reference..
Tracking
About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Approve as lang experiment.
- Implement in nightly.
- Add documentation to the dev guide.
- See the instructions.
- Add documentation to the reference.
- See the instructions.
- Accept an RFC.
- Add formatting for new syntax to the style guide.
- See the nightly style procedure.
- Stabilize.
- See the instructions.
Unresolved Questions
TODO.
Related
Implementation history
TODO.
Footnotes
-
or
#[macro_export]of course, but it already sets the visibility topub, so nothing is changing here. ↩
Thanks to @yaahc for writing this up and volunteering to do this exploration. I'm happy to champion it. Under our process, that means that this experiment is accepted.
I'm nominating for visibility and to unearth any possible problems with this that might be apparent to others on the team.