Skip to content

Commit 1d38d39

Browse files
committed
Add idenfitiers to mbe and proc-macro
1 parent 687faf9 commit 1d38d39

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

src/macros-by-example.md

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Macros By Example
22

3+
r[macro.decl]
4+
5+
r[macro.decl.syntax]
36
> **<sup>Syntax</sup>**\
47
> _MacroRulesDefinition_ :\
58
> &nbsp;&nbsp; `macro_rules` `!` [IDENTIFIER] _MacroRulesDef_
@@ -39,6 +42,7 @@
3942
> _MacroTranscriber_ :\
4043
> &nbsp;&nbsp; [_DelimTokenTree_]
4144
45+
r[macro.decl.intro]
4246
`macro_rules` allows users to define syntax extension in a declarative way. We
4347
call such extensions "macros by example" or simply "macros".
4448

@@ -51,10 +55,15 @@ items), types, or patterns.
5155

5256
## Transcribing
5357

58+
r[macro.decl.transcription]
59+
60+
r[macro.decl.transcription.intro]
5461
When a macro is invoked, the macro expander looks up macro invocations by name,
5562
and tries each macro rule in turn. It transcribes the first successful match; if
56-
this results in an error, then future matches are not tried. When matching, no
57-
lookahead is performed; if the compiler cannot unambiguously determine how to
63+
this results in an error, then future matches are not tried.
64+
65+
r[macro.decl.transcription.lookahead]
66+
When matching, no lookahead is performed; if the compiler cannot unambiguously determine how to
5867
parse the macro invocation one token at a time, then it is an error. In the
5968
following example, the compiler does not look ahead past the identifier to see
6069
if the following token is a `)`, even though that would allow it to parse the
@@ -68,6 +77,7 @@ macro_rules! ambiguity {
6877
ambiguity!(error); // Error: local ambiguity
6978
```
7079

80+
r[macro.decl.transcription.syntax]
7181
In both the matcher and the transcriber, the `$` token is used to invoke special
7282
behaviours from the macro engine (described below in [Metavariables] and
7383
[Repetitions]). Tokens that aren't part of such an invocation are matched and
@@ -78,6 +88,8 @@ instance, the matcher `(())` will match `{()}` but not `{{}}`. The character
7888

7989
### Forwarding a matched fragment
8090

91+
r[macro.decl.transcription.fragment]
92+
8193
When forwarding a matched fragment to another macro-by-example, matchers in
8294
the second macro will see an opaque AST of the fragment type. The second macro
8395
can't use literal tokens to match the fragments in the matcher, only a
@@ -116,9 +128,14 @@ foo!(3);
116128

117129
## Metavariables
118130

131+
r[macro.decl.meta]
132+
133+
r[macro.decl.meta.intro]
119134
In the matcher, `$` _name_ `:` _fragment-specifier_ matches a Rust syntax
120-
fragment of the kind specified and binds it to the metavariable `$`_name_. Valid
121-
fragment specifiers are:
135+
fragment of the kind specified and binds it to the metavariable `$`_name_.
136+
137+
r[macro.decl.meta.specifier]
138+
Valid fragment specifiers are:
122139

123140
* `item`: an [_Item_]
124141
* `block`: a [_BlockExpression_]
@@ -136,18 +153,23 @@ fragment specifiers are:
136153
* `vis`: a possibly empty [_Visibility_] qualifier
137154
* `literal`: matches `-`<sup>?</sup>[_LiteralExpression_]
138155

156+
r[macro.decl.meta.transcription]
139157
In the transcriber, metavariables are referred to simply by `$`_name_, since
140158
the fragment kind is specified in the matcher. Metavariables are replaced with
141-
the syntax element that matched them. The keyword metavariable `$crate` can be
142-
used to refer to the current crate; see [Hygiene] below. Metavariables can be
159+
the syntax element that matched them.
160+
161+
r[macro.decl.meta.dollar-crate]
162+
The keyword metavariable `$crate` can be used to refer to the current crate; see [Hygiene] below. Metavariables can be
143163
transcribed more than once or not at all.
144164

165+
r[macro.decl.meta.expr-underscore]
145166
For reasons of backwards compatibility, though `_` [is also an
146167
expression][_UnderscoreExpression_], a standalone underscore is not matched by
147168
the `expr` fragment specifier. However, `_` is matched by the `expr` fragment
148169
specifier when it appears as a subexpression.
149170
For the same reason, a standalone [const block] is not matched but it is matched when appearing as a subexpression.
150171

172+
r[macro.decl.meta.edition2021]
151173
> **Edition differences**: Starting with the 2021 edition, `pat` fragment-specifiers match top-level or-patterns (that is, they accept [_Pattern_]).
152174
>
153175
> Before the 2021 edition, they match exactly the same fragments as `pat_param` (that is, they accept [_PatternNoTopAlt_]).
@@ -156,22 +178,31 @@ For the same reason, a standalone [const block] is not matched but it is matched
156178
157179
## Repetitions
158180

181+
r[macro.decl.repetition]
182+
183+
r[macro.decl.repetition.intro]
159184
In both the matcher and transcriber, repetitions are indicated by placing the
160185
tokens to be repeated inside `$(``)`, followed by a repetition operator,
161-
optionally with a separator token between. The separator token can be any token
186+
optionally with a separator token between.
187+
188+
r[macro.decl.repetition.separator]
189+
The separator token can be any token
162190
other than a delimiter or one of the repetition operators, but `;` and `,` are
163191
the most common. For instance, `$( $i:ident ),*` represents any number of
164192
identifiers separated by commas. Nested repetitions are permitted.
165193

194+
r[macro.decl.repetition.operators]
166195
The repetition operators are:
167196

168197
- `*` --- indicates any number of repetitions.
169198
- `+` --- indicates any number but at least one.
170199
- `?` --- indicates an optional fragment with zero or one occurrence.
171200

201+
r[macro.decl.repetition.optional-restriction]
172202
Since `?` represents at most one occurrence, it cannot be used with a
173203
separator.
174204

205+
r[macro.decl.repetition.fragment]
175206
The repeated fragment both matches and transcribes to the specified number of
176207
the fragment, separated by the separator token. Metavariables are matched to
177208
every repetition of their corresponding fragment. For instance, the `$( $i:ident
@@ -198,13 +229,17 @@ compiler knows how to expand them properly:
198229

199230
## Scoping, Exporting, and Importing
200231

232+
r[macro.decl.scope]
233+
234+
r[macro.decl.scope.intro]
201235
For historical reasons, the scoping of macros by example does not work entirely
202236
like items. Macros have two forms of scope: textual scope, and path-based scope.
203237
Textual scope is based on the order that things appear in source files, or even
204238
across multiple files, and is the default scoping. It is explained further below.
205239
Path-based scope works exactly the same way that item scoping does. The scoping,
206240
exporting, and importing of macros is controlled largely by attributes.
207241

242+
r[macro.decl.scope.unqualified]
208243
When a macro is invoked by an unqualified identifier (not part of a multi-part
209244
path), it is first looked up in textual scoping. If this does not yield any
210245
results, then it is looked up in path-based scoping. If the macro's name is
@@ -224,6 +259,9 @@ self::lazy_static!{} // Path-based lookup ignores our macro, finds imported one.
224259

225260
### Textual Scope
226261

262+
r[macro.decl.scope.textual]
263+
264+
r[macro.decl.scope.textual.intro]
227265
Textual scope is based largely on the order that things appear in source files,
228266
and works similarly to the scope of local variables declared with `let` except
229267
it also applies at the module level. When `macro_rules!` is used to define a
@@ -253,6 +291,7 @@ mod has_macro {
253291
m!{} // OK: appears after declaration of m in src/lib.rs
254292
```
255293

294+
r[macro.decl.scope.textual.shadow]
256295
It is not an error to define a macro multiple times; the most recent declaration
257296
will shadow the previous one unless it has gone out of scope.
258297

@@ -299,6 +338,9 @@ fn foo() {
299338

300339
### The `macro_use` attribute
301340

341+
r[macro.decl.scope.macro_use]
342+
343+
r[macro.decl.scope.macro_use.mod-decl]
302344
The *`macro_use` attribute* has two purposes. First, it can be used to make a
303345
module's macro scope not end when the module is closed, by applying it to a
304346
module:
@@ -314,6 +356,7 @@ mod inner {
314356
m!();
315357
```
316358

359+
r[macro.decl.scope.macro_use.prelude]
317360
Second, it can be used to import macros from another crate, by attaching it to
318361
an `extern crate` declaration appearing in the crate's root module. Macros
319362
imported this way are imported into the [`macro_use` prelude], not textually,
@@ -332,11 +375,15 @@ lazy_static!{}
332375
// self::lazy_static!{} // Error: lazy_static is not defined in `self`
333376
```
334377

378+
r[macro.decl.scope.macro_use.export]
335379
Macros to be imported with `#[macro_use]` must be exported with
336380
`#[macro_export]`, which is described below.
337381

338382
### Path-Based Scope
339383

384+
r[macro.decl.scope.path]
385+
386+
r[macro.decl.scope.path.intro]
340387
By default, a macro has no path-based scope. However, if it has the
341388
`#[macro_export]` attribute, then it is declared in the crate root scope and can
342389
be referred to normally as such:
@@ -358,11 +405,15 @@ mod mac {
358405
}
359406
```
360407

408+
r[macro.decl.scope.path.export]
361409
Macros labeled with `#[macro_export]` are always `pub` and can be referred to
362410
by other crates, either by path or by `#[macro_use]` as described above.
363411

364412
## Hygiene
365413

414+
r[macro.decl.hygiene]
415+
416+
r[macreo.decl.hygiene.intro]
366417
By default, all identifiers referred to in a macro are expanded as-is, and are
367418
looked up at the macro's invocation site. This can lead to issues if a macro
368419
refers to an item or macro which isn't in scope at the invocation site. To
@@ -406,6 +457,7 @@ pub mod inner {
406457
}
407458
```
408459

460+
r[macro.decl.hygiene.vis]
409461
Additionally, even though `$crate` allows a macro to refer to items within its
410462
own crate when expanding, its use has no effect on visibility. An item or macro
411463
referred to must still be visible from the invocation site. In the following
@@ -429,6 +481,7 @@ fn foo() {}
429481
> modified to use `$crate` or `local_inner_macros` to work well with path-based
430482
> imports.
431483
484+
r[macro.decl.hygeine.local_inner_macros]
432485
When a macro is exported, the `#[macro_export]` attribute can have the
433486
`local_inner_macros` keyword added to automatically prefix all contained macro
434487
invocations with `$crate::`. This is intended primarily as a tool to migrate
@@ -449,9 +502,15 @@ macro_rules! helper {
449502

450503
## Follow-set Ambiguity Restrictions
451504

505+
r[macro.decl.follow-set]
506+
507+
r[macro.decl.follow-set.intro]
452508
The parser used by the macro system is reasonably powerful, but it is limited in
453-
order to prevent ambiguity in current or future versions of the language. In
454-
particular, in addition to the rule about ambiguous expansions, a nonterminal
509+
order to prevent ambiguity in current or future versions of the language.
510+
511+
512+
r[macro.decl.follow-set.token-restriction]
513+
In particular, in addition to the rule about ambiguous expansions, a nonterminal
455514
matched by a metavariable must be followed by a token which has been decided can
456515
be safely used after that kind of match.
457516

@@ -464,19 +523,32 @@ matcher would become ambiguous or would misparse, breaking working code.
464523
Matchers like `$i:expr,` or `$i:expr;` would be legal, however, because `,` and
465524
`;` are legal expression separators. The specific rules are:
466525

526+
r[macro.decl.follow-set.token-expr-stmt]
467527
* `expr` and `stmt` may only be followed by one of: `=>`, `,`, or `;`.
528+
529+
r[macro.decl.follow-set.token-pat_param]
468530
* `pat_param` may only be followed by one of: `=>`, `,`, `=`, `|`, `if`, or `in`.
531+
532+
r[macro.decl.follow-set.token-pat]
469533
* `pat` may only be followed by one of: `=>`, `,`, `=`, `if`, or `in`.
534+
535+
r[macro.decl.follow-set.token-path-ty]
470536
* `path` and `ty` may only be followed by one of: `=>`, `,`, `=`, `|`, `;`,
471537
`:`, `>`, `>>`, `[`, `{`, `as`, `where`, or a macro variable of `block`
472538
fragment specifier.
539+
540+
r[macro.decl.follow-set.token-vis]
473541
* `vis` may only be followed by one of: `,`, an identifier other than a
474542
non-raw `priv`, any token that can begin a type, or a metavariable with a
475543
`ident`, `ty`, or `path` fragment specifier.
544+
545+
r[macro.decl.follow-set.token-other]
476546
* All other fragment specifiers have no restrictions.
477547

548+
r[macro.decl.follow-set.edition2021]
478549
> **Edition differences**: Before the 2021 edition, `pat` may also be followed by `|`.
479550
551+
r[macro.decl.follow-set.repetition]
480552
When repetitions are involved, then the rules apply to every possible number of
481553
expansions, taking separators into account. This means:
482554

0 commit comments

Comments
 (0)