Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ declare_features! (
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)),
(unstable, deref_patterns, "1.79.0", Some(87121)),
/// Allows deriving the From trait on single-field structs.
(unstable, derive_from, "1.91.0", Some(144889)),
/// Allows giving non-const impls custom diagnostic messages if attempted to be used as const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ The tracking issue for this feature is: [#87121]

------------------------

> **Note**: This feature is incomplete. In the future, it is meant to supersede
> [`box_patterns`].
> **Note**: This feature supersedes [`box_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
is currently a placeholder).

```rust
#![feature(deref_patterns)]
#![allow(incomplete_features)]

let mut v = vec![Box::new(Some(0))];

Expand Down Expand Up @@ -58,7 +56,6 @@ Like [`box_patterns`], deref patterns may move out of boxes:

```rust
# #![feature(deref_patterns)]
# #![allow(incomplete_features)]
struct NoCopy;
let deref!(x) = Box::new(NoCopy);
drop::<NoCopy>(x);
Expand All @@ -69,7 +66,6 @@ allowing then to be used in deref patterns:

```rust
# #![feature(deref_patterns)]
# #![allow(incomplete_features)]
match ("test".to_string(), Box::from("test"), b"test".to_vec()) {
("test", "test", b"test") => {}
_ => panic!(),
Expand Down
1 change: 0 additions & 1 deletion tests/mir-opt/building/match/deref-patterns/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//@ compile-flags: -Z mir-opt-level=0 -C panic=abort

#![feature(deref_patterns)]
#![expect(incomplete_features)]
#![crate_type = "lib"]

// EMIT_MIR string.foo.PreCodegen.after.mir
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@ run-pass
//@ check-run-results
#![feature(deref_patterns)]
#![expect(incomplete_features)]

fn main() {
test(Some(String::from("42")));
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@ revisions: explicit implicit
//@ run-pass
#![feature(deref_patterns)]
#![allow(incomplete_features)]

use std::rc::Rc;

Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//@ run-pass
// Test the execution of deref patterns.
#![feature(deref_patterns)]
#![allow(incomplete_features)]

#[cfg(explicit)]
fn branch(vec: Vec<u32>) -> u32 {
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/byte-string-type-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//@ dont-require-annotations: NOTE

#![feature(deref_patterns)]
#![expect(incomplete_features)]

fn main() {
// Baseline 1: under normal circumstances, byte string literal patterns have type `&[u8; N]`,
Expand Down
18 changes: 9 additions & 9 deletions tests/ui/pattern/deref-patterns/byte-string-type-errors.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:13:12
--> $DIR/byte-string-type-errors.rs:12:12
|
LL | if let b"test" = () {}
| ^^^^^^^ -- this expression has type `()`
| |
| expected `()`, found `&[u8; 4]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:20:12
--> $DIR/byte-string-type-errors.rs:19:12
|
LL | if let b"test" = &[] as &[i8] {}
| ^^^^^^^ ------------ this expression has type `&[i8]`
Expand All @@ -18,7 +18,7 @@ LL | if let b"test" = &[] as &[i8] {}
found reference `&'static [u8]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:25:12
--> $DIR/byte-string-type-errors.rs:24:12
|
LL | if let b"test" = *(&[] as &[i8]) {}
| ^^^^^^^ --------------- this expression has type `[i8]`
Expand All @@ -29,7 +29,7 @@ LL | if let b"test" = *(&[] as &[i8]) {}
found slice `[u8]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:30:12
--> $DIR/byte-string-type-errors.rs:29:12
|
LL | if let b"test" = [()] {}
| ^^^^^^^ ---- this expression has type `[(); 1]`
Expand All @@ -40,23 +40,23 @@ LL | if let b"test" = [()] {}
found array `[u8; 4]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:33:12
--> $DIR/byte-string-type-errors.rs:32:12
|
LL | if let b"test" = *b"this array is too long" {}
| ^^^^^^^ -------------------------- this expression has type `[u8; 22]`
| |
| expected an array with a size of 22, found one with a size of 4

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:39:12
--> $DIR/byte-string-type-errors.rs:38:12
|
LL | if let b"test" = &mut () {}
| ^^^^^^^ ------- this expression has type `&mut ()`
| |
| expected `()`, found `&[u8; 4]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:44:12
--> $DIR/byte-string-type-errors.rs:43:12
|
LL | if let b"test" = &mut [] as &mut [i8] {}
| ^^^^^^^ -------------------- this expression has type `&mut [i8]`
Expand All @@ -67,7 +67,7 @@ LL | if let b"test" = &mut [] as &mut [i8] {}
found slice `[u8]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:48:12
--> $DIR/byte-string-type-errors.rs:47:12
|
LL | if let b"test" = &mut [()] {}
| ^^^^^^^ --------- this expression has type `&mut [(); 1]`
Expand All @@ -78,7 +78,7 @@ LL | if let b"test" = &mut [()] {}
found array `[u8; 4]`

error[E0308]: mismatched types
--> $DIR/byte-string-type-errors.rs:52:12
--> $DIR/byte-string-type-errors.rs:51:12
|
LL | if let b"test" = &mut *b"this array is too long" {}
| ^^^^^^^ ------------------------------- this expression has type `&mut [u8; 22]`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(deref_patterns)]
#![allow(incomplete_features)]

use std::rc::Rc;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0508]: cannot move out of type `[Struct]`, a non-copy slice
--> $DIR/cant_move_out_of_pattern.rs:9:11
--> $DIR/cant_move_out_of_pattern.rs:8:11
|
LL | match b {
| ^ cannot move out of here
Expand All @@ -16,7 +16,7 @@ LL | deref!([ref x]) => x,
| +++

error[E0507]: cannot move out of a shared reference
--> $DIR/cant_move_out_of_pattern.rs:17:11
--> $DIR/cant_move_out_of_pattern.rs:16:11
|
LL | match rc {
| ^^
Expand All @@ -33,7 +33,7 @@ LL | deref!(ref x) => x,
| +++

error[E0508]: cannot move out of type `[Struct]`, a non-copy slice
--> $DIR/cant_move_out_of_pattern.rs:25:11
--> $DIR/cant_move_out_of_pattern.rs:24:11
|
LL | match b {
| ^ cannot move out of here
Expand All @@ -50,7 +50,7 @@ LL | [ref x] => x,
| +++

error[E0507]: cannot move out of a shared reference
--> $DIR/cant_move_out_of_pattern.rs:35:11
--> $DIR/cant_move_out_of_pattern.rs:34:11
|
LL | match rc {
| ^^
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/closure_capture.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ run-pass
#![feature(deref_patterns)]
#![allow(incomplete_features)]

use std::rc::Rc;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
//! we'd get without `deref_patterns` enabled.

#![cfg_attr(deref_patterns, feature(deref_patterns))]
#![cfg_attr(deref_patterns, expect(incomplete_features))]

fn uninferred<T>() -> T { unimplemented!() }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/const-pats-do-not-mislead-inference.rs:33:12
--> $DIR/const-pats-do-not-mislead-inference.rs:32:12
|
LL | if let b"..." = &&x {}
| ^^^^^^ --- this expression has type `&&_`
Expand All @@ -10,7 +10,7 @@ LL | if let b"..." = &&x {}
found reference `&'static [u8; 3]`

error[E0308]: mismatched types
--> $DIR/const-pats-do-not-mislead-inference.rs:39:12
--> $DIR/const-pats-do-not-mislead-inference.rs:38:12
|
LL | if let "..." = &Box::new(x) {}
| ^^^^^ ------------ this expression has type `&Box<_>`
Expand All @@ -25,7 +25,7 @@ LL | if let "..." = &*Box::new(x) {}
| +

error[E0308]: mismatched types
--> $DIR/const-pats-do-not-mislead-inference.rs:45:12
--> $DIR/const-pats-do-not-mislead-inference.rs:44:12
|
LL | if let b"..." = Box::new(&x) {}
| ^^^^^^ ------------ this expression has type `Box<&_>`
Expand All @@ -40,7 +40,7 @@ LL | if let b"..." = *Box::new(&x) {}
| +

error[E0308]: mismatched types
--> $DIR/const-pats-do-not-mislead-inference.rs:51:12
--> $DIR/const-pats-do-not-mislead-inference.rs:50:12
|
LL | if let "..." = &mut x {}
| ^^^^^ ------ this expression has type `&mut _`
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/default-infer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ check-pass
#![feature(deref_patterns)]
#![expect(incomplete_features)]

fn main() {
match <_ as Default>::default() {
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/deref-box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//! and `DerefMut::deref_mut`. Test that they work as expected.

#![feature(deref_patterns)]
#![expect(incomplete_features)]

fn unbox_1<T>(b: Box<T>) -> T {
let deref!(x) = b;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//! inside a deref pattern inside a closure: rust-lang/rust#125059

#![feature(deref_patterns)]
#![allow(incomplete_features, unused)]

fn simple_vec(vec: Vec<u32>) -> u32 {
(|| match Vec::<u32>::new() {
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/fake_borrows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(deref_patterns)]
#![allow(incomplete_features)]

#[rustfmt::skip]
fn main() {
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/pattern/deref-patterns/fake_borrows.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> $DIR/fake_borrows.rs:9:16
--> $DIR/fake_borrows.rs:8:16
|
LL | match v {
| - immutable borrow occurs here
Expand All @@ -10,7 +10,7 @@ LL | _ if { v[0] = true; false } => {}
| mutable borrow occurs here

error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> $DIR/fake_borrows.rs:16:16
--> $DIR/fake_borrows.rs:15:16
|
LL | match v {
| - immutable borrow occurs here
Expand All @@ -21,7 +21,7 @@ LL | _ if { v[0] = true; false } => {}
| mutable borrow occurs here

error[E0510]: cannot assign `*b` in match guard
--> $DIR/fake_borrows.rs:26:16
--> $DIR/fake_borrows.rs:25:16
|
LL | match b {
| - value is immutable in match guard
Expand All @@ -30,7 +30,7 @@ LL | _ if { *b = true; false } => {}
| ^^^^^^^^^ cannot assign

error[E0510]: cannot assign `*b` in match guard
--> $DIR/fake_borrows.rs:33:16
--> $DIR/fake_borrows.rs:32:16
|
LL | match b {
| - value is immutable in match guard
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(deref_patterns)]
#![expect(incomplete_features)]

fn main() {
let vec![const { vec![] }]: Vec<usize> = vec![];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
error[E0532]: expected a pattern, found a function call
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:4:9
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>

error[E0532]: expected a pattern, found a function call
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:4:9
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>

error: arbitrary expressions aren't allowed in patterns
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:4:14
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
| ^^^^^^^^^^^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead

error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit`
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:4:9
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/implicit-const-deref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! scrutinee and end up with a type error; this would prevent us from reporting that only constants
//! supporting structural equality can be used as patterns.
#![feature(deref_patterns)]
#![allow(incomplete_features)]

const EMPTY: Vec<()> = Vec::new();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: constant of non-structural type `Vec<()>` in a pattern
--> $DIR/implicit-const-deref.rs:15:9
--> $DIR/implicit-const-deref.rs:14:9
|
LL | const EMPTY: Vec<()> = Vec::new();
| -------------------- constant defined here
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/implicit-cow-deref.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@ run-pass
//! Test that implicit deref patterns interact as expected with `Cow` constructor patterns.
#![feature(deref_patterns)]
#![allow(incomplete_features)]

use std::borrow::Cow;
use std::rc::Rc;
Expand Down
1 change: 0 additions & 1 deletion tests/ui/pattern/deref-patterns/recursion-limit.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Test that implicit deref patterns respect the recursion limit
#![feature(deref_patterns)]
#![allow(incomplete_features)]
#![recursion_limit = "8"]

use std::ops::Deref;
Expand Down
Loading
Loading