Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a00cc5d

Browse files
committedJun 12, 2022
dollar-dollar
1 parent 0cd078d commit a00cc5d

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed
 

‎src/macros-by-example.md

+47
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,53 @@ compiler knows how to expand them properly:
193193
not have the same number. This requirement applies to every layer of nested
194194
repetitions.
195195

196+
## Dollar-dollar ($$)
197+
198+
`$$` expands to a single `$`.
199+
200+
Since metavariable expressions always apply during the expansion of a macro, they cannot be used in recursive macro definitions and this is where `$$` expressions comes into play, i.e., `$$` can be used to resolve ambiguities in nested macros.
201+
202+
The following example illustrates a macro that fails to compile due to the ambiguity of the repetition in a nested macro:
203+
204+
```rust,compile_fail
205+
macro_rules! foo_error {
206+
() => {
207+
macro_rules! bar_error {
208+
( $( $any:tt )* ) => { $( $any )* };
209+
// ^^^^^^^^^^^ error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
210+
}
211+
};
212+
}
213+
214+
foo_error!();
215+
```
216+
217+
The following resolves the problem by escaping the `$` in the repetition with `$$`:
218+
219+
```rust
220+
macro_rules! foo_ok {
221+
() => {
222+
macro_rules! bar_ok {
223+
( $$( $any:tt )* ) => { $$( $any )* };
224+
}
225+
};
226+
}
227+
228+
foo_ok!();
229+
```
230+
231+
One consequence of such expansion is that deeper nested levels make dollar-dollar declarations grown linearly, starting at `$$`, then `$$$$`, then `$$$$$` and so on. This is also necessary to be fully featured so that it is possible to specify names of metavariables using other metavariables at each nesting level.
232+
233+
```
234+
$foo => bar => bar // Evaluate foo at level 1
235+
$$foo => $foo => bar // Evaluate foo at level 2
236+
$$$foo => $bar => baz // Evaluate foo at level 1, and use that as a name at level 2
237+
$$$$foo => $$foo => $foo // Evaluate foo at level 3
238+
$$$$$foo => $$bar => $bar // Evaluate foo at level 1, and use that as a name at level 3
239+
$$$$$$foo => $$$foo => $bar // Evaluate foo at level 2, and use that as a name at level 3
240+
$$$$$$$foo => $$$bar => $baz // Evaluate foo at level 1, use that at level 2, and then use *that* at level 3
241+
```
242+
196243
## Scoping, Exporting, and Importing
197244

198245
For historical reasons, the scoping of macros by example does not work entirely

0 commit comments

Comments
 (0)
Please sign in to comment.