about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2022-07-05 07:42:19 +0000
committerDeadbeef <ent3rm4n@gmail.com>2022-11-17 12:46:43 +0000
commit0537d301c520ffc1a6069df6dd5012c679fe29ca (patch)
tree8f5ac3e516848559066c56a7fda6afce0153a007
parentb2cb42d6a7b14b35e79f56228682148ecdd8a6a9 (diff)
downloadrust-0537d301c520ffc1a6069df6dd5012c679fe29ca.tar.gz
rust-0537d301c520ffc1a6069df6dd5012c679fe29ca.zip
Add feature gate
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/test/ui/deref-patterns/basic.rs3
-rw-r--r--src/test/ui/deref-patterns/gate.rs7
-rw-r--r--src/test/ui/deref-patterns/gate.stderr11
-rw-r--r--src/test/ui/deref-patterns/mir.rs4
-rw-r--r--src/test/ui/deref-patterns/mir.stdout84
8 files changed, 69 insertions, 45 deletions
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 5cf2fdde392..3a1db1193b3 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -376,6 +376,8 @@ declare_features! (
     (active, deprecated_safe, "1.61.0", Some(94978), None),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (active, deprecated_suggestion, "1.61.0", Some(94785), None),
+    /// Allows patterns to dereference values to match them.
+    (active, deref_patterns, "1.64.0", Some(87121), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
     (active, doc_auto_cfg, "1.58.0", Some(43781), None),
     /// Allows `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index f2d5f754c6f..b20949bcbd5 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
+        if self.tcx.features().deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
             let tcx = self.tcx;
             let expected = self.resolve_vars_if_possible(expected);
             pat_ty = match expected.kind() {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a56450a3573..a06e613b82f 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -597,6 +597,7 @@ symbols! {
         deref,
         deref_method,
         deref_mut,
+        deref_patterns,
         deref_target,
         derive,
         derive_const,
diff --git a/src/test/ui/deref-patterns/basic.rs b/src/test/ui/deref-patterns/basic.rs
index aa854ed7532..e03f2455954 100644
--- a/src/test/ui/deref-patterns/basic.rs
+++ b/src/test/ui/deref-patterns/basic.rs
@@ -1,5 +1,6 @@
 // run-pass
 // check-run-results
+#![feature(deref_patterns)]
 
 fn main() {
     test(Some(String::from("42")));
@@ -13,4 +14,4 @@ fn test(o: Option<String>) {
         Some(_) => println!("something else?"),
         None => println!("nil"),
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/ui/deref-patterns/gate.rs b/src/test/ui/deref-patterns/gate.rs
new file mode 100644
index 00000000000..90d0448e94a
--- /dev/null
+++ b/src/test/ui/deref-patterns/gate.rs
@@ -0,0 +1,7 @@
+// gate-test-deref_patterns
+fn main() {
+    match String::new() {
+        "" | _ => {}
+        //~^ mismatched types
+    }
+}
diff --git a/src/test/ui/deref-patterns/gate.stderr b/src/test/ui/deref-patterns/gate.stderr
new file mode 100644
index 00000000000..7ffd0eb7e6c
--- /dev/null
+++ b/src/test/ui/deref-patterns/gate.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/gate.rs:3:9
+   |
+LL |     match String::new() {
+   |           ------------- this expression has type `String`
+LL |         "" | _ => {}
+   |         ^^ expected struct `String`, found `&str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/deref-patterns/mir.rs b/src/test/ui/deref-patterns/mir.rs
index 3be4a82d76c..2e7d26d0dfd 100644
--- a/src/test/ui/deref-patterns/mir.rs
+++ b/src/test/ui/deref-patterns/mir.rs
@@ -1,5 +1,7 @@
 // compile-flags: -Z unpretty=mir
 // build-pass
+#![feature(deref_patterns)]
+
 fn main() {
     let s = Some(String::new());
     let a;
@@ -7,4 +9,4 @@ fn main() {
         Some("a") => a = 1234,
         s => a = 4321,
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/ui/deref-patterns/mir.stdout b/src/test/ui/deref-patterns/mir.stdout
index 211f50fa1a8..e73d37efb24 100644
--- a/src/test/ui/deref-patterns/mir.stdout
+++ b/src/test/ui/deref-patterns/mir.stdout
@@ -1,99 +1,99 @@
 // WARNING: This output format is intended for human consumers only
 // and is subject to change without notice. Knock yourself out.
 fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/mir.rs:3:11: 3:11
-    let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:4:9: 4:10
-    let mut _2: std::string::String;     // in scope 0 at $DIR/mir.rs:4:18: 4:31
-    let mut _4: &std::string::String;    // in scope 0 at $DIR/mir.rs:7:14: 7:17
-    let mut _5: &str;                    // in scope 0 at $DIR/mir.rs:7:14: 7:17
-    let mut _6: bool;                    // in scope 0 at $DIR/mir.rs:7:14: 7:17
-    let mut _7: isize;                   // in scope 0 at $DIR/mir.rs:7:9: 7:18
-    let mut _9: bool;                    // in scope 0 at $DIR/mir.rs:10:1: 10:2
+    let mut _0: ();                      // return place in scope 0 at $DIR/mir.rs:5:11: 5:11
+    let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:6:9: 6:10
+    let mut _2: std::string::String;     // in scope 0 at $DIR/mir.rs:6:18: 6:31
+    let mut _4: &std::string::String;    // in scope 0 at $DIR/mir.rs:9:14: 9:17
+    let mut _5: &str;                    // in scope 0 at $DIR/mir.rs:9:14: 9:17
+    let mut _6: bool;                    // in scope 0 at $DIR/mir.rs:9:14: 9:17
+    let mut _7: isize;                   // in scope 0 at $DIR/mir.rs:9:9: 9:18
+    let mut _9: bool;                    // in scope 0 at $DIR/mir.rs:12:1: 12:2
     scope 1 {
-        debug s => _1;                   // in scope 1 at $DIR/mir.rs:4:9: 4:10
-        let _3: i32;                     // in scope 1 at $DIR/mir.rs:5:9: 5:10
+        debug s => _1;                   // in scope 1 at $DIR/mir.rs:6:9: 6:10
+        let _3: i32;                     // in scope 1 at $DIR/mir.rs:7:9: 7:10
         scope 2 {
-            debug a => _3;               // in scope 2 at $DIR/mir.rs:5:9: 5:10
-            let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:8:9: 8:10
+            debug a => _3;               // in scope 2 at $DIR/mir.rs:7:9: 7:10
+            let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:10:9: 10:10
             scope 3 {
-                debug s => _8;           // in scope 3 at $DIR/mir.rs:8:9: 8:10
+                debug s => _8;           // in scope 3 at $DIR/mir.rs:10:9: 10:10
             }
         }
     }
 
     bb0: {
-        _9 = const false;                // scope 0 at $DIR/mir.rs:4:9: 4:10
-        _2 = String::new() -> bb1;       // scope 0 at $DIR/mir.rs:4:18: 4:31
+        _9 = const false;                // scope 0 at $DIR/mir.rs:6:9: 6:10
+        _2 = String::new() -> bb1;       // scope 0 at $DIR/mir.rs:6:18: 6:31
                                          // mir::Constant
-                                         // + span: $DIR/mir.rs:4:18: 4:29
+                                         // + span: $DIR/mir.rs:6:18: 6:29
                                          // + literal: Const { ty: fn() -> String {String::new}, val: Value(Scalar(<ZST>)) }
     }
 
     bb1: {
-        _9 = const true;                 // scope 0 at $DIR/mir.rs:4:13: 4:32
-        Deinit(_1);                      // scope 0 at $DIR/mir.rs:4:13: 4:32
-        ((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:4:13: 4:32
-        discriminant(_1) = 1;            // scope 0 at $DIR/mir.rs:4:13: 4:32
-        _7 = discriminant(_1);           // scope 2 at $DIR/mir.rs:6:11: 6:12
-        switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:6:5: 6:12
+        _9 = const true;                 // scope 0 at $DIR/mir.rs:6:13: 6:32
+        Deinit(_1);                      // scope 0 at $DIR/mir.rs:6:13: 6:32
+        ((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:6:13: 6:32
+        discriminant(_1) = 1;            // scope 0 at $DIR/mir.rs:6:13: 6:32
+        _7 = discriminant(_1);           // scope 2 at $DIR/mir.rs:8:11: 8:12
+        switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:8:5: 8:12
     }
 
     bb2: {
-        _9 = const false;                // scope 2 at $DIR/mir.rs:8:9: 8:10
-        _8 = move _1;                    // scope 2 at $DIR/mir.rs:8:9: 8:10
-        _3 = const 4321_i32;             // scope 3 at $DIR/mir.rs:8:14: 8:22
-        drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:8:21: 8:22
+        _9 = const false;                // scope 2 at $DIR/mir.rs:10:9: 10:10
+        _8 = move _1;                    // scope 2 at $DIR/mir.rs:10:9: 10:10
+        _3 = const 4321_i32;             // scope 3 at $DIR/mir.rs:10:14: 10:22
+        drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:10:21: 10:22
     }
 
     bb3: {
-        _4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:7:14: 7:17
-        _5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:7:14: 7:17
+        _4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:9:14: 9:17
+        _5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:9:14: 9:17
                                          // mir::Constant
-                                         // + span: $DIR/mir.rs:7:14: 7:17
+                                         // + span: $DIR/mir.rs:9:14: 9:17
                                          // + literal: Const { ty: for<'r> fn(&'r String) -> &'r <String as Deref>::Target {<String as Deref>::deref}, val: Value(Scalar(<ZST>)) }
     }
 
     bb4: {
-        _6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:7:14: 7:17
+        _6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:9:14: 9:17
                                          // mir::Constant
-                                         // + span: $DIR/mir.rs:7:14: 7:17
+                                         // + span: $DIR/mir.rs:9:14: 9:17
                                          // + literal: Const { ty: for<'r, 's> fn(&'r str, &'s str) -> bool {<str as PartialEq>::eq}, val: Value(Scalar(<ZST>)) }
                                          // mir::Constant
-                                         // + span: $DIR/mir.rs:7:14: 7:17
+                                         // + span: $DIR/mir.rs:9:14: 9:17
                                          // + literal: Const { ty: &str, val: Value(Slice(..)) }
     }
 
     bb5: {
-        switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:7:14: 7:17
+        switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:9:14: 9:17
     }
 
     bb6: {
-        _3 = const 1234_i32;             // scope 2 at $DIR/mir.rs:7:22: 7:30
-        goto -> bb7;                     // scope 2 at $DIR/mir.rs:7:22: 7:30
+        _3 = const 1234_i32;             // scope 2 at $DIR/mir.rs:9:22: 9:30
+        goto -> bb7;                     // scope 2 at $DIR/mir.rs:9:22: 9:30
     }
 
     bb7: {
-        switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:10:1: 10:2
+        switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:12:1: 12:2
     }
 
     bb8: {
-        _9 = const false;                // scope 0 at $DIR/mir.rs:10:1: 10:2
-        return;                          // scope 0 at $DIR/mir.rs:10:2: 10:2
+        _9 = const false;                // scope 0 at $DIR/mir.rs:12:1: 12:2
+        return;                          // scope 0 at $DIR/mir.rs:12:2: 12:2
     }
 
     bb9 (cleanup): {
-        resume;                          // scope 0 at $DIR/mir.rs:3:1: 10:2
+        resume;                          // scope 0 at $DIR/mir.rs:5:1: 12:2
     }
 
     bb10: {
-        drop(_1) -> bb8;                 // scope 0 at $DIR/mir.rs:10:1: 10:2
+        drop(_1) -> bb8;                 // scope 0 at $DIR/mir.rs:12:1: 12:2
     }
 
     bb11 (cleanup): {
-        drop(_1) -> bb9;                 // scope 0 at $DIR/mir.rs:10:1: 10:2
+        drop(_1) -> bb9;                 // scope 0 at $DIR/mir.rs:12:1: 12:2
     }
 
     bb12 (cleanup): {
-        switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:10:1: 10:2
+        switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:12:1: 12:2
     }
 }