$crate was added to allow
macro_rules! macros to refer to their defining crate, provide
$mod to allow
macro_rules! macros to refer to their defining module.
(I've deliberately used
$mod and not
$self, despite non-macro paths being
::self::*, to avoid conflicting with potential use of
$self for method-position macros.)
macro_rules! macros to integrate into the module/privacy system a little bit better again. (While we wait for full-hygiene
macros 2.0, which use def-site name lookup by default.)
$mod doesn't seem like it gives
macro_rules! any new powers, since the macro could just use
$crate::path::to::me instead. But
$mod unlocks new functionality for two specific cases:
- Macro expanded macros don't know ahead of time what module they're going to be defined in, so don't know the path to the module. You could pass the definition module in, but either you bind it as
$:pathand it's basically completely useless since you can't refer to an item in the module from the bound path, or you pass it in as
$($path_head:ident)? $(::$path_segment)*and can't use the path when repeating any other macro binder repetition.
$modalso allows privacy to potentially be based on the defining module instead of use site.
$mod is currently allowed as a macro binder, as is every other keyword (yes, including
$crate... kinda). In order to make this a compatible change:
- < editionNext, warn when
$modis used as a macro binder. If
$modis not a macro binder, it can be used as a keyword.
- >= editionNext, make using
$modas a macro binder a hard error. (Consider doing this for all other keywords as well.)
As an alternative,
$crate::self should never work as a path in the current compiler and could be used.
$:pathmatches a full path-to-item, including turbofish, so is a basically useless matcher in practice. Basically the only use is if you want to refer to a name in at least two of the type/item/macro namespaces from the same binder. Basically
:pathis only useful for capturing and using a tuple struct path like a tuple struct, since it's both in the type and item namespaces, and can be generic. ↩︎
What was the rollout story for
$crate? Currently, it doesn't introduce a binder, and seems to match the unwritable crate reference token. I have no idea what the cross crate behavior is. ↩︎