Stabilize #[my_macro] mod foo; (part of proc_macro_hygiene)#157857
Stabilize #[my_macro] mod foo; (part of proc_macro_hygiene)#157857TimNN wants to merge 1 commit into
#[my_macro] mod foo; (part of proc_macro_hygiene)#157857Conversation
|
cc @Amanieu, @folkertdev, @sayantn |
Removed the |
|
@petrochenkov: Based on the labels you added, I assume this looks reasonable to you. Could you do the |
|
Ok, if the guide says so, cc @rust-lang/lang @rust-lang/lang-advisors. |
|
@TimNN Did this also gate |
|
@joshtriplett: I assume you mean the unstable If so, they also currently reject |
|
@TimNN Will this PR make them start accepting it? (I'm hoping it does.) |
Stabilization report
Summary
Allow
mod foo;(an "outlined" module) in the input of attribute and derive (proc) macros.Tracking:
proc_macro_hygienefeature covers multiple related features. This PR proposes only a partial stabilizationReference PRs:
What is stabilized
Currently,
mod foo;(an outlined / non-inline) module is explicitly rejected in the input of derive and attribute (proc) macros.This PR removes the check, allowing
mod foo;.The module is provided to the macro as it is written in the source code, that is in its "not-yet-loaded" form without a body.
What isn't stabilized
The remaining parts of
proc_macro_hygieneare not stabilized (specifically, attribute macros in places where they aren't currently allowed).Design
Reference
rust-lang/reference#2284
RFC history
This feature has not been explicitly specified by any RFC.
proc_macrostabilization,#[my_macro] mod foo;specifically was feature gated.mod foo;was actually provided to macros as the loadedmod foo { ... }mod foo;was provided to macros as-is.proc_macrostabilization, expand: Feature gate out-of-line modules in proc macro input #66078 mademod fooanywhere in the input to derive or attribute proc macros unstable.mod foo;were unstable.Answers to unresolved questions
N/A
Post-RFC changes
See the RFC history above.
Key points
The main design decision is whether outlined modules should be passed to proc macros with or without their body.
Arguments in favor of "without their body":
#[my_macro] mod foo;(the "not-yet-loaded" version of the module is passed to the macro) is natural to the current setup, stable and is not going to change".mod foo;in their input is not even recognized by the compiler and thus not expanded. Attribute and derive proc macros also receiving the unexpandedmod foo;in their input makes the two consistent.inlcude!("foo.rs"), are also not expanded before being passed to proc macros. Providing modules without their body would be consistent with that.mod foo;to proc macros with its body would (as far as I know) be the only case where a proc macro would not get exactly what is written in the source code as its input.Arguments in favor of "with their body":
#[my_macro] mod foo;and#[my_macro] mod foo {}would have different behavior, which means that in the presence of proc macros, migrating an inline module to an outlined one would no longer be a purely syntactic change, but could affect the behavior of the proc macro.#[my_macro] mod foo;and#![my_macro]infoo.rs(currently unstable) would have different behavior.#[cfg(false)]on a module as an outer attribute means the corresponding file can be missig or have syntax errors, while using it as an inner attribute requires the file to be syntactically valid.Nightly extensions
No.
Doors closed
None.
If, in the future, there is a desire to make the module body of outlined modules available to proc macros, there are multiple ways to add that in a backward-compatible way (e.g. an explicit opt-in during the proc macro registration, or an API in the
proc_macrocrate).Feedback
Call for testing
No.
Nightly use
Searching Github produces 4.4k files. Reviewing the first page of results shows many repositories that haven't been updated in multiple years, so it is unclear which part of the
proc_macro_hygienefeature they actually use (other parts of the feature were previously stabilized).Implementation
Major parts
The restriction is currently implemented as an explicit visitor of the proc macro input, rejecting outlined modules. The visitor is removed in this PR.
Coverage
See the test changes attached to this PR. The added tests explicitly verify that proc macros receive
mod foo;as an input without its body, to ensure that the behavior doesn't unintentionally change in the future.Outstanding bugs
None.
Outstanding FIXMEs
None.
Tool changes
Generally none. The feature is a minor addition to the inputs that (proc) macros accept, and should not require special handling in any of the tools.
rust-analyzer has some existing limitations around handling modules transformed by proc macros (e.g. (on stable) auto-complete does not work if a proc macro transforms
mod foo {}tomod foo;). It works fine for simple case where the the proc macro leaves themod foo;mostly unmodified.Breaking changes
N/A: The feature is not expected to cause any breakage.
Type system, opsem
N/A: This feature only affects the AST, not type checking.
Common interactions
Temporaries
No.
Drop order
No.
Pre-expansion / post-expansion
No. (At least nothing that doesn't equally apply to existing stable proc macros).
Edition hygiene
N/A: Not gated on an edition.
SemVer implications
No.
Exposing other features
No.
History
See the RFC History section above.
Acknowledgments
Open items
None.
r? @petrochenkov for an initial review (feel free to edit the stabilization report if you like)