Tracking issue for `pub use` reexport of macros from within submodules without `macro_export`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
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-export[^1]. 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..
[^1]: or #[macro_export] of course, but it already sets the visibility to pub, so nothing is changing here.
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the experiment proposal and the related issues #53977 and PR #139493, then review the linked dev guide and Reference instructions. The tracking checklist shows that implementation, dev-guide and Reference documentation, an RFC, style-guide formatting, and stabilization remain; completion is defined by advancing those explicitly listed steps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100