Skip to content

Commit 420e2bc

Browse files
authored
Merge pull request #1625 from chorman0773/spec-add-identifiers-macros-rest
Add spec identifier syntax to macro subchapters
2 parents 9c21bee + 1f10a46 commit 420e2bc

File tree

2 files changed

+126
-11
lines changed

2 files changed

+126
-11
lines changed

src/macros-by-example.md

+80-11
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

@@ -293,12 +332,14 @@ fn foo() {
293332
m!();
294333
}
295334

296-
297335
// m!(); // Error: m is not in scope.
298336
```
299337

300338
### The `macro_use` attribute
301339

340+
r[macro.decl.scope.macro_use]
341+
342+
r[macro.decl.scope.macro_use.mod-decl]
302343
The *`macro_use` attribute* has two purposes. First, it can be used to make a
303344
module's macro scope not end when the module is closed, by applying it to a
304345
module:
@@ -314,6 +355,7 @@ mod inner {
314355
m!();
315356
```
316357

358+
r[macro.decl.scope.macro_use.prelude]
317359
Second, it can be used to import macros from another crate, by attaching it to
318360
an `extern crate` declaration appearing in the crate's root module. Macros
319361
imported this way are imported into the [`macro_use` prelude], not textually,
@@ -332,11 +374,15 @@ lazy_static!{}
332374
// self::lazy_static!{} // Error: lazy_static is not defined in `self`
333375
```
334376

377+
r[macro.decl.scope.macro_use.export]
335378
Macros to be imported with `#[macro_use]` must be exported with
336379
`#[macro_export]`, which is described below.
337380

338381
### Path-Based Scope
339382

383+
r[macro.decl.scope.path]
384+
385+
r[macro.decl.scope.path.intro]
340386
By default, a macro has no path-based scope. However, if it has the
341387
`#[macro_export]` attribute, then it is declared in the crate root scope and can
342388
be referred to normally as such:
@@ -358,11 +404,15 @@ mod mac {
358404
}
359405
```
360406

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

364411
## Hygiene
365412

413+
r[macro.decl.hygiene]
414+
415+
r[macro.decl.hygiene.intro]
366416
By default, all identifiers referred to in a macro are expanded as-is, and are
367417
looked up at the macro's invocation site. This can lead to issues if a macro
368418
refers to an item or macro which isn't in scope at the invocation site. To
@@ -406,6 +456,7 @@ pub mod inner {
406456
}
407457
```
408458

459+
r[macro.decl.hygiene.vis]
409460
Additionally, even though `$crate` allows a macro to refer to items within its
410461
own crate when expanding, its use has no effect on visibility. An item or macro
411462
referred to must still be visible from the invocation site. In the following
@@ -429,6 +480,7 @@ fn foo() {}
429480
> modified to use `$crate` or `local_inner_macros` to work well with path-based
430481
> imports.
431482
483+
r[macro.decl.hygiene.local_inner_macros]
432484
When a macro is exported, the `#[macro_export]` attribute can have the
433485
`local_inner_macros` keyword added to automatically prefix all contained macro
434486
invocations with `$crate::`. This is intended primarily as a tool to migrate
@@ -449,9 +501,14 @@ macro_rules! helper {
449501

450502
## Follow-set Ambiguity Restrictions
451503

504+
r[macro.decl.follow-set]
505+
506+
r[macro.decl.follow-set.intro]
452507
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
508+
order to prevent ambiguity in current or future versions of the language.
509+
510+
r[macro.decl.follow-set.token-restriction]
511+
In particular, in addition to the rule about ambiguous expansions, a nonterminal
455512
matched by a metavariable must be followed by a token which has been decided can
456513
be safely used after that kind of match.
457514

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

524+
r[macro.decl.follow-set.token-expr-stmt]
467525
* `expr` and `stmt` may only be followed by one of: `=>`, `,`, or `;`.
526+
527+
r[macro.decl.follow-set.token-pat_param]
468528
* `pat_param` may only be followed by one of: `=>`, `,`, `=`, `|`, `if`, or `in`.
529+
530+
r[macro.decl.follow-set.token-pat]
469531
* `pat` may only be followed by one of: `=>`, `,`, `=`, `if`, or `in`.
532+
533+
r[macro.decl.follow-set.token-path-ty]
470534
* `path` and `ty` may only be followed by one of: `=>`, `,`, `=`, `|`, `;`,
471535
`:`, `>`, `>>`, `[`, `{`, `as`, `where`, or a macro variable of `block`
472536
fragment specifier.
537+
538+
r[macro.decl.follow-set.token-vis]
473539
* `vis` may only be followed by one of: `,`, an identifier other than a
474540
non-raw `priv`, any token that can begin a type, or a metavariable with a
475541
`ident`, `ty`, or `path` fragment specifier.
542+
543+
r[macro.decl.follow-set.token-other]
476544
* All other fragment specifiers have no restrictions.
477545

546+
r[macro.decl.follow-set.edition2021]
478547
> **Edition differences**: Before the 2021 edition, `pat` may also be followed by `|`.
479548
549+
r[macro.decl.follow-set.repetition]
480550
When repetitions are involved, then the rules apply to every possible number of
481551
expansions, taking separators into account. This means:
482552

@@ -490,7 +560,6 @@ expansions, taking separators into account. This means:
490560
* If the repetition can match zero times (`*` or `?`), then whatever comes
491561
after must be able to follow whatever comes before.
492562

493-
494563
For more detail, see the [formal specification].
495564

496565
[const block]: expressions/block-expr.md#const-blocks

0 commit comments

Comments
 (0)