|
24 | 24 | > [_Token_]<sub>_except $ and delimiters_</sub>\
|
25 | 25 | > | _MacroMatcher_\
|
26 | 26 | > | `$` [IDENTIFIER] `:` _MacroFragSpec_\
|
27 |
| -> | `$` `(` _MacroMatch_<sup>+</sup> `)` _MacroRepSep_<sup>?</sup> _MacroKleeneOp_ |
| 27 | +> | `$` `(` _MacroMatch_<sup>+</sup> `)` _MacroRepSep_<sup>?</sup> _MacroRepOp_ |
28 | 28 | >
|
29 | 29 | > _MacroFragSpec_ :\
|
30 | 30 | > `block` | `expr` | `ident` | `item` | `lifetime` | `literal`\
|
31 | 31 | > | `meta` | `pat` | `path` | `stmt` | `tt` | `ty` | `vis`
|
32 | 32 | >
|
33 | 33 | > _MacroRepSep_ :\
|
34 |
| -> [_Token_]<sub>_except delimiters and kleene operators_</sub> |
| 34 | +> [_Token_]<sub>_except delimiters and repetition operators_</sub> |
35 | 35 | >
|
36 |
| -> _MacroKleeneOp_<sub>2015</sub> :\ |
37 |
| -> `*` | `+` |
38 |
| -> |
39 |
| -> _MacroKleeneOp_<sub>2018+</sub> :\ |
40 |
| -> `*` | `+` | `?` |
| 36 | +> _MacroRepOp_<sub>2018+</sub> :\ |
| 37 | +> `*` | `+` | `?`<sub>2018+</sub> |
41 | 38 | >
|
42 | 39 | > _MacroTranscriber_ :\
|
43 | 40 | > [_DelimTokenTree_]
|
44 | 41 |
|
45 | 42 | `macro_rules` allows users to define syntax extension in a declarative way. We
|
46 | 43 | call such extensions "macros by example" or simply "macros".
|
47 | 44 |
|
48 |
| -Macros can expand to expressions, statements, items, types, or patterns. |
49 |
| - |
50 |
| -The macro expander looks up macro invocations by name, and tries each macro |
51 |
| -rule in turn. It transcribes the first successful match. Matching and |
52 |
| -transcription are closely related to each other, and we will describe them |
53 |
| -together. |
54 |
| - |
55 |
| -The macro expander matches and transcribes every token that does not begin with |
56 |
| -a `$` literally, including delimiters. For parsing reasons, delimiters must be |
57 |
| -balanced, but they are otherwise not special. |
58 |
| - |
59 |
| -In the matcher, `$` _name_ `:` _designator_ matches the nonterminal in the Rust |
60 |
| -syntax named by _designator_. Valid designators are: |
61 |
| - |
62 |
| -* `item`: an [_Item_] |
63 |
| -* `block`: a [_BlockExpression_] |
64 |
| -* `stmt`: a [_Statement_] without the trailing semicolon |
65 |
| -* `pat`: a [_Pattern_] |
66 |
| -* `expr`: an [_Expression_] |
67 |
| -* `ty`: a [_Type_] |
68 |
| -* `ident`: an [IDENTIFIER_OR_KEYWORD] |
69 |
| -* `path`: a [_TypePath_] style path |
70 |
| -* `tt`: a [_TokenTree_] (a single [token] or tokens in matching delimiters `()`, `[]`, or `{}`) |
71 |
| -* `meta`: a [_MetaItem_], the contents of an attribute |
72 |
| -* `lifetime`: a [LIFETIME_TOKEN] |
73 |
| -* `vis`: a [_Visibility_] qualifier |
74 |
| -* `literal`: matches `-`<sup>?</sup>[_LiteralExpression_] |
| 45 | +Each macro by example has a name, and one or more _rules_. Each rule has two |
| 46 | +parts: a _matcher_, describing the syntax that it matches, and a _transcriber_, |
| 47 | +describing the syntax that will replace a successfully matched invocation. Both |
| 48 | +the matcher and the transcriber must be surrounded by delimiters. Macros can |
| 49 | +expand to expressions, statements, items (including traits, impls, and foreign |
| 50 | +items), types, or patterns. |
| 51 | + |
| 52 | +When a macro is invoked, the macro expander looks up macro invocations by name, |
| 53 | +and tries each macro rule in turn. It transcribes the first successful match; if |
| 54 | +this results in an error, then future matches are not tried. When matching, no |
| 55 | +lookahead is performed; if the compiler cannot unambiguously determine how to |
| 56 | +parse the macro invocation one token at a time, then it is an error. In the |
| 57 | +following example, the compiler does not look ahead past the identifier to see |
| 58 | +if the following token is a `)`, even though that would allow it to parse the |
| 59 | +invocation unambiguously: |
| 60 | + |
| 61 | +```rust,compile_fail |
| 62 | +macro_rules! ambiguity { |
| 63 | + ($($i:ident)* $j:ident) => { ($($i)-*) * $j }; |
| 64 | +} |
| 65 | +
|
| 66 | +ambiguity!(error); // Error: local ambiguity |
| 67 | +``` |
| 68 | + |
| 69 | +In both the matcher and the transcriber, the `$` token is used to invoke special |
| 70 | +behaviours from the macro engine. Tokens that aren't part of such an invocation |
| 71 | +are matched and transcribed literally, with one exception. The exception is that |
| 72 | +the outer delimiters for the matcher will match any pair of delimiters. Thus, |
| 73 | +for instance, the matcher `(())` will match `{()}` but not `{{}}`. The character |
| 74 | +`$` cannot be matched or transcribed literally. |
| 75 | + |
| 76 | +## Metavariables |
| 77 | + |
| 78 | +In the matcher, `$` _name_ `:` _fragment-specifier_ matches a Rust syntax |
| 79 | +fragment of the kind specified and binds it to the metavariable `$`_name_. Valid |
| 80 | +fragment specifiers are: |
| 81 | + |
| 82 | + * `item`: an [_Item_] |
| 83 | + * `block`: a [_BlockExpression_] |
| 84 | + * `stmt`: a [_Statement_] without the trailing semicolon (except for item |
| 85 | + statements that require semicolons) |
| 86 | + * `pat`: a [_Pattern_] |
| 87 | + * `expr`: an [_Expression_] |
| 88 | + * `ty`: a [_Type_] |
| 89 | + * `ident`: an [IDENTIFIER_OR_KEYWORD] |
| 90 | + * `path`: a [_TypePath_] style path |
| 91 | + * `tt`: a [_TokenTree_] (a single [token] or tokens in matching delimiters `()`, `[]`, or `{}`) |
| 92 | + * `meta`: a [_MetaItem_], the contents of an attribute |
| 93 | + * `lifetime`: a [LIFETIME_TOKEN] |
| 94 | + * `vis`: a possibly empty [_Visibility_] qualifier |
| 95 | + * `literal`: matches `-`<sup>?</sup>[_LiteralExpression_] |
| 96 | + |
| 97 | +In the transcriber, metavariables are referred to simply by $`_name_`, since |
| 98 | +the fragment kind is specified in the matcher. Metavariables are replaced with |
| 99 | +the syntax element that matched them. The keyword metavariable `$crate` can be |
| 100 | +used to refer to the current crate; see [Hygiene] below. Metavariables can be |
| 101 | +transcribed more than once or not at all. |
| 102 | + |
| 103 | +## Repititions |
| 104 | + |
| 105 | +In both the matcher and transcriber, repetitions are indicated by placing the |
| 106 | +tokens to be repeated inside `$( ... )`, followed by a repetition operator, |
| 107 | +optionally with a separator token between. The separator token can be any token |
| 108 | +other than a delimiter or one of the repetition operators, but `;` and `,` are |
| 109 | +the most common. For instance, `$( $i:ident ),*` represents any number of |
| 110 | +identifiers separated by commas. Nested repititions are permitted. |
| 111 | + |
| 112 | +The repetition operators are `*`, which indicates any number of repetitions, |
| 113 | +`+`, which indicates any number but at least one, and `?` which indicates an |
| 114 | +optional fragment with zero or one occurrences. Since `?` represents at most one |
| 115 | +occurrence, it cannot be used with a separator. |
| 116 | + |
| 117 | +The repeated fragment both matches and transcribes to the specified number of |
| 118 | +the fragment, separated by the separator token. Metavariables are matched to |
| 119 | +every repetition of their corresponding fragment, so for instance, the `$( |
| 120 | +$i:ident ),*` example above matches `$i` to all of the identifiers in the list. |
| 121 | + |
| 122 | +During transcription, additional restrictions apply to repititions so that the |
| 123 | +compiler knows how to expand them properly. First, a metavariable must appear in |
| 124 | +exactly the same number, kind, and nesting order of repetitions in the |
| 125 | +transcriber as it did in the matcher. So for the matcher `$( $i:ident ),*`, the |
| 126 | +transcribers `=> $i`, `=> $( $( $i)* )*`, and `=> $( $i )+` are all illegal, but |
| 127 | +`=> $( $i );*` is correct and replaces a comma-separated list of identifiers |
| 128 | +with a semicolon-separated list. |
| 129 | + |
| 130 | +Second, each repetition in the transcriber must contain at least one |
| 131 | +metavariable in order to decide now many times to expand it. If multiple |
| 132 | +metavariables appear in the same repetition, they must be bound to the same |
| 133 | +number of fragments. For instance, `( $( $i:ident ),* ; $( $j:ident ),* ) => ( |
| 134 | +$( ($i,$j) ),*` must bind the same number of `$i` fragments as `$j` fragments. |
| 135 | +This means that invoking the macro with `(a, b, c; d, e, f`) is legal and |
| 136 | +expands to `((a,d), (b,e), c,f))`, but `(a, b, c; d, e)` is illegal because it |
| 137 | +does not have the same number. This requirement applies to every layer of nested |
| 138 | +repetitions. |
| 139 | + |
| 140 | +> **Edition Differences**: The `?` repetition operator did not exist before the |
| 141 | +> 2018 edition. Prior to the 2018 Edition, `?` was an allowed |
| 142 | +> separator token, rather than a repetition operator. |
| 143 | +
|
| 144 | +## Scoping, Exporting, and Importing |
| 145 | + |
| 146 | +For historical reasons, the scoping of macros by example does not work entirely like |
| 147 | +items. Macros have two forms of scope: textual scope, and path-based scope. |
| 148 | +Textual scope is based on the order that things appear in source files, or even |
| 149 | +across multiple files, and is the default scoping. It's explained further below. |
| 150 | +Path-based scope works exactly the same way that item scoping does. The scoping, |
| 151 | +exporting, and importing of macros is controlled largely by attributes. |
| 152 | + |
| 153 | +When a macro is invoked by an unqualified identifier (not part of a multi-part |
| 154 | +path), it's first looked up in textual scoping. If this does not yield any |
| 155 | +results, then it is looked up in path-based scoping. If the macro's name is |
| 156 | +qualified with a path, then it is only looked up in path-based scoping. |
| 157 | + |
| 158 | +```rust,ignore |
| 159 | +use lazy_static::lazy_static; // Path-based import. |
| 160 | +
|
| 161 | +macro_rules! lazy_static { // Textual definition. |
| 162 | + (lazy) => {}; |
| 163 | +} |
| 164 | +
|
| 165 | +lazy_static!{lazy} // Textual lookup finds our macro first. |
| 166 | +self::lazy_static!{} // Path-based lookup ignores our macro, finds imported one. |
| 167 | +``` |
| 168 | + |
| 169 | +### Textual Scope |
| 170 | + |
| 171 | +Textual scope is based largely on the order that things appear in source files, |
| 172 | +and works similarly to the scope of local variables declared with `let` except |
| 173 | +it also applies at the module level. When `macro_rules!` is used to define a |
| 174 | +macro, the macro enters scope after the definition (note that it can still be |
| 175 | +used recursively, since names are looked up from the invocation site), up until |
| 176 | +its surrounding scope, typically a module, is closed. This can enter child |
| 177 | +modules and even span across multiple files: |
| 178 | + |
| 179 | +```rust,ignore |
| 180 | +//// src/lib.rs |
| 181 | +mod has_macro { |
| 182 | + // m!{} // Error: m is not in scope. |
| 183 | +
|
| 184 | + macro_rules! m { |
| 185 | + () => {}; |
| 186 | + } |
| 187 | + m!{} // OK: appears after declaration of m. |
| 188 | +
|
| 189 | + mod uses_macro; |
| 190 | +} |
| 191 | +
|
| 192 | +// m!{} // Error: m is not in scope. |
| 193 | +
|
| 194 | +//// src/has_macro/uses_macro.rs |
| 195 | +
|
| 196 | +m!{} // OK: appears after delcaration of m in src/lib.rs |
| 197 | +``` |
| 198 | + |
| 199 | +It is not an error to define a macro multiple times; the most recent declaration |
| 200 | +will shadow the previous one unless it has gone out of scope. |
| 201 | + |
| 202 | +```rust |
| 203 | +macro_rules! m { |
| 204 | + (1) => {}; |
| 205 | +} |
| 206 | + |
| 207 | +m!(1); |
| 208 | + |
| 209 | +mod inner { |
| 210 | + m!(1); |
| 211 | + |
| 212 | + macro_rules! m { |
| 213 | + (2) => {}; |
| 214 | + } |
| 215 | + // m!(1); // Error: no rule matches '1' |
| 216 | + m!(2); |
| 217 | + |
| 218 | + macro_rules! m { |
| 219 | + (3) => {}; |
| 220 | + } |
| 221 | + m!(3); |
| 222 | +} |
| 223 | + |
| 224 | +m!(1); |
| 225 | +``` |
| 226 | + |
| 227 | +Macros can be declared and used locally inside functions as well, and work |
| 228 | +similarly: |
| 229 | + |
| 230 | +```rust |
| 231 | +fn foo() { |
| 232 | + // m!(); // Error: m is not in scope. |
| 233 | + macro_rules! m { |
| 234 | + () => {}; |
| 235 | + } |
| 236 | + m!(); |
| 237 | +} |
| 238 | + |
| 239 | + |
| 240 | +// m!(); // Error: m is not in scope. |
| 241 | +``` |
| 242 | + |
| 243 | +The `#[macro_use]` attribute has two purposes. First, it can be used to make a |
| 244 | +module's macro scope not end when the module is closed, by applying it to a |
| 245 | +module: |
| 246 | + |
| 247 | +```rust |
| 248 | +#[macro_use] |
| 249 | +mod inner { |
| 250 | + macro_rules! m { |
| 251 | + () => {}; |
| 252 | + } |
| 253 | +} |
| 254 | + |
| 255 | +m!(); |
| 256 | +``` |
| 257 | + |
| 258 | +Second, it can be used to import macros from another crate, by attaching it to |
| 259 | +an `extern crate` declaration appearing in the crate's root module. Macros |
| 260 | +imported this way are imported into the prelude of the crate, not textually, |
| 261 | +which means that they can be uare shadowed by any other name. While macros |
| 262 | +imported by `#[macro_use]` can be used before the import statement, in case of a |
| 263 | +conflict, the last macro imported wins. Optionally, a list of macros to import |
| 264 | +can be specified; this is not supported when `#[macro_use]` is applied to a |
| 265 | +module. |
| 266 | + |
| 267 | +```rust,ignore |
| 268 | +#[macro_use(lazy_static)] // Or #[macro_use] to import all macros. |
| 269 | +extern crate lazy_static; |
| 270 | +
|
| 271 | +lazy_static!{}; |
| 272 | +// self::lazy_static!{} // Error: lazy_static is not defined inself |
| 273 | +``` |
| 274 | + |
| 275 | +Macros to be imported with `#[macro_use]` must be exported with |
| 276 | +`#[macro_export]`, which is described below. |
| 277 | + |
| 278 | +### Path-Based Scope |
| 279 | + |
| 280 | +By default, a macro has no path-based scope. However, if it has the |
| 281 | +`#[macro_export]` attribute, then it is declared in the crate root scope and can |
| 282 | +be referred to normally as such: |
| 283 | + |
| 284 | +```rust |
| 285 | +self::m!(); |
| 286 | +m!(); // OK: Path-based lookup finds m in the current module. |
| 287 | + |
| 288 | +mod inner { |
| 289 | + super::m!(); |
| 290 | + crate::m!(); |
| 291 | +} |
| 292 | + |
| 293 | +mod mac { |
| 294 | + #[macro_export] |
| 295 | + macro_rules! m { |
| 296 | + () => {}; |
| 297 | + } |
| 298 | +} |
| 299 | +``` |
| 300 | + |
| 301 | +Macros labeled with `#[macro_export]` are always `pub` and can be referred to |
| 302 | +by other crates, either by path or by `#[macro_use]` as described above. |
| 303 | + |
| 304 | +## Hygiene |
| 305 | + |
| 306 | +By default, all identifiers referred to in a macro are expanded as-is, and are |
| 307 | +looked up at the macro's invocation site. This can lead to issues if a macro |
| 308 | +refers to an item or macro which isn't in scope at the invocation site. In order |
| 309 | +to alleviate this, the `$crate` metavariable can be used at the start of a path |
| 310 | +in order to force lookup to occur inside the crate defining the macro. |
| 311 | + |
| 312 | +```rust,ignore |
| 313 | +//// Definitions in the `helper_macro` crate. |
| 314 | +#[macro_export] |
| 315 | +macro_rules! helped { |
| 316 | + // () => { helper!() } // This might lead to an error due to 'helper' not being in scope. |
| 317 | + () => { $crate::helper!() } |
| 318 | +} |
| 319 | +
|
| 320 | +#[macro_export] |
| 321 | +macro_rules! helper { |
| 322 | + () => { () } |
| 323 | +} |
| 324 | +
|
| 325 | +//// Usage in another crate. |
| 326 | +// Note that `helper_macro::helper` is not imported! |
| 327 | +use helper_macro::helped; |
| 328 | +
|
| 329 | +fn unit() { |
| 330 | + helped!(); |
| 331 | +} |
| 332 | +``` |
| 333 | + |
| 334 | +Note that, because `$crate` refers to the current crate, it must be used with a |
| 335 | +fully qualified module path when referring to non-macro items: |
| 336 | + |
| 337 | +```rust |
| 338 | +pub mod inner { |
| 339 | + #[macro_export] |
| 340 | + macro_rules! call_foo { |
| 341 | + () => { $crate::inner::foo() }; |
| 342 | + } |
| 343 | + |
| 344 | + pub fn foo() {} |
| 345 | +} |
| 346 | +``` |
| 347 | + |
| 348 | +Additionally, even though `$crate` allows a macro to refer to items within its |
| 349 | +own crate when expanding, its use has no effect on visibility. An item or macro |
| 350 | +referred to must still be visible from the invocation site. In the following |
| 351 | +example, any attempt to invoke `call_foo!()` from outside its crate will fail |
| 352 | +because `foo()` is not public. |
| 353 | + |
| 354 | +```rust |
| 355 | +#[macro_export] |
| 356 | +macro_rules! call_foo { |
| 357 | + () => { $crate::foo() }; |
| 358 | +} |
| 359 | + |
| 360 | +fn foo() {} |
| 361 | +``` |
| 362 | + |
| 363 | +> **Version & Edition Differences**: Prior to Rust 1.30, `$crate` and |
| 364 | +> `local_inner_macros` (below) were unsupported. They were added alongside |
| 365 | +> path-based imports of macros (described above), in order to ensure that helper |
| 366 | +> macros did not need to be manually imported by users of a macro-exporting |
| 367 | +> crate. Crates written for earlier versions of Rust that use helper macros need |
| 368 | +> to be modified to use `$crate` or `local_inner_macros` in order to work well |
| 369 | +> with path-based imports. |
| 370 | +
|
| 371 | +When a macro is exported, the `#[macro_export]` attribute can have the |
| 372 | +`local_inner_macros` keyword added in order to automatically prefix all |
| 373 | +contained macro invocations with `$crate::`. This is intended primarily as a |
| 374 | +tool to migrate code written before `$crate` was added to the language to work |
| 375 | +with Rust 2018's path-based imports of macros. Its use is discouraged in new |
| 376 | +code. |
| 377 | + |
| 378 | +```rust |
| 379 | +#[macro_export(local_inner_macros)] |
| 380 | +macro_rules! helped { |
| 381 | + () => { helper!() } // Automatically converted to $crate::helper!(). |
| 382 | +} |
| 383 | + |
| 384 | +#[macro_export] |
| 385 | +macro_rules! helper { |
| 386 | + () => { () } |
| 387 | +} |
| 388 | +``` |
| 389 | + |
| 390 | +## Follow-set Ambiguity Restrictions |
| 391 | + |
| 392 | +The parser used by the macro system is reasonably powerful, but it is limited in |
| 393 | +order to prevent ambiguity in current or future versions of the language. In |
| 394 | +particular, in addition to the rule about ambiguous expansions, a nonterminal |
| 395 | +matched by a metavariable must be followed by a token which has been decided can |
| 396 | +be safely used after that kind of match. |
| 397 | + |
| 398 | +As an example, a macro matcher like `$i:expr [ , ]` could in theory be accepted |
| 399 | +in Rust today, since `[,]` cannot be part of a legal expression and therefore |
| 400 | +the parse would always be unambiguous. However, because `[` can start trailing |
| 401 | +expressions, `[` is not a character which can safely be ruled out as coming |
| 402 | +after an expression. If `[,]` were accepted in a later version of Rust, this |
| 403 | +matcher would become ambiguous or would misparse, breaking working code. |
| 404 | +Matchers like `$i:expr,` or `$i:expr;` would be legal, however, because `,` and |
| 405 | +`;` are legal expression separators. The specific rules are: |
| 406 | + |
| 407 | + * `expr` and `stmt` may only be followed by one of: `=>`, `,`, or `;`. |
| 408 | + * `pat` may only be followed by one of: `=>`, `,`, `=`, `|`, `if`, or `in`. |
| 409 | + * `path` and `ty` may only be followed by one of: `=>`, `,`, `=`, `|`, `;`, |
| 410 | + `:`, `>`, `>>`, `[`, `{`, `as`, `where`, or a macro variable of `block` |
| 411 | + fragment specifier. |
| 412 | + * `vis` may only be followed by one of: `,`, an identifier other than a |
| 413 | + non-raw `priv`, any token that can begin a type, or a metavariable with a |
| 414 | + `ident`, `ty`, or `path` fragment specifier. |
| 415 | + * All other fragment specifiers have no restrictions. |
| 416 | + |
| 417 | +When repetitions are involved, then the rules apply to every possible number of |
| 418 | +expansions, taking separators into account. This means: |
| 419 | + |
| 420 | + * If the repetition includes a separator, that separator must be able to |
| 421 | + follow the contents of the repitition. |
| 422 | + * If the repitition can repeat multiple times (`*` or `+`), then the contents |
| 423 | + must be able to follow themselves. |
| 424 | + * The contents of the repetition must be able to follow whatever comes |
| 425 | + before, and whatever comes after must be able to follow the contents of the |
| 426 | + repitition. |
| 427 | + * If the repitition can match zero times (`*` or `?`), then whatever comes |
| 428 | + after must be able to follow whatever comes before. |
| 429 | + |
| 430 | + |
| 431 | +For more detail, see the [formal specification]. |
75 | 432 |
|
76 | 433 | [IDENTIFIER]: identifiers.html
|
77 | 434 | [IDENTIFIER_OR_KEYWORD]: identifiers.html
|
78 | 435 | [LIFETIME_TOKEN]: tokens.html#lifetimes-and-loop-labels
|
| 436 | +[formal specification]: macro-ambiguity.html |
79 | 437 | [_BlockExpression_]: expressions/block-expr.html
|
| 438 | +[_DelimTokenTree_]: macros.html |
80 | 439 | [_Expression_]: expressions.html
|
81 | 440 | [_Item_]: items.html
|
82 | 441 | [_LiteralExpression_]: expressions/literal-expr.html
|
83 | 442 | [_MetaItem_]: attributes.html
|
84 | 443 | [_Pattern_]: patterns.html
|
85 | 444 | [_Statement_]: statements.html
|
86 | 445 | [_TokenTree_]: macros.html#macro-invocation
|
| 446 | +[_Token_]: tokens.html |
87 | 447 | [_TypePath_]: paths.html#paths-in-types
|
88 | 448 | [_Type_]: types.html#type-expressions
|
89 | 449 | [_Visibility_]: visibility-and-privacy.html
|
90 | 450 | [token]: tokens.html
|
91 |
| - |
92 |
| -In the transcriber, the |
93 |
| -designator is already known, and so only the name of a matched nonterminal comes |
94 |
| -after the dollar sign. |
95 |
| - |
96 |
| -In both the matcher and transcriber, the Kleene star-like operator indicates |
97 |
| -repetition. The Kleene star operator consists of `$` and parentheses, |
98 |
| -optionally followed by a separator token, followed by `*`, `+`, or `?`. `*` |
99 |
| -means zero or more repetitions; `+` means _at least_ one repetition; `?` means |
100 |
| -at most one repetition. The parentheses are not matched or transcribed. On the |
101 |
| -matcher side, a name is bound to _all_ of the names it matches, in a structure |
102 |
| -that mimics the structure of the repetition encountered on a successful match. |
103 |
| -The job of the transcriber is to sort that structure out. Also, `?`, unlike `*` |
104 |
| -and `+`, does _not_ allow a separator, since one could never match against it |
105 |
| -anyway. |
106 |
| - |
107 |
| -> **Edition Differences**: The `?` Kleene operator did not exist before the |
108 |
| -> 2018 edition. |
109 |
| -
|
110 |
| -> **Edition Differences**: Prior to the 2018 Edition, `?` was an allowed |
111 |
| -> separator token, rather than a Kleene operator. It is no longer allowed as a |
112 |
| -> separator as of the 2018 edition. This avoids ambiguity with the `?` Kleene |
113 |
| -> operator. |
114 |
| -
|
115 |
| -The rules for transcription of these repetitions are called "Macro By Example". |
116 |
| -Essentially, one "layer" of repetition is discharged at a time, and all of them |
117 |
| -must be discharged by the time a name is transcribed. Therefore, `( $( $i:ident |
118 |
| -),* ) => ( $i )` is an invalid macro, but `( $( $i:ident ),* ) => ( $( $i:ident |
119 |
| -),* )` is acceptable (if trivial). |
120 |
| - |
121 |
| -When Macro By Example encounters a repetition, it examines all of the `$` |
122 |
| -_name_ s that occur in its body. At the "current layer", they all must repeat |
123 |
| -the same number of times, so ` ( $( $i:ident ),* ; $( $j:ident ),* ) => ( $( |
124 |
| -($i,$j) ),* )` is valid if given the argument `(a,b,c ; d,e,f)`, but not |
125 |
| -`(a,b,c ; d,e)`. The repetition walks through the choices at that layer in |
126 |
| -lockstep, so the former input transcribes to `(a,d), (b,e), (c,f)`. |
127 |
| - |
128 |
| -Nested repetitions are allowed. |
129 |
| - |
130 |
| -### Parsing limitations |
131 |
| - |
132 |
| -The parser used by the macro system is reasonably powerful, but the parsing of |
133 |
| -Rust syntax is restricted in two ways: |
134 |
| - |
135 |
| -1. Macro definitions are required to include suitable separators after parsing |
136 |
| - expressions and other bits of the Rust grammar. This implies that |
137 |
| - a macro definition like `$i:expr [ , ]` is not legal, because `[` could be part |
138 |
| - of an expression. A macro definition like `$i:expr,` or `$i:expr;` would be legal, |
139 |
| - however, because `,` and `;` are legal separators. See [RFC 550] for more information. |
140 |
| - Specifically: |
141 |
| - |
142 |
| - * `expr` and `stmt` may only be followed by one of `=>`, `,`, or `;`. |
143 |
| - * `pat` may only be followed by one of `=>`, `,`, `=`, `|`, `if`, or `in`. |
144 |
| - * `path` and `ty` may only be followed by one of `=>`, `,`, `=`, `|`, `;`, |
145 |
| - `:`, `>`, `>>`, `[`, `{`, `as`, `where`, or a macro variable of `block` |
146 |
| - fragment type. |
147 |
| - * `vis` may only be followed by one of `,`, `priv`, a raw identifier, any |
148 |
| - token that can begin a type, or a macro variable of `ident`, `ty`, or |
149 |
| - `path` fragment type. |
150 |
| - * All other fragment types have no restrictions. |
151 |
| - |
152 |
| -2. The parser must have eliminated all ambiguity by the time it reaches a `$` |
153 |
| - _name_ `:` _designator_. This requirement most often affects name-designator |
154 |
| - pairs when they occur at the beginning of, or immediately after, a `$(...)*`; |
155 |
| - requiring a distinctive token in front can solve the problem. For example: |
156 |
| - |
157 |
| - ```rust |
158 |
| - // The matcher `$($i:ident)* $e:expr` would be ambiguous because the parser |
159 |
| - // would be forced to choose between an identifier or an expression. Use some |
160 |
| - // token to distinguish them. |
161 |
| - macro_rules! example { |
162 |
| - ($(I $i:ident)* E $e:expr) => { ($($i)-*) * $e }; |
163 |
| - } |
164 |
| - let foo = 2; |
165 |
| - let bar = 3; |
166 |
| - // The following expands to `(foo - bar) * 5` |
167 |
| - example!(I foo I bar E 5); |
168 |
| - ``` |
169 |
| - |
170 |
| -[RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md |
171 |
| -[_DelimTokenTree_]: macros.html |
172 |
| -[_Token_]: tokens.html |
| 451 | +[Hygiene]: #hygiene |
0 commit comments