33* Procedural macros* allow creating syntax extensions as execution of a function.
44Procedural macros come in one of three flavors:
55
6- * Bang macros - ` custom_bang !(...)`
6+ * Function-like macros - ` custom !(...)`
77* Derive mode macros - ` #[derive(CustomMode)] `
88* Attribute macros - ` #[CustomAttribute] `
99
@@ -89,87 +89,56 @@ in certain respects. These limitations include:
8989 exists on stable your only option is to `panic!` or to in some cases expand to
9090 an invocation of the `compile_error!` macro with a custom message.
9191
92- # ## Bang Macros
92+ # # Function-like procedural macros
9393
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.
9795
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.
100101
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.
111104
112105```rust,ignore
113- // my-macro/src/lib.rs
114106extern crate proc_macro;
115-
116- use proc_macro::*;
107+ use proc_macro::TokenStream;
117108
118109# [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()
121112}
122113```
123114
124- And now let's invoke it:
115+ And then we use it a binary crate to print "42" to standard output.
125116
126117``` rust,ignore
127- // src/main.rs
128- extern crate my_macro ;
118+ extern crate proc_macro_examples;
119+ use proc_macro_examples::make_answer ;
129120
130- my_macro::foo!(fn answer() -> u32 { 3 } );
121+ make_answer!( );
131122
132123fn main() {
133- println!("the answer was: {}", answer());
124+ println!("{}", answer());
134125}
135126```
136127
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![]; ` .
164133
165134### Derive mode macros
166135
167136* Derive mode macros* define new modes for the ` derive ` attribute. The macros
168137define new items given the token stream of a [ struct] , [ enum] , or [ union] . They
169138also define derive mode helper attributes.
170139
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 ` .
173142
174143The input [ ` TokenStream ` ] is the token stream of the item that has the ` derive `
175144attribute on it. The output [ ` TokenStream ` ] must be a set of items that are
@@ -184,7 +153,7 @@ extern crate proc_macro;
184153use proc_macro::TokenStream;
185154
186155#[proc_macro_derive(AnswerFn)]
187- pub fn foo (_item: TokenStream) -> TokenStream {
156+ pub fn derive_answer_fn (_item: TokenStream) -> TokenStream {
188157 "fn answer() -> u32 { 42 }".parse().unwrap()
189158}
190159```
@@ -326,8 +295,10 @@ fn invoke4() {}
326295[ custom attributes ] : attributes.html
327296[ crate type ] : linkage.html
328297[ item ] : items.html
298+ [ item declaration statements ] : statements.html#item-declarations
329299[ function ] : items/functions.html
330300[ macro ] : macros.html
331301[ module ] : items/modules.html
302+ [ modules ] : items/modules.html
332303[ procedural macro tutorial ] : ../book/2018-edition/appendix-04-macros.html#procedural-macros-for-custom-derive
333304[ public ] : visibility-and-privacy.html
0 commit comments