@@ -555,28 +555,45 @@ Users of `rustc` can define new syntax extensions in two ways:
555
555
556
556
## Macros
557
557
558
- ` macro_rules ` allows users to define syntax extension in a declarative way. We
559
- call such extensions "macros by example" or simply "macros" — to be distinguished
560
- from the "procedural macros" defined in [ compiler plugins] [ plugin ] .
558
+ ` macro_rules ` allows users to define syntax extensions in a declarative way.
559
+ We call such extensions "macros by example" or simply "macros" — to be
560
+ distinguished from the "procedural macros" defined in [ compiler plugins] [ plugin ] .
561
561
562
- Currently, macros can expand to expressions, statements, items, or patterns.
562
+ As shown below, the body of a ` macro_rules ` macro consists of one or more
563
+ semicolon-separated arms, similar in appearance to a ` match ` statement. On
564
+ the left side of the ` => ` is a matcher describing the syntax that the macro
565
+ accepts, optionally capturing parts of it for use in the transcriber, which
566
+ is on the right side of the ` => ` . (Choice of delimiters for the macro body,
567
+ matchers, and transcribers is arbitrary.)
563
568
564
- (A ` sep_token ` is any token other than ` * ` and ` + ` . A ` non_special_token ` is
565
- any token other than a delimiter or ` $ ` .)
569
+ ``` rust,ignore
570
+ macro_rules! /* name of macro */ {
571
+ (/* matcher for arm 1 */) => { /* transcriber for arm 1 */ };
572
+ (/* matcher for arm 2 */) => { /* transcriber for arm 2 */ }
573
+ }
574
+ ```
566
575
567
- The macro expander looks up macro invocations by name, and tries each macro
568
- rule in turn. It transcribes the first successful match. Matching and
576
+ Currently, macros can expand to expressions, statements, items, patterns, or
577
+ types[ ^ typemacros ] . This distinction is inferred from the context in which the
578
+ macro is invoked, and carefully written macros may work in multiple contexts.
579
+
580
+ [ ^ typemacros ] : Gated by
581
+ [ the ` type_macros ` feature] ( https://github.com/rust-lang/rust/issues/27245 ) .
582
+
583
+ The macro expander looks up macro invocations by name, and tries each
584
+ arm in turn. It transcribes the first successful match. Matching and
569
585
transcription are closely related to each other, and we will describe them
570
586
together.
571
587
572
- ### Macro By Example
588
+ ### Macros By Example
573
589
574
590
The macro expander matches and transcribes every token that does not begin with
575
591
a ` $ ` literally, including delimiters. For parsing reasons, delimiters must be
576
592
balanced, but they are otherwise not special.
577
593
578
594
In the matcher, ` $ ` _ name_ ` : ` _ designator_ matches the nonterminal in the Rust
579
- syntax named by _ designator_ . Valid designators are:
595
+ syntax named by _ designator_ (also called a _ fragment specifier_ ). Valid
596
+ designators are:
580
597
581
598
* ` item ` : an [ item] ( #items )
582
599
* ` block ` : a [ block] ( #block-expressions )
@@ -586,36 +603,36 @@ syntax named by _designator_. Valid designators are:
586
603
* ` ty ` : a [ type] ( #types )
587
604
* ` ident ` : an [ identifier] ( #identifiers )
588
605
* ` path ` : a [ path] ( #paths )
589
- * ` tt ` : either side of the ` => ` in macro rules
606
+ * ` tt ` : a "token tree": either one [ token] ( #token ) or a delimited sequence
607
+ of token trees
590
608
* ` meta ` : the contents of an [ attribute] ( #attributes )
591
609
592
- In the transcriber, the
593
- designator is already known, and so only the name of a matched nonterminal comes
594
- after the dollar sign.
610
+ In the transcriber, the designator is already known, and so only the name of a matched
611
+ nonterminal comes after the dollar sign.
595
612
596
- In both the matcher and transcriber, the Kleene star-like operator indicates
613
+ In both the matcher and transcriber, the Kleene star operator indicates
597
614
repetition. The Kleene star operator consists of ` $ ` and parentheses, optionally
598
615
followed by a separator token, followed by ` * ` or ` + ` . ` * ` means zero or more
599
- repetitions, ` + ` means at least one repetition. The parentheses are not matched or
616
+ repetitions; ` + ` means at least one repetition. The parentheses are not matched or
600
617
transcribed. On the matcher side, a name is bound to _ all_ of the names it
601
618
matches, in a structure that mimics the structure of the repetition encountered
602
619
on a successful match. The job of the transcriber is to sort that structure
603
620
out.
604
621
605
- The rules for transcription of these repetitions are called "Macro By Example".
622
+ The rules for transcription of these repetitions are called "Macros By Example".
606
623
Essentially, one "layer" of repetition is discharged at a time, and all of them
607
624
must be discharged by the time a name is transcribed. Therefore, `( $( $i: ident
608
- ),* ) => ( $i )` is an invalid macro, but ` ( $( $i: ident ),* ) => ( $( $i: ident
609
- ), * )` is acceptable (if trivial).
625
+ ),* ) => ( $i )` is an invalid macro, but ` ( $( $i: ident ),* ) => ( $( $i ), * )`
626
+ is acceptable (though trivial).
610
627
611
- When Macro By Example encounters a repetition, it examines all of the ` $ `
628
+ When Macros By Example encounters a repetition, it examines all of the ` $ `
612
629
_ name_ s that occur in its body. At the "current layer", they all must repeat
613
630
the same number of times, so ` ( $( $i: ident ),* ; $( $j: ident ),* ) => ( $(
614
631
($i,$j) ),* )` is valid if given the argument ` (a,b,c ; d,e,f)`, but not
615
632
` (a,b,c ; d,e) ` . The repetition walks through the choices at that layer in
616
633
lockstep, so the former input transcribes to ` (a,d), (b,e), (c,f) ` .
617
634
618
- Nested repetitions are allowed.
635
+ Nested repetitions are allowed. In the transcriber, ` * ` vs ` + ` does not matter.
619
636
620
637
### Parsing limitations
621
638
@@ -634,6 +651,8 @@ Rust syntax is restricted in two ways:
634
651
635
652
[ RFC 550 ] : https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md
636
653
654
+ ### Scoping
655
+
637
656
# Crates and source files
638
657
639
658
Although Rust, like any other language, can be implemented by an interpreter as
0 commit comments