Skip to content

Commit bd41796

Browse files
committed
Add common patterns section
1 parent dd56572 commit bd41796

File tree

1 file changed

+81
-2
lines changed

1 file changed

+81
-2
lines changed

text/0000-pub-macro-rules.md

+81-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
- Feature Name: `pub_macro_rules`
2-
- Start Date: 2021-01-25
1+
- Feature Name: `macro_rules_visibility_v3`
2+
- Start Date: 2021-01-07
33
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
44
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
55

@@ -91,6 +91,7 @@ To migrate to a path scoping visibility system the following would need to be up
9191
* publicly re-export them from the top-level module of the crate where the macro is defined
9292
* Remove `#[macro_use]` where annotating a module
9393
* mark all the macros in the previously annotated module as `pub(crate)`
94+
* mark the module itself as pub(crate) if not already `pub(crate)` or `pub`
9495
* annotate the macro invocation with a path to the module where the macro is defined.
9596
* Remove `#[macro_use]` from from `extern crate` item
9697
* change all uses of macros to qualified `$EXTERNAL_CRATE::$MACRO_NAME` invocations.
@@ -99,6 +100,84 @@ These steps should be automatable so that rustfix can be used to aid in migratio
99100

100101
Roughly what percentage of use cases will be machine migratable is an open question.
101102

103+
## Translating Common Patterns
104+
105+
The following are how common patterns in macros today translate to the next path based scoping system.
106+
107+
### Deeply nested macros
108+
109+
Macro use makes all macros inside a child module available to the parent module.
110+
111+
```rust
112+
113+
#[macro_use]
114+
mod m {
115+
#[macro_use]
116+
mod n {
117+
macro_rules! define_foo { () => { fn foo() {} } }
118+
}
119+
}
120+
121+
122+
define_foo!();
123+
```
124+
125+
This would be translated as:
126+
127+
```rust
128+
pub(crate) mod m {
129+
pub(crate) mod n {
130+
pub(crate) macro_rules! define_foo { () => { fn foo() {} } }
131+
}
132+
}
133+
134+
135+
m::n::define_foo!();
136+
```
137+
138+
### Recursive macros
139+
140+
Recursive macros are macros that call themselves (perhaps with different arguments)
141+
142+
```rust
143+
macro_rules! print_expr {
144+
($e:expr) => {{
145+
println!("Going to do {}", stringify!($e));
146+
print_expr!(no_print => $e)
147+
}};
148+
(no_print => $e:expr) => {{
149+
$e
150+
}};
151+
}
152+
```
153+
154+
Naively changing this to path based scope would not work as it is not guaranteed that the unqualified `print_expr` name is in scope.
155+
156+
TODO: Describe how we'll handle this
157+
158+
### "Private" macros
159+
160+
Macros can use "private" macros (i.e., macros defined inside of other macros).
161+
162+
```rust
163+
macro_rules! foo {
164+
($o:expr) => {{
165+
macro_rules! __helper {
166+
($e:expr) => {{
167+
println!("Expression: {}", stringify!($e));
168+
$e
169+
}};
170+
}
171+
172+
__helper!($o)
173+
}};
174+
}
175+
```
176+
177+
Naively changing this
178+
179+
TODO: Describe how we'll handle this
180+
102181
# Guide-level explanation
103182

104183
[guide-level-explanation]: #guide-level-explanation

0 commit comments

Comments
 (0)