From 7410cbf03f55788ff768a9b6f0b2f098c1ab7053 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Wed, 28 Aug 2024 20:10:26 +0200
Subject: [PATCH 1/7] Revert warning empty patterns as unreachable

(cherry picked from commit 5b7be148ea0128daad309cf5a123c868a65d7737)
---
 .../rustc_pattern_analysis/src/usefulness.rs  |   6 +-
 .../usefulness/empty-types.never_pats.stderr  | 188 +-----------------
 .../usefulness/empty-types.normal.stderr      | 188 +-----------------
 tests/ui/pattern/usefulness/empty-types.rs    |  46 ++---
 .../usefulness/explain-unreachable-pats.rs    |   1 +
 .../explain-unreachable-pats.stderr           |  28 +--
 tests/ui/pattern/usefulness/impl-trait.rs     |   1 +
 tests/ui/pattern/usefulness/impl-trait.stderr |  32 +--
 .../ui/reachable/unreachable-loop-patterns.rs |   1 +
 .../unreachable-loop-patterns.stderr          |   4 +-
 .../rfc-0000-never_patterns/unreachable.rs    |   1 +
 .../unreachable.stderr                        |  14 +-
 .../uninhabited/patterns.rs                   |   1 +
 .../uninhabited/patterns_same_crate.rs        |   1 +
 .../uninhabited/patterns_same_crate.stderr    |  12 +-
 tests/ui/uninhabited/uninhabited-patterns.rs  |   1 +
 .../uninhabited/uninhabited-patterns.stderr   |   8 +-
 17 files changed, 86 insertions(+), 447 deletions(-)

diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 6535afcc39862..814559a66c568 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -951,7 +951,11 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
             self.is_scrutinee && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
         // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
         // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
-        let empty_arms_are_unreachable = self.validity.is_known_valid();
+        // We don't want to warn empty patterns as unreachable by default just yet. We will in a
+        // later version of rust or under a different lint name, see
+        // https://github.com/rust-lang/rust/pull/129103.
+        let empty_arms_are_unreachable = self.validity.is_known_valid()
+            && (is_toplevel_exception || cx.is_exhaustive_patterns_feature_on());
         // Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the
         // toplevel exception and `exhaustive_patterns` cases for backwards compatibility.
         let can_omit_empty_arms = self.validity.is_known_valid()
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 68213a2d661e0..fe9c431982004 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -43,30 +43,6 @@ LL +         _ => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:70:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(u32, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:76:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:79:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error: unreachable pattern
   --> $DIR/empty-types.rs:83:9
    |
@@ -94,22 +70,6 @@ LL +         Ok(_) => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:94:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:99:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
   --> $DIR/empty-types.rs:96:11
    |
@@ -156,54 +116,6 @@ help: you might want to use `let else` to handle the variant that isn't matched
 LL |     let Ok(_x) = &res_u32_never else { todo!() };
    |                                 ++++++++++++++++
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:112:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:115:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:118:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:119:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:122:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:123:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error: unreachable pattern
   --> $DIR/empty-types.rs:132:13
    |
@@ -220,22 +132,6 @@ LL |             _ if false => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:143:13
-   |
-LL |             Some(_) => {}
-   |             ^^^^^^^ matches no values because `Void` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:147:13
-   |
-LL |             None => {}
-   |             ---- matches all the relevant values
-LL |             _ => {}
-   |             ^ no value can reach this
-
 error[E0004]: non-exhaustive patterns: `Some(!)` not covered
   --> $DIR/empty-types.rs:156:15
    |
@@ -303,30 +199,6 @@ LL |         _ => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:284:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:287:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:288:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0005]: refutable pattern in local binding
   --> $DIR/empty-types.rs:297:13
    |
@@ -474,30 +346,6 @@ LL +         _ => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:368:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:371:9
-   |
-LL |         [_, _, _] => {}
-   |         ^^^^^^^^^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:374:9
-   |
-LL |         [_, ..] => {}
-   |         ^^^^^^^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
   --> $DIR/empty-types.rs:388:11
    |
@@ -534,40 +382,6 @@ LL ~         [..] if false => {},
 LL +         [] => todo!()
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:416:9
-   |
-LL |         Some(_) => {}
-   |         ^^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:421:9
-   |
-LL |         Some(_a) => {}
-   |         ^^^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:426:9
-   |
-LL |         None => {}
-   |         ---- matches all the relevant values
-LL |         // !useful, !reachable
-LL |         _ => {}
-   |         ^ no value can reach this
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:431:9
-   |
-LL |         None => {}
-   |         ---- matches all the relevant values
-LL |         // !useful, !reachable
-LL |         _a => {}
-   |         ^^ no value can reach this
-
 error[E0004]: non-exhaustive patterns: `&Some(!)` not covered
   --> $DIR/empty-types.rs:451:11
    |
@@ -744,7 +558,7 @@ LL ~         None => {},
 LL +         Some(!)
    |
 
