about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorChris Denton <chris@chrisdenton.dev>2025-04-28 23:29:15 +0000
committerGitHub <noreply@github.com>2025-04-28 23:29:15 +0000
commit8dd26cb195df77d991ee7826b1aa587d9f638e78 (patch)
tree0058bbe7abcd05b01f63ae9df2cc3470ddcf66c5 /src
parent17495e0030250202c28be85a35b366e37a32df3b (diff)
parent4e555fa52c5e853a47c7865397a1d6787643a51c (diff)
Rollup merge of #140022 - dianne:box-deref-pats, r=Nadrieril
allow deref patterns to move out of boxes

This adds a case to lower deref patterns on boxes using a built-in deref instead of a `Deref::deref` or `DerefMut::deref_mut` call: if `deref!(inner): Box<T>` is matching on place `place`, the inner pattern `inner` now matches on `*place` rather than a temporary. No longer needing to call a method also means it won't borrow the scrutinee in match arms. This allows for bindings in `inner` to move out of `*place`.

For comparison with box patterns, this uses the same MIR lowering but different THIR. Consequently, deref patterns on boxes are treated the same as any other deref patterns in match exhaustiveness analysis. Box patterns can't quite be implemented in terms of deref patterns until exhaustiveness checking for deref patterns is implemented (I'll open a PR for exhaustiveness soon!).

Tracking issue: #87121

r? ``@Nadrieril``
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/deref-patterns.md15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md
index d0a64538e8c..0cc7106da48 100644
--- a/src/doc/unstable-book/src/language-features/deref-patterns.md
+++ b/src/doc/unstable-book/src/language-features/deref-patterns.md
@@ -7,7 +7,7 @@ The tracking issue for this feature is: [#87121]
 ------------------------
 
 > **Note**: This feature is incomplete. In the future, it is meant to supersede
-> [`box_patterns`](./box-patterns.md) and [`string_deref_patterns`](./string-deref-patterns.md).
+> [`box_patterns`] and [`string_deref_patterns`].
 
 This feature permits pattern matching on [smart pointers in the standard library] through their
 `Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which
@@ -54,6 +54,17 @@ if let [b] = &mut *v {
 assert_eq!(v, [Box::new(Some(2))]);
 ```
 
+Like [`box_patterns`], deref patterns may move out of boxes:
+
+```rust
+# #![feature(deref_patterns)]
+# #![allow(incomplete_features)]
+struct NoCopy;
+// Match exhaustiveness analysis is not yet implemented.
+let deref!(x) = Box::new(NoCopy) else { unreachable!() };
+drop::<NoCopy>(x);
+```
+
 Additionally, when `deref_patterns` is enabled, string literal patterns may be written where `str`
 is expected. Likewise, byte string literal patterns may be written where `[u8]` or `[u8; _]` is
 expected. This lets them be used in `deref!(_)` patterns:
@@ -75,4 +86,6 @@ match *"test" {
 
 Implicit deref pattern syntax is not yet supported for string or byte string literals.
 
+[`box_patterns`]: ./box-patterns.md
+[`string_deref_patterns`]: ./string-deref-patterns.md
 [smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors