about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-11-30 00:44:33 +0000
committervarkor <github@varkor.com>2018-11-30 10:41:09 +0000
commite018268ffad0e3d2704705cb3337b6195b5cba08 (patch)
tree4c373238dc5fb7504e1d4cef30a91099a473233a
parentf1f6d87eab20f62a4fbb16b327f16fa69dbbaf99 (diff)
downloadrust-e018268ffad0e3d2704705cb3337b6195b5cba08.tar.gz
rust-e018268ffad0e3d2704705cb3337b6195b5cba08.zip
Add precise_pointer_size_matching feature
-rw-r--r--src/librustc/ty/sty.rs7
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs5
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/test/ui/exhaustive_integer_patterns.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs14
-rw-r--r--src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr15
6 files changed, 42 insertions, 2 deletions
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index a18e3a27546..fbc98696574 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1780,6 +1780,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
         }
     }
 
+    pub fn is_pointer_sized(&self) -> bool {
+        match self.sty {
+            Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
+            _ => false,
+        }
+    }
+
     pub fn is_machine(&self) -> bool {
         match self.sty {
             Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 82e368198f2..a2fbfd70a65 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -1129,7 +1129,8 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
 
         // For privately empty and non-exhaustive enums, we work as if there were an "extra"
         // `_` constructor for the type, so we can never match over all constructors.
-        let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive;
+        let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive ||
+            (pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching);
 
         if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive {
             split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
@@ -1436,7 +1437,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Construct
         _ => return false,
     };
     if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
-        true
+        !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching
     } else {
         false
     }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 53faf04f278..15679322663 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -439,6 +439,8 @@ declare_features! (
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
 
+    // Exhaustive pattern matching on `usize` and `isize`.
+    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
     // #[doc(keyword = "...")]
     (active, doc_keyword, "1.28.0", Some(51315), None),
diff --git a/src/test/ui/exhaustive_integer_patterns.rs b/src/test/ui/exhaustive_integer_patterns.rs
index cddb301dbdf..ad955fbe05d 100644
--- a/src/test/ui/exhaustive_integer_patterns.rs
+++ b/src/test/ui/exhaustive_integer_patterns.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(precise_pointer_size_matching)]
 #![feature(exclusive_range_pattern)]
 
 #![deny(unreachable_patterns)]
diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
new file mode 100644
index 00000000000..1208552d256
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs
@@ -0,0 +1,14 @@
+#![feature(exclusive_range_pattern)]
+
+use std::usize::MAX;
+
+fn main() {
+    match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
+        0..=MAX => {}
+    }
+
+    match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
+        1..=20 => {}
+        -5..3 => {}
+    }
+}
diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
new file mode 100644
index 00000000000..5806f6f0391
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr
@@ -0,0 +1,15 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/feature-gate-precise_pointer_size_matching.rs:6:11
+   |
+LL |     match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
+   |           ^^^^^^ pattern `_` not covered
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
+   |
+LL |     match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
+   |           ^^^^^^ pattern `_` not covered
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.