@@ -15,11 +15,16 @@ This RFC specifies the architecture of the procedural macro system. It relies on
15
15
[ RFC 1561] ( https://github.com/rust-lang/rfcs/pull/1561 ) which specifies the
16
16
naming and modularisation of macros. It leaves many of the details for further
17
17
RFCs, in particular the details of the APIs available to macro authors
18
- (tentatively called ` libmacro ` ). See this [ blog post] ( http://ncameron.org/blog/libmacro/ )
19
- for some ideas of how that might look.
18
+ (tentatively called ` libproc_macro ` , formerly ` libmacro ` ). See this
19
+ [ blog post] ( http://ncameron.org/blog/libmacro/ ) for some ideas of how that might
20
+ look.
21
+
22
+ [ RFC 1681] ( https://github.com/rust-lang/rfcs/pull/1681 ) specified a mechanism
23
+ for custom derive using 'macros 1.1'. That RFC is essentially a subset of this
24
+ one. Changes and differences are noted throughout the text.
20
25
21
26
At the highest level, macros are defined by implementing functions marked with
22
- a ` #[macro ] ` attribute. Macros operate on a list of tokens provided by the
27
+ a ` #[proc_macro ] ` attribute. Macros operate on a list of tokens provided by the
23
28
compiler and return a list of tokens that the macro use is replaced by. We
24
29
provide low-level facilities for operating on these tokens. Higher level
25
30
facilities (e.g., for parsing tokens to an AST) should exist as library crates.
@@ -57,13 +62,18 @@ like macro is used with syntax `foo!(...)`, and an attribute-like macro with
57
62
` #[foo(...)] ... ` . Macros may be used in the same places as ` macro_rules ` macros
58
63
and this remains unchanged.
59
64
65
+ There is also a third kind, custom derive, which are specified in [ RFC
66
+ 1681] ( https://github.com/rust-lang/rfcs/pull/1681 ) . This RFC extends the
67
+ facilities open to custom derive macros beyond the string-based system of RFC
68
+ 1681 .
69
+
60
70
To define a procedural macro, the programmer must write a function with a
61
71
specific signature and attribute. Where ` foo ` is the name of a function-like
62
72
macro:
63
73
64
74
```
65
- #[macro ]
66
- pub fn foo(TokenStream, &mut MacroContext ) -> TokenStream;
75
+ #[proc_macro ]
76
+ pub fn foo(TokenStream) -> TokenStream;
67
77
```
68
78
69
79
The first argument is the tokens between the delimiters in the macro use.
@@ -75,8 +85,8 @@ The value returned replaces the macro use.
75
85
Attribute-like:
76
86
77
87
```
78
- #[macro_attribute ]
79
- pub fn foo(Option<TokenStream>, TokenStream, &mut MacroContext ) -> TokenStream;
88
+ #[prco_macro_attribute ]
89
+ pub fn foo(Option<TokenStream>, TokenStream) -> TokenStream;
80
90
```
81
91
82
92
The first argument is a list of the tokens between the delimiters in the macro
@@ -101,54 +111,93 @@ by another macro without parsing, in which case they do not need to parse. The
101
111
distinction is not statically enforced. It could be, but I don't think the
102
112
overhead would be justified.
103
113
104
- We also introduce a special configuration option: ` #[cfg(macro)] ` . Items with
114
+ Custom derive:
115
+
116
+ ```
117
+ #[proc_macro_derive]
118
+ pub fn foo(TokenStream) -> TokenStream;
119
+ ```
120
+
121
+ Similar to attribute-like macros, the item a custom derive applies to must
122
+ parse. Custom derives may on be applied to the items that a built-in derive may
123
+ be applied to (structs and enums).
124
+
125
+ Currently, macros implementing custom derive only have the option of converting
126
+ the ` TokenStream ` to a string and converting a result string back to a
127
+ ` TokenStream ` . This option will remain, but macro authors will also be able to
128
+ operate directly on the ` TokenStream ` (which should be preferred, since it
129
+ allows for hygiene and span support).
130
+
131
+ Procedural macros which take an identifier before the argument list (e.g, `foo!
132
+ bar(...)`) will not be supported (at least initially).
133
+
134
+ My feeling is that this macro form is not used enough to justify its existence.
135
+ From a design perspective, it encourages uses of macros for language extension,
136
+ rather than syntactic abstraction. I feel that such macros are at higher risk of
137
+ making programs incomprehensible and of fragmenting the ecosystem).
138
+
139
+ Behind the scenes, these functions implement traits for each macro kind. We may
140
+ in the future allow implementing these traits directly, rather than just
141
+ implementing the above functions. By adding methods to these traits, we can
142
+ allow macro implementations to pass data to the compiler, for example,
143
+ specifying hygiene information or allowing for fast re-compilation.
144
+
145
+ ## ` proc-macro ` crates
146
+
147
+ [ Macros 1.1] ( https://github.com/rust-lang/rfcs/pull/1681 ) added a new crate
148
+ type: proc-macro. This both allows procedural macros to be declared within the
149
+ crate, and dictates how the crate is compiled. Procedural macros must use
150
+ this crate type.
151
+
152
+ We introduce a special configuration option: ` #[cfg(proc_macro)] ` . Items with
105
153
this configuration are not macros themselves but are compiled only for macro
106
154
uses.
107
155
108
- Initially, it will only be legal to apply ` #[cfg(macro)] ` to a whole crate and
109
- the ` #[macro] ` and ` #[macro_attribute] ` attributes may only appear within a
110
- ` #[cfg(macro)] ` crate. This has the effect of partitioning crates into macro-
111
- defining and non-macro defining crates. Macros may not be used in the crate in
112
- which they are defined, although they may be called as regular functions. In the
113
- future, I hope we can relax these restrictions so that macro and non-macro code
114
- can live in the same crate.
156
+ If a crate is a ` proc-macro ` crate, then the ` proc_macro ` cfg variable is true
157
+ for the whole crate. Initially it will be false for all other crates. This has
158
+ the effect of partitioning crates into macro- defining and non-macro defining
159
+ crates. In the future, I hope we can relax these restrictions so that macro and
160
+ non-macro code can live in the same crate.
115
161
116
162
Importing macros for use means using ` extern crate ` to make the crate available
117
163
and then using ` use ` imports or paths to name macros, just like other items.
118
164
Again, see [ RFC 1561] ( https://github.com/rust-lang/rfcs/pull/1561 ) for more
119
165
details.
120
166
121
- When a ` #[cfg(macro)] ` crate is ` extern crate ` ed, it's items (even public ones)
122
- are not available to the importing crate; only macros declared in that crate.
123
- There should be a lint to warn about public items which will not be visible due
124
- to ` #[cfg(macro)] ` . The crate is dynamically linked with the compiler at
125
- compile-time, rather than with the importing crate at runtime.
167
+ When a ` proc-macro ` crate is ` extern crate ` ed, it's items (even public ones) are
168
+ not available to the importing crate; only macros declared in that crate. There
169
+ should be a lint to warn about public items which will not be visible due to
170
+ ` proc_macro ` . The crate is used by the compiler at compile-time, rather than
171
+ linked with the importing crate at runtime.
172
+
173
+ [ Macros 1.1] ( https://github.com/rust-lang/rfcs/pull/1681 ) required ` #[macro_use] `
174
+ on ` extern crate ` which imports procedural macros. This will not be required
175
+ and should be deprecated.
126
176
127
177
128
178
## Writing procedural macros
129
179
130
180
Procedural macro authors should not use the compiler crates (libsyntax, etc.).
131
- Using these will remain unstable. We will make available a new crate, libmacro,
132
- which will follow the usual path to stabilisation, will be part of the Rust
133
- distribution, and will be required to be used by procedural macros (because, at
134
- the least, it defines the types used in the required signatures).
181
+ Using these will remain unstable. We will make available a new crate,
182
+ libproc_macro, which will follow the usual path to stabilisation, will be part
183
+ of the Rust distribution, and will be required to be used by procedural macros
184
+ (because, at the least, it defines the types used in the required signatures).
135
185
136
- The details of libmacro will be specified in a future RFC. In the meantime, this
137
- [ blog post] ( http://ncameron.org/blog/libmacro/ ) gives an idea of what it might
138
- contain.
186
+ The details of libproc_macro will be specified in a future RFC. In the meantime,
187
+ this [ blog post] ( http://ncameron.org/blog/libmacro/ ) gives an idea of what it
188
+ might contain.
139
189
140
- The philosophy here is that libmacro will contain low-level tools for
190
+ The philosophy here is that libproc_macro will contain low-level tools for
141
191
constructing macros, dealing with tokens, hygiene, pattern matching, quasi-
142
192
quoting, interactions with the compiler, etc. For higher level abstractions
143
193
(such as parsing and an AST), macros should use external libraries (there are no
144
- restrictions on ` #[cfg(macro )] ` crates using other crates).
194
+ restrictions on ` #[cfg(proc_macro )] ` crates using other crates).
145
195
146
- The ` MacroContext ` is an object passed to all procedural macro definitions. It
147
- is the main entry point to the libmacro API and for interaction with the
148
- compiler. Via the ` MacroContext ` , a procedural macro can access information
149
- about the context in which it is used and defined, and perform operations which
150
- rely on the state of the compiler. It will be more fully defined in the upcoming
151
- RFC proposing libmacro.
196
+ A ` MacroContext ` is an object placed in thread-local storage when a macro is
197
+ expanded. It contains data about how the macro is being used and defined. It is
198
+ expected that for most uses, macro authors will not use the ` MacroContext `
199
+ directly, but it will be used by library functions. It will be more fully
200
+ defined in the upcoming RFC proposing libproc_macro.
152
201
153
202
Rust macros are hygienic by default. Hygiene is a large and complex subject, but
154
203
to summarise: effectively, naming takes place in the context of the macro
@@ -157,8 +206,8 @@ definition, not the expanded macro.
157
206
Procedural macros often want to bend the rules around macro hygiene, for example
158
207
to make items or variables more widely nameable than they would be by default.
159
208
Procedural macros will be able to take part in the application of the hygiene
160
- algorithm via libmacro . Again, full details must wait for the libmacro RFC and a
161
- sketch is available in this [ blog post] ( http://ncameron.org/blog/libmacro/ ) .
209
+ algorithm via libproc_macro . Again, full details must wait for the libproc_macro
210
+ RFC and a sketch is available in this [ blog post] ( http://ncameron.org/blog/libmacro/ ) .
162
211
163
212
164
213
## Tokens
@@ -219,12 +268,12 @@ pub enum TokenKind {
219
268
// The content of the comment can be found from the span.
220
269
Comment(CommentKind),
221
270
222
- // Symbol is the string contents, not including delimiters. It would be nice
271
+ // `text` is the string contents, not including delimiters. It would be nice
223
272
// to avoid an allocation in the common case that the string is in the
224
- // source code. We might be able to use `&'Codemap str` or something.
225
- // `Option<usize> is for the count of `#`s if the string is a raw string. If
273
+ // source code. We might be able to use `&'codemap str` or something.
274
+ // `raw_markers` is for the count of `#`s if the string is a raw string. If
226
275
// the string is not raw, then it will be `None`.
227
- String( Symbol, Option<usize>, StringKind) ,
276
+ String { text: Symbol, raw_markers: Option<usize>, kind: StringKind } ,
228
277
229
278
// char literal, span includes the `'` delimiters.
230
279
Char(char),
@@ -269,6 +318,10 @@ pub enum StringKind {
269
318
pub struct Symbol { ... }
270
319
```
271
320
321
+ Note that although tokens exclude whitespace, by examining the spans of tokens,
322
+ a procedural macro can get the string representation of a ` TokenStream ` and thus
323
+ has access to whitespace information.
324
+
272
325
### Open question: ` Punctuation(char) ` and multi-char operators.
273
326
274
327
Rust has many compound operators, e.g., ` << ` . It's not clear how best to deal
@@ -294,14 +347,14 @@ Some solutions:
294
347
## Staging
295
348
296
349
1 . Implement [ RFC 1561] ( https://github.com/rust-lang/rfcs/pull/1561 ) .
297
- 2 . Implement ` #[macro ] ` and ` #[cfg(macro )] ` and the function approach to
350
+ 2 . Implement ` #[proc_macro ] ` and ` #[cfg(proc_macro )] ` and the function approach to
298
351
defining macros. However, pass the existing data structures to the macros,
299
352
rather than tokens and ` MacroContext ` .
300
- 3 . Implement libmacro and make this available to macros. At this stage both old
353
+ 3 . Implement libproc_macro and make this available to macros. At this stage both old
301
354
and new macros are available (functions with different signatures). This will
302
355
require an RFC and considerable refactoring of the compiler.
303
356
4 . Implement some high-level macro facilities in external crates on top of
304
- libmacro . It is hoped that much of this work will be community-led.
357
+ libproc_macro . It is hoped that much of this work will be community-led.
305
358
5 . After some time to allow conversion, deprecate the old-style macros. Later,
306
359
remove old macros completely.
307
360
@@ -345,7 +398,10 @@ latter can be written today, the former require more work on an interface to the
345
398
compiler to be practical).
346
399
347
400
We could use the ` macro ` keyword rather than the ` fn ` keyword to declare a
348
- macro. We would then not require a ` #[macro] ` attribute.
401
+ macro. We would then not require a ` #[proc_macro] ` attribute.
402
+
403
+ We could use ` #[macro] ` instead of ` #[proc_macro] ` (and similarly for the other
404
+ attributes). This would require making ` macro ` a contextual keyword.
349
405
350
406
We could have a dedicated syntax for procedural macros, similar to the
351
407
` macro_rules ` syntax for macros by example. Since a procedural macro is really
@@ -365,31 +421,6 @@ would require additional rules on token trees and may not be possible.
365
421
# Unresolved questions
366
422
[ unresolved ] : #unresolved-questions
367
423
368
- ### macros with an extra identifier
369
-
370
- We currently allow procedural macros to take an extra ident after the macro name
371
- and before the arguments, e.g., ` foo! bar(...) ` where ` foo ` is the macro name
372
- and ` bar ` is the extra identifier. This is used for ` macro_rules ` and is useful
373
- for macros which define classes of items, rather than instances of items. E.g.,
374
- a ` struct! ` macro might be used similarly to the ` struct ` keyword.
375
-
376
- My feeling is that this macro form is not used enough to justify its existence.
377
- From a design perspective, it encourages uses of macros for language extension,
378
- rather than syntactic abstraction. I feel that such macros are at higher risk of
379
- making programs incomprehensible and of fragmenting the ecosystem).
380
-
381
- Therefore, I would like to remove them from the language. Alternatively, they
382
- could be incorporated into the new design by having another kind of macro
383
- function:
384
-
385
- ```
386
- #[macro_with_ident]
387
- pub fn foo(&Token, TokenStream, &mut MacroContext) -> TokenStream;
388
- ```
389
-
390
- where the first argument is the extra identifier.
391
-
392
-
393
424
### Linking model
394
425
395
426
Currently, procedural macros are dynamically linked with the compiler. This
0 commit comments