Hey all! It’s been some time now since Help stabilize a subset of Macros 2.0!, and a lot has happened in the meantime. I’d like to both try to collect my own thoughts about this here as well as try to post a general status update on the stabilization of a “macros 1.2” and the current open questions.
FCP for stable
Two primary features have gone through FCP for stability:
- #35896 - Tracking issue for “macro naming and modularisation”
- #38356 - Tracking issue for RFC 1566: Procedural macros
At the time of FCP proposal I wrote a detailed design of what’s to become stable and here’s a gist if you don’t want to load the whole comment thread. As of this writing the proposed design here has not changed. Some snags, however, have been hit along the way which have held up stabilization.
Internal helpers for macro_rules!
This is an issue that we discovered as a sort of late-breaking bug. Immactulately articulated by @dtolnay the bug here is with crates that have internal helpers for exported macro_rules!
macros. I won’t go too much into the details of the bug here (@dtolnay did a great job in his writeup), so it’s sufficient to say that two bugs were discovered here:
- First, existing macros aren’t compatible with
use
. This has now been solved with a new#[macro_export(local_inner_macros)]
attribute. This is planned to become stable in the 1.30.0 release (today’s nightly is 1.29.0) pending any major bugs coming up. - Second, the recommended fix on the 2018 edition is to use
$crate::__foo_internal!()
. This however does not work for the defining crate, it only works across crates. At this point it looks like we’re going to stabilize this behavior and consider this a bugfix to fix in a future release.
As a result, internal helpers in macro_rules!
are resolved and fixes are in nightly, we’re just waiting another cycle before stabilization to ensure that the new local_inner_macros
attribute has time to stabilize.
Bugs in procedural macros
Procedural macros have been in the compiler for quite some time now, and throughout this time they’ve acrrued quite the number of interesting corner cases and such. There’s a category for these bugs on our issue tracker and some are tagged as A-macros-1.2
to block 1.2 as well, but otherwise many of these are existing bugs in custom derive or don’t affect behavior that’s stabilizing.
Some of the more notorious bugs are:
-
#50504- proc_macro! expansion can refer to items defined in the root w/o importing them (fixed in #51952) -
#52219- #![feature(proc_macro)] breaks some custom derive attributes (fixed in #52230) -
#52225- Procedural macro crates should require at most one definition per macro name (fixed in #52383) -
#52226 - Ambiguity between custom derive attributes and proc macro attributes
- More discussion on the issue, this is very new and not fully understood to me yet what fix is in scope.
- #52269 - interaction between built-in and custom derives via shadowing is unclear
Stabilization
There’s two aspects that need to be stabilized here. The first is the new proc_macro
crate APIs as well as the new attributes that can be defined in #![crate_type = "proc-macro"]
crates. This is being done in #52081.
The second is use_extern_macros
, the ability to use macros with the module system. This is being done in #50911. This itself can be theoretically split into two pieces as well, one where macro_rules!
is integrated with the module system and one where custom attributes/procedural macros are integrated. The former (macro_rules!
) is blocked on giving local_inner_macros
another cycle to bake. The latter (procedural macros) should be stabilizable once some of the above bugs have been sorted out.
My goal is that we’re still on track for the 2018 edition for sure with both procedural macros and macro_rules!
-via-the-module-system. My hope is to land procedural macros in the 1.29 release (current nightly) and the remaining macro_rules!
pieces during the 1.30 release. This depends on issues that arise, however!
In any case if I’m missing something here please let me know! I’ll try to keep this updated as we approach the 1.29 release and 1.30.