Skip to content

Commit 93d13e9

Browse files
committed
add an unstable book chapter
- Clarifies the uses of implicit and explicit deref patterns - Includes motivating examples for both syntaxes - Shows the interaction with match ergonomics for reference types - Cross-links with `string_deref_patterns` and `box_patterns` The examples are contrived, but hopefully the intent comes across.
1 parent 4c4b61b commit 93d13e9

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/doc/unstable-book/src/language-features/box-patterns.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The tracking issue for this feature is: [#29641]
66

77
------------------------
88

9+
> **Note**: This feature will be superseded by [`deref_patterns`] in the future.
10+
911
Box patterns let you match on `Box<T>`s:
1012

1113

@@ -28,3 +30,5 @@ fn main() {
2830
}
2931
}
3032
```
33+
34+
[`deref_patterns`]: ./deref-patterns.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# `deref_patterns`
2+
3+
The tracking issue for this feature is: [#87121]
4+
5+
[#87121]: https://github.com/rust-lang/rust/issues/87121
6+
7+
------------------------
8+
9+
> **Note**: This feature is incomplete. In the future, it is meant to supersede
10+
> [`box_patterns`](./box-patterns.md) and [`string_deref_patterns`](./string-deref-patterns.md).
11+
12+
This feature permits pattern matching on [smart pointers in the standard library] through their
13+
`Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which
14+
is currently a placeholder).
15+
16+
```rust
17+
#![feature(deref_patterns)]
18+
#![allow(incomplete_features)]
19+
20+
let mut v = vec![Box::new(Some(0))];
21+
22+
// Implicit dereferences are inserted when a pattern can match against the
23+
// result of repeatedly dereferencing but can't match against a smart
24+
// pointer itself. This works alongside match ergonomics for references.
25+
if let [Some(x)] = &mut v {
26+
*x += 1;
27+
}
28+
29+
// Explicit `deref!(_)` patterns may instead be used when finer control is
30+
// needed, e.g. to dereference only a single smart pointer, or to bind the
31+
// the result of dereferencing to a variable.
32+
if let deref!([deref!(opt_x @ Some(1))]) = &mut v {
33+
opt_x.as_mut().map(|x| *x += 1);
34+
}
35+
36+
assert_eq!(v, [Box::new(Some(2))]);
37+
```
38+
39+
Without this feature, it may be necessary to introduce temporaries to represent dereferenced places
40+
when matching on nested structures:
41+
42+
```rust
43+
let mut v = vec![Box::new(Some(0))];
44+
if let [b] = &mut *v {
45+
if let Some(x) = &mut **b {
46+
*x += 1;
47+
}
48+
}
49+
if let [b] = &mut *v {
50+
if let opt_x @ Some(1) = &mut **b {
51+
opt_x.as_mut().map(|x| *x += 1);
52+
}
53+
}
54+
assert_eq!(v, [Box::new(Some(2))]);
55+
```
56+
57+
[smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors

src/doc/unstable-book/src/language-features/string-deref-patterns.md

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The tracking issue for this feature is: [#87121]
66

77
------------------------
88

9+
> **Note**: This feature will be superseded by [`deref_patterns`] in the future.
10+
911
This feature permits pattern matching `String` to `&str` through [its `Deref` implementation].
1012

1113
```rust
@@ -42,4 +44,5 @@ pub fn is_it_the_answer(value: Value) -> bool {
4244
}
4345
```
4446

47+
[`deref_patterns`]: ./deref-patterns.md
4548
[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String

0 commit comments

Comments
 (0)