Skip to content

Commit 0537d30

Browse files
committed
Add feature gate
1 parent b2cb42d commit 0537d30

File tree

8 files changed

+69
-45
lines changed

8 files changed

+69
-45
lines changed

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ declare_features! (
376376
(active, deprecated_safe, "1.61.0", Some(94978), None),
377377
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
378378
(active, deprecated_suggestion, "1.61.0", Some(94785), None),
379+
/// Allows patterns to dereference values to match them.
380+
(active, deref_patterns, "1.64.0", Some(87121), None),
379381
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
380382
(active, doc_auto_cfg, "1.58.0", Some(43781), None),
381383
/// Allows `#[doc(cfg(...))]`.

compiler/rustc_hir_typeck/src/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
401401
}
402402
}
403403

404-
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
404+
if self.tcx.features().deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
405405
let tcx = self.tcx;
406406
let expected = self.resolve_vars_if_possible(expected);
407407
pat_ty = match expected.kind() {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ symbols! {
597597
deref,
598598
deref_method,
599599
deref_mut,
600+
deref_patterns,
600601
deref_target,
601602
derive,
602603
derive_const,

src/test/ui/deref-patterns/basic.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// run-pass
22
// check-run-results
3+
#![feature(deref_patterns)]
34

45
fn main() {
56
test(Some(String::from("42")));
@@ -13,4 +14,4 @@ fn test(o: Option<String>) {
1314
Some(_) => println!("something else?"),
1415
None => println!("nil"),
1516
}
16-
}
17+
}

src/test/ui/deref-patterns/gate.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// gate-test-deref_patterns
2+
fn main() {
3+
match String::new() {
4+
"" | _ => {}
5+
//~^ mismatched types
6+
}
7+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/gate.rs:3:9
3+
|
4+
LL | match String::new() {
5+
| ------------- this expression has type `String`
6+
LL | "" | _ => {}
7+
| ^^ expected struct `String`, found `&str`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/deref-patterns/mir.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// compile-flags: -Z unpretty=mir
22
// build-pass
3+
#![feature(deref_patterns)]
4+
35
fn main() {
46
let s = Some(String::new());
57
let a;
68
match s {
79
Some("a") => a = 1234,
810
s => a = 4321,
911
}
10-
}
12+
}

src/test/ui/deref-patterns/mir.stdout

+42-42
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,99 @@
11
// WARNING: This output format is intended for human consumers only
22
// and is subject to change without notice. Knock yourself out.
33
fn main() -> () {
4-
let mut _0: (); // return place in scope 0 at $DIR/mir.rs:3:11: 3:11
5-
let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:4:9: 4:10
6-
let mut _2: std::string::String; // in scope 0 at $DIR/mir.rs:4:18: 4:31
7-
let mut _4: &std::string::String; // in scope 0 at $DIR/mir.rs:7:14: 7:17
8-
let mut _5: &str; // in scope 0 at $DIR/mir.rs:7:14: 7:17
9-
let mut _6: bool; // in scope 0 at $DIR/mir.rs:7:14: 7:17
10-
let mut _7: isize; // in scope 0 at $DIR/mir.rs:7:9: 7:18
11-
let mut _9: bool; // in scope 0 at $DIR/mir.rs:10:1: 10:2
4+
let mut _0: (); // return place in scope 0 at $DIR/mir.rs:5:11: 5:11
5+
let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:6:9: 6:10
6+
let mut _2: std::string::String; // in scope 0 at $DIR/mir.rs:6:18: 6:31
7+
let mut _4: &std::string::String; // in scope 0 at $DIR/mir.rs:9:14: 9:17
8+
let mut _5: &str; // in scope 0 at $DIR/mir.rs:9:14: 9:17
9+
let mut _6: bool; // in scope 0 at $DIR/mir.rs:9:14: 9:17
10+
let mut _7: isize; // in scope 0 at $DIR/mir.rs:9:9: 9:18
11+
let mut _9: bool; // in scope 0 at $DIR/mir.rs:12:1: 12:2
1212
scope 1 {
13-
debug s => _1; // in scope 1 at $DIR/mir.rs:4:9: 4:10
14-
let _3: i32; // in scope 1 at $DIR/mir.rs:5:9: 5:10
13+
debug s => _1; // in scope 1 at $DIR/mir.rs:6:9: 6:10
14+
let _3: i32; // in scope 1 at $DIR/mir.rs:7:9: 7:10
1515
scope 2 {
16-
debug a => _3; // in scope 2 at $DIR/mir.rs:5:9: 5:10
17-
let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:8:9: 8:10
16+
debug a => _3; // in scope 2 at $DIR/mir.rs:7:9: 7:10
17+
let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:10:9: 10:10
1818
scope 3 {
19-
debug s => _8; // in scope 3 at $DIR/mir.rs:8:9: 8:10
19+
debug s => _8; // in scope 3 at $DIR/mir.rs:10:9: 10:10
2020
}
2121
}
2222
}
2323

2424
bb0: {
25-
_9 = const false; // scope 0 at $DIR/mir.rs:4:9: 4:10
26-
_2 = String::new() -> bb1; // scope 0 at $DIR/mir.rs:4:18: 4:31
25+
_9 = const false; // scope 0 at $DIR/mir.rs:6:9: 6:10
26+
_2 = String::new() -> bb1; // scope 0 at $DIR/mir.rs:6:18: 6:31
2727
// mir::Constant
28-
// + span: $DIR/mir.rs:4:18: 4:29
28+
// + span: $DIR/mir.rs:6:18: 6:29
2929
// + literal: Const { ty: fn() -> String {String::new}, val: Value(Scalar(<ZST>)) }
3030
}
3131

3232
bb1: {
33-
_9 = const true; // scope 0 at $DIR/mir.rs:4:13: 4:32
34-
Deinit(_1); // scope 0 at $DIR/mir.rs:4:13: 4:32
35-
((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:4:13: 4:32
36-
discriminant(_1) = 1; // scope 0 at $DIR/mir.rs:4:13: 4:32
37-
_7 = discriminant(_1); // scope 2 at $DIR/mir.rs:6:11: 6:12
38-
switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:6:5: 6:12
33+
_9 = const true; // scope 0 at $DIR/mir.rs:6:13: 6:32
34+
Deinit(_1); // scope 0 at $DIR/mir.rs:6:13: 6:32
35+
((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:6:13: 6:32
36+
discriminant(_1) = 1; // scope 0 at $DIR/mir.rs:6:13: 6:32
37+
_7 = discriminant(_1); // scope 2 at $DIR/mir.rs:8:11: 8:12
38+
switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:8:5: 8:12
3939
}
4040

4141
bb2: {
42-
_9 = const false; // scope 2 at $DIR/mir.rs:8:9: 8:10
43-
_8 = move _1; // scope 2 at $DIR/mir.rs:8:9: 8:10
44-
_3 = const 4321_i32; // scope 3 at $DIR/mir.rs:8:14: 8:22
45-
drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:8:21: 8:22
42+
_9 = const false; // scope 2 at $DIR/mir.rs:10:9: 10:10
43+
_8 = move _1; // scope 2 at $DIR/mir.rs:10:9: 10:10
44+
_3 = const 4321_i32; // scope 3 at $DIR/mir.rs:10:14: 10:22
45+
drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:10:21: 10:22
4646
}
4747

4848
bb3: {
49-
_4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:7:14: 7:17
50-
_5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:7:14: 7:17
49+
_4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:9:14: 9:17
50+
_5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:9:14: 9:17
5151
// mir::Constant
52-
// + span: $DIR/mir.rs:7:14: 7:17
52+
// + span: $DIR/mir.rs:9:14: 9:17
5353
// + literal: Const { ty: for<'r> fn(&'r String) -> &'r <String as Deref>::Target {<String as Deref>::deref}, val: Value(Scalar(<ZST>)) }
5454
}
5555

5656
bb4: {
57-
_6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:7:14: 7:17
57+
_6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:9:14: 9:17
5858
// mir::Constant
59-
// + span: $DIR/mir.rs:7:14: 7:17
59+
// + span: $DIR/mir.rs:9:14: 9:17
6060
// + literal: Const { ty: for<'r, 's> fn(&'r str, &'s str) -> bool {<str as PartialEq>::eq}, val: Value(Scalar(<ZST>)) }
6161
// mir::Constant
62-
// + span: $DIR/mir.rs:7:14: 7:17
62+
// + span: $DIR/mir.rs:9:14: 9:17
6363
// + literal: Const { ty: &str, val: Value(Slice(..)) }
6464
}
6565

6666
bb5: {
67-
switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:7:14: 7:17
67+
switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:9:14: 9:17
6868
}
6969

7070
bb6: {
71-
_3 = const 1234_i32; // scope 2 at $DIR/mir.rs:7:22: 7:30
72-
goto -> bb7; // scope 2 at $DIR/mir.rs:7:22: 7:30
71+
_3 = const 1234_i32; // scope 2 at $DIR/mir.rs:9:22: 9:30
72+
goto -> bb7; // scope 2 at $DIR/mir.rs:9:22: 9:30
7373
}
7474

7575
bb7: {
76-
switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:10:1: 10:2
76+
switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:12:1: 12:2
7777
}
7878

7979
bb8: {
80-
_9 = const false; // scope 0 at $DIR/mir.rs:10:1: 10:2
81-
return; // scope 0 at $DIR/mir.rs:10:2: 10:2
80+
_9 = const false; // scope 0 at $DIR/mir.rs:12:1: 12:2
81+
return; // scope 0 at $DIR/mir.rs:12:2: 12:2
8282
}
8383

8484
bb9 (cleanup): {
85-
resume; // scope 0 at $DIR/mir.rs:3:1: 10:2
85+
resume; // scope 0 at $DIR/mir.rs:5:1: 12:2
8686
}
8787

8888
bb10: {
89-
drop(_1) -> bb8; // scope 0 at $DIR/mir.rs:10:1: 10:2
89+
drop(_1) -> bb8; // scope 0 at $DIR/mir.rs:12:1: 12:2
9090
}
9191

9292
bb11 (cleanup): {
93-
drop(_1) -> bb9; // scope 0 at $DIR/mir.rs:10:1: 10:2
93+
drop(_1) -> bb9; // scope 0 at $DIR/mir.rs:12:1: 12:2
9494
}
9595

9696
bb12 (cleanup): {
97-
switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:10:1: 10:2
97+
switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:12:1: 12:2
9898
}
9999
}

0 commit comments

Comments
 (0)