Skip to content

Commit a42c445

Browse files
KivooeoNoratrieb
authored andcommitted
add misc 7
1 parent f0c77f0 commit a42c445

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

code/examples/misc_7.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
macro_rules! capture {
2+
($e:expr) => {
3+
transform!($e)
4+
};
5+
}
6+
7+
macro_rules! transform {
8+
($a:tt + $b:tt) => {
9+
$a * $b
10+
};
11+
($other:expr) => {
12+
$other
13+
};
14+
}
15+
16+
fn main() {
17+
let x = capture!(2 + 3);
18+
println!("{}", x); // what this will print?
19+
}

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- [Miscellaneous 4](./misc/4.md)
1717
- [Miscellaneous 5](./misc/5.md)
1818
- [Miscellaneous 6](./misc/6.md)
19+
- [Miscellaneous 7](./misc/7.md)
1920
- [Miscellaneous 8](./misc/8.md)
2021
- [Miscellaneous 9](./misc/9.md)
2122
- [Miscellaneous 10](./misc/10.md)

src/misc/7.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1-
<!--
1+
# Misc 7 @Kivooeo
22

3-
try to destructure a captured metavariable into its token parts in a macro rules matcher, which does not work
3+
{{#include ../include/quiz-is-wip.md}}
44

5-
-->
5+
```rust
6+
{{#include ../../code/examples/misc_7.rs}}
7+
```
8+
9+
<details>
10+
<summary>Solution</summary>
11+
12+
It will prints `5`.
13+
14+
Once a token is captured as an expression (`:expr`), it becomes opaque to macro pattern matching and cannot be destructured into its component tokens.
15+
16+
When `capture!(2 + 3)` is invoked, the `$e:expr` matcher captures `2 + 3` as a single expression token tree. This captured expression is then passed to `transform!($e)`, which attempts to match it against the pattern `$a:tt + $b:tt`.
17+
18+
However, because `$e` was already captured as an `:expr`, it cannot be pattern-matched as separate tokens anymore. The first arm `$a:tt + $b:tt` fails to match, so the second arm `$other:expr` matches instead, and the expression `2 + 3` is returned as-is, evaluating to `5`.
19+
20+
</details>

0 commit comments

Comments
 (0)