3
3
* Procedural macros* allow creating syntax extensions as execution of a function.
4
4
Procedural macros come in one of three flavors:
5
5
6
- * Bang macros - ` custom_bang !(...)`
6
+ * Function-like macros - ` custom !(...)`
7
7
* Derive mode macros - ` #[derive(CustomMode)] `
8
8
* Attribute macros - ` #[CustomAttribute] `
9
9
@@ -89,87 +89,56 @@ in certain respects. These limitations include:
89
89
exists on stable your only option is to `panic!` or to in some cases expand to
90
90
an invocation of the `compile_error!` macro with a custom message.
91
91
92
- # ## Bang Macros
92
+ # # Function-like procedural macros
93
93
94
- This flavor of procedural macro is like writing `macro_rules!` only you get to
95
- execute arbitrary code over the input tokens instead of being limited to
96
- `macro_rules!` syntax.
94
+ Function-like procedural macros define new invokable macros.
97
95
98
- Procedural bang macros are defined with the `#[proc_macro]` attribute and have
99
- the following signature:
96
+ These macros are defined by a [public] [function] with the `proc_maco`
97
+ [attribute ] and a signature of `(TokenStream) -> TokenStream`. The input
98
+ [`TokenStream` ] is what is inside the delimiters of the macro invocation and the
99
+ output [`TokenStream`] replaces the entire macro invocation. It may contain an
100
+ arbitrary number of items.
100
101
101
- ```rust,ignore
102
- # [proc_macro]
103
- pub fn foo(input: TokenStream) -> TokenStream {
104
- // ...
105
- }
106
- ```
107
-
108
- This item is defining a procedural bang macro (` #[proc_macro] ` ) which is called
109
- ` foo ` . The first argument is the input to the macro which explore in a second,
110
- and the return value is the tokens that it should expand to.
102
+ For example, the following macro definition ignores its input and outputs a
103
+ function `answer` into its scope.
111
104
112
105
```rust,ignore
113
- // my-macro/src/lib.rs
114
106
extern crate proc_macro;
115
-
116
- use proc_macro::*;
107
+ use proc_macro::TokenStream;
117
108
118
109
# [proc_macro]
119
- pub fn foo(input : TokenStream) -> TokenStream {
120
- input
110
+ pub fn make_answer(_item : TokenStream) -> TokenStream {
111
+ "fn answer() -> u32 { 42 }".parse().unwrap()
121
112
}
122
113
```
123
114
124
- And now let's invoke it:
115
+ And then we use it a binary crate to print "42" to standard output.
125
116
126
117
``` rust,ignore
127
- // src/main.rs
128
- extern crate my_macro ;
118
+ extern crate proc_macro_examples;
119
+ use proc_macro_examples::make_answer ;
129
120
130
- my_macro::foo!(fn answer() -> u32 { 3 } );
121
+ make_answer!( );
131
122
132
123
fn main() {
133
- println!("the answer was: {}", answer());
124
+ println!("{}", answer());
134
125
}
135
126
```
136
127
137
- First up, let's see what the input to our macro looks like by modifying our
138
- macro:
139
-
140
- ``` rust,ignore
141
- // my-macro/src/lib.rs
142
- #[proc_macro]
143
- pub fn foo(input: TokenStream) -> TokenStream {
144
- println!("{:#?}", input);
145
- input
146
- }
147
- ```
148
-
149
- The macro invocation is effectively replaced by
150
- the return value of the macro, creating the function that we provided as input.
151
- We can see another example of this where we simply ignore the input:
152
-
153
- ``` rust,ignore
154
- // my-macro/src/lib.rs
155
- #[proc_macro]
156
- pub fn foo(_input: TokenStream) -> TokenStream {
157
- "fn answer() -> u32 { 4 }".parse().unwrap()
158
- }
159
- ```
160
-
161
- ```
162
- the answer was: 4
163
- ```
128
+ These macros are only invokable in [ modules] . They cannot even be invoked to
129
+ make [ item declaration statements] . Furthermore, they must either be invoked
130
+ with curly braces and no semicolon or a different delimiter followed by a
131
+ semicolon. For example, ` make_answer ` from the previous example can be invoked
132
+ as ` make_answer!{} ` , ` make_answer!(); ` or ` make_answer![]; ` .
164
133
165
134
### Derive mode macros
166
135
167
136
* Derive mode macros* define new modes for the ` derive ` attribute. The macros
168
137
define new items given the token stream of a [ struct] , [ enum] , or [ union] . They
169
138
also define derive mode helper attributes.
170
139
171
- Custom derivers are defined by a [ public] [ function] with the ` proc_maco_derive `
172
- attribute and a signature of ` (TokenStream) -> TokenStream ` .
140
+ Custom deriver modes are defined by a [ public] [ function] with the
141
+ ` proc_maco_derive ` attribute and a signature of ` (TokenStream) -> TokenStream ` .
173
142
174
143
The input [ ` TokenStream ` ] is the token stream of the item that has the ` derive `
175
144
attribute on it. The output [ ` TokenStream ` ] must be a set of items that are
@@ -184,7 +153,7 @@ extern crate proc_macro;
184
153
use proc_macro::TokenStream;
185
154
186
155
#[proc_macro_derive(AnswerFn)]
187
- pub fn foo (_item: TokenStream) -> TokenStream {
156
+ pub fn derive_answer_fn (_item: TokenStream) -> TokenStream {
188
157
"fn answer() -> u32 { 42 }".parse().unwrap()
189
158
}
190
159
```
@@ -326,8 +295,10 @@ fn invoke4() {}
326
295
[ custom attributes ] : attributes.html
327
296
[ crate type ] : linkage.html
328
297
[ item ] : items.html
298
+ [ item declaration statements ] : statements.html#item-declarations
329
299
[ function ] : items/functions.html
330
300
[ macro ] : macros.html
331
301
[ module ] : items/modules.html
302
+ [ modules ] : items/modules.html
332
303
[ procedural macro tutorial ] : ../book/2018-edition/appendix-04-macros.html#procedural-macros-for-custom-derive
333
304
[ public ] : visibility-and-privacy.html
0 commit comments