about summary refs log tree commit diff
path: root/src/test/ui/pattern
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-22 18:29:38 +0000
committerbors <bors@rust-lang.org>2020-11-22 18:29:38 +0000
commitc643dd2ec8fed2852f5eee8f776d657293a6a8f2 (patch)
treeaf4808d37329c7591dead286316631357f5f7947 /src/test/ui/pattern
parent52e3cf13aa9716f6648b1cad286ccd8d37aa315f (diff)
parent3213efcd9ab32cbe4e69c4322e6a992a9e64f0ff (diff)
downloadrust-c643dd2ec8fed2852f5eee8f776d657293a6a8f2.tar.gz
rust-c643dd2ec8fed2852f5eee8f776d657293a6a8f2.zip
Auto merge of #79243 - Nadrieril:consolidate-tests, r=varkor
Consolidate exhaustiveness-related tests

I hunted for tests that only exercised the match exhaustiveness algorithm and regrouped them. I also improved integer-range tests since I had found them lacking while hacking around.
The interest is mainly so that one can pass `--test-args patterns` and catch most relevant tests.

r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
Diffstat (limited to 'src/test/ui/pattern')
-rw-r--r--src/test/ui/pattern/integer-range-binding.rs (renamed from src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/const-pat-ice.rs (renamed from src/test/ui/pattern/const-pat-ice.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs (renamed from src/test/ui/pattern/deny-irrefutable-let-patterns.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr (renamed from src/test/ui/pattern/deny-irrefutable-let-patterns.stderr)0
-rw-r--r--src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs172
-rw-r--r--src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr146
-rw-r--r--src/test/ui/pattern/usefulness/floats.rs (renamed from src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs)6
-rw-r--r--src/test/ui/pattern/usefulness/floats.stderr (renamed from src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr)16
-rw-r--r--src/test/ui/pattern/usefulness/guards-not-exhaustive.rs18
-rw-r--r--src/test/ui/pattern/usefulness/guards.rs22
-rw-r--r--src/test/ui/pattern/usefulness/guards.stderr12
-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.rs (renamed from src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs)15
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr (renamed from src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.stderr)15
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.rs112
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr146
-rw-r--r--src/test/ui/pattern/usefulness/irrefutable-let-patterns.rs (renamed from src/test/ui/pattern/irrefutable-let-patterns.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/issue-12116.rs21
-rw-r--r--src/test/ui/pattern/usefulness/issue-12116.stderr14
-rw-r--r--src/test/ui/pattern/usefulness/issue-12369.rs11
-rw-r--r--src/test/ui/pattern/usefulness/issue-12369.stderr14
-rw-r--r--src/test/ui/pattern/usefulness/issue-13727.rs15
-rw-r--r--src/test/ui/pattern/usefulness/issue-13727.stderr14
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.rs17
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-2111.rs12
-rw-r--r--src/test/ui/pattern/usefulness/issue-2111.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-30240-b.rs15
-rw-r--r--src/test/ui/pattern/usefulness/issue-30240-b.stderr14
-rw-r--r--src/test/ui/pattern/usefulness/issue-30240-rpass.rs14
-rw-r--r--src/test/ui/pattern/usefulness/issue-30240.rs10
-rw-r--r--src/test/ui/pattern/usefulness/issue-30240.stderr21
-rw-r--r--src/test/ui/pattern/usefulness/issue-3096-1.rs3
-rw-r--r--src/test/ui/pattern/usefulness/issue-3096-1.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-3096-2.rs6
-rw-r--r--src/test/ui/pattern/usefulness/issue-3096-2.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-31221.rs34
-rw-r--r--src/test/ui/pattern/usefulness/issue-31221.stderr32
-rw-r--r--src/test/ui/pattern/usefulness/issue-31561.rs10
-rw-r--r--src/test/ui/pattern/usefulness/issue-31561.stderr26
-rw-r--r--src/test/ui/pattern/usefulness/issue-3601.rs34
-rw-r--r--src/test/ui/pattern/usefulness/issue-3601.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-39362.rs18
-rw-r--r--src/test/ui/pattern/usefulness/issue-39362.stderr17
-rw-r--r--src/test/ui/pattern/usefulness/issue-40221.rs16
-rw-r--r--src/test/ui/pattern/usefulness/issue-40221.stderr18
-rw-r--r--src/test/ui/pattern/usefulness/issue-4321.rs8
-rw-r--r--src/test/ui/pattern/usefulness/issue-4321.stderr12
-rw-r--r--src/test/ui/pattern/usefulness/issue-43253.rs47
-rw-r--r--src/test/ui/pattern/usefulness/issue-43253.stderr52
-rw-r--r--src/test/ui/pattern/usefulness/issue-50900.rs19
-rw-r--r--src/test/ui/pattern/usefulness/issue-50900.stderr15
-rw-r--r--src/test/ui/pattern/usefulness/issue-57472.rs35
-rw-r--r--src/test/ui/pattern/usefulness/issue-57472.stderr20
-rw-r--r--src/test/ui/pattern/usefulness/issue-66501.rs (renamed from src/test/ui/pattern/issue-66501.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/match-range-fail-dominate.rs49
-rw-r--r--src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr93
-rw-r--r--src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs36
-rw-r--r--src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr21
66 files changed, 1524 insertions, 601 deletions
diff --git a/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/integer-range-binding.rs
index ff065882d96..ff065882d96 100644
--- a/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs
+++ b/src/test/ui/pattern/integer-range-binding.rs
diff --git a/src/test/ui/pattern/const-pat-ice.rs b/src/test/ui/pattern/usefulness/const-pat-ice.rs
index abfacf3936b..abfacf3936b 100644
--- a/src/test/ui/pattern/const-pat-ice.rs
+++ b/src/test/ui/pattern/usefulness/const-pat-ice.rs
diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs
index 14040c8ada6..14040c8ada6 100644
--- a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs
+++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs
diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr
index 308a6c7c58e..308a6c7c58e 100644
--- a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr
diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs
deleted file mode 100644
index 78cc0d28fb0..00000000000
--- a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-#![feature(precise_pointer_size_matching)]
-#![feature(exclusive_range_pattern)]
-#![deny(unreachable_patterns)]
-#![deny(overlapping_patterns)]
-
-use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};
-
-fn main() {
-    let x: u8 = 0;
-
-    // A single range covering the entire domain.
-    match x {
-        0 ..= 255 => {} // ok
-    }
-
-    // A combination of ranges and values.
-    // These are currently allowed to be overlapping.
-    match x {
-        0 ..= 32 => {}
-        33 => {}
-        34 .. 128 => {}
-        100 ..= 200 => {}
-        200 => {} //~ ERROR unreachable pattern
-        201 ..= 255 => {}
-    }
-
-    // An incomplete set of values.
-    match x { //~ ERROR non-exhaustive patterns
-        0 .. 128 => {}
-    }
-
-    // A more incomplete set of values.
-    match x { //~ ERROR non-exhaustive patterns
-        0 ..= 10 => {}
-        20 ..= 30 => {}
-        35 => {}
-        70 .. 255 => {}
-    }
-
-    let x: i8 = 0;
-    match x { //~ ERROR non-exhaustive patterns
-        -7 => {}
-        -5..=120 => {}
-        -2..=20 => {}
-        //~^ ERROR unreachable pattern
-        125 => {}
-    }
-
-    // Let's test other types too!
-    let c: char = '\u{0}';
-    match c {
-        '\u{0}' ..= char::MAX => {} // ok
-    }
-
-    // We can actually get away with just covering the
-    // following two ranges, which correspond to all
-    // valid Unicode Scalar Values.
-    match c {
-        '\u{0000}' ..= '\u{D7FF}' => {}
-        '\u{E000}' ..= '\u{10_FFFF}' => {}
-    }
-
-    match 0u16 {
-        0 ..= u16::MAX => {} // ok
-    }
-
-    match 0u32 {
-        0 ..= u32::MAX => {} // ok
-    }
-
-    match 0u64 {
-        0 ..= u64::MAX => {} // ok
-    }
-
-    match 0u128 {
-        0 ..= u128::MAX => {} // ok
-    }
-
-    match 0i8 {
-        -128 ..= 127 => {} // ok
-    }
-
-    match 0i8 { //~ ERROR non-exhaustive patterns
-        -127 ..= 127 => {}
-    }
-
-    match 0i16 {
-        i16::MIN ..= i16::MAX => {} // ok
-    }
-
-    match 0i16 { //~ ERROR non-exhaustive patterns
-        i16::MIN ..= -1 => {}
-        1 ..= i16::MAX => {}
-    }
-
-    match 0i32 {
-        i32::MIN ..= i32::MAX => {} // ok
-    }
-
-    match 0i64 {
-        i64::MIN ..= i64::MAX => {} // ok
-    }
-
-    match 0i128 {
-        i128::MIN ..= i128::MAX => {} // ok
-    }
-
-    // Make sure that guards don't factor into the exhaustiveness checks.
-    match 0u8 { //~ ERROR non-exhaustive patterns
-        0 .. 128 => {}
-        128 ..= 255 if true => {}
-    }
-
-    match 0u8 {
-        0 .. 128 => {}
-        128 ..= 255 if false => {}
-        128 ..= 255 => {} // ok, because previous arm was guarded
-    }
-
-    // Now things start getting a bit more interesting. Testing products!
-    match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
-        (1, _) => {}
-        (_, None) => {}
-    }
-
-    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 0u8 {
-        0 .. 2 => {}
-        1 ..= 2 => {} //~ ERROR multiple patterns covering the same range
-        _ => {}
-    }
-
-    const LIM: u128 = u128::MAX - 1;
-    match 0u128 { //~ ERROR non-exhaustive patterns
-        0 ..= LIM => {}
-    }
-
-    match 0u128 { //~ ERROR non-exhaustive patterns
-        0 ..= 4 => {}
-    }
-
-    match 0u128 { //~ ERROR non-exhaustive patterns
-        4 ..= u128::MAX => {}
-    }
-
-    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/exhaustive_integer_patterns.stderr b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr
deleted file mode 100644
index 9f076c50a8f..00000000000
--- a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr
+++ /dev/null
@@ -1,146 +0,0 @@
-error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:23:9
-   |
-LL |         200 => {}
-   |         ^^^
-   |
-note: the lint level is defined here
-  --> $DIR/exhaustive_integer_patterns.rs:3:9
-   |
-LL | #![deny(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:28:11
-   |
-LL |     match x {
-   |           ^ pattern `128_u8..=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: `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:33:11
-   |
-LL |     match x {
-   |           ^ patterns `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more 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: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:44:9
-   |
-LL |         -2..=20 => {}
-   |         ^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more not covered
-  --> $DIR/exhaustive_integer_patterns.rs:41:11
-   |
-LL |     match x {
-   |           ^ patterns `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more 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/exhaustive_integer_patterns.rs:83:11
-   |
-LL |     match 0i8 {
-   |           ^^^ 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_i16` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:91:11
-   |
-LL |     match 0i16 {
-   |           ^^^^ pattern `0_i16` 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 `i16`
-
-error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:109:11
-   |
-LL |     match 0u8 {
-   |           ^^^ pattern `128_u8..=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, Some(_))` and `(2_u8..=u8::MAX, Some(_))` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:121:11
-   |
-LL |     match (0u8, Some(())) {
-   |           ^^^^^^^^^^^^^^^ patterns `(0_u8, Some(_))` and `(2_u8..=u8::MAX, Some(_))` 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, Option<()>)`
-
-error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:126: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: multiple patterns covering the same range
-  --> $DIR/exhaustive_integer_patterns.rs:141:9
-   |
-LL |         0 .. 2 => {}
-   |         ------ this range overlaps on `1_u8`
-LL |         1 ..= 2 => {}
-   |         ^^^^^^^ overlapping patterns
-   |
-note: the lint level is defined here
-  --> $DIR/exhaustive_integer_patterns.rs:4:9
-   |
-LL | #![deny(overlapping_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:146:11
-   |
-LL |     match 0u128 {
-   |           ^^^^^ 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/exhaustive_integer_patterns.rs:150:11
-   |
-LL |     match 0u128 {
-   |           ^^^^^ 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..=3_u128` not covered
-  --> $DIR/exhaustive_integer_patterns.rs:154:11
-   |
-LL |     match 0u128 {
-   |           ^^^^^ pattern `0_u128..=3_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: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:162:9
-   |
-LL |         &FOO => {}
-   |         ^^^^
-
-error: unreachable pattern
-  --> $DIR/exhaustive_integer_patterns.rs:163:9
-   |
-LL |         BAR => {}
-   |         ^^^
-
-error: aborting due to 16 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs b/src/test/ui/pattern/usefulness/floats.rs
index 588fecbf10d..095f5ac9a89 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs
+++ b/src/test/ui/pattern/usefulness/floats.rs
@@ -10,4 +10,10 @@ fn main() {
     match 0.0 { //~ ERROR non-exhaustive patterns
       0.0..=1.0 => {}
     }
+
+    match 1.0f64 {
+      0.01f64 ..= 6.5f64 => {}
+      0.02f64 => {} //~ ERROR unreachable pattern
+      _ => {}
+    };
 }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr b/src/test/ui/pattern/usefulness/floats.stderr
index 4835fa86cc0..464bfbdb2c3 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr
+++ b/src/test/ui/pattern/usefulness/floats.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/non-exhaustive-float-range-match.rs:10:11
+  --> $DIR/floats.rs:10:11
    |
 LL |     match 0.0 {
    |           ^^^ pattern `_` not covered
@@ -7,6 +7,18 @@ LL |     match 0.0 {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `f64`
 
-error: aborting due to previous error
+error: unreachable pattern
+  --> $DIR/floats.rs:16:7
+   |
+LL |       0.02f64 => {}
+   |       ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/floats.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+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/guards-not-exhaustive.rs b/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs
deleted file mode 100644
index b74f162c0c6..00000000000
--- a/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-pass
-
-#![allow(non_snake_case)]
-
-#[derive(Copy, Clone)]
-enum Q { R(Option<usize>) }
-
-fn xyzzy(q: Q) -> usize {
-    match q {
-        Q::R(S) if S.is_some() => { 0 }
-        _ => 1
-    }
-}
-
-
-pub fn main() {
-    assert_eq!(xyzzy(Q::R(Some(5))), 0);
-}
diff --git a/src/test/ui/pattern/usefulness/guards.rs b/src/test/ui/pattern/usefulness/guards.rs
new file mode 100644
index 00000000000..b15440cf608
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/guards.rs
@@ -0,0 +1,22 @@
+#![feature(exclusive_range_pattern)]
+#![deny(unreachable_patterns)]
+
+enum Q { R(Option<usize>) }
+
+pub fn main() {
+    match Q::R(None) {
+        Q::R(S) if S.is_some() => {}
+        _ => {}
+    }
+
+    match 0u8 { //~ ERROR non-exhaustive patterns
+        0 .. 128 => {}
+        128 ..= 255 if true => {}
+    }
+
+    match 0u8 {
+        0 .. 128 => {}
+        128 ..= 255 if false => {}
+        128 ..= 255 => {} // ok, because previous arm was guarded
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/guards.stderr b/src/test/ui/pattern/usefulness/guards.stderr
new file mode 100644
index 00000000000..61f7facb330
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/guards.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered
+  --> $DIR/guards.rs:12:11
+   |
+LL |     match 0u8 {
+   |           ^^^ pattern `128_u8..=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: 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/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/non-exhaustive-pattern-pointer-size-int.rs b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
index 0c52876e21f..a2aa655ca54 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs
+++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs
@@ -1,23 +1,18 @@
-use std::{usize, isize};
-
+// This tests that the lint message explains the reason for the error.
 fn main() {
     match 0usize {
-        //~^ ERROR non-exhaustive patterns
+        //~^ 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 => {}
+        0..=usize::MAX => {}
     }
 
     match 0isize {
-        //~^ ERROR non-exhaustive patterns
+        //~^ 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 => {}
+        isize::MIN..=isize::MAX => {}
     }
-
-    match 7usize {}
-    //~^ ERROR non-exhaustive patterns
-    //~| NOTE the matched value is of type `usize`
 }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.stderr b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
index d0aa452fd38..37e73a68f22 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:4:11
+  --> $DIR/precise_pointer_matching-message.rs:3:11
    |
 LL |     match 0usize {
    |           ^^^^^^ pattern `_` not covered
@@ -10,7 +10,7 @@ LL |     match 0usize {
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 
 error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:12:11
+  --> $DIR/precise_pointer_matching-message.rs:11:11
    |
 LL |     match 0isize {
    |           ^^^^^^ pattern `_` not covered
@@ -20,15 +20,6 @@ LL |     match 0isize {
    = 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/non-exhaustive-pattern-pointer-size-int.rs:20: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 3 previous errors
+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
+
diff --git a/src/test/ui/pattern/irrefutable-let-patterns.rs b/src/test/ui/pattern/usefulness/irrefutable-let-patterns.rs
index d400ef0bbd6..d400ef0bbd6 100644
--- a/src/test/ui/pattern/irrefutable-let-patterns.rs
+++ b/src/test/ui/pattern/usefulness/irrefutable-let-patterns.rs
diff --git a/src/test/ui/pattern/usefulness/issue-12116.rs b/src/test/ui/pattern/usefulness/issue-12116.rs
new file mode 100644
index 00000000000..8b391cd95d7
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-12116.rs
@@ -0,0 +1,21 @@
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![deny(unreachable_patterns)]
+
+enum IntList {
+    Cons(isize, Box<IntList>),
+    Nil
+}
+
+fn tail(source_list: &IntList) -> IntList {
+    match source_list {
+        &IntList::Cons(val, box ref next_list) => tail(next_list),
+        &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, box IntList::Nil),
+//~^ ERROR unreachable pattern
+        _                          => panic!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/pattern/usefulness/issue-12116.stderr b/src/test/ui/pattern/usefulness/issue-12116.stderr
new file mode 100644
index 00000000000..4d162eb77e7
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-12116.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/issue-12116.rs:15:9
+   |
+LL |         &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, box IntList::Nil),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-12116.rs:5:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/usefulness/issue-12369.rs b/src/test/ui/pattern/usefulness/issue-12369.rs
new file mode 100644
index 00000000000..0481c1fd9e1
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-12369.rs
@@ -0,0 +1,11 @@
+#![deny(unreachable_patterns)]
+
+fn main() {
+    let sl = vec![1,2,3];
+    let v: isize = match &*sl {
+        &[] => 0,
+        &[a,b,c] => 3,
+        &[a, ref rest @ ..] => a,
+        &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern
+    };
+}
diff --git a/src/test/ui/pattern/usefulness/issue-12369.stderr b/src/test/ui/pattern/usefulness/issue-12369.stderr
new file mode 100644
index 00000000000..aab2be78c9a
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-12369.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/issue-12369.rs:9:9
+   |
+LL |         &[10,a, ref rest @ ..] => 10
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-12369.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/usefulness/issue-13727.rs b/src/test/ui/pattern/usefulness/issue-13727.rs
new file mode 100644
index 00000000000..7fb565ef3bf
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-13727.rs
@@ -0,0 +1,15 @@
+#![allow(overflowing_literals)]
+#![deny(unreachable_patterns)]
+
+fn test(val: u8) {
+  match val {
+    256 => print!("0b1110\n"),
+    512 => print!("0b1111\n"),
+    //~^ ERROR: unreachable pattern
+    _   => print!("fail\n"),
+  }
+}
+
+fn main() {
+  test(1);
+}
diff --git a/src/test/ui/pattern/usefulness/issue-13727.stderr b/src/test/ui/pattern/usefulness/issue-13727.stderr
new file mode 100644
index 00000000000..07ca56a566f
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-13727.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/issue-13727.rs:7:5
+   |
+LL |     512 => print!("0b1111\n"),
+   |     ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-13727.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs
new file mode 100644
index 00000000000..ed134c175ed
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-15129.rs
@@ -0,0 +1,17 @@
+pub enum T {
+    T1(()),
+    T2(())
+}
+
+pub enum V {
+    V1(isize),
+    V2(bool)
+}
+
+fn main() {
+    match (T::T1(()), V::V2(true)) {
+    //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered
+        (T::T1(()), V::V1(i)) => (),
+        (T::T2(()), V::V2(b)) => ()
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr
new file mode 100644
index 00000000000..aa4434e72b5
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-15129.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered
+  --> $DIR/issue-15129.rs:12:11
+   |
+LL |     match (T::T1(()), V::V2(true)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` 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 `(T, V)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-2111.rs b/src/test/ui/pattern/usefulness/issue-2111.rs
new file mode 100644
index 00000000000..7e5835e8697
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-2111.rs
@@ -0,0 +1,12 @@
+fn foo(a: Option<usize>, b: Option<usize>) {
+  match (a,b) {
+  //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered
+    (Some(a), Some(b)) if a == b => { }
+    (Some(_), None) |
+    (None, Some(_)) => { }
+  }
+}
+
+fn main() {
+  foo(None, None);
+}
diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr
new file mode 100644
index 00000000000..a39a479e078
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-2111.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: `(None, None)` not covered
+  --> $DIR/issue-2111.rs:2:9
+   |
+LL |   match (a,b) {
+   |         ^^^^^ pattern `(None, None)` 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 `(Option<usize>, Option<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/issue-30240-b.rs b/src/test/ui/pattern/usefulness/issue-30240-b.rs
new file mode 100644
index 00000000000..01a6e7d8cb9
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-30240-b.rs
@@ -0,0 +1,15 @@
+#![deny(unreachable_patterns)]
+
+fn main() {
+    match "world" {
+        "hello" => {}
+        _ => {},
+    }
+
+    match "world" {
+        ref _x if false => {}
+        "hello" => {}
+        "hello" => {} //~ ERROR unreachable pattern
+        _ => {},
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-30240-b.stderr b/src/test/ui/pattern/usefulness/issue-30240-b.stderr
new file mode 100644
index 00000000000..59d64bc256b
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-30240-b.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/issue-30240-b.rs:12:9
+   |
+LL |         "hello" => {}
+   |         ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-30240-b.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/usefulness/issue-30240-rpass.rs b/src/test/ui/pattern/usefulness/issue-30240-rpass.rs
new file mode 100644
index 00000000000..ab16614fd30
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-30240-rpass.rs
@@ -0,0 +1,14 @@
+// run-pass
+fn main() {
+    let &ref a = &[0i32] as &[_];
+    assert_eq!(a, &[0i32] as &[_]);
+
+    let &ref a = "hello";
+    assert_eq!(a, "hello");
+
+    match "foo" {
+        "fool" => unreachable!(),
+        "foo" => {},
+        ref _x => unreachable!()
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-30240.rs b/src/test/ui/pattern/usefulness/issue-30240.rs
new file mode 100644
index 00000000000..a0c0d1626ec
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-30240.rs
@@ -0,0 +1,10 @@
+fn main() {
+    match "world" { //~ ERROR non-exhaustive patterns: `&_`
+        "hello" => {}
+    }
+
+    match "world" { //~ ERROR non-exhaustive patterns: `&_`
+        ref _x if false => {}
+        "hello" => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-30240.stderr b/src/test/ui/pattern/usefulness/issue-30240.stderr
new file mode 100644
index 00000000000..a2c58d6e051
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-30240.stderr
@@ -0,0 +1,21 @@
+error[E0004]: non-exhaustive patterns: `&_` not covered
+  --> $DIR/issue-30240.rs:2:11
+   |
+LL |     match "world" {
+   |           ^^^^^^^ 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 `&str`
+
+error[E0004]: non-exhaustive patterns: `&_` not covered
+  --> $DIR/issue-30240.rs:6:11
+   |
+LL |     match "world" {
+   |           ^^^^^^^ 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 `&str`
+
+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/issue-3096-1.rs b/src/test/ui/pattern/usefulness/issue-3096-1.rs
new file mode 100644
index 00000000000..edc3b322305
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3096-1.rs
@@ -0,0 +1,3 @@
+fn main() {
+    match () { } //~ ERROR non-exhaustive
+}
diff --git a/src/test/ui/pattern/usefulness/issue-3096-1.stderr b/src/test/ui/pattern/usefulness/issue-3096-1.stderr
new file mode 100644
index 00000000000..97c34755189
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3096-1.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: type `()` is non-empty
+  --> $DIR/issue-3096-1.rs:2:11
+   |
+LL |     match () { }
+   |           ^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-3096-2.rs b/src/test/ui/pattern/usefulness/issue-3096-2.rs
new file mode 100644
index 00000000000..a26e425809f
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3096-2.rs
@@ -0,0 +1,6 @@
+enum Bottom { }
+
+fn main() {
+    let x = &() as *const () as *const Bottom;
+    match x { } //~ ERROR non-exhaustive patterns
+}
diff --git a/src/test/ui/pattern/usefulness/issue-3096-2.stderr b/src/test/ui/pattern/usefulness/issue-3096-2.stderr
new file mode 100644
index 00000000000..472d1a91e6a
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3096-2.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty
+  --> $DIR/issue-3096-2.rs:5:11
+   |
+LL |     match x { }
+   |           ^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `*const Bottom`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-31221.rs b/src/test/ui/pattern/usefulness/issue-31221.rs
new file mode 100644
index 00000000000..e03f1ec5bc2
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-31221.rs
@@ -0,0 +1,34 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(non_snake_case)]
+#![deny(unreachable_patterns)]
+
+#[derive(Clone, Copy)]
+enum Enum {
+    Var1,
+    Var2,
+}
+
+fn main() {
+    use Enum::*;
+    let s = Var1;
+    match s {
+        Var1 => (),
+        Var3 => (),
+        Var2 => (),
+        //~^ ERROR unreachable pattern
+    };
+    match &s {
+        &Var1 => (),
+        &Var3 => (),
+        &Var2 => (),
+        //~^ ERROR unreachable pattern
+    };
+    let t = (Var1, Var1);
+    match t {
+        (Var1, b) => (),
+        (c, d) => (),
+        anything => ()
+        //~^ ERROR unreachable pattern
+    };
+}
diff --git a/src/test/ui/pattern/usefulness/issue-31221.stderr b/src/test/ui/pattern/usefulness/issue-31221.stderr
new file mode 100644
index 00000000000..7d349144456
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-31221.stderr
@@ -0,0 +1,32 @@
+error: unreachable pattern
+  --> $DIR/issue-31221.rs:18:9
+   |
+LL |         Var3 => (),
+   |         ---- matches any value
+LL |         Var2 => (),
+   |         ^^^^ unreachable pattern
+   |
+note: the lint level is defined here
+  --> $DIR/issue-31221.rs:4:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/issue-31221.rs:24:9
+   |
+LL |         &Var3 => (),
+   |         ----- matches any value
+LL |         &Var2 => (),
+   |         ^^^^^ unreachable pattern
+
+error: unreachable pattern
+  --> $DIR/issue-31221.rs:31:9
+   |
+LL |         (c, d) => (),
+   |         ------ matches any value
+LL |         anything => ()
+   |         ^^^^^^^^ unreachable pattern
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/pattern/usefulness/issue-31561.rs b/src/test/ui/pattern/usefulness/issue-31561.rs
new file mode 100644
index 00000000000..813b2409cc8
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-31561.rs
@@ -0,0 +1,10 @@
+enum Thing {
+    Foo(u8),
+    Bar,
+    Baz
+}
+
+fn main() {
+    let Thing::Foo(y) = Thing::Foo(1);
+    //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered
+}
diff --git a/src/test/ui/pattern/usefulness/issue-31561.stderr b/src/test/ui/pattern/usefulness/issue-31561.stderr
new file mode 100644
index 00000000000..2f562b23692
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-31561.stderr
@@ -0,0 +1,26 @@
+error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
+  --> $DIR/issue-31561.rs:8:9
+   |
+LL | / enum Thing {
+LL | |     Foo(u8),
+LL | |     Bar,
+   | |     --- not covered
+LL | |     Baz
+   | |     --- not covered
+LL | | }
+   | |_- `Thing` defined here
+...
+LL |       let Thing::Foo(y) = Thing::Foo(1);
+   |           ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `Thing`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |     if let Thing::Foo(y) = Thing::Foo(1) { /* */ }
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0005`.
diff --git a/src/test/ui/pattern/usefulness/issue-3601.rs b/src/test/ui/pattern/usefulness/issue-3601.rs
new file mode 100644
index 00000000000..e33359beccd
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3601.rs
@@ -0,0 +1,34 @@
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+
+struct HTMLImageData {
+    image: Option<String>
+}
+
+struct ElementData {
+    kind: Box<ElementKind>
+}
+
+enum ElementKind {
+    HTMLImageElement(HTMLImageData)
+}
+
+enum NodeKind {
+    Element(ElementData)
+}
+
+struct NodeData {
+    kind: Box<NodeKind>,
+}
+
+fn main() {
+    let mut id = HTMLImageData { image: None };
+    let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) };
+    let n = NodeData {kind : box NodeKind::Element(ed)};
+    // n.b. span could be better
+    match n.kind {
+        box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
+            box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
+        },
+    };
+}
diff --git a/src/test/ui/pattern/usefulness/issue-3601.stderr b/src/test/ui/pattern/usefulness/issue-3601.stderr
new file mode 100644
index 00000000000..c873c20cca8
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-3601.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered
+  --> $DIR/issue-3601.rs:30:44
+   |
+LL |         box NodeKind::Element(ed) => match ed.kind {
+   |                                            ^^^^^^^ pattern `Box(_, _)` 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 `Box<ElementKind>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-39362.rs b/src/test/ui/pattern/usefulness/issue-39362.rs
new file mode 100644
index 00000000000..ea3c8f88e0b
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-39362.rs
@@ -0,0 +1,18 @@
+enum Foo {
+    Bar { bar: Bar, id: usize }
+}
+
+enum Bar {
+    A, B, C, D, E, F
+}
+
+fn test(f: Foo) {
+    match f {
+        //~^ ERROR non-exhaustive patterns
+        //~| patterns
+        Foo::Bar { bar: Bar::A, .. } => (),
+        Foo::Bar { bar: Bar::B, .. } => (),
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/pattern/usefulness/issue-39362.stderr b/src/test/ui/pattern/usefulness/issue-39362.stderr
new file mode 100644
index 00000000000..8c162e55619
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-39362.stderr
@@ -0,0 +1,17 @@
+error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
+  --> $DIR/issue-39362.rs:10:11
+   |
+LL | / enum Foo {
+LL | |     Bar { bar: Bar, id: usize }
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       match f {
+   |             ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more 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 `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-40221.rs b/src/test/ui/pattern/usefulness/issue-40221.rs
new file mode 100644
index 00000000000..e1f7e975b80
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-40221.rs
@@ -0,0 +1,16 @@
+enum P {
+    C(PC),
+}
+
+enum PC {
+    Q,
+    QA,
+}
+
+fn test(proto: P) {
+    match proto { //~ ERROR non-exhaustive patterns
+        P::C(PC::Q) => (),
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/pattern/usefulness/issue-40221.stderr b/src/test/ui/pattern/usefulness/issue-40221.stderr
new file mode 100644
index 00000000000..98efe805a0b
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-40221.stderr
@@ -0,0 +1,18 @@
+error[E0004]: non-exhaustive patterns: `C(QA)` not covered
+  --> $DIR/issue-40221.rs:11:11
+   |
+LL | / enum P {
+LL | |     C(PC),
+   | |     - not covered
+LL | | }
+   | |_- `P` defined here
+...
+LL |       match proto {
+   |             ^^^^^ pattern `C(QA)` 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 `P`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-4321.rs b/src/test/ui/pattern/usefulness/issue-4321.rs
new file mode 100644
index 00000000000..9715f2eba2f
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-4321.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let tup = (true, true);
+    println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered
+        (false, false) => "foo",
+        (false, true) => "bar",
+        (true, true) => "baz"
+    });
+}
diff --git a/src/test/ui/pattern/usefulness/issue-4321.stderr b/src/test/ui/pattern/usefulness/issue-4321.stderr
new file mode 100644
index 00000000000..1e8852556b1
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-4321.stderr
@@ -0,0 +1,12 @@
+error[E0004]: non-exhaustive patterns: `(true, false)` not covered
+  --> $DIR/issue-4321.rs:3:31
+   |
+LL |     println!("foo {:}", match tup {
+   |                               ^^^ pattern `(true, 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 `(bool, bool)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-43253.rs b/src/test/ui/pattern/usefulness/issue-43253.rs
deleted file mode 100644
index 349ba11a7cd..00000000000
--- a/src/test/ui/pattern/usefulness/issue-43253.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// check-pass
-#![feature(exclusive_range_pattern)]
-#![warn(unreachable_patterns)]
-#![warn(overlapping_patterns)]
-
-fn main() {
-    // These cases should generate no warning.
-    match 10 {
-        1..10 => {},
-        10 => {},
-        _ => {},
-    }
-
-    match 10 {
-        1..10 => {},
-        9..=10 => {}, //~ WARNING multiple patterns covering the same range
-        _ => {},
-    }
-
-    match 10 {
-        1..10 => {},
-        10..=10 => {},
-        _ => {},
-    }
-
-    // These cases should generate "unreachable pattern" warnings.
-    match 10 {
-        1..10 => {},
-        9 => {}, //~ WARNING unreachable pattern
-        _ => {},
-    }
-
-    match 10 {
-        1..10 => {},
-        8..=9 => {}, //~ WARNING unreachable pattern
-        _ => {},
-    }
-
-    match 10 {
-        5..7 => {},
-        6 => {}, //~ WARNING unreachable pattern
-        1..10 => {},
-        9..=9 => {}, //~ WARNING unreachable pattern
-        6 => {}, //~ WARNING unreachable pattern
-        _ => {},
-    }
-}
diff --git a/src/test/ui/pattern/usefulness/issue-43253.stderr b/src/test/ui/pattern/usefulness/issue-43253.stderr
deleted file mode 100644
index 04feef1706c..00000000000
--- a/src/test/ui/pattern/usefulness/issue-43253.stderr
+++ /dev/null
@@ -1,52 +0,0 @@
-warning: multiple patterns covering the same range
-  --> $DIR/issue-43253.rs:16:9
-   |
-LL |         1..10 => {},
-   |         ----- this range overlaps on `9_i32`
-LL |         9..=10 => {},
-   |         ^^^^^^ overlapping patterns
-   |
-note: the lint level is defined here
-  --> $DIR/issue-43253.rs:4:9
-   |
-LL | #![warn(overlapping_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
-  --> $DIR/issue-43253.rs:29:9
-   |
-LL |         9 => {},
-   |         ^
-   |
-note: the lint level is defined here
-  --> $DIR/issue-43253.rs:3:9
-   |
-LL | #![warn(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
-  --> $DIR/issue-43253.rs:35:9
-   |
-LL |         8..=9 => {},
-   |         ^^^^^
-
-warning: unreachable pattern
-  --> $DIR/issue-43253.rs:41:9
-   |
-LL |         6 => {},
-   |         ^
-
-warning: unreachable pattern
-  --> $DIR/issue-43253.rs:43:9
-   |
-LL |         9..=9 => {},
-   |         ^^^^^
-
-warning: unreachable pattern
-  --> $DIR/issue-43253.rs:44:9
-   |
-LL |         6 => {},
-   |         ^
-
-warning: 6 warnings emitted
-
diff --git a/src/test/ui/pattern/usefulness/issue-50900.rs b/src/test/ui/pattern/usefulness/issue-50900.rs
new file mode 100644
index 00000000000..27135af9575
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-50900.rs
@@ -0,0 +1,19 @@
+#[derive(PartialEq, Eq)]
+pub struct Tag(pub Context, pub u16);
+
+#[derive(PartialEq, Eq)]
+pub enum Context {
+    Tiff,
+    Exif,
+}
+
+impl Tag {
+    const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665);
+}
+
+fn main() {
+    match Tag::ExifIFDPointer {
+    //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered
+        Tag::ExifIFDPointer => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-50900.stderr b/src/test/ui/pattern/usefulness/issue-50900.stderr
new file mode 100644
index 00000000000..d378b6e8efe
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-50900.stderr
@@ -0,0 +1,15 @@
+error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
+  --> $DIR/issue-50900.rs:15:11
+   |
+LL | pub struct Tag(pub Context, pub u16);
+   | ------------------------------------- `Tag` defined here
+...
+LL |     match Tag::ExifIFDPointer {
+   |           ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` 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 `Tag`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/issue-57472.rs b/src/test/ui/pattern/usefulness/issue-57472.rs
new file mode 100644
index 00000000000..1131006374c
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-57472.rs
@@ -0,0 +1,35 @@
+#![crate_type="lib"]
+#![deny(unreachable_patterns)]
+
+mod test_struct {
+    // Test the exact copy of the minimal example
+    // posted in the issue.
+    pub struct Punned {
+        foo: [u8; 1],
+        bar: [u8; 1],
+    }
+
+    pub fn test(punned: Punned) {
+        match punned {
+            Punned { foo: [_], .. } => println!("foo"),
+            Punned { bar: [_], .. } => println!("bar"),
+            //~^ ERROR unreachable pattern [unreachable_patterns]
+        }
+    }
+}
+
+mod test_union {
+    // Test the same thing using a union.
+    pub union Punned {
+        foo: [u8; 1],
+        bar: [u8; 1],
+    }
+
+    pub fn test(punned: Punned) {
+        match punned {
+            Punned { foo: [_] } => println!("foo"),
+            Punned { bar: [_] } => println!("bar"),
+            //~^ ERROR unreachable pattern [unreachable_patterns]
+        }
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-57472.stderr b/src/test/ui/pattern/usefulness/issue-57472.stderr
new file mode 100644
index 00000000000..26efdf6dbaf
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-57472.stderr
@@ -0,0 +1,20 @@
+error: unreachable pattern
+  --> $DIR/issue-57472.rs:15:13
+   |
+LL |             Punned { bar: [_], .. } => println!("bar"),
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-57472.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/issue-57472.rs:31:13
+   |
+LL |             Punned { bar: [_] } => println!("bar"),
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/pattern/issue-66501.rs b/src/test/ui/pattern/usefulness/issue-66501.rs
index ffcfd4ad83e..ffcfd4ad83e 100644
--- a/src/test/ui/pattern/issue-66501.rs
+++ b/src/test/ui/pattern/usefulness/issue-66501.rs
diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs
deleted file mode 100644
index 37c4ccda0f5..00000000000
--- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-#![deny(unreachable_patterns, overlapping_patterns)]
-
-fn main() {
-    match 5 {
-      1 ..= 10 => { }
-      5 ..= 6 => { }
-      //~^ ERROR unreachable pattern
-      _ => {}
-    };
-
-    match 5 {
-      3 ..= 6 => { }
-      4 ..= 6 => { }
-      //~^ ERROR unreachable pattern
-      _ => {}
-    };
-
-    match 5 {
-      4 ..= 6 => { }
-      4 ..= 6 => { }
-      //~^ ERROR unreachable pattern
-      _ => {}
-    };
-
-    match 'c' {
-      'A' ..= 'z' => {}
-      'a' ..= 'z' => {}
-      //~^ ERROR unreachable pattern
-      _ => {}
-    };
-
-    match 1.0f64 {
-      0.01f64 ..= 6.5f64 => {}
-      //~^ WARNING floating-point types cannot be used in patterns
-      //~| WARNING floating-point types cannot be used in patterns
-      //~| WARNING floating-point types cannot be used in patterns
-      //~| WARNING floating-point types cannot be used in patterns
-      //~| WARNING this was previously accepted by the compiler
-      //~| WARNING this was previously accepted by the compiler
-      //~| WARNING this was previously accepted by the compiler
-      //~| WARNING this was previously accepted by the compiler
-      0.02f64 => {} //~ ERROR unreachable pattern
-      //~^ WARNING floating-point types cannot be used in patterns
-      //~| WARNING floating-point types cannot be used in patterns
-      //~| WARNING this was previously accepted by the compiler
-      //~| WARNING this was previously accepted by the compiler
-      _ => {}
-    };
-}
diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr
deleted file mode 100644
index 6922170fccb..00000000000
--- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr
+++ /dev/null
@@ -1,93 +0,0 @@
-error: unreachable pattern
-  --> $DIR/match-range-fail-dominate.rs:6:7
-   |
-LL |       5 ..= 6 => { }
-   |       ^^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/match-range-fail-dominate.rs:1:9
-   |
-LL | #![deny(unreachable_patterns, overlapping_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/match-range-fail-dominate.rs:13:7
-   |
-LL |       4 ..= 6 => { }
-   |       ^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/match-range-fail-dominate.rs:20:7
-   |
-LL |       4 ..= 6 => { }
-   |       ^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/match-range-fail-dominate.rs:27:7
-   |
-LL |       'a' ..= 'z' => {}
-   |       ^^^^^^^^^^^
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:33:7
-   |
-LL |       0.01f64 ..= 6.5f64 => {}
-   |       ^^^^^^^
-   |
-   = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:33:19
-   |
-LL |       0.01f64 ..= 6.5f64 => {}
-   |                   ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:42:7
-   |
-LL |       0.02f64 => {}
-   |       ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: unreachable pattern
-  --> $DIR/match-range-fail-dominate.rs:42:7
-   |
-LL |       0.02f64 => {}
-   |       ^^^^^^^
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:33:7
-   |
-LL |       0.01f64 ..= 6.5f64 => {}
-   |       ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:33:19
-   |
-LL |       0.01f64 ..= 6.5f64 => {}
-   |                   ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-warning: floating-point types cannot be used in patterns
-  --> $DIR/match-range-fail-dominate.rs:42:7
-   |
-LL |       0.02f64 => {}
-   |       ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
-
-error: aborting due to 5 previous errors; 6 warnings emitted
-
diff --git a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs
new file mode 100644
index 00000000000..cb44c1da76b
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs
@@ -0,0 +1,36 @@
+#[deny(unreachable_patterns)]
+
+fn parse_data1(data: &[u8]) -> u32 {
+    match data {
+        b"" => 1,
+        _ => 2,
+    }
+}
+
+fn parse_data2(data: &[u8]) -> u32 {
+    match data { //~ ERROR non-exhaustive patterns: `&[_, ..]` not covered
+        b"" => 1,
+    }
+}
+
+fn parse_data3(data: &[u8; 0]) -> u8 {
+    match data {
+        b"" => 1,
+    }
+}
+
+fn parse_data4(data: &[u8]) -> u8 {
+    match data { //~ ERROR non-exhaustive patterns
+        b"aaa" => 0,
+        [_, _, _] => 1,
+    }
+}
+
+fn parse_data5(data: &[u8; 3]) -> u8 {
+    match data {
+        b"aaa" => 0,
+        [_, _, _] => 1,
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr
new file mode 100644
index 00000000000..6ce53a4f21e
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr
@@ -0,0 +1,21 @@
+error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
+  --> $DIR/type_polymorphic_byte_str_literals.rs:11:11
+   |
+LL |     match data {
+   |           ^^^^ 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 `&[u8]`
+
+error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
+  --> $DIR/type_polymorphic_byte_str_literals.rs:23:11
+   |
+LL |     match data {
+   |           ^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more 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: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.