Skip to content

Commit 68854f4

Browse files
committed
Macros by example 2.0 (macro!)
Macros by example 2.0. A replacement for `macro_rules!`. This is mostly a placeholder RFC since many of the issues affecting the new macro system are (or will be) addressed in other RFCs. This RFC may be expanded at a later date.
1 parent 849ca2f commit 68854f4

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

text/0000-macros.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
- Feature Name: macro
2+
- Start Date: 2016-04-17
3+
- RFC PR: (leave this empty)
4+
- Rust Issue: (leave this empty)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Macros by example 2.0. A replacement for `macro_rules!`. This is mostly a
10+
placeholder RFC since many of the issues affecting the new macro system are
11+
(or will be) addressed in other RFCs. This RFC may be expanded at a later date.
12+
13+
Currently in this RFC:
14+
15+
* That we should have a new macro by example system,
16+
* a new keyword for declaring macros.
17+
18+
In other RFCs:
19+
20+
* Naming and modularisation (#1561).
21+
22+
May be added to this RFC later (or might be separate RFCs):
23+
24+
* more detailed syntax proposal,
25+
* hygiene improvements.
26+
27+
Note this RFC does not involve procedural macros (aka syntax extensions).
28+
29+
30+
# Motivation
31+
[motivation]: #motivation
32+
33+
There are several changes to the macro by example system which are desirable but
34+
backwards compatible (See [RFC 1561](https://github.com/rust-lang/rfcs/pull/1561)
35+
for some changes to macro naming and modularisation, I would also like to
36+
propose improvements to hygiene in macros, and some improved syntax).
37+
38+
In order to maintain Rust's backwards compatibility guarantees, we cannot change
39+
the existing system (`macro_rules!`) to accommodate these changes. I therefore
40+
propose a new macro by example system to live alongside `macro_rules!`.
41+
42+
Example (possible) improvements:
43+
44+
```rust
45+
// Naming (RFC 1561)
46+
47+
fn main() {
48+
a::foo!(...);
49+
}
50+
51+
mod a {
52+
// Macro privacy (TBA)
53+
pub macro! foo { ... }
54+
}
55+
```
56+
57+
```rust
58+
// Relative paths (part of hygiene reform, TBA)
59+
60+
mod a {
61+
pub macro! foo { ... bar() ... }
62+
fn bar() { ... }
63+
}
64+
65+
fn main() {
66+
a::foo!(...); // Expansion calls a::bar
67+
}
68+
```
69+
70+
```rust
71+
// Syntax (TBA)
72+
73+
macro! foo($a: ident) => {
74+
return $a + 1;
75+
}
76+
```
77+
78+
I believe it is extremely important that moving to the new macro system is as
79+
straightforward as possible for both macro users and authors. This must be the
80+
case so that users make the transition to the new system and we are not left
81+
with two systems forever.
82+
83+
A goal of this design is that for macro users, there is no difference in using
84+
the two systems other than how macros are named. For macro authors, most macros
85+
that work in the old system should work in the new system with minimal changes.
86+
Macros which will need some adjustment are those that exploit holes in the
87+
current hygiene system.
88+
89+
90+
# Detailed design
91+
[design]: #detailed-design
92+
93+
There will be a new system of macros by example using similar syntax and
94+
semantics to the current `macro_rules!` system.
95+
96+
A macro by example is declared using the `macro` keyword with the `!`
97+
operator. For example, where a macro `foo` is declared today as `macro_rules!
98+
foo { ... }`, it will be declared using `macro! foo { ... }`. I leave the syntax
99+
of the macro body for later specification.
100+
101+
102+
# Drawbacks
103+
[drawbacks]: #drawbacks
104+
105+
There is a risk that `macro_rules!` is good enough for most users and there is
106+
low adoption of the new system. Possibly worse would be that there is high
107+
adoption but little migration from the old system, leading to us having to
108+
support two systems forever.
109+
110+
111+
# Alternatives
112+
[alternatives]: #alternatives
113+
114+
Make backwards incompatible changes to `macro_rules!`. This is probably a
115+
non-starter due to our stability guarantees. We might be able to make something
116+
work if this was considered desirable.
117+
118+
Limit ourselves to backwards compatible changes to `macro_rules!`. I don't think
119+
this is worthwhile. It's not clear we can make meaningful improvements without
120+
breaking backwards compatibility.
121+
122+
Don't use a keyword - either make `macro` not a keyword or use a different word
123+
for the macros by example syntax.
124+
125+
Use `macro` instead of `macro!` (we might want to use bare `macro` for
126+
procedural macros, not clear if the overlap will be a problem).
127+
128+
Live with the existing system.
129+
130+
131+
# Unresolved questions
132+
[unresolved]: #unresolved-questions
133+
134+
What to do with `macro_rules`? We will need to maintain it at least until `macro!`
135+
is stable. Hopefully, we can then deprecate it (some time will be required to
136+
migrate users to the new system). Eventually, I hope we can remove `macro_rules!`.
137+
That will take a long time, and would require a 2.0 version of Rust to strictly
138+
adhere to our stability guarantees.
139+
140+
There are many questions still to be answered as this RFC and some sister RFCs
141+
are developed.

0 commit comments

Comments
 (0)