-error: aborting due to 65 previous errors; 1 warning emitted
+error: aborting due to 42 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0004, E0005.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index 8f60dad4467bc..201b0b5c3fde3 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -34,30 +34,6 @@ LL +         _ => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:70:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(u32, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:76:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:79:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error: unreachable pattern
   --> $DIR/empty-types.rs:83:9
    |
@@ -85,22 +61,6 @@ LL +         Ok(_) => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:94:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:99:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
   --> $DIR/empty-types.rs:96:11
    |
@@ -147,54 +107,6 @@ help: you might want to use `let else` to handle the variant that isn't matched
 LL |     let Ok(_x) = &res_u32_never else { todo!() };
    |                                 ++++++++++++++++
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:112:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:115:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:118:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:119:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:122:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:123:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error: unreachable pattern
   --> $DIR/empty-types.rs:132:13
    |
@@ -211,22 +123,6 @@ LL |             _ if false => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:143:13
-   |
-LL |             Some(_) => {}
-   |             ^^^^^^^ matches no values because `Void` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:147:13
-   |
-LL |             None => {}
-   |             ---- matches all the relevant values
-LL |             _ => {}
-   |             ^ no value can reach this
-
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
   --> $DIR/empty-types.rs:156:15
    |
@@ -294,30 +190,6 @@ LL |         _ => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:284:9
-   |
-LL |         (_, _) => {}
-   |         ^^^^^^ matches no values because `(!, !)` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:287:9
-   |
-LL |         Ok(_) => {}
-   |         ^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:288:9
-   |
-LL |         Err(_) => {}
-   |         ^^^^^^ matches no values because `Result<!, !>` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0005]: refutable pattern in local binding
   --> $DIR/empty-types.rs:297:13
    |
@@ -465,30 +337,6 @@ LL +         _ => todo!(),
 LL +     }
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:368:9
-   |
-LL |         _ => {}
-   |         ^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:371:9
-   |
-LL |         [_, _, _] => {}
-   |         ^^^^^^^^^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:374:9
-   |
-LL |         [_, ..] => {}
-   |         ^^^^^^^ matches no values because `[!; 3]` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
   --> $DIR/empty-types.rs:388:11
    |
@@ -525,40 +373,6 @@ LL ~         [..] if false => {},
 LL +         [] => todo!()
    |
 
-error: unreachable pattern
-  --> $DIR/empty-types.rs:416:9
-   |
-LL |         Some(_) => {}
-   |         ^^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:421:9
-   |
-LL |         Some(_a) => {}
-   |         ^^^^^^^^ matches no values because `!` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:426:9
-   |
-LL |         None => {}
-   |         ---- matches all the relevant values
-LL |         // !useful, !reachable
-LL |         _ => {}
-   |         ^ no value can reach this
-
-error: unreachable pattern
-  --> $DIR/empty-types.rs:431:9
-   |
-LL |         None => {}
-   |         ---- matches all the relevant values
-LL |         // !useful, !reachable
-LL |         _a => {}
-   |         ^^ no value can reach this
-
 error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
   --> $DIR/empty-types.rs:451:11
    |
@@ -735,7 +549,7 @@ LL ~         None => {},
 LL +         Some(_) => todo!()
    |
 
-error: aborting due to 65 previous errors
+error: aborting due to 42 previous errors
 
 Some errors have detailed explanations: E0004, E0005.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.rs b/tests/ui/pattern/usefulness/empty-types.rs
