Skip to content

Commit 220f9a4

Browse files
committed
Grammar: macros
1 parent 457b072 commit 220f9a4

9 files changed

+197
-19
lines changed

src/expressions.md

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
>       | [_BreakExpression_]\
2727
>       | [_RangeExpression_]\
2828
>       | [_ReturnExpression_]\
29+
>       | [_MacroInvocation_]\
2930
>    )
3031
>
3132
> _ExpressionWithBlock_ :\
@@ -341,6 +342,7 @@ They are never allowed before:
341342
[_LazyBooleanExpression_]: expressions/operator-expr.html#lazy-boolean-operators
342343
[_LiteralExpression_]: expressions/literal-expr.html
343344
[_LoopExpression_]: expressions/loop-expr.html
345+
[_MacroInvocation_]: macros.html#macro-invocation
344346
[_MatchExpression_]: expressions/match-expr.html
345347
[_MethodCallExpression_]: expressions/method-call-expr.html
346348
[_OperatorExpression_]: expressions/operator-expr.html

src/items.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
>       | [_Trait_]\
1818
>       | [_Implementation_]\
1919
>       | [_ExternBlock_]\
20-
>       | _Macro_\
21-
>       | _MacroDefinition_\
20+
>       | [_MacroInvocationSemi_] [^novis]\
21+
>       | [_MacroRulesDefinition_] [^novis]\
2222
>    )
2323
2424
An _item_ is a component of a crate. Items are organized within a crate by a
@@ -55,12 +55,16 @@ qualified by the name of the enclosing item, or is private to the enclosing
5555
item (in the case of functions). The grammar specifies the exact locations in
5656
which sub-item declarations may appear.
5757

58+
[^novis]: Macros may not start with a visibility modifier.
59+
5860
[_ConstantItem_]: items/constant-items.html
5961
[_Enumeration_]: items/enumerations.html
6062
[_ExternBlock_]: items/external-blocks.html
6163
[_ExternCrate_]: items/extern-crates.html
6264
[_Function_]: items/functions.html
6365
[_Implementation_]: items/implementations.html
66+
[_MacroInvocationSemi_]: macros.html#macro-invocation
67+
[_MacroRulesDefinition_]: macros-by-example.html
6468
[_Module_]: items/modules.html
6569
[_OuterAttribute_]: attributes.html
6670
[_StaticItem_]: items/static-items.html

src/items/implementations.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
> _InherentImplItem_ :\
1414
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
1515
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
16-
> &nbsp;&nbsp; ( [_ConstantItem_] | [_Function_] | [_Method_] )
16+
> &nbsp;&nbsp; ( [_ConstantItem_] | [_Function_] | [_Method_] | [_MacroInvocationSemi_]&nbsp;[^novis] )
1717
>
1818
> _TraitImpl_ :\
1919
> &nbsp;&nbsp; `unsafe`<sup>?</sup> `impl` [_Generics_] `!`<sup>?</sup>
@@ -27,7 +27,7 @@
2727
> _TraitImplItem_ :\
2828
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
2929
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
30-
> &nbsp;&nbsp; ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] | [_Method_] )
30+
> &nbsp;&nbsp; ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] | [_Method_] | [_MacroInvocationSemi_]&nbsp;[^novis] )
3131
3232
An _implementation_ is an item that associates items with an _implementing type_.
3333
Implementations are defined with the keyword `impl` and contain functions
@@ -175,11 +175,14 @@ attributes must come before any associated items. That attributes that have
175175
meaning here are [`cfg`], [`deprecated`], [`doc`], and [the lint check
176176
attributes].
177177

178+
[^novis]: Macro invocations may not start with a visibility modifier.
179+
178180
[IDENTIFIER]: identifiers.html
179181
[_ConstantItem_]: items/constant-items.html
180182
[_Function_]: items/functions.html
181183
[_Generics_]: items/generics.html
182184
[_InnerAttribute_]: attributes.html
185+
[_MacroInvocationSemi_]: macros.html#macro-invocation
183186
[_Method_]: items/associated-items.html#methods
184187
[_OuterAttribute_]: attributes.html
185188
[_TypeAlias_]: items/type-aliases.html

