about summary refs log tree commit diff
path: root/src/test/ui/pattern/usefulness/integer-ranges
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2020-11-20 19:03:56 +0000
committerNadrieril <nadrieril+git@gmail.com>2020-11-21 01:38:42 +0000
commit3213efcd9ab32cbe4e69c4322e6a992a9e64f0ff (patch)
tree19c5ec010eb470784cfab27165a8ef17cd548f8c /src/test/ui/pattern/usefulness/integer-ranges
parent82bf5b61cd8e03e463f7877d7b3a801c8ba60f13 (diff)
downloadrust-3213efcd9ab32cbe4e69c4322e6a992a9e64f0ff.tar.gz
rust-3213efcd9ab32cbe4e69c4322e6a992a9e64f0ff.zip
Improve integer range tests
Diffstat (limited to 'src/test/ui/pattern/usefulness/integer-ranges')
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs101
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr111
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs53
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr80
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs38
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs48
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr129
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs18
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr25
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.rs112
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr146
12 files changed, 873 insertions, 0 deletions
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs
new file mode 100644
index 00000000000..5a44dfc28bb
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs
@@ -0,0 +1,101 @@
+#![feature(exclusive_range_pattern)]
+#![feature(assoc_char_consts)]
+#![deny(unreachable_patterns)]
+
+macro_rules! m {
+    ($s:expr, $($t:tt)+) => {
+        match $s { $($t)+ => {} }
+    }
+}
+
+macro_rules! test_int {
+    ($s:expr, $min:path, $max:path) => {
+        m!($s, $min..=$max);
+        m!($s, $min..5 | 5..=$max);
+        m!($s, $min..=4 | 5..=$max);
+        m!($s, $min..$max | $max);
+        m!(($s, true), ($min..5, true) | (5..=$max, true) | ($min..=$max, false));
+    }
+}
+
+fn main() {
+    test_int!(0u8, u8::MIN, u8::MAX);
+    test_int!(0u16, u16::MIN, u16::MAX);
+    test_int!(0u32, u32::MIN, u32::MAX);
+    test_int!(0u64, u64::MIN, u64::MAX);
+    test_int!(0u128, u128::MIN, u128::MAX);
+
+    test_int!(0i8, i8::MIN, i8::MAX);
+    test_int!(0i16, i16::MIN, i16::MAX);
+    test_int!(0i32, i32::MIN, i32::MAX);
+    test_int!(0i64, i64::MIN, i64::MAX);
+    test_int!(0i128, i128::MIN, i128::MAX);
+
+    m!('a', '\u{0}'..=char::MAX);
+    m!('a', '\u{0}'..='\u{10_FFFF}');
+    // We can get away with just covering the following two ranges, which correspond to all valid
+    // Unicode Scalar Values.
+    m!('a', '\u{0}'..='\u{D7FF}' | '\u{E000}'..=char::MAX);
+    m!('a', '\u{0}'..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..=char::MAX);
+
+    let 0..=255 = 0u8;
+    let -128..=127 = 0i8;
+    let -2147483648..=2147483647 = 0i32;
+    let '\u{0000}'..='\u{10FFFF}' = 'v';
+
+    // Almost exhaustive
+    m!(0u8, 0..255); //~ ERROR non-exhaustive patterns
+    m!(0u8, 0..=254); //~ ERROR non-exhaustive patterns
+    m!(0u8, 1..=255); //~ ERROR non-exhaustive patterns
+    m!(0u8, 0..42 | 43..=255); //~ ERROR non-exhaustive patterns
+    m!(0i8, -128..127); //~ ERROR non-exhaustive patterns
+    m!(0i8, -128..=126); //~ ERROR non-exhaustive patterns
+    m!(0i8, -127..=127); //~ ERROR non-exhaustive patterns
+    match 0i8 { //~ ERROR non-exhaustive patterns
+        i8::MIN ..= -1 => {}
+        1 ..= i8::MAX => {}
+    }
+    const ALMOST_MAX: u128 = u128::MAX - 1;
+    m!(0u128, 0..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+    m!(0u128, 0..=4); //~ ERROR non-exhaustive patterns
+    m!(0u128, 1..=u128::MAX); //~ ERROR non-exhaustive patterns
+
+    // More complicatedly (non-)exhaustive
+    match 0u8 {
+        0 ..= 30 => {}
+        20 ..= 70 => {}
+        50 ..= 255 => {}
+    }
+    match (0u8, true) { //~ ERROR non-exhaustive patterns
+        (0 ..= 125, false) => {}
+        (128 ..= 255, false) => {}
+        (0 ..= 255, true) => {}
+    }
+    match (0u8, true) { // ok
+        (0 ..= 125, false) => {}
+        (128 ..= 255, false) => {}
+        (0 ..= 255, true) => {}
+        (125 .. 128, false) => {}
+    }
+    match (true, 0u8) {
+        (true, 0 ..= 255) => {}
+        (false, 0 ..= 125) => {}
+        (false, 128 ..= 255) => {}
+        (false, 125 .. 128) => {}
+    }
+    match Some(0u8) {
+        None => {}
+        Some(0 ..= 125) => {}
+        Some(128 ..= 255) => {}
+        Some(125 .. 128) => {}
+    }
+    const FOO: u8 = 41;
+    const BAR: &u8 = &42;
+    match &0u8 {
+        0..41 => {}
+        &FOO => {}
+        BAR => {}
+        43..=255 => {}
+    }
+
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
new file mode 100644
index 00000000000..2e0023348e4
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
@@ -0,0 +1,111 @@
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+  --> $DIR/exhaustiveness.rs:47:8
+   |
+LL |     m!(0u8, 0..255);
+   |        ^^^ pattern `u8::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+  --> $DIR/exhaustiveness.rs:48:8
+   |
+LL |     m!(0u8, 0..=254);
+   |        ^^^ pattern `u8::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `0_u8` not covered
+  --> $DIR/exhaustiveness.rs:49:8
+   |
+LL |     m!(0u8, 1..=255);
+   |        ^^^ pattern `0_u8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `42_u8` not covered
+  --> $DIR/exhaustiveness.rs:50:8
+   |
+LL |     m!(0u8, 0..42 | 43..=255);
+   |        ^^^ pattern `42_u8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u8`
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+  --> $DIR/exhaustiveness.rs:51:8
+   |
+LL |     m!(0i8, -128..127);
+   |        ^^^ pattern `i8::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+  --> $DIR/exhaustiveness.rs:52:8
+   |
+LL |     m!(0i8, -128..=126);
+   |        ^^^ pattern `i8::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
+  --> $DIR/exhaustiveness.rs:53:8
+   |
+LL |     m!(0i8, -127..=127);
+   |        ^^^ pattern `i8::MIN` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `0_i8` not covered
+  --> $DIR/exhaustiveness.rs:54:11
+   |
+LL |     match 0i8 {
+   |           ^^^ pattern `0_i8` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `i8`
+
+error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
+  --> $DIR/exhaustiveness.rs:59:8
+   |
+LL |     m!(0u128, 0..=ALMOST_MAX);
+   |        ^^^^^ pattern `u128::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
+  --> $DIR/exhaustiveness.rs:60:8
+   |
+LL |     m!(0u128, 0..=4);
+   |        ^^^^^ pattern `5_u128..=u128::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `0_u128` not covered
+  --> $DIR/exhaustiveness.rs:61:8
+   |
+LL |     m!(0u128, 1..=u128::MAX);
+   |        ^^^^^ pattern `0_u128` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `u128`
+
+error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
+  --> $DIR/exhaustiveness.rs:69:11
+   |
+LL |     match (0u8, true) {
+   |           ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `(u8, bool)`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs
new file mode 100644
index 00000000000..af720a05693
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs
@@ -0,0 +1,53 @@
+#![feature(exclusive_range_pattern)]
+#![deny(overlapping_patterns)]
+
+macro_rules! m {
+    ($s:expr, $t1:pat, $t2:pat) => {
+        match $s {
+            $t1 => {}
+            $t2 => {}
+            _ => {}
+        }
+    }
+}
+
+fn main() {
+    m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 31..=40);
+    m!(0u8, 20..=30, 29..=40);
+    m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20.. 30, 28..=40);
+    m!(0u8, 20.. 30, 30..=40);
+    m!(0u8, 20..=30, 30..=30);
+    m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 29..=30);
+    m!(0u8, 20..=30, 20..=20);
+    m!(0u8, 20..=30, 20..=21);
+    m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 20);
+    m!(0u8, 20..=30, 25);
+    m!(0u8, 20..=30, 30);
+    m!(0u8, 20.. 30, 29);
+    m!(0u8, 20, 20..=30); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 25, 20..=30);
+    m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range
+
+    match (0u8, true) {
+        (0..=10, true) => {}
+        (10..20, true) => {} // not detected
+        (10..20, false) => {}
+        _ => {}
+    }
+    match (true, 0u8) {
+        (true, 0..=10) => {}
+        (true, 10..20) => {} //~ ERROR multiple patterns covering the same range
+        (false, 10..20) => {}
+        _ => {}
+    }
+    match Some(0u8) {
+        Some(0..=10) => {}
+        Some(10..20) => {} //~ ERROR multiple patterns covering the same range
+        _ => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
new file mode 100644
index 00000000000..7bb747cdf6f
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
@@ -0,0 +1,80 @@
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:15:22
+   |
+LL |     m!(0u8, 20..=30, 30..=40);
+   |             -------  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `30_u8`
+   |
+note: the lint level is defined here
+  --> $DIR/overlapping_range_endpoints.rs:2:9
+   |
+LL | #![deny(overlapping_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:16:22
+   |
+LL |     m!(0u8, 30..=40, 20..=30);
+   |             -------  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:19:22
+   |
+LL |     m!(0u8, 20.. 30, 29..=40);
+   |             -------  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `29_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:23:22
+   |
+LL |     m!(0u8, 20..=30, 30..=31);
+   |             -------  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:27:22
+   |
+LL |     m!(0u8, 20..=30, 19..=20);
+   |             -------  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `20_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:32:17
+   |
+LL |     m!(0u8, 20, 20..=30);
+   |             --  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `20_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:34:17
+   |
+LL |     m!(0u8, 30, 20..=30);
+   |             --  ^^^^^^^ overlapping patterns
+   |             |
+   |             this range overlaps on `30_u8`
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:44:16
+   |
+LL |         (true, 0..=10) => {}
+   |                ------ this range overlaps on `10_u8`
+LL |         (true, 10..20) => {}
+   |                ^^^^^^ overlapping patterns
+
+error: multiple patterns covering the same range
+  --> $DIR/overlapping_range_endpoints.rs:50:14
+   |
+LL |         Some(0..=10) => {}
+   |              ------ this range overlaps on `10_u8`
+LL |         Some(10..20) => {}
+   |              ^^^^^^ overlapping patterns
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs
new file mode 100644
index 00000000000..6173053cc4f
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs
@@ -0,0 +1,38 @@
+#![feature(precise_pointer_size_matching)]
+#![feature(exclusive_range_pattern)]
+
+macro_rules! m {
+    ($s:expr, $($t:tt)+) => {
+        match $s { $($t)+ => {} }
+    }
+}
+
+fn main() {
+    match 0usize {
+        0 ..= usize::MAX => {}
+    }
+
+    match 0isize {
+        isize::MIN ..= isize::MAX => {}
+    }
+
+    m!(0usize, 0..=usize::MAX);
+    m!(0usize, 0..5 | 5..=usize::MAX);
+    m!(0usize, 0..usize::MAX | usize::MAX);
+    m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+
+    m!(0isize, isize::MIN..=isize::MAX);
+    m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+    m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+    m!((0isize, true), (isize::MIN..5, true)
+        | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false));
+
+    match 0isize {
+        isize::MIN ..= -1 => {}
+        0 => {}
+        1 ..= isize::MAX => {}
+    }
+
+    match 7usize {}
+    //~^ ERROR non-exhaustive patterns
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr
new file mode 100644
index 00000000000..0b3c65166ee
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+  --> $DIR/pointer-sized-int-allow.rs:36:11
+   |
+LL |     match 7usize {}
+   |           ^^^^^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs
new file mode 100644
index 00000000000..9292f22e09e
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs
@@ -0,0 +1,48 @@
+#![feature(exclusive_range_pattern)]
+
+macro_rules! m {
+    ($s:expr, $($t:tt)+) => {
+        match $s { $($t)+ => {} }
+    }
+}
+
+fn main() {
+    match 0usize {
+        //~^ ERROR non-exhaustive patterns
+        0 ..= usize::MAX => {}
+    }
+
+    match 0isize {
+        //~^ ERROR non-exhaustive patterns
+        isize::MIN ..= isize::MAX => {}
+    }
+
+    m!(0usize, 0..=usize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!(0usize, 0..5 | 5..=usize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!(0usize, 0..usize::MAX | usize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+    //~^ ERROR non-exhaustive patterns
+
+    m!(0isize, isize::MIN..=isize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+    //~^ ERROR non-exhaustive patterns
+    m!((0isize, true), (isize::MIN..5, true)
+        | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false));
+    //~^^ ERROR non-exhaustive patterns
+
+    match 0isize {
+        //~^ ERROR non-exhaustive patterns
+        isize::MIN ..= -1 => {}
+        0 => {}
+        1 ..= isize::MAX => {}
+    }
+
+    match 7usize {}
+    //~^ ERROR non-exhaustive patterns
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr
new file mode 100644
index 00000000000..9d566b0e775
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr
@@ -0,0 +1,129 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:10:11
+   |
+LL |     match 0usize {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:15:11
+   |
+LL |     match 0isize {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:20:8
+   |
+LL |     m!(0usize, 0..=usize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:22:8
+   |
+LL |     m!(0usize, 0..5 | 5..=usize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:24:8
+   |
+LL |     m!(0usize, 0..usize::MAX | usize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+  --> $DIR/pointer-sized-int-deny.rs:26:8
+   |
+LL |     m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false));
+   |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `(usize, bool)`
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:29:8
+   |
+LL |     m!(0isize, isize::MIN..=isize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:31:8
+   |
+LL |     m!(0isize, isize::MIN..5 | 5..=isize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:33:8
+   |
+LL |     m!(0isize, isize::MIN..isize::MAX | isize::MAX);
+   |        ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+  --> $DIR/pointer-sized-int-deny.rs:35:8
+   |
+LL |     m!((0isize, true), (isize::MIN..5, true)
+   |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `(isize, bool)`
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/pointer-sized-int-deny.rs:39:11
+   |
+LL |     match 0isize {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+  --> $DIR/pointer-sized-int-deny.rs:46:11
+   |
+LL |     match 7usize {}
+   |           ^^^^^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
new file mode 100644
index 00000000000..a2aa655ca54
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
@@ -0,0 +1,18 @@
+// This tests that the lint message explains the reason for the error.
+fn main() {
+    match 0usize {
+        //~^ ERROR non-exhaustive patterns: `_` not covered
+        //~| NOTE pattern `_` not covered
+        //~| NOTE the matched value is of type `usize`
+        //~| NOTE `usize` does not have a fixed maximum value
+        0..=usize::MAX => {}
+    }
+
+    match 0isize {
+        //~^ ERROR non-exhaustive patterns: `_` not covered
+        //~| NOTE pattern `_` not covered
+        //~| NOTE the matched value is of type `isize`
+        //~| NOTE `isize` does not have a fixed maximum value
+        isize::MIN..=isize::MAX => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
new file mode 100644
index 00000000000..37e73a68f22
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
@@ -0,0 +1,25 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/precise_pointer_matching-message.rs:3:11
+   |
+LL |     match 0usize {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/precise_pointer_matching-message.rs:11:11
+   |
+LL |     match 0isize {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `isize`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
new file mode 100644
index 00000000000..9078e65f667
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
@@ -0,0 +1,112 @@
+#![feature(exclusive_range_pattern)]
+#![deny(unreachable_patterns)]
+
+macro_rules! m {
+    ($s:expr, $t1:pat, $t2:pat) => {
+        match $s {
+            $t1 => {}
+            $t2 => {}
+            _ => {}
+        }
+    }
+}
+
+fn main() {
+    m!(0u8, 42, 41);
+    m!(0u8, 42, 42); //~ ERROR unreachable pattern
+    m!(0u8, 42, 43);
+
+    m!(0u8, 20..=30, 19);
+    m!(0u8, 20..=30, 20); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 21); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 25); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 29); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 30); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 31);
+    m!(0u8, 20..30, 19);
+    m!(0u8, 20..30, 20); //~ ERROR unreachable pattern
+    m!(0u8, 20..30, 21); //~ ERROR unreachable pattern
+    m!(0u8, 20..30, 25); //~ ERROR unreachable pattern
+    m!(0u8, 20..30, 29); //~ ERROR unreachable pattern
+    m!(0u8, 20..30, 30);
+    m!(0u8, 20..30, 31);
+
+    m!(0u8, 20..=30, 20..=30); //~ ERROR unreachable pattern
+    m!(0u8, 20.. 30, 20.. 30); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 20.. 30); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 19..=30);
+    m!(0u8, 20..=30, 21..=30); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 20..=29); //~ ERROR unreachable pattern
+    m!(0u8, 20..=30, 20..=31);
+    m!('a', 'A'..='z', 'a'..='z'); //~ ERROR unreachable pattern
+
+    match 0u8 {
+        5 => {},
+        6 => {},
+        7 => {},
+        8 => {},
+        5..=8 => {}, //~ ERROR unreachable pattern
+        _ => {},
+    }
+    match 0u8 {
+        0..10 => {},
+        10..20 => {},
+        5..15 => {}, //~ ERROR unreachable pattern
+        _ => {},
+    }
+    match 0u8 {
+        0..10 => {},
+        10..20 => {},
+        20..30 => {},
+        5..25 => {}, //~ ERROR unreachable pattern
+        _ => {},
+    }
+    match 0u8 {
+        0..10 => {},
+        10 => {},
+        11..=23 => {},
+        19..30 => {},
+        5..25 => {}, //~ ERROR unreachable pattern
+        _ => {},
+    }
+    match 0usize {
+        0..10 => {},
+        10..20 => {},
+        5..15 => {}, // FIXME: should be unreachable
+        _ => {},
+    }
+    // Chars between '\u{D7FF}' and '\u{E000}' are invalid even though ranges that contain them are
+    // allowed.
+    match 'a' {
+        _ => {},
+        '\u{D7FF}'..='\u{E000}' => {}, //~ ERROR unreachable pattern
+    }
+    match 'a' {
+        '\u{0}'..='\u{D7FF}' => {},
+        '\u{E000}'..='\u{10_FFFF}' => {},
+        '\u{D7FF}'..='\u{E000}' => {}, // FIXME should be unreachable
+    }
+
+    match (0u8, true) {
+        (0..=255, false) => {}
+        (0..=255, true) => {} // ok
+    }
+    match (true, 0u8) {
+        (false, 0..=255) => {}
+        (true, 0..=255) => {} // ok
+    }
+
+    const FOO: i32 = 42;
+    const BAR: &i32 = &42;
+    match &0 {
+        &42 => {}
+        &FOO => {} //~ ERROR unreachable pattern
+        BAR => {} //~ ERROR unreachable pattern
+        _ => {}
+    }
+    // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933
+    match &0 {
+        BAR => {} // ok
+        _ => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr
new file mode 100644
index 00000000000..8baf0d50c88
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr
@@ -0,0 +1,146 @@
+error: unreachable pattern
+  --> $DIR/reachability.rs:16:17
+   |
+LL |     m!(0u8, 42, 42);
+   |                 ^^
+   |
+note: the lint level is defined here
+  --> $DIR/reachability.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:20:22
+   |
+LL |     m!(0u8, 20..=30, 20);
+   |                      ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:21:22
+   |
+LL |     m!(0u8, 20..=30, 21);
+   |                      ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:22:22
+   |
+LL |     m!(0u8, 20..=30, 25);
+   |                      ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:23:22
+   |
+LL |     m!(0u8, 20..=30, 29);
+   |                      ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:24:22
+   |
+LL |     m!(0u8, 20..=30, 30);
+   |                      ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:27:21
+   |
+LL |     m!(0u8, 20..30, 20);
+   |                     ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:28:21
+   |
+LL |     m!(0u8, 20..30, 21);
+   |                     ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:29:21
+   |
+LL |     m!(0u8, 20..30, 25);
+   |                     ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:30:21
+   |
+LL |     m!(0u8, 20..30, 29);
+   |                     ^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:34:22
+   |
+LL |     m!(0u8, 20..=30, 20..=30);
+   |                      ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:35:22
+   |
+LL |     m!(0u8, 20.. 30, 20.. 30);
+   |                      ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:36:22
+   |
+LL |     m!(0u8, 20..=30, 20.. 30);
+   |                      ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:38:22
+   |
+LL |     m!(0u8, 20..=30, 21..=30);
+   |                      ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:39:22
+   |
+LL |     m!(0u8, 20..=30, 20..=29);
+   |                      ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:41:24
+   |
+LL |     m!('a', 'A'..='z', 'a'..='z');
+   |                        ^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:48:9
+   |
+LL |         5..=8 => {},
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:54:9
+   |
+LL |         5..15 => {},
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:61:9
+   |
+LL |         5..25 => {},
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:69:9
+   |
+LL |         5..25 => {},
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:82:9
+   |
+LL |         '\u{D7FF}'..='\u{E000}' => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:103:9
+   |
+LL |         &FOO => {}
+   |         ^^^^
+
+error: unreachable pattern
+  --> $DIR/reachability.rs:104:9
+   |
+LL |         BAR => {}
+   |         ^^^
+
+error: aborting due to 23 previous errors
+