index d561a0e9c128b..9e5f273a39052 100644
--- a/tests/ui/pattern/usefulness/empty-types.rs
+++ b/tests/ui/pattern/usefulness/empty-types.rs
@@ -67,16 +67,16 @@ fn basic(x: NeverBundle) {
     let tuple_half_never: (u32, !) = x.tuple_half_never;
     match tuple_half_never {}
     match tuple_half_never {
-        (_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
 
     let tuple_never: (!, !) = x.tuple_never;
     match tuple_never {}
     match tuple_never {
-        _ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match tuple_never {
-        (_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match tuple_never.0 {}
     match tuple_never.0 {
@@ -91,12 +91,12 @@ fn basic(x: NeverBundle) {
     }
     match res_u32_never {
         Ok(_) => {}
-        Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match res_u32_never {
         //~^ ERROR non-exhaustive
         Ok(0) => {}
-        Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     let Ok(_x) = res_u32_never;
     let Ok(_x) = res_u32_never.as_ref();
@@ -109,18 +109,18 @@ fn basic(x: NeverBundle) {
     let result_never: Result<!, !> = x.result_never;
     match result_never {}
     match result_never {
-        _ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
-        _ => {}     //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _ => {}     //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {}  //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
-        Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Ok(_) => {}  //[exhaustive_patterns]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
 }
 
@@ -140,11 +140,11 @@ fn void_same_as_never(x: NeverBundle) {
         }
         match opt_void {
             None => {}
-            Some(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+            Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
         }
         match opt_void {
             None => {}
-            _ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+            _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
         }
 
         let ref_void: &Void = &x.void;
@@ -281,11 +281,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
         _ => {} //~ ERROR unreachable pattern
     }
     match tuple_never {
-        (_, _) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {}  //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
-        Err(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Ok(_) => {}  //[exhaustive_patterns]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
 
     // These should be considered !known_valid and not warn unreachable.
@@ -365,13 +365,13 @@ fn arrays_and_slices(x: NeverBundle) {
     let array_3_never: [!; 3] = x.array_3_never;
     match array_3_never {}
     match array_3_never {
-        _ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match array_3_never {
-        [_, _, _] => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        [_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match array_3_never {
-        [_, ..] => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        [_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
 
     let ref_array_3_never: &[!; 3] = &array_3_never;
@@ -413,22 +413,22 @@ fn bindings(x: NeverBundle) {
     match opt_never {
         None => {}
         // !useful, !reachable
-        Some(_) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        Some(_a) => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        _ => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        _a => {} //[exhaustive_patterns,normal,never_pats]~ ERROR unreachable pattern
+        _a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
     }
 
     // The scrutinee is known_valid, but under the `&` isn't anymore.
diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs
index 1cfa5212414bb..f1af7f294cbd8 100644
--- a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs
+++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs
@@ -1,4 +1,5 @@
 #![feature(never_type)]
+#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 //~^ NOTE lint level is defined here
 
diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr
index 7023c2775e9a7..67f83a8517504 100644
--- a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr
+++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr
@@ -1,5 +1,5 @@
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:10:9
+  --> $DIR/explain-unreachable-pats.rs:11:9
    |
 LL |         (1 | 2,) => {}
    |         -------- matches all the relevant values
@@ -8,19 +8,19 @@ LL |         (2,) => {}
    |         ^^^^ no value can reach this
    |
 note: the lint level is defined here
-  --> $DIR/explain-unreachable-pats.rs:2:9
+  --> $DIR/explain-unreachable-pats.rs:3:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:21:9
+  --> $DIR/explain-unreachable-pats.rs:22:9
    |
 LL |         (1 | 2,) => {}
    |         ^^^^^^^^ no value can reach this
    |
 note: multiple earlier patterns match some of the same values
-  --> $DIR/explain-unreachable-pats.rs:21:9
+  --> $DIR/explain-unreachable-pats.rs:22:9
    |
 LL |         (1,) => {}
    |         ---- matches some of the same values
@@ -32,13 +32,13 @@ LL |         (1 | 2,) => {}
    |         ^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:40:9
+  --> $DIR/explain-unreachable-pats.rs:41:9
    |
 LL |         1 ..= 6 => {}
    |         ^^^^^^^ no value can reach this
    |
 note: multiple earlier patterns match some of the same values
-  --> $DIR/explain-unreachable-pats.rs:40:9
+  --> $DIR/explain-unreachable-pats.rs:41:9
    |
 LL |         1 => {}
    |         - matches some of the same values
@@ -56,7 +56,7 @@ LL |         1 ..= 6 => {}
    |         ^^^^^^^ ...and 2 other patterns collectively make this unreachable
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:51:9
+  --> $DIR/explain-unreachable-pats.rs:52:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^ matches no values because `!` is uninhabited
@@ -64,7 +64,7 @@ LL |         Err(_) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:65:9
+  --> $DIR/explain-unreachable-pats.rs:66:9
    |
 LL |         (Err(_), Err(_)) => {}
    |         ^^^^^^^^^^^^^^^^ matches no values because `Void2` is uninhabited
@@ -72,7 +72,7 @@ LL |         (Err(_), Err(_)) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:72:9
+  --> $DIR/explain-unreachable-pats.rs:73:9
    |
 LL |         (Err(_), Err(_)) => {}
    |         ^^^^^^^^^^^^^^^^ matches no values because `Void1` is uninhabited
@@ -80,7 +80,7 @@ LL |         (Err(_), Err(_)) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:82:11
+  --> $DIR/explain-unreachable-pats.rs:83:11
    |
 LL |     if let (0
    |             - matches all the relevant values
@@ -89,13 +89,13 @@ LL |         | 0, _) = (0, 0) {}
    |           ^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:92:9
+  --> $DIR/explain-unreachable-pats.rs:93:9
    |
 LL |         (_, true) => {}
    |         ^^^^^^^^^ no value can reach this
    |
 note: multiple earlier patterns match some of the same values
-  --> $DIR/explain-unreachable-pats.rs:92:9
+  --> $DIR/explain-unreachable-pats.rs:93:9
    |
 LL |         (true, _) => {}
    |         --------- matches some of the same values
@@ -107,7 +107,7 @@ LL |         (_, true) => {}
    |         ^^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:105:9
+  --> $DIR/explain-unreachable-pats.rs:106:9
    |
 LL |         (true, _) => {}
    |         --------- matches all the relevant values
@@ -116,7 +116,7 @@ LL |         (true, true) => {}
    |         ^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/explain-unreachable-pats.rs:117:9
+  --> $DIR/explain-unreachable-pats.rs:118:9
    |
 LL |         (_, true, 0..10) => {}
    |         ---------------- matches all the relevant values
diff --git a/tests/ui/pattern/usefulness/impl-trait.rs b/tests/ui/pattern/usefulness/impl-trait.rs
index c1cc279f74ce9..16560a092675f 100644
--- a/tests/ui/pattern/usefulness/impl-trait.rs
+++ b/tests/ui/pattern/usefulness/impl-trait.rs
@@ -1,6 +1,7 @@
 #![feature(never_type)]
 #![feature(type_alias_impl_trait)]
 #![feature(non_exhaustive_omitted_patterns_lint)]
+#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 // Test that the lint traversal handles opaques correctly
 #![deny(non_exhaustive_omitted_patterns)]
diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr
index 34b157f0fc443..f2945fca82bed 100644
--- a/tests/ui/pattern/usefulness/impl-trait.stderr
+++ b/tests/ui/pattern/usefulness/impl-trait.stderr
@@ -1,18 +1,18 @@
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:16:13
+  --> $DIR/impl-trait.rs:17:13
    |
 LL |             _ => {}
    |             ^ matches no values because `Void` is uninhabited
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
-  --> $DIR/impl-trait.rs:4:9
+  --> $DIR/impl-trait.rs:5:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:30:13
+  --> $DIR/impl-trait.rs:31:13
    |
 LL |             _ => {}
    |             ^ matches no values because `Void` is uninhabited
@@ -20,7 +20,7 @@ LL |             _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:44:13
+  --> $DIR/impl-trait.rs:45:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^ matches no values because `Void` is uninhabited
@@ -28,7 +28,7 @@ LL |             Some(_) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:48:13
+  --> $DIR/impl-trait.rs:49:13
    |
 LL |             None => {}
    |             ---- matches all the relevant values
@@ -36,7 +36,7 @@ LL |             _ => {}
    |             ^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:58:13
+  --> $DIR/impl-trait.rs:59:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^ matches no values because `Void` is uninhabited
@@ -44,7 +44,7 @@ LL |             Some(_) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:62:13
+  --> $DIR/impl-trait.rs:63:13
    |
 LL |             None => {}
    |             ---- matches all the relevant values
@@ -52,7 +52,7 @@ LL |             _ => {}
    |             ^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:75:9
+  --> $DIR/impl-trait.rs:76:9
    |
 LL |         _ => {}
    |         ^ matches no values because `Void` is uninhabited
@@ -60,7 +60,7 @@ LL |         _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:85:9
+  --> $DIR/impl-trait.rs:86:9
    |
 LL |         _ => {}
    |         - matches any value
@@ -68,7 +68,7 @@ LL |         Some((a, b)) => {}
    |         ^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:93:13
+  --> $DIR/impl-trait.rs:94:13
    |
 LL |             _ => {}
    |             ^ matches no values because `Void` is uninhabited
@@ -76,7 +76,7 @@ LL |             _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:104:9
+  --> $DIR/impl-trait.rs:105:9
    |
 LL |         Some((a, b)) => {}
    |         ------------ matches all the relevant values
@@ -84,7 +84,7 @@ LL |         Some((mut x, mut y)) => {
    |         ^^^^^^^^^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:123:13
+  --> $DIR/impl-trait.rs:124:13
    |
 LL |             _ => {}
    |             - matches any value
@@ -92,7 +92,7 @@ LL |             Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:137:13
+  --> $DIR/impl-trait.rs:138:13
    |
 LL |             _ => {}
    |             ^ matches no values because `SecretelyVoid` is uninhabited
@@ -100,7 +100,7 @@ LL |             _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:150:13
+  --> $DIR/impl-trait.rs:151:13
    |
 LL |             _ => {}
    |             ^ matches no values because `SecretelyDoubleVoid` is uninhabited
@@ -108,7 +108,7 @@ LL |             _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
-  --> $DIR/impl-trait.rs:22:11
+  --> $DIR/impl-trait.rs:23:11
    |
 LL |     match return_never_rpit(x) {}
    |           ^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `T` is non-empty
-  --> $DIR/impl-trait.rs:36:11
+  --> $DIR/impl-trait.rs:37:11
    |
 LL |     match return_never_tait(x) {}
    |           ^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/reachable/unreachable-loop-patterns.rs b/tests/ui/reachable/unreachable-loop-patterns.rs
index d074e3a6ece4b..9be37ecf2bb27 100644
--- a/tests/ui/reachable/unreachable-loop-patterns.rs
+++ b/tests/ui/reachable/unreachable-loop-patterns.rs
@@ -1,3 +1,4 @@
+#![feature(exhaustive_patterns)]
 #![feature(never_type, never_type_fallback)]
 #![allow(unreachable_code)]
 #![deny(unreachable_patterns)]
diff --git a/tests/ui/reachable/unreachable-loop-patterns.stderr b/tests/ui/reachable/unreachable-loop-patterns.stderr
index 03959ac160695..290f45700b2e4 100644
--- a/tests/ui/reachable/unreachable-loop-patterns.stderr
+++ b/tests/ui/reachable/unreachable-loop-patterns.stderr
@@ -1,12 +1,12 @@
 error: unreachable pattern
-  --> $DIR/unreachable-loop-patterns.rs:16:9
+  --> $DIR/unreachable-loop-patterns.rs:17:9
    |
 LL |     for _ in unimplemented!() as Void {}
    |         ^ matches no values because `Void` is uninhabited
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
-  --> $DIR/unreachable-loop-patterns.rs:3:9
+  --> $DIR/unreachable-loop-patterns.rs:4:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
index f68da4aa17316..6d7815f7a9eb0 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
@@ -1,3 +1,4 @@
+#![feature(exhaustive_patterns)]
 #![feature(never_patterns)]
 #![allow(incomplete_features)]
 #![allow(dead_code, unreachable_code)]
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.stderr
index 6b3f303eeab84..90874760a56fa 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.stderr
@@ -1,18 +1,18 @@
 error: unreachable pattern
-  --> $DIR/unreachable.rs:14:9
+  --> $DIR/unreachable.rs:15:9
    |
 LL |         Err(!),
    |         ^^^^^^ matches no values because `Void` is uninhabited
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
-  --> $DIR/unreachable.rs:4:9
+  --> $DIR/unreachable.rs:5:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/unreachable.rs:17:19
+  --> $DIR/unreachable.rs:18:19
    |
 LL |     let (Ok(_x) | Err(!)) = res_void;
    |                   ^^^^^^ matches no values because `Void` is uninhabited
@@ -20,7 +20,7 @@ LL |     let (Ok(_x) | Err(!)) = res_void;
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/unreachable.rs:19:12
+  --> $DIR/unreachable.rs:20:12
    |
 LL |     if let Err(!) = res_void {}
    |            ^^^^^^ matches no values because `Void` is uninhabited
@@ -28,7 +28,7 @@ LL |     if let Err(!) = res_void {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/unreachable.rs:21:24
+  --> $DIR/unreachable.rs:22:24
    |
 LL |     if let (Ok(true) | Err(!)) = res_void {}
    |                        ^^^^^^ matches no values because `Void` is uninhabited
@@ -36,7 +36,7 @@ LL |     if let (Ok(true) | Err(!)) = res_void {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/unreachable.rs:23:23
+  --> $DIR/unreachable.rs:24:23
    |
 LL |     for (Ok(mut _x) | Err(!)) in [res_void] {}
    |                       ^^^^^^ matches no values because `Void` is uninhabited
@@ -44,7 +44,7 @@ LL |     for (Ok(mut _x) | Err(!)) in [res_void] {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/unreachable.rs:27:18
+  --> $DIR/unreachable.rs:28:18
    |
 LL | fn foo((Ok(_x) | Err(!)): Result<bool, Void>) {}
    |                  ^^^^^^ matches no values because `Void` is uninhabited
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
index be55ad51578be..4c51499676320 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
@@ -1,5 +1,6 @@
 //@ aux-build:uninhabited.rs
 //@ build-pass (FIXME(62277): could be check-pass?)
+#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 
 extern crate uninhabited;
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
index 1194d7b858d60..ca375e367bee7 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
@@ -1,3 +1,4 @@
+#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 #![feature(never_type)]
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
index 7e7dc802e7fbf..600670964e6a2 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
@@ -1,18 +1,18 @@
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:51:9
+  --> $DIR/patterns_same_crate.rs:52:9
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^ matches no values because `UninhabitedEnum` is uninhabited
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
-  --> $DIR/patterns_same_crate.rs:1:9
+  --> $DIR/patterns_same_crate.rs:2:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:56:9
+  --> $DIR/patterns_same_crate.rs:57:9
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
@@ -20,7 +20,7 @@ LL |         Some(_x) => (),
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:60:15
+  --> $DIR/patterns_same_crate.rs:61:15
    |
 LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
@@ -28,7 +28,7 @@ LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabite
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:64:15
+  --> $DIR/patterns_same_crate.rs:65:15
    |
 LL |     while let Some(_x) = uninhabited_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
@@ -36,7 +36,7 @@ LL |     while let Some(_x) = uninhabited_struct() {
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:67:15
+  --> $DIR/patterns_same_crate.rs:68:15
    |
 LL |     while let Some(_x) = uninhabited_tuple_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited
diff --git a/tests/ui/uninhabited/uninhabited-patterns.rs b/tests/ui/uninhabited/uninhabited-patterns.rs
index 988383e691b4e..b7429464fa5a0 100644
--- a/tests/ui/uninhabited/uninhabited-patterns.rs
+++ b/tests/ui/uninhabited/uninhabited-patterns.rs
@@ -1,3 +1,4 @@
+#![feature(exhaustive_patterns)]
 #![feature(box_patterns)]
 #![feature(never_type)]
 #![deny(unreachable_patterns)]
diff --git a/tests/ui/uninhabited/uninhabited-patterns.stderr b/tests/ui/uninhabited/uninhabited-patterns.stderr
index 0e1c9d31a731f..db0166ad5f2c5 100644
--- a/tests/ui/uninhabited/uninhabited-patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-patterns.stderr
@@ -1,18 +1,18 @@
 error: unreachable pattern
-  --> $DIR/uninhabited-patterns.rs:29:9
+  --> $DIR/uninhabited-patterns.rs:30:9
    |
 LL |         Ok(box _) => (),
    |         ^^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
-  --> $DIR/uninhabited-patterns.rs:3:9
+  --> $DIR/uninhabited-patterns.rs:4:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/uninhabited-patterns.rs:38:9
+  --> $DIR/uninhabited-patterns.rs:39:9
    |
 LL |         Err(Ok(_y)) => (),
    |         ^^^^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited
@@ -20,7 +20,7 @@ LL |         Err(Ok(_y)) => (),
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/uninhabited-patterns.rs:41:15
+  --> $DIR/uninhabited-patterns.rs:42:15
    |
 LL |     while let Some(_y) = foo() {
    |               ^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited

From 03faf4f9867bb943edaf6926d1a575f046407f62 Mon Sep 17 00:00:00 2001
From: Chris Denton <chris@chrisdenton.dev>
Date: Fri, 6 Sep 2024 21:21:49 +0000
Subject: [PATCH 2/7] Win: Add dbghelp to the list of import libraries

(cherry picked from commit 8966207afd038cbef4b951ce2a58351e2a66b8fe)
---
 library/windows_targets/src/lib.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index 1965b6cf4ce8f..395cd6a4bab55 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -38,4 +38,5 @@ pub macro link {
 #[link(name = "ntdll")]
 #[link(name = "userenv")]
 #[link(name = "ws2_32")]
+#[link(name = "dbghelp")] // required for backtrace-rs symbolization
 extern "C" {}

From e7246aefbefbcf16ae2828ecbaefcf5e8b725ae1 Mon Sep 17 00:00:00 2001
From: Deadbeef <ent3rm4n@gmail.com>
Date: Mon, 9 Sep 2024 18:36:21 +0800
Subject: [PATCH 3/7] `RepeatN`: use MaybeUninit

(cherry picked from commit 4c8b84ae82ce66ea62e323c8dff68475d5d375b3)
---
 library/core/src/iter/sources/repeat_n.rs | 60 +++++++++++++++++------
 library/core/tests/iter/sources.rs        | 24 +++++++++
 2 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
index 9c0621933638e..7e162ff387baf 100644
--- a/library/core/src/iter/sources/repeat_n.rs
+++ b/library/core/src/iter/sources/repeat_n.rs
@@ -1,5 +1,6 @@
+use crate::fmt;
 use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
-use crate::mem::ManuallyDrop;
+use crate::mem::{self, MaybeUninit};
 use crate::num::NonZero;
 
 /// Creates a new iterator that repeats a single element a given number of times.
@@ -58,14 +59,12 @@ use crate::num::NonZero;
 #[inline]
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
 pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
-    let mut element = ManuallyDrop::new(element);
-
-    if count == 0 {
-        // SAFETY: we definitely haven't dropped it yet, since we only just got
-        // passed it in, and because the count is zero the instance we're about
-        // to create won't drop it, so to avoid leaking we need to now.
-        unsafe { ManuallyDrop::drop(&mut element) };
-    }
+    let element = if count == 0 {
+        // `element` gets dropped eagerly.
+        MaybeUninit::uninit()
+    } else {
+        MaybeUninit::new(element)
+    };
 
     RepeatN { element, count }
 }
@@ -74,15 +73,23 @@ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
 ///
 /// This `struct` is created by the [`repeat_n()`] function.
 /// See its documentation for more.
-#[derive(Clone, Debug)]
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
 pub struct RepeatN<A> {
     count: usize,
-    // Invariant: has been dropped iff count == 0.
-    element: ManuallyDrop<A>,
+    // Invariant: uninit iff count == 0.
+    element: MaybeUninit<A>,
 }
 
 impl<A> RepeatN<A> {
+    /// Returns the element if it hasn't been dropped already.
+    fn element_ref(&self) -> Option<&A> {
+        if self.count > 0 {
+            // SAFETY: The count is non-zero, so it must be initialized.
+            Some(unsafe { self.element.assume_init_ref() })
+        } else {
+            None
+        }
+    }
     /// If we haven't already dropped the element, return it in an option.
     ///
     /// Clears the count so it won't be dropped again later.
@@ -90,15 +97,36 @@ impl<A> RepeatN<A> {
     fn take_element(&mut self) -> Option<A> {
         if self.count > 0 {
             self.count = 0;
+            let element = mem::replace(&mut self.element, MaybeUninit::uninit());
             // SAFETY: We just set count to zero so it won't be dropped again,
             // and it used to be non-zero so it hasn't already been dropped.
-            unsafe { Some(ManuallyDrop::take(&mut self.element)) }
+            unsafe { Some(element.assume_init()) }
         } else {
             None
         }
     }
 }
 
+#[stable(feature = "iter_repeat_n", since = "1.82.0")]
+impl<A: Clone> Clone for RepeatN<A> {
+    fn clone(&self) -> RepeatN<A> {
+        RepeatN {
+            count: self.count,
+            element: self.element_ref().cloned().map_or_else(MaybeUninit::uninit, MaybeUninit::new),
+        }
+    }
+}
+
+#[stable(feature = "iter_repeat_n", since = "1.82.0")]
+impl<A: fmt::Debug> fmt::Debug for RepeatN<A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("RepeatN")
+            .field("count", &self.count)
+            .field("element", &self.element_ref())
+            .finish()
+    }
+}
+
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
 impl<A> Drop for RepeatN<A> {
     fn drop(&mut self) {
@@ -194,9 +222,11 @@ impl<A: Clone> UncheckedIterator for RepeatN<A> {
             // SAFETY: the check above ensured that the count used to be non-zero,
             // so element hasn't been dropped yet, and we just lowered the count to
             // zero so it won't be dropped later, and thus it's okay to take it here.
-            unsafe { ManuallyDrop::take(&mut self.element) }
+            unsafe { mem::replace(&mut self.element, MaybeUninit::uninit()).assume_init() }
         } else {
-            A::clone(&self.element)
+            // SAFETY: the count is non-zero, so it must have not been dropped yet.
+            let element = unsafe { self.element.assume_init_ref() };
+            A::clone(element)
         }
     }
 }
diff --git a/library/core/tests/iter/sources.rs b/library/core/tests/iter/sources.rs
index eb8c80dd08724..506febaa056a8 100644
--- a/library/core/tests/iter/sources.rs
+++ b/library/core/tests/iter/sources.rs
@@ -156,3 +156,27 @@ fn test_repeat_n_drop() {
     drop((x0, x1, x2));
     assert_eq!(count.get(), 3);
 }
+
+#[test]
+fn test_repeat_n_soundness() {
+    let x = std::iter::repeat_n(String::from("use after free"), 0);
+    println!("{x:?}");
+
+    pub struct PanicOnClone;
+
+    impl Clone for PanicOnClone {
+        fn clone(&self) -> Self {
+            unreachable!()
+        }
+    }
+
+    // `repeat_n` should drop the element immediately if `count` is zero.
+    // `Clone` should then not try to clone the element.
+    let x = std::iter::repeat_n(PanicOnClone, 0);
+    let _ = x.clone();
+
+    let mut y = std::iter::repeat_n(Box::new(0), 1);
+    let x = y.next().unwrap();
+    let _z = y;
+    assert_eq!(0, *x);
+}

From f004b77fdedbc977919c42fb3719b8a1298c7242 Mon Sep 17 00:00:00 2001
From: DianQK <dianqk@dianqk.net>
Date: Wed, 11 Sep 2024 07:59:27 +0800
Subject: [PATCH 4/7] Update LLVM to 19 327ca6c

(cherry picked from commit 7c692e13b171c04b6bb6baa4d5aa138beecf8da8)
---
 src/llvm-project | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/llvm-project b/src/llvm-project
index 2b259b3c201f9..4b8d29c585687 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 2b259b3c201f939f2ed8d2fb0a0e9b37dd2d1321
+Subproject commit 4b8d29c585687084bbcf21471e04f279d1eddc0a

From 85f29bda083958dd02bcb54b06ccd4b35523a6ff Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@google.com>
Date: Mon, 16 Sep 2024 17:11:02 -0700
Subject: [PATCH 5/7] Revert "Rollup merge of #129749 - krasimirgg:llvm-20-lto,
 r=nikic"

This reverts commit 8c7a7e346be4cdf13e77ab4acbfb5ade819a4e60, reversing
changes made to a00bd75b6c5c96d0a35afa2dc07ce3155112d278.

(cherry picked from commit 472fef6a70d6621611a20f13f02c16be93589f5c)
---
 compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index da27db29c87ad..c7306b0516fa0 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1212,11 +1212,7 @@ struct LLVMRustThinLTOData {
   // Not 100% sure what these are, but they impact what's internalized and
   // what's inlined across modules, I believe.
 #if LLVM_VERSION_GE(18, 0)
-#if LLVM_VERSION_GE(20, 0)
-  FunctionImporter::ImportListsTy ImportLists;
-#else
   DenseMap<StringRef, FunctionImporter::ImportMapTy> ImportLists;
-#endif
   DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists;
   DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries;
 #else
@@ -1425,13 +1421,13 @@ LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data,
   return true;
 }
 
-extern "C" bool LLVMRustPrepareThinLTOImport(LLVMRustThinLTOData *Data,
+extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data,
                                              LLVMModuleRef M,
                                              LLVMTargetMachineRef TM) {
   Module &Mod = *unwrap(M);
   TargetMachine &Target = *unwrap(TM);
 
-  const auto &ImportList = Data->ImportLists[Mod.getModuleIdentifier()];
+  const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
   auto Loader = [&](StringRef Identifier) {
     const auto &Memory = Data->ModuleMap.lookup(Identifier);
     auto &Context = Mod.getContext();
@@ -1614,7 +1610,7 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
                                            LLVMRustThinLTOData *Data) {
   SmallString<40> Key;
   llvm::lto::Config conf;
-  const auto &ImportList = Data->ImportLists[ModId];
+  const auto &ImportList = Data->ImportLists.lookup(ModId);
   const auto &ExportList = Data->ExportLists.lookup(ModId);
   const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);

From 49891df793fcb048df16dcf62072807312bf34d3 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 18 Sep 2024 16:45:27 -0400
Subject: [PATCH 6/7] Check params for unsafety in THIR

(cherry picked from commit 12f2bcde63285bf2b2f9f9ac615d4edf139a3f0e)
---
 .../rustc_mir_build/src/check_unsafety.rs     | 14 ++++++++++++++
 tests/ui/unsafe/union-pat-in-param.rs         | 19 +++++++++++++++++++
 tests/ui/unsafe/union-pat-in-param.stderr     | 19 +++++++++++++++++++
 3 files changed, 52 insertions(+)
 create mode 100644 tests/ui/unsafe/union-pat-in-param.rs
 create mode 100644 tests/ui/unsafe/union-pat-in-param.stderr

diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 4ce796cea7ad3..e5ea147e81abb 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -218,6 +218,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
                 warnings: self.warnings,
                 suggest_unsafe_block: self.suggest_unsafe_block,
             };
+            // params in THIR may be unsafe, e.g. a union pattern.
+            for param in &inner_thir.params {
+                if let Some(param_pat) = param.pat.as_deref() {
+                    inner_visitor.visit_pat(param_pat);
+                }
+            }
+            // Visit the body.
             inner_visitor.visit_expr(&inner_thir[expr]);
             // Unsafe blocks can be used in the inner body, make sure to take it into account
             self.safety_context = inner_visitor.safety_context;
@@ -1066,6 +1073,13 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
         warnings: &mut warnings,
         suggest_unsafe_block: true,
     };
+    // params in THIR may be unsafe, e.g. a union pattern.
+    for param in &thir.params {
+        if let Some(param_pat) = param.pat.as_deref() {
+            visitor.visit_pat(param_pat);
+        }
+    }
+    // Visit the body.
     visitor.visit_expr(&thir[expr]);
 
     warnings.sort_by_key(|w| w.block_span);
diff --git a/tests/ui/unsafe/union-pat-in-param.rs b/tests/ui/unsafe/union-pat-in-param.rs
new file mode 100644
index 0000000000000..8454bfb20dcb8
--- /dev/null
+++ b/tests/ui/unsafe/union-pat-in-param.rs
@@ -0,0 +1,19 @@
+union U {
+    a: &'static i32,
+    b: usize,
+}
+
+fn fun(U { a }: U) {
+    //~^ ERROR access to union field is unsafe
+    dbg!(*a);
+}
+
+fn main() {
+    fun(U { b: 0 });
+
+    let closure = |U { a }| {
+        //~^ ERROR access to union field is unsafe
+        dbg!(*a);
+    };
+    closure(U { b: 0 });
+}
diff --git a/tests/ui/unsafe/union-pat-in-param.stderr b/tests/ui/unsafe/union-pat-in-param.stderr
new file mode 100644
index 0000000000000..b9709b7cc9bf1
--- /dev/null
+++ b/tests/ui/unsafe/union-pat-in-param.stderr
@@ -0,0 +1,19 @@
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-pat-in-param.rs:6:12
+   |
+LL | fn fun(U { a }: U) {
+   |            ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-pat-in-param.rs:14:24
+   |
+LL |     let closure = |U { a }| {
+   |                        ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.

From 4bf632f51e33071b397da8b858f87d9cfdb38606 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 20 Sep 2024 13:31:21 -0700
Subject: [PATCH 7/7] Limit `run-make` tests using `-Zbuild-std` to nightly

See https://github.com/rust-lang/rust/issues/130634
---
 tests/run-make/compiler-builtins/rmake.rs   | 1 +
 tests/run-make/thumb-none-cortex-m/rmake.rs | 1 +
 2 files changed, 2 insertions(+)

diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
index 42ed07d9dafae..6d3ed5c077ff9 100644
--- a/tests/run-make/compiler-builtins/rmake.rs
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -11,6 +11,7 @@
 // wasm and nvptx targets don't produce rlib files that object can parse.
 //@ ignore-wasm
 //@ ignore-nvptx64
+//@ only-nightly
 
 #![deny(warnings)]
 
diff --git a/tests/run-make/thumb-none-cortex-m/rmake.rs b/tests/run-make/thumb-none-cortex-m/rmake.rs
index 0ddb91d378fb7..5cacc4fe327dc 100644
--- a/tests/run-make/thumb-none-cortex-m/rmake.rs
+++ b/tests/run-make/thumb-none-cortex-m/rmake.rs
@@ -13,6 +13,7 @@
 //! - thumbv7m-none-eabi (Bare Cortex-M3)
 
 //@ only-thumb
+//@ only-nightly
 
 use std::path::PathBuf;