diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index c73fbefb2a401..0bc49365921c0 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -42,7 +42,7 @@ the pattern in the above code: # let input_1 = T::SpecialA(0); # let input_2 = T::SpecialA(0); macro_rules! early_return { - ($inp:expr, $sp:path) => ( // invoke it like `(input_5 SpecialE)` + ($inp:expr, $sp:path) => ( // invoke it like `(input_5, SpecialE)` match $inp { $sp(x) => { return x; } _ => {} @@ -59,7 +59,7 @@ early_return!(input_2, T::SpecialB); ~~~~ Macros are defined in pattern-matching style: in the above example, the text -`($inp:expr $sp:ident)` that appears on the left-hand side of the `=>` is the +`($inp:expr, $sp:path)` that appears on the left-hand side of the `=>` is the *macro invocation syntax*, a pattern denoting how to write a call to the macro. The text on the right-hand side of the `=>`, beginning with `match $inp`, is the *macro transcription syntax*: what the macro expands to. @@ -74,6 +74,8 @@ conforms to the following rules: 2. `$` has special meaning (described below). 3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is forbidden. +4. Some arguments can be followed only by a limited set of separators, to +avoid ambiguity (described below). Otherwise, the invocation syntax is free-form. @@ -86,7 +88,8 @@ To take a fragment of Rust code as an argument, write `$` followed by a name `foo`.) * `expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`.) -* `ty` (a type. Examples: `int`, `Vec<(char, String)>`, `&T`.) +* `ty` (a type. Examples: `i32`, `Vec<(char, String)>`, `&T`.) +* `path` (a path to struct or enum variant. Example: `T::SpecialA`) * `pat` (a pattern, usually appearing in a `match` or on the left-hand side of a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.) * `block` (a sequence of actions. Example: `{ log(error, "hi"); return 12; }`) @@ -97,6 +100,12 @@ rules of tokenization apply, So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a macro that could be invoked like: `my_macro!(i->(( 2+2 )))`. +To avoid ambiguity, macro invocation syntax must conform to the following rules: +* `expr` must be followed by `=>`, `,` or `;`. +* `ty` and `path` must be followed by `=>`, `,`, `:`, `=`, `>` or `as`. +* `pat` must be followed by `=>`, `,` or `=`. +* `ident` and `block` can be followed by any token. + ## Invocation location A macro invocation may take the place of (and therefore expand to) an