]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/procedural-macros.md
New upstream version 1.37.0+dfsg1
[rustc.git] / src / doc / reference / src / procedural-macros.md
CommitLineData
8bb4bdeb
XL
1## Procedural Macros
2
abe05a73 3*Procedural macros* allow creating syntax extensions as execution of a function.
b7449926 4Procedural macros come in one of three flavors:
8bb4bdeb 5
b7449926 6* [Function-like macros] - `custom!(...)`
532ac7d7 7* [Derive macros] - `#[derive(CustomDerive)]`
b7449926
XL
8* [Attribute macros] - `#[CustomAttribute]`
9
10Procedural macros allow you to run code at compile time that operates over Rust
11syntax, both consuming and producing Rust syntax. You can sort of think of
12procedural macros as functions from an AST to another AST.
13
14Procedural macros must be defined in a crate with the [crate type] of
15`proc-macro`.
16
17> **Note**: When using Cargo, Procedural macro crates are defined with the
0bf4aa26 18> `proc-macro` key in your manifest:
b7449926
XL
19>
20> ```toml
21> [lib]
22> proc-macro = true
23> ```
24
25As functions, they must either return syntax, panic, or loop endlessly. Returned
26syntax either replaces or adds the syntax depending on the kind of procedural
27macro. Panics are caught by the compiler and are turned into a compiler error.
28Endless loops are not caught by the compiler which hangs the compiler.
29
30Procedural macros run during compilation, and thus have the same resources that
31the compiler has. For example, standard input, error, and output are the same
32that the compiler has access to. Similarly, file access is the same. Because
33of this, procedural macros have the same security concerns that [Cargo's
34build scripts] have.
35
36Procedural macros have two ways of reporting errors. The first is to panic. The
37second is to emit a [`compile_error`] macro invocation.
38
39### The `proc_macro` crate
40
13cf67c4 41Procedural macro crates almost always will link to the compiler-provided
b7449926
XL
42[`proc_macro` crate]. The `proc_macro` crate provides types required for
43writing procedural macros and facilities to make it easier.
44
45This crate primarily contains a [`TokenStream`] type. Procedural macros operate
46over *token streams* instead of AST nodes, which is a far more stable interface
47over time for both the compiler and for procedural macros to target. A
48*token stream* is roughly equivalent to `Vec<TokenTree>` where a `TokenTree`
49can roughly be thought of as lexical token. For example `foo` is an `Ident`
50token, `.` is a `Punct` token, and `1.2` is a `Literal` token. The `TokenStream`
51type, unlike `Vec<TokenTree>`, is cheap to clone.
52
53All tokens have an associated `Span`. A `Span` is an opaque value that cannot
54be modified but can be manufactured. `Span`s represent an extent of source
55code within a program and are primarily used for error reporting. You can modify
56the `Span` of any token.
57
58### Procedural macro hygiene
59
60Procedural macros are *unhygienic*. This means they behave as if the output
61token stream was simply written inline to the code it's next to. This means that
62it's affected by external items and also affects external imports.
63
64Macro authors need to be careful to ensure their macros work in as many contexts
65as possible given this limitation. This often includes using absolute paths to
66items in libraries (for example, `::std::option::Option` instead of `Option`) or
67by ensuring that generated functions have names that are unlikely to clash with
68other functions (like `__internal_foo` instead of `foo`).
69
70### Function-like procedural macros
71
72*Function-like procedural macros* are procedural macros that are invoked using
73the macro invocation operator (`!`).
74
75These macros are defined by a [public]&#32;[function] with the `proc_macro`
76[attribute] and a signature of `(TokenStream) -> TokenStream`. The input
77[`TokenStream`] is what is inside the delimiters of the macro invocation and the
78output [`TokenStream`] replaces the entire macro invocation. It may contain an
79arbitrary number of [items]. These macros cannot expand to syntax that defines
532ac7d7 80new `macro_rules` style macros.
b7449926
XL
81
82For example, the following macro definition ignores its input and outputs a
83function `answer` into its scope.
8bb4bdeb
XL
84
85```rust,ignore
b7449926 86extern crate proc_macro;
8bb4bdeb
XL
87use proc_macro::TokenStream;
88
b7449926
XL
89#[proc_macro]
90pub fn make_answer(_item: TokenStream) -> TokenStream {
91 "fn answer() -> u32 { 42 }".parse().unwrap()
92}
8bb4bdeb
XL
93```
94
b7449926
XL
95And then we use it a binary crate to print "42" to standard output.
96
97```rust,ignore
98extern crate proc_macro_examples;
99use proc_macro_examples::make_answer;
100
101make_answer!();
102
103fn main() {
104 println!("{}", answer());
105}
106```
107
108These macros are only invokable in [modules]. They cannot even be invoked to
109create [item declaration statements]. Furthermore, they must either be invoked
110with curly braces and no semicolon or a different delimiter followed by a
111semicolon. For example, `make_answer` from the previous example can be invoked
112as `make_answer!{}`, `make_answer!();` or `make_answer![];`.
113
532ac7d7 114### Derive macros
b7449926 115
532ac7d7
XL
116*Derive macros* define new inputs for the [`derive` attribute]. These macros
117can create new [items] given the token stream of a [struct], [enum], or [union].
118They can also define [derive macro helper attributes].
b7449926 119
532ac7d7 120Custom derive macros are defined by a [public]&#32;[function] with the
b7449926
XL
121`proc_macro_derive` attribute and a signature of `(TokenStream) -> TokenStream`.
122
123The input [`TokenStream`] is the token stream of the item that has the `derive`
124attribute on it. The output [`TokenStream`] must be a set of items that are
125then appended to the [module] or [block] that the item from the input
126[`TokenStream`] is in.
127
532ac7d7 128The following is an example of a derive macro. Instead of doing anything
b7449926
XL
129useful with its input, it just appends a function `answer`.
130
131```rust,ignore
132extern crate proc_macro;
133use proc_macro::TokenStream;
134
135#[proc_macro_derive(AnswerFn)]
136pub fn derive_answer_fn(_item: TokenStream) -> TokenStream {
137 "fn answer() -> u32 { 42 }".parse().unwrap()
138}
139```
140
532ac7d7 141And then using said derive macro:
b7449926
XL
142
143```rust,ignore
144extern crate proc_macro_examples;
145use proc_macro_examples::AnswerFn;
146
147#[derive(AnswerFn)]
148struct Struct;
149
150fn main() {
151 assert_eq!(42, answer());
152}
153```
154
532ac7d7 155#### Derive macro helper attributes
b7449926 156
532ac7d7
XL
157Derive macros can add additional [attributes] into the scope of the [item]
158they are on. Said attributes are called *derive macro helper attributes*. These
b7449926 159attributes are [inert], and their only purpose is to be fed into the derive
532ac7d7 160macro that defined them. That said, they can be seen by all macros.
b7449926
XL
161
162The way to define helper attributes is to put an `attributes` key in the
163`proc_macro_derive` macro with a comma separated list of identifiers that are
164the names of the helper attributes.
165
532ac7d7 166For example, the following derive macro defines a helper attribute
b7449926
XL
167`helper`, but ultimately doesn't do anything with it.
168
169```rust,ignore
170# #[crate_type="proc-macro"]
171# extern crate proc_macro;
172# use proc_macro::TokenStream;
173
174#[proc_macro_derive(HelperAttr, attributes(helper))]
175pub fn derive_helper_attr(_item: TokenStream) -> TokenStream {
dc9dc135 176 TokenStream::new()
b7449926
XL
177}
178```
179
532ac7d7 180And then usage on the derive macro on a struct:
b7449926
XL
181
182```rust,ignore
183# #![crate_type="proc-macro"]
184# extern crate proc_macro_examples;
185# use proc_macro_examples::HelperAttr;
186
187#[derive(HelperAttr)]
188struct Struct {
189 #[helper] field: ()
190}
191```
192
193### Attribute macros
194
195*Attribute macros* define new [attributes] which can be attached to [items].
196
197Attribute macros are defined by a [public]&#32;[function] with the
532ac7d7
XL
198`proc_macro_attribute` [attribute] that has a signature of `(TokenStream,
199TokenStream) -> TokenStream`. The first [`TokenStream`] is the delimited token
200tree following the attribute's name, not including the outer delimiters. If
201the attribute is written as a bare attribute name, the attribute
202[`TokenStream`] is empty. The second [`TokenStream`] is the rest of the [item]
203including other [attributes] on the [item]. The returned [`TokenStream`]
204replaces the [item] with an arbitrary number of [items]. These macros cannot
205expand to syntax that defines new `macro_rules` style macros.
b7449926
XL
206
207For example, this attribute macro takes the input stream and returns it as is,
208effectively being the no-op of attributes.
209
210```rust,ignore
211# #![crate_type = "proc-macro"]
212# extern crate proc_macro;
213# use proc_macro::TokenStream;
214
215#[proc_macro_attribute]
216pub fn return_as_is(_attr: TokenStream, item: TokenStream) -> TokenStream {
217 item
218}
219```
220
221This following example shows the stringified [`TokenStream`s] that the attribute
222macros see. The output will show in the output of the compiler. The output is
223shown in the comments after the function prefixed with "out:".
224
225```rust,ignore
226// my-macro/src/lib.rs
227# extern crate proc_macro;
228# use proc_macro::TokenStream;
229
230#[proc_macro_attribute]
13cf67c4 231pub fn show_streams(attr: TokenStream, item: TokenStream) -> TokenStream {
b7449926 232 println!("attr: \"{}\"", attr.to_string());
13cf67c4 233 println!("item: \"{}\"", item.to_string());
b7449926
XL
234 item
235}
236```
237
238```rust,ignore
239// src/lib.rs
240extern crate my_macro;
241
242use my_macro::show_streams;
243
244// Example: Basic function
245#[show_streams]
246fn invoke1() {}
247// out: attr: ""
248// out: item: "fn invoke1() { }"
249
532ac7d7 250// Example: Attribute with input
b7449926
XL
251#[show_streams(bar)]
252fn invoke2() {}
253// out: attr: "bar"
254// out: item: "fn invoke2() {}"
255
532ac7d7
XL
256// Example: Multiple tokens in the input
257#[show_streams(multiple => tokens)]
b7449926 258fn invoke3() {}
532ac7d7 259// out: attr: "multiple => tokens"
b7449926
XL
260// out: item: "fn invoke3() {}"
261
13cf67c4 262// Example:
b7449926
XL
263#[show_streams { delimiters }]
264fn invoke4() {}
532ac7d7
XL
265// out: attr: "delimiters"
266// out: item: "fn invoke4() {}"
b7449926 267```
abe05a73 268
b7449926
XL
269[`TokenStream`]: ../proc_macro/struct.TokenStream.html
270[`TokenStream`s]: ../proc_macro/struct.TokenStream.html
271[`compile_error`]: ../std/macro.compile_error.html
532ac7d7 272[`derive` attribute]: attributes/derive.html
b7449926
XL
273[`proc_macro` crate]: ../proc_macro/index.html
274[Cargo's build scripts]: ../cargo/reference/build-scripts.html
532ac7d7 275[Derive macros]: #derive-macros
b7449926
XL
276[Attribute macros]: #attribute-macros
277[Function-like macros]: #function-like-procedural-macros
278[attribute]: attributes.html
279[attributes]: attributes.html
13cf67c4 280[block]: expressions/block-expr.html
b7449926 281[crate type]: linkage.html
532ac7d7 282[derive macro helper attributes]: #derive-macro-helper-attributes
b7449926
XL
283[enum]: items/enumerations.html
284[inert]: attributes.html#active-and-inert-attributes
285[item]: items.html
286[item declaration statements]: statements.html#item-declarations
287[items]: items.html
288[function]: items/functions.html
b7449926
XL
289[module]: items/modules.html
290[modules]: items/modules.html
b7449926
XL
291[public]: visibility-and-privacy.html
292[struct]: items/structs.html
13cf67c4 293[union]: items/unions.html