about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-12-06 07:48:52 +0100
committerGitHub <noreply@github.com>2018-12-06 07:48:52 +0100
commite57ed0ddab4403a62d129f52af696420b94439d8 (patch)
tree77ef84418588272c7dd3b0e7cf98ddb7ce39a243
parenta88feabac40537bd03aaec5d409ed43c6572b006 (diff)
parented64b1927b4e929e905f778870a9f53d75216b34 (diff)
downloadrust-e57ed0ddab4403a62d129f52af696420b94439d8.tar.gz
rust-e57ed0ddab4403a62d129f52af696420b94439d8.zip
Rollup merge of #56362 - varkor:stabilise-exhaustive-integer-patterns, r=nikomatsakis
Stabilise exhaustive integer patterns

This is dependent on the FCP for https://github.com/rust-lang/rfcs/pull/2591 being completed, but that should happen tomorrow, so there's little harm in opening this PR early.

Closes #50907.
-rw-r--r--src/librustc/ty/sty.rs7
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs56
-rw-r--r--src/libsyntax/feature_gate.rs6
-rw-r--r--src/test/ui/consts/const-match-check.eval1.stderr4
-rw-r--r--src/test/ui/consts/const-match-check.eval2.stderr4
-rw-r--r--src/test/ui/consts/const-match-check.matchck.stderr16
-rw-r--r--src/test/ui/consts/const-pattern-irrefutable.rs6
-rw-r--r--src/test/ui/consts/const-pattern-irrefutable.stderr12
-rw-r--r--src/test/ui/exhaustive_integer_patterns.rs13
-rw-r--r--src/test/ui/exhaustive_integer_patterns.stderr28
-rw-r--r--src/test/ui/feature-gate-exhaustive_integer_patterns.rs16
-rw-r--r--src/test/ui/feature-gate-exhaustive_integer_patterns.stderr9
-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
-rw-r--r--src/test/ui/for/for-loop-refutable-pattern-error-message.stderr4
-rw-r--r--src/test/ui/match/match-non-exhaustive.stderr4
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs13
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr9
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-match.rs3
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-match.stderr14
-rw-r--r--src/test/ui/precise_pointer_size_matching.rs33
-rw-r--r--src/test/ui/precise_pointer_size_matching.stderr15
-rw-r--r--src/test/ui/refutable-pattern-errors.rs2
-rw-r--r--src/test/ui/refutable-pattern-errors.stderr4
24 files changed, 194 insertions, 113 deletions
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 1416cb17fea..4f5ed8889f3 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1787,6 +1787,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 0570cd278f3..5db7b6ceb5d 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -584,7 +584,6 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                                   -> Vec<Constructor<'tcx>>
 {
     debug!("all_constructors({:?})", pcx.ty);
-    let exhaustive_integer_patterns = cx.tcx.features().exhaustive_integer_patterns;
     let ctors = match pcx.ty.sty {
         ty::Bool => {
             [true, false].iter().map(|&b| {
@@ -614,7 +613,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 .map(|v| Variant(v.did))
                 .collect()
         }
-        ty::Char if exhaustive_integer_patterns => {
+        ty::Char => {
             vec![
                 // The valid Unicode Scalar Value ranges.
                 ConstantRange('\u{0000}' as u128,
@@ -629,14 +628,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 ),
             ]
         }
-        ty::Int(ity) if exhaustive_integer_patterns => {
+        ty::Int(ity) => {
             // FIXME(49937): refactor these bit manipulations into interpret.
             let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
             let min = 1u128 << (bits - 1);
             let max = (1u128 << (bits - 1)) - 1;
             vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
         }
-        ty::Uint(uty) if exhaustive_integer_patterns => {
+        ty::Uint(uty) => {
             // FIXME(49937): refactor these bit manipulations into interpret.
             let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
             let max = !0u128 >> (128 - bits);
@@ -775,8 +774,17 @@ impl<'tcx> IntRange<'tcx> {
     fn from_ctor(tcx: TyCtxt<'_, 'tcx, 'tcx>,
                  ctor: &Constructor<'tcx>)
                  -> Option<IntRange<'tcx>> {
+        // Floating-point ranges are permitted and we don't want
+        // to consider them when constructing integer ranges.
+        fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool {
+            match ty.sty {
+                ty::Char | ty::Int(_) | ty::Uint(_) => true,
+                _ => false,
+            }
+        }
+
         match ctor {
-            ConstantRange(lo, hi, ty, end) => {
+            ConstantRange(lo, hi, ty, end) if is_integral(ty) => {
                 // Perform a shift if the underlying types are signed,
                 // which makes the interval arithmetic simpler.
                 let bias = IntRange::signed_bias(tcx, ty);
@@ -789,7 +797,7 @@ impl<'tcx> IntRange<'tcx> {
                     Some(IntRange { range: lo..=(hi - offset), ty })
                 }
             }
-            ConstantValue(val) => {
+            ConstantValue(val) if is_integral(val.ty) => {
                 let ty = val.ty;
                 if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
                     let bias = IntRange::signed_bias(tcx, ty);
@@ -799,9 +807,7 @@ impl<'tcx> IntRange<'tcx> {
                     None
                 }
             }
-            Single | Variant(_) | Slice(_) => {
-                None
-            }
+            _ => None,
         }
     }
 
@@ -933,12 +939,10 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
                 // If a constructor appears in a `match` arm, we can
                 // eliminate it straight away.
                 refined_ctors = vec![]
-            } else if tcx.features().exhaustive_integer_patterns {
-                if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
-                    // Refine the required constructors for the type by subtracting
-                    // the range defined by the current constructor pattern.
-                    refined_ctors = interval.subtract_from(tcx, refined_ctors);
-                }
+            } else if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
+                // Refine the required constructors for the type by subtracting
+                // the range defined by the current constructor pattern.
+                refined_ctors = interval.subtract_from(tcx, refined_ctors);
             }
 
             // If the constructor patterns that have been considered so far
@@ -1094,7 +1098,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| {
@@ -1390,17 +1395,16 @@ fn slice_pat_covered_by_constructor<'tcx>(
 // Whether to evaluate a constructor using exhaustive integer matching. This is true if the
 // constructor is a range or constant with an integer type.
 fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Constructor<'tcx>) -> bool {
-    if tcx.features().exhaustive_integer_patterns {
-        let ty = match ctor {
-            ConstantValue(value) => value.ty,
-            ConstantRange(_, _, ty, _) => ty,
-            _ => return false,
-        };
-        if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
-            return true;
-        }
+    let ty = match ctor {
+        ConstantValue(value) => value.ty,
+        ConstantRange(_, _, ty, _) => ty,
+        _ => return false,
+    };
+    if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
+        !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching
+    } else {
+        false
     }
-    false
 }
 
 /// For exhaustive integer matching, some constructors are grouped within other constructors
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index fac7ff2bf34..2c5d58ea8cb 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -439,8 +439,8 @@ declare_features! (
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
 
-    // Integer match exhaustiveness checking
-    (active, exhaustive_integer_patterns, "1.30.0", Some(50907), 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),
@@ -683,6 +683,8 @@ declare_features! (
     (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
     // Allows use of the :literal macro fragment specifier (RFC 1576)
     (accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
+    // Integer match exhaustiveness checking (RFC 2591)
+    (accepted, exhaustive_integer_patterns, "1.32.0", Some(50907), None),
     // Use `?` as the Kleene "at most one" operator
     (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
     // `Self` struct constructor (RFC 2302)
diff --git a/src/test/ui/consts/const-match-check.eval1.stderr b/src/test/ui/consts/const-match-check.eval1.stderr
index 3caf1491aba..703453e6bdd 100644
--- a/src/test/ui/consts/const-match-check.eval1.stderr
+++ b/src/test/ui/consts/const-match-check.eval1.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:35:15
    |
 LL |     A = { let 0 = 0; 0 },
-   |               ^ pattern `_` not covered
+   |               ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.eval2.stderr b/src/test/ui/consts/const-match-check.eval2.stderr
index de85d4d73db..6caff93e642 100644
--- a/src/test/ui/consts/const-match-check.eval2.stderr
+++ b/src/test/ui/consts/const-match-check.eval2.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:41:24
    |
 LL |     let x: [i32; { let 0 = 0; 0 }] = [];
-   |                        ^ pattern `_` not covered
+   |                        ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.matchck.stderr b/src/test/ui/consts/const-match-check.matchck.stderr
index bbf1169c577..9e45045d27e 100644
--- a/src/test/ui/consts/const-match-check.matchck.stderr
+++ b/src/test/ui/consts/const-match-check.matchck.stderr
@@ -1,26 +1,26 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:14:22
    |
 LL | const X: i32 = { let 0 = 0; 0 };
-   |                      ^ pattern `_` not covered
+   |                      ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:18:23
    |
 LL | static Y: i32 = { let 0 = 0; 0 };
-   |                       ^ pattern `_` not covered
+   |                       ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:23:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `_` not covered
+   |                          ^ pattern `-2147483648i32..=-1i32` not covered
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
   --> $DIR/const-match-check.rs:29:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `_` not covered
+   |                          ^ pattern `-2147483648i32..=-1i32` not covered
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/consts/const-pattern-irrefutable.rs b/src/test/ui/consts/const-pattern-irrefutable.rs
index af0b95e002d..278864d6de9 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.rs
+++ b/src/test/ui/consts/const-pattern-irrefutable.rs
@@ -19,8 +19,8 @@ use foo::d;
 const a: u8 = 2;
 
 fn main() {
-    let a = 4; //~ ERROR refutable pattern in local binding: `_` not covered
-    let c = 4; //~ ERROR refutable pattern in local binding: `_` not covered
-    let d = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+    let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
+    let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
+    let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
     fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
 }
diff --git a/src/test/ui/consts/const-pattern-irrefutable.stderr b/src/test/ui/consts/const-pattern-irrefutable.stderr
index 6d5738f3328..d9ad16cd0e8 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.stderr
+++ b/src/test/ui/consts/const-pattern-irrefutable.stderr
@@ -1,19 +1,19 @@
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:22:9
    |
-LL |     let a = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:23:9
    |
-LL |     let c = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `_` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
   --> $DIR/const-pattern-irrefutable.rs:24:9
    |
-LL |     let d = 4; //~ ERROR refutable pattern in local binding: `_` not covered
+LL |     let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
    |         ^ interpreted as a constant pattern, not new variable
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/exhaustive_integer_patterns.rs b/src/test/ui/exhaustive_integer_patterns.rs
index 7825aaa2912..020382d9fe1 100644
--- a/src/test/ui/exhaustive_integer_patterns.rs
+++ b/src/test/ui/exhaustive_integer_patterns.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(exhaustive_integer_patterns)]
+#![feature(precise_pointer_size_matching)]
 #![feature(exclusive_range_pattern)]
+
 #![deny(unreachable_patterns)]
 
-use std::{char, usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128};
+use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};
 
 fn main() {
     let x: u8 = 0;
@@ -68,10 +69,6 @@ fn main() {
         '\u{E000}' ..= '\u{10_FFFF}' => {}
     }
 
-    match 0usize {
-        0 ..= usize::MAX => {} // ok
-    }
-
     match 0u16 {
         0 ..= u16::MAX => {} // ok
     }
@@ -88,10 +85,6 @@ fn main() {
         0 ..= u128::MAX => {} // ok
     }
 
-    match 0isize {
-        isize::MIN ..= isize::MAX => {} // ok
-    }
-
     match 0i8 {
         -128 ..= 127 => {} // ok
     }
diff --git a/src/test/ui/exhaustive_integer_patterns.stderr b/src/test/ui/exhaustive_integer_patterns.stderr
index 44b05a12aeb..011e93683fb 100644
--- a/src/test/ui/exhaustive_integer_patterns.stderr
+++ b/src/test/ui/exhaustive_integer_patterns.stderr
@@ -1,83 +1,83 @@
 error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:32:9
+  --> $DIR/exhaustive_integer_patterns.rs:33:9
    |
 LL |         200 => {} //~ ERROR unreachable pattern
    |         ^^^
    |
 note: lint level defined here
-  --> $DIR/exhaustive_integer_patterns.rs:13:9
+  --> $DIR/exhaustive_integer_patterns.rs:14:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:37:11
+  --> $DIR/exhaustive_integer_patterns.rs:38:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ pattern `128u8..=255u8` not covered
 
 error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:42:11
+  --> $DIR/exhaustive_integer_patterns.rs:43:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
 
 error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:53:9
+  --> $DIR/exhaustive_integer_patterns.rs:54:9
    |
 LL |         -2..=20 => {} //~ ERROR unreachable pattern
    |         ^^^^^^^
 
 error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:50:11
+  --> $DIR/exhaustive_integer_patterns.rs:51:11
    |
 LL |     match x { //~ ERROR non-exhaustive patterns
    |           ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
 
 error[E0004]: non-exhaustive patterns: `-128i8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:99:11
+  --> $DIR/exhaustive_integer_patterns.rs:92:11
    |
 LL |     match 0i8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `-128i8` not covered
 
 error[E0004]: non-exhaustive patterns: `0i16` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:107:11
+  --> $DIR/exhaustive_integer_patterns.rs:100:11
    |
 LL |     match 0i16 { //~ ERROR non-exhaustive patterns
    |           ^^^^ pattern `0i16` not covered
 
 error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:125:11
+  --> $DIR/exhaustive_integer_patterns.rs:118:11
    |
 LL |     match 0u8 { //~ ERROR non-exhaustive patterns
    |           ^^^ pattern `128u8..=255u8` not covered
 
 error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:137:11
+  --> $DIR/exhaustive_integer_patterns.rs:130:11
    |
 LL |     match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
 
 error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:142:11
+  --> $DIR/exhaustive_integer_patterns.rs:135:11
    |
 LL |     match (0u8, true) { //~ ERROR non-exhaustive patterns
    |           ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered
 
 error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:162:11
+  --> $DIR/exhaustive_integer_patterns.rs:155:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered
 
 error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:166:11
+  --> $DIR/exhaustive_integer_patterns.rs:159:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered
 
 error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:170:11
+  --> $DIR/exhaustive_integer_patterns.rs:163:11
    |
 LL |     match 0u128 { //~ ERROR non-exhaustive patterns
    |           ^^^^^ pattern `0u128..=3u128` not covered
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs b/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
deleted file mode 100644
index 3aa15229455..00000000000
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let x: u8 = 0;
-    match x { //~ ERROR non-exhaustive patterns: `_` not covered
-        0 ..= 255 => {}
-    }
-}
diff --git a/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr b/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr
deleted file mode 100644
index 63d98f6b5eb..00000000000
--- a/src/test/ui/feature-gate-exhaustive_integer_patterns.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/feature-gate-exhaustive_integer_patterns.rs:13:11
-   |
-LL |     match x { //~ ERROR non-exhaustive patterns: `_` not covered
-   |           ^ pattern `_` not covered
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
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`.
diff --git a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
index b76c2ffc240..9b19fc80e2b 100644
--- a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
+++ b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in `for` loop binding: `&_` not covered
+error[E0005]: refutable pattern in `for` loop binding: `&-2147483648i32..=0i32` not covered
   --> $DIR/for-loop-refutable-pattern-error-message.rs:12:9
    |
 LL |     for &1 in [1].iter() {} //~ ERROR refutable pattern in `for` loop binding
-   |         ^^ pattern `&_` not covered
+   |         ^^ pattern `&-2147483648i32..=0i32` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/match/match-non-exhaustive.stderr b/src/test/ui/match/match-non-exhaustive.stderr
index 04f09caceed..ad895b448dd 100644
--- a/src/test/ui/match/match-non-exhaustive.stderr
+++ b/src/test/ui/match/match-non-exhaustive.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `_` not covered
+error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
   --> $DIR/match-non-exhaustive.rs:12:11
    |
 LL |     match 0 { 1 => () } //~ ERROR non-exhaustive patterns
-   |           ^ pattern `_` not covered
+   |           ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/match-non-exhaustive.rs:13:11
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs
new file mode 100644
index 00000000000..588fecbf10d
--- /dev/null
+++ b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.rs
@@ -0,0 +1,13 @@
+#![allow(illegal_floating_point_literal_pattern)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+    match 0.0 {
+      0.0..=1.0 => {}
+      _ => {} // ok
+    }
+
+    match 0.0 { //~ ERROR non-exhaustive patterns
+      0.0..=1.0 => {}
+    }
+}
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr
new file mode 100644
index 00000000000..2e285afb380
--- /dev/null
+++ b/src/test/ui/non-exhaustive/non-exhaustive-float-range-match.stderr
@@ -0,0 +1,9 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/non-exhaustive-float-range-match.rs:10:11
+   |
+LL |     match 0.0 { //~ ERROR non-exhaustive patterns
+   |           ^^^ pattern `_` not covered
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
index 13b62429f46..99a0c5d6626 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-match.rs
+++ b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
@@ -22,7 +22,8 @@ fn main() {
     match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
       None => {}
     }
-    match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, _)` not covered
+    match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
+                      //  and `(_, _, 5i32..=2147483647i32)` not covered
       (_, _, 4) => {}
     }
     match (t::a, t::a) { //~ ERROR non-exhaustive patterns: `(a, a)` not covered
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
index f48a0bc15eb..d3703a44454 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
+++ b/src/test/ui/non-exhaustive/non-exhaustive-match.stderr
@@ -16,32 +16,32 @@ error[E0004]: non-exhaustive patterns: `Some(_)` not covered
 LL |     match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
    |           ^^^^^^^^ pattern `Some(_)` not covered
 
-error[E0004]: non-exhaustive patterns: `(_, _, _)` not covered
+error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
   --> $DIR/non-exhaustive-match.rs:25:11
    |
-LL |     match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, _)` not covered
-   |           ^^^^^^^^^ pattern `(_, _, _)` not covered
+LL |     match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
+   |           ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
 
 error[E0004]: non-exhaustive patterns: `(a, a)` not covered
-  --> $DIR/non-exhaustive-match.rs:28:11
+  --> $DIR/non-exhaustive-match.rs:29:11
    |
 LL |     match (t::a, t::a) { //~ ERROR non-exhaustive patterns: `(a, a)` not covered
    |           ^^^^^^^^^^^^ pattern `(a, a)` not covered
 
 error[E0004]: non-exhaustive patterns: `b` not covered
-  --> $DIR/non-exhaustive-match.rs:32:11
+  --> $DIR/non-exhaustive-match.rs:33:11
    |
 LL |     match t::a { //~ ERROR non-exhaustive patterns: `b` not covered
    |           ^^^^ pattern `b` not covered
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/non-exhaustive-match.rs:43:11
+  --> $DIR/non-exhaustive-match.rs:44:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered
    |           ^^^^ pattern `[]` not covered
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered
-  --> $DIR/non-exhaustive-match.rs:56:11
+  --> $DIR/non-exhaustive-match.rs:57:11
    |
 LL |     match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
    |           ^^^^ pattern `[_, _, _, _]` not covered
diff --git a/src/test/ui/precise_pointer_size_matching.rs b/src/test/ui/precise_pointer_size_matching.rs
new file mode 100644
index 00000000000..759b63b188b
--- /dev/null
+++ b/src/test/ui/precise_pointer_size_matching.rs
@@ -0,0 +1,33 @@
+// normalize-stderr-32bit: "-2147483648isize" -> "$$ISIZE_MIN"
+// normalize-stderr-64bit: "-9223372036854775808isize" -> "$$ISIZE_MIN"
+// normalize-stderr-32bit: "2147483647isize" -> "$$ISIZE_MAX"
+// normalize-stderr-64bit: "9223372036854775807isize" -> "$$ISIZE_MAX"
+// normalize-stderr-32bit: "4294967295usize" -> "$$USIZE_MAX"
+// normalize-stderr-64bit: "18446744073709551615usize" -> "$$USIZE_MAX"
+
+#![feature(precise_pointer_size_matching)]
+#![feature(exclusive_range_pattern)]
+
+#![deny(unreachable_patterns)]
+
+use std::{usize, isize};
+
+fn main() {
+    match 0isize {
+        isize::MIN ..= isize::MAX => {} // ok
+    }
+
+    match 0usize {
+        0 ..= usize::MAX => {} // ok
+    }
+
+    match 0isize { //~ ERROR non-exhaustive patterns
+        1 ..= 8 => {}
+        -5 ..= 20 => {}
+    }
+
+    match 0usize { //~ ERROR non-exhaustive patterns
+        1 ..= 8 => {}
+        5 ..= 20 => {}
+    }
+}
diff --git a/src/test/ui/precise_pointer_size_matching.stderr b/src/test/ui/precise_pointer_size_matching.stderr
new file mode 100644
index 00000000000..4acbec6c7ff
--- /dev/null
+++ b/src/test/ui/precise_pointer_size_matching.stderr
@@ -0,0 +1,15 @@
+error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
+  --> $DIR/precise_pointer_size_matching.rs:24:11
+   |
+LL |     match 0isize { //~ ERROR non-exhaustive patterns
+   |           ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
+
+error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered
+  --> $DIR/precise_pointer_size_matching.rs:29:11
+   |
+LL |     match 0usize { //~ ERROR non-exhaustive patterns
+   |           ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/refutable-pattern-errors.rs b/src/test/ui/refutable-pattern-errors.rs
index 7b4009481ab..a140e421a57 100644
--- a/src/test/ui/refutable-pattern-errors.rs
+++ b/src/test/ui/refutable-pattern-errors.rs
@@ -14,5 +14,5 @@ fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
 
 fn main() {
     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-    //~^ ERROR refutable pattern in local binding: `(_, _)` not covered
+    //~^ ERROR refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
 }
diff --git a/src/test/ui/refutable-pattern-errors.stderr b/src/test/ui/refutable-pattern-errors.stderr
index c2d5fe001fc..42aa5727895 100644
--- a/src/test/ui/refutable-pattern-errors.stderr
+++ b/src/test/ui/refutable-pattern-errors.stderr
@@ -4,11 +4,11 @@ error[E0005]: refutable pattern in function argument: `(_, _)` not covered
 LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
    |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
 
-error[E0005]: refutable pattern in local binding: `(_, _)` not covered
+error[E0005]: refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
   --> $DIR/refutable-pattern-errors.rs:16:9
    |
 LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-   |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(-2147483648i32..=0i32, _)` not covered
 
 error: aborting due to 2 previous errors