src/items/traits.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
> &nbsp;&nbsp; `}`
1010
>
1111
> _TraitItem_ :\
12-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (_TraitFunc_ | _TraitMethod_ | _TraitConst_ | _TraitType_)
12+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
13+
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; _TraitFunc_\
14+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitMethod_\
15+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitConst_\
16+
> &nbsp;&nbsp; &nbsp;&nbsp; | _TraitType_\
17+
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MacroInvocationSemi_]\
18+
> &nbsp;&nbsp; )
1319
>
1420
> _TraitFunc_ :\
1521
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitFunctionDecl_ ( `;` | [_BlockExpression_] )
@@ -205,6 +211,7 @@ trait T {
205211
[_FunctionQualifiers_]: items/functions.html
206212
[_FunctionReturnType_]: items/functions.html
207213
[_Generics_]: items/generics.html
214+
[_MacroInvocationSemi_]: macros.html#macro-invocation
208215
[_OuterAttribute_]: attributes.html
209216
[_Pattern_]: patterns.html
210217
[_SelfParam_]: items/associated-items.html#methods

src/macros-by-example.md

+79-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
11
# Macros By Example
22

3+
> **<sup>Syntax</sup>**\
4+
> _MacroRulesDefinition_ :\
5+
> &nbsp;&nbsp; `macro_rules` `!` [IDENTIFIER] _MacroRulesDef_
6+
>
7+
> _MacroRulesDef_ :\
8+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _MacroRules_ `)` `;`\
9+
> &nbsp;&nbsp; | `[` _MacroRules_ `]` `;`\
10+
> &nbsp;&nbsp; | `{` _MacroRules_ `}`
11+
>
12+
> _MacroRules_ :\
13+
> &nbsp;&nbsp; _MacroRule_ ( `;` _MacroRule_ )<sup>\*</sup> `;`<sup>?</sup>
14+
>
15+
> _MacroRule_ :\
16+
> &nbsp;&nbsp; _MacroMatcher_ `=>` _MacroTranscriber_
17+
>
18+
> _MacroMatcher_ :\
19+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _MacroMatch_<sup>\*</sup> `)`\
20+
> &nbsp;&nbsp; | `[` _MacroMatch_<sup>\*</sup> `]`\
21+
> &nbsp;&nbsp; | `{` _MacroMatch_<sup>\*</sup> `}`
22+
>
23+
> _MacroMatch_ :\
24+
> &nbsp;&nbsp; &nbsp;&nbsp; [_Token_]<sub>_except $ and delimiters_</sub>\
25+
> &nbsp;&nbsp; | _MacroMatcher_\
26+
> &nbsp;&nbsp; | `$` [IDENTIFIER] `:` _MacroFragSpec_\
27+
> &nbsp;&nbsp; | `$` `(` _MacroMatch_<sup>+</sup> `)` _MacroRepSep_<sup>?</sup> _MacroKleeneOp_
28+
>
29+
> _MacroFragSpec_ :\
30+
> &nbsp;&nbsp; &nbsp;&nbsp; `block` | `expr` | `ident` | `item` | `lifetime` | `literal`\
31+
> &nbsp;&nbsp; | `meta` | `pat` | `path` | `stmt` | `tt` | `ty` | `vis`
32+
>
33+
> _MacroRepSep_ :\
34+
> &nbsp;&nbsp; [_Token_]<sub>_except delimiters and kleene operators_</sub>
35+
>
36+
> _MacroKleeneOp_<sub>2015</sub> :\
37+
> &nbsp;&nbsp; `*` | `+`
38+
>
39+
> _MacroKleeneOp_<sub>2018+</sub> :\
40+
> &nbsp;&nbsp; `*` | `+` | `?`
41+
>
42+
> _MacroTranscriber_ :\
43+
> &nbsp;&nbsp; [_DelimTokenTree_]
44+
345
`macro_rules` allows users to define syntax extension in a declarative way. We
446
call such extensions "macros by example" or simply "macros".
547

6-
Currently, macros can expand to expressions, statements, items, or patterns.
7-
8-
(A `sep_token` is any token other than `*` and `+`. A `non_special_token` is
9-
any token other than a delimiter or `$`.)
48+
Macros can expand to expressions, statements, items, types, or patterns.
1049

1150
The macro expander looks up macro invocations by name, and tries each macro
1251
rule in turn. It transcribes the first successful match. Matching and
@@ -27,11 +66,11 @@ syntax named by _designator_. Valid designators are:
2766
* `expr`: an [expression]
2867
* `ty`: a [type]
2968
* `ident`: an [identifier] or [keyword]
30-
* `path`: a [path]
31-
* `tt`: a token tree (a single [token] by matching `()`, `[]`, or `{}`)
69+
* `path`: a [_TypePath_] style path
70+
* `tt`: a [token tree]&nbsp;(a single [token] or tokens in matching delimiters `()`, `[]`, or `{}`)
3271
* `meta`: the contents of an [attribute]
33-
* `lifetime`: a lifetime. Examples: `'static`, `'a`.
34-
* `vis`: a (visibility qualifier)[visibility-and-privacy]
72+
* `lifetime`: a [lifetime]. Examples: `'static`, `'a`.
73+
* `vis`: a [visibility qualifier]
3574

3675
[item]: items.html
3776
[block]: expressions/block-expr.html
@@ -41,10 +80,12 @@ syntax named by _designator_. Valid designators are:
4180
[type]: types.html
4281
[identifier]: identifiers.html
4382
[keyword]: keywords.html
44-
[path]: paths.html
83+
[_TypePath_]: paths.html#paths-in-types
84+
[token tree]: macros.html#macro-invocation
4585
[token]: tokens.html
4686
[attribute]: attributes.html
47-
[visibility-and-privacy]: visibility-and-privacy.html
87+
[lifetime]: tokens.html#lifetimes-and-loop-labels
88+
[visibility qualifier]: visibility-and-privacy.html
4889

4990
In the transcriber, the
5091
designator is already known, and so only the name of a matched nonterminal comes
@@ -94,9 +135,36 @@ Rust syntax is restricted in two ways:
94135
a macro definition like `$i:expr [ , ]` is not legal, because `[` could be part
95136
of an expression. A macro definition like `$i:expr,` or `$i:expr;` would be legal,
96137
however, because `,` and `;` are legal separators. See [RFC 550] for more information.
138+
Specifically:
139+
140+
* `expr` and `stmt` may only be followed by one of `=>`, `,`, or `;`.
141+
* `pat` may only be followed by one of `=>`, `,`, `=`, `|`, `if`, or `in`.
142+
* `path` and `ty` may only be followed by one of `=>`, `,`, `=`, `|`, `;`,
143+
`:`, `>`, `[`, `{`, `as`, `where`, or a macro variable of `block`
144+
fragment type.
145+
* `vis` may only be followed by one of `,`, `priv`, a raw identifier, any
146+
token that can begin a type, or a macro variable of `ident`, `ty`, or
147+
`path` fragment type.
148+
* All other fragment types have no restrictions.
149+
97150
2. The parser must have eliminated all ambiguity by the time it reaches a `$`
98151
_name_ `:` _designator_. This requirement most often affects name-designator
99152
pairs when they occur at the beginning of, or immediately after, a `$(...)*`;
100-
requiring a distinctive token in front can solve the problem.
153+
requiring a distinctive token in front can solve the problem. For example:
154+
155+
```rust
156+
// The matcher `$($i:ident)* $e:expr` would be ambiguous because the parser
157+
// would be forced to choose between an identifier or an expression. Use some
158+
// token to distinguish them.
159+
macro_rules! example {
160+
($(I $i:ident)* E $e:expr) => { ($($i)-*) * $e };
161+
}
162+
let foo = 2;
163+
let bar = 3;
164+
// The following expands to `(foo - bar) * 5`
165+
example!(I foo I bar E 5);
166+
```
101167

102168
[RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md
169+
[_DelimTokenTree_]: macros.html
170+
[_Token_]: tokens.html

src/macros.md

+88
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,94 @@ There are two ways to define new macros:
99
* [Macros by Example] define new syntax in a higher-level, declarative way.
1010
* [Procedural Macros] can be used to implement custom derive.
1111

12+
## Macro Invocation
13+
14+
> **<sup>Syntax</sup>**\
15+
> _MacroInvocation_ :\
16+
> &nbsp;&nbsp; [_SimplePath_] `!` _DelimTokenTree_
17+
>
18+
> _DelimTokenTree_ :\
19+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _TokenTree_<sup>\*</sup> `)`\
20+
> &nbsp;&nbsp; | `[` _TokenTree_<sup>\*</sup> `]`\
21+
> &nbsp;&nbsp; | `{` _TokenTree_<sup>\*</sup> `}`
22+
>
23+
> _TokenTree_ :\
24+
> &nbsp;&nbsp; [_Token_]<sub>_except delimiters_</sub> | _DelimTokenTree_
25+
>
26+
> _MacroInvocationSemi_ :\
27+
> &nbsp;&nbsp; &nbsp;&nbsp; [_SimplePath_] `!` `(` _TokenTree_<sup>\*</sup> `)` `;`\
28+
> &nbsp;&nbsp; | [_SimplePath_] `!` `[` _TokenTree_<sup>\*</sup> `]` `;`\
29+
> &nbsp;&nbsp; | [_SimplePath_] `!` `{` _TokenTree_<sup>\*</sup> `}`
30+
31+
A macro invocation executes a macro at compile time and replaces the
32+
invocation with the result of the macro. Macros may be invoked in the
33+
following situations:
34+
35+
* [Expressions] and [statements]
36+
* [Patterns]
37+
* [Types]
38+
* [Items] including [associated items]
39+
* [`macro_rules`] transcribers
40+
41+
When used as an item or a statement, the _MacroInvocationSemi_ form is used
42+
where a semicolon is required at the end when not using curly braces.
43+
[Visibility qualifiers] are never allowed before a macro invocation or
44+
[`macro_rules`] definition.
45+
46+
```rust
47+
// Used as an expression.
48+
let x = vec![1,2,3];
49+
50+
// Used as a statement.
51+
println!("Hello!");
52+
53+
// Used in a pattern.
54+
macro_rules! pat {
55+
($i:ident) => (Some($i))
56+
}
57+
58+
if let pat!(x) = Some(1) {
59+
assert_eq!(x, 1);
60+
}
61+
62+
// Used in a type.
63+
macro_rules! Tuple {
64+
{ $A:ty, $B:ty } => { ($A, $B) };
65+
}
66+
67+
type N2 = Tuple!(i32, i32);
68+
69+
// Used as an item.
70+
# use std::cell::RefCell;
71+
thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
72+
73+
// Used as an associated item.
74+
macro_rules! const_maker {
75+
($t:ty, $v:tt) => { const CONST: $t = $v; };
76+
}
77+
trait T {
78+
const_maker!{i32, 7}
79+
}
80+
81+
// Macro calls within macros.
82+
macro_rules! example {
83+
() => { println!("Macro call in a macro!") };
84+
}
85+
example!();
86+
```
87+
1288
[Macros by Example]: macros-by-example.html
1389
[Procedural Macros]: procedural-macros.html
90+
[_SimplePath_]: paths.html#simple-paths
91+
[_Token_]: tokens.html
92+
[associated items]: items/associated-items.html
1493
[compiler plugins]: ../unstable-book/language-features/plugin.html
94+
[delimiters]: tokens.html#delimiters
95+
[expressions]: expressions.html
96+
[items]: items.html
97+
[`macro_rules`]: macros-by-example.html
98+
[patterns]: patterns.html
99+
[statements]: statements.html
100+
[tokens]: tokens.html
101+
[types]: types.html
102+
[visibility qualifiers]: visibility-and-privacy.html

src/patterns.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
> &nbsp;&nbsp; | [_TuplePattern_]\
1313
> &nbsp;&nbsp; | [_GroupedPattern_]\
1414
> &nbsp;&nbsp; | [_SlicePattern_]\
15-
> &nbsp;&nbsp; | [_PathPattern_]
15+
> &nbsp;&nbsp; | [_PathPattern_]\
16+
> &nbsp;&nbsp; | [_MacroInvocation_]
1617
1718
Patterns are used to match values against structures and to,
1819
optionally, bind variables to values inside these structures. They are also
@@ -653,6 +654,7 @@ refer to refutable constants or enum variants for enums with multiple variants.
653654
[_GroupedPattern_]: #grouped-patterns
654655
[_IdentifierPattern_]: #identifier-patterns
655656
[_LiteralPattern_]: #literal-patterns
657+
[_MacroInvocation_]: macros.html#macro-invocation
656658
[_PathInExpression_]: paths.html#paths-in-expressions
657659
[_PathPattern_]: #path-patterns
658660
[_Pattern_]: #patterns

src/statements.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
> &nbsp;&nbsp; &nbsp;&nbsp; `;`\
66
> &nbsp;&nbsp; | [_Item_]\
77
> &nbsp;&nbsp; | [_LetStatement_]\
8-
> &nbsp;&nbsp; | [_ExpressionStatement_]
8+
> &nbsp;&nbsp; | [_ExpressionStatement_]\
9+
> &nbsp;&nbsp; | [_MacroInvocationSemi_]
910
1011

1112
A *statement* is a component of a [block], which is in turn a component of an
@@ -130,6 +131,7 @@ statement are [`cfg`], and [the lint check attributes].
130131
[_Expression_]: expressions.html
131132
[_Item_]: items.html
132133
[_LetStatement_]: #let-statements
134+
[_MacroInvocationSemi_]: macros.html#macro-invocation
133135
[_OuterAttribute_]: attributes.html
134136
[_Pattern_]: patterns.html
135137
[_Type_]: types.html

src/types.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
> &nbsp;&nbsp; | [_SliceType_]\
2020
> &nbsp;&nbsp; | [_InferredType_]\
2121
> &nbsp;&nbsp; | [_QualifiedPathInType_]\
22-
> &nbsp;&nbsp; | [_BareFunctionType_]
22+
> &nbsp;&nbsp; | [_BareFunctionType_]\
23+
> &nbsp;&nbsp; | [_MacroInvocation_]
2324
2425
Every variable, item and value in a Rust program has a type. The _type_ of a
2526
*value* defines the interpretation of the memory holding it.
@@ -868,6 +869,7 @@ impl Printable for String {
868869
[_ImplTraitType_]: #impl-trait
869870
[_InferredType_]: #inferred-type
870871
[_Lifetime_]: trait-bounds.html
872+
[_MacroInvocation_]: macros.html#macro-invocation
871873
[_NeverType_]: #never-type
872874
[_ParenthesizedType_]: #parenthesized-types
873875
[_QualifiedPathInType_]: paths.html#qualified-paths

0 commit comments

Comments
 (0)