|
| 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 |
0 commit comments