|
| 1 | +% Advanced macros |
| 2 | + |
| 3 | +This chapter picks up where the [introductory macro chapter](macros.html) left |
| 4 | +off. |
| 5 | + |
| 6 | +# Syntactic requirements |
| 7 | + |
| 8 | +Even when Rust code contains un-expanded macros, it can be parsed as a full |
| 9 | +syntax tree. This property can be very useful for editors and other tools that |
| 10 | +process code. It also has a few consequences for the design of Rust's macro |
| 11 | +system. |
| 12 | + |
| 13 | +One consequence is that Rust must determine, when it parses a macro invocation, |
| 14 | +whether the macro stands in for |
| 15 | + |
| 16 | +* zero or more items, |
| 17 | +* zero or more methods, |
| 18 | +* an expression, |
| 19 | +* a statement, or |
| 20 | +* a pattern. |
| 21 | + |
| 22 | +A macro invocation within a block could stand for some items, or for an |
| 23 | +expression / statement. Rust uses a simple rule to resolve this ambiguity. A |
| 24 | +macro invocation that stands for items must be either |
| 25 | + |
| 26 | +* delimited by curly braces, e.g. `foo! { ... }`, or |
| 27 | +* terminated by a semicolon, e.g. `foo!(...);` |
| 28 | + |
| 29 | +Another consequence of pre-expansion parsing is that the macro invocation must |
| 30 | +consist of valid Rust tokens. Furthermore, parentheses, brackets, and braces |
| 31 | +must be balanced within a macro invocation. For example, `foo!([)` is |
| 32 | +forbidden. This allows Rust to know where the macro invocation ends. |
| 33 | + |
| 34 | +More formally, the macro invocation body must be a sequence of *token trees*. |
| 35 | +A token tree is defined recursively as either |
| 36 | + |
| 37 | +* a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or |
| 38 | +* any other single token. |
| 39 | + |
| 40 | +Within a matcher, each metavariable has a *fragment specifier*, identifying |
| 41 | +which syntactic form it matches. |
| 42 | + |
| 43 | +* `ident`: an identifier. Examples: `x`; `foo`. |
| 44 | +* `path`: a qualified name. Example: `T::SpecialA`. |
| 45 | +* `expr`: an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`. |
| 46 | +* `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`. |
| 47 | +* `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`. |
| 48 | +* `stmt`: a single statement. Example: `let x = 3`. |
| 49 | +* `block`: a brace-delimited sequence of statements. Example: |
| 50 | + `{ log(error, "hi"); return 12; }`. |
| 51 | +* `item`: an [item][]. Examples: `fn foo() { }`; `struct Bar;`. |
| 52 | +* `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`. |
| 53 | +* `tt`: a single token tree. |
| 54 | + |
| 55 | +There are additional rules regarding the next token after a metavariable: |
| 56 | + |
| 57 | +* `expr` variables must be followed by one of: `=> , ;` |
| 58 | +* `ty` and `path` variables must be followed by one of: `=> , : = > as` |
| 59 | +* `pat` variables must be followed by one of: `=> , =` |
| 60 | +* Other variables may be followed by any token. |
| 61 | + |
| 62 | +These rules provide some flexibility for Rust's syntax to evolve without |
| 63 | +breaking existing macros. |
| 64 | + |
| 65 | +The macro system does not deal with parse ambiguity at all. For example, the |
| 66 | +grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would |
| 67 | +be forced to choose between parsing `$t` and parsing `$e`. Changing the |
| 68 | +invocation syntax to put a distinctive token in front can solve the problem. In |
| 69 | +this case, you can write `$(T $t:ty)* E $e:exp`. |
| 70 | + |
| 71 | +[item]: ../reference.html#items |
| 72 | + |
| 73 | +# Scoping and macro import/export |
| 74 | + |
| 75 | +Macros are expanded at an early stage in compilation, before name resolution. |
| 76 | +One downside is that scoping works differently for macros, compared to other |
| 77 | +constructs in the language. |
| 78 | + |
| 79 | +Definition and expansion of macros both happen in a single depth-first, |
| 80 | +lexical-order traversal of a crate's source. So a macro defined at module scope |
| 81 | +is visible to any subsequent code in the same module, which includes the body |
| 82 | +of any subsequent child `mod` items. |
| 83 | + |
| 84 | +A macro defined within the body of a single `fn`, or anywhere else not at |
| 85 | +module scope, is visible only within that item. |
| 86 | + |
| 87 | +If a module has the `macro_use` attribute, its macros are also visible in its |
| 88 | +parent module after the child's `mod` item. If the parent also has `macro_use` |
| 89 | +then the macros will be visible in the grandparent after the parent's `mod` |
| 90 | +item, and so forth. |
| 91 | + |
| 92 | +The `macro_use` attribute can also appear on `extern crate`. In this context |
| 93 | +it controls which macros are loaded from the external crate, e.g. |
| 94 | + |
| 95 | +```rust,ignore |
| 96 | +#[macro_use(foo, bar)] |
| 97 | +extern crate baz; |
| 98 | +``` |
| 99 | + |
| 100 | +If the attribute is given simply as `#[macro_use]`, all macros are loaded. If |
| 101 | +there is no `#[macro_use]` attribute then no macros are loaded. Only macros |
| 102 | +defined with the `#[macro_export]` attribute may be loaded. |
| 103 | + |
| 104 | +To load a crate's macros *without* linking it into the output, use `#[no_link]` |
| 105 | +as well. |
| 106 | + |
| 107 | +An example: |
| 108 | + |
| 109 | +```rust |
| 110 | +macro_rules! m1 { () => (()) } |
| 111 | + |
| 112 | +// visible here: m1 |
| 113 | + |
| 114 | +mod foo { |
| 115 | + // visible here: m1 |
| 116 | + |
| 117 | + #[macro_export] |
| 118 | + macro_rules! m2 { () => (()) } |
| 119 | + |
| 120 | + // visible here: m1, m2 |
| 121 | +} |
| 122 | + |
| 123 | +// visible here: m1 |
| 124 | + |
| 125 | +macro_rules! m3 { () => (()) } |
| 126 | + |
| 127 | +// visible here: m1, m3 |
| 128 | + |
| 129 | +#[macro_use] |
| 130 | +mod bar { |
| 131 | + // visible here: m1, m3 |
| 132 | + |
| 133 | + macro_rules! m4 { () => (()) } |
| 134 | + |
| 135 | + // visible here: m1, m3, m4 |
| 136 | +} |
| 137 | + |
| 138 | +// visible here: m1, m3, m4 |
| 139 | +# fn main() { } |
| 140 | +``` |
| 141 | + |
| 142 | +When this library is loaded with `#[macro_use] extern crate`, only `m2` will |
| 143 | +be imported. |
| 144 | + |
| 145 | +The Rust Reference has a [listing of macro-related |
| 146 | +attributes](../reference.html#macro--and-plugin-related-attributes). |
| 147 | + |
| 148 | +# The variable `$crate` |
| 149 | + |
| 150 | +A further difficulty occurs when a macro is used in multiple crates. Say that |
| 151 | +`mylib` defines |
| 152 | + |
| 153 | +```rust |
| 154 | +pub fn increment(x: u32) -> u32 { |
| 155 | + x + 1 |
| 156 | +} |
| 157 | + |
| 158 | +#[macro_export] |
| 159 | +macro_rules! inc_a { |
| 160 | + ($x:expr) => ( ::increment($x) ) |
| 161 | +} |
| 162 | + |
| 163 | +#[macro_export] |
| 164 | +macro_rules! inc_b { |
| 165 | + ($x:expr) => ( ::mylib::increment($x) ) |
| 166 | +} |
| 167 | +# fn main() { } |
| 168 | +``` |
| 169 | + |
| 170 | +`inc_a` only works within `mylib`, while `inc_b` only works outside the |
| 171 | +library. Furthermore, `inc_b` will break if the user imports `mylib` under |
| 172 | +another name. |
| 173 | + |
| 174 | +Rust does not (yet) have a hygiene system for crate references, but it does |
| 175 | +provide a simple workaround for this problem. Within a macro imported from a |
| 176 | +crate named `foo`, the special macro variable `$crate` will expand to `::foo`. |
| 177 | +By contrast, when a macro is defined and then used in the same crate, `$crate` |
| 178 | +will expand to nothing. This means we can write |
| 179 | + |
| 180 | +```rust |
| 181 | +#[macro_export] |
| 182 | +macro_rules! inc { |
| 183 | + ($x:expr) => ( $crate::increment($x) ) |
| 184 | +} |
| 185 | +# fn main() { } |
| 186 | +``` |
| 187 | + |
| 188 | +to define a single macro that works both inside and outside our library. The |
| 189 | +function name will expand to either `::increment` or `::mylib::increment`. |
| 190 | + |
| 191 | +To keep this system simple and correct, `#[macro_use] extern crate ...` may |
| 192 | +only appear at the root of your crate, not inside `mod`. This ensures that |
| 193 | +`$crate` is a single identifier. |
| 194 | + |
| 195 | +# A final note |
| 196 | + |
| 197 | +Macros, as currently implemented, are not for the faint of heart. Even |
| 198 | +ordinary syntax errors can be more difficult to debug when they occur inside a |
| 199 | +macro, and errors caused by parse problems in generated code can be very |
| 200 | +tricky. Invoking the `log_syntax!` macro can help elucidate intermediate |
| 201 | +states, invoking `trace_macros!(true)` will automatically print those |
| 202 | +intermediate states out, and passing the flag `--pretty expanded` as a |
| 203 | +command-line argument to the compiler will show the result of expansion. |
| 204 | + |
| 205 | +If Rust's macro system can't do what you need, you may want to write a |
| 206 | +[compiler plugin](plugins.html) instead. Compared to `macro_rules!` |
| 207 | +macros, this is significantly more work, the interfaces are much less stable, |
| 208 | +and the warnings about debugging apply ten-fold. In exchange you get the |
| 209 | +flexibility of running arbitrary Rust code within the compiler. Syntax |
| 210 | +extension plugins are sometimes called *procedural macros* for this reason. |
0 commit comments