about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-11 23:23:25 +0000
committerbors <bors@rust-lang.org>2024-09-11 23:23:25 +0000
commit3afb2bb76ce56e860e45d8858ef5b5f00059e1b1 (patch)
tree317c9de7d672a4ead2cb76df76570854ccb0a957 /tests
parent8d6b88b168e45ee1624699c19443c49665322a91 (diff)
parentb4201d3f78f31146c53e8dbaefba9fdd79cdf6b6 (diff)
downloadrust-3afb2bb76ce56e860e45d8858ef5b5f00059e1b1.tar.gz
rust-3afb2bb76ce56e860e45d8858ef5b5f00059e1b1.zip
Auto merge of #130253 - workingjubilee:rollup-npqpnaf, r=workingjubilee
Rollup of 10 pull requests

Successful merges:

 - #129103 (Don't warn empty branches unreachable for now)
 - #129696 (update stdarch)
 - #129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - #130077 (Fix linking error when compiling for 32-bit watchOS)
 - #130114 (Remove needless returns detected by clippy in the compiler)
 - #130168 (maint: update docs for change_time ext and doc links)
 - #130228 (notify Miri when intrinsics are changed)
 - #130239 (miri: fix overflow detection for unsigned pointer offset)
 - #130244 (Use the same span for attributes and Try expansion of ?)
 - #130248 (Limit `libc::link` usage to `nto70` target only, not NTO OS)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/consts/const-float-bits-conv.rs161
-rw-r--r--tests/ui/consts/const-float-classify.rs76
-rw-r--r--tests/ui/consts/const-float-classify.stderr11
-rw-r--r--tests/ui/float/classify-runtime-const.rs82
-rw-r--r--tests/ui/float/conv-bits-runtime-const.rs168
-rw-r--r--tests/ui/numbers-arithmetic/issue-105626.rs1
-rw-r--r--tests/ui/pattern/usefulness/empty-types.never_pats.stderr188
-rw-r--r--tests/ui/pattern/usefulness/empty-types.normal.stderr188
-rw-r--r--tests/ui/pattern/usefulness/empty-types.rs46
-rw-r--r--tests/ui/pattern/usefulness/explain-unreachable-pats.rs1
-rw-r--r--tests/ui/pattern/usefulness/explain-unreachable-pats.stderr28
-rw-r--r--tests/ui/pattern/usefulness/impl-trait.rs1
-rw-r--r--tests/ui/pattern/usefulness/impl-trait.stderr32
-rw-r--r--tests/ui/reachable/unreachable-loop-patterns.rs1
-rw-r--r--tests/ui/reachable/unreachable-loop-patterns.stderr4
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs1
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/unreachable.stderr14
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs1
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr17
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs1
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr10
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs1
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr12
-rw-r--r--tests/ui/uninhabited/uninhabited-patterns.rs1
-rw-r--r--tests/ui/uninhabited/uninhabited-patterns.stderr8
25 files changed, 342 insertions, 712 deletions
diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs
deleted file mode 100644
index 869498d1076..00000000000
--- a/tests/ui/consts/const-float-bits-conv.rs
+++ /dev/null
@@ -1,161 +0,0 @@
-//@ compile-flags: -Zmir-opt-level=0
-//@ run-pass
-
-#![feature(const_float_classify)]
-#![feature(f16, f16_const)]
-#![feature(f128, f128_const)]
-#![allow(unused_macro_rules)]
-// Don't promote
-const fn nop<T>(x: T) -> T { x }
-
-macro_rules! const_assert {
-    ($a:expr) => {
-        {
-            const _: () = assert!($a);
-            assert!(nop($a));
-        }
-    };
-    ($a:expr, $b:expr) => {
-        {
-            const _: () = assert!($a == $b);
-            assert_eq!(nop($a), nop($b));
-        }
-    };
-}
-
-fn has_broken_floats() -> bool {
-    // i586 targets are broken due to <https://github.com/rust-lang/rust/issues/114479>.
-    std::env::var("TARGET").is_ok_and(|v| v.contains("i586"))
-}
-
-#[cfg(target_arch = "x86_64")]
-fn f16(){
-    const_assert!((1f16).to_bits(), 0x3c00);
-    const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
-    const_assert!((12.5f16).to_bits(), 0x4a40);
-    const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
-    const_assert!((1337f16).to_bits(), 0x6539);
-    const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
-    const_assert!((-14.25f16).to_bits(), 0xcb20);
-    const_assert!(f16::from_bits(0x3c00), 1.0);
-    const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
-    const_assert!(f16::from_bits(0x4a40), 12.5);
-    const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
-    const_assert!(f16::from_bits(0x5be0), 252.0);
-    const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
-    const_assert!(f16::from_bits(0xcb20), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signalingness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
-    const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
-    const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
-
-    const_assert!(f16::from_bits(QUIET_NAN).is_nan());
-    const_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
-    const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
-    if !has_broken_floats() {
-        const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
-    }
-}
-
-fn f32() {
-    const_assert!((1f32).to_bits(), 0x3f800000);
-    const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
-    const_assert!((12.5f32).to_bits(), 0x41480000);
-    const_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
-    const_assert!((1337f32).to_bits(), 0x44a72000);
-    const_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
-    const_assert!((-14.25f32).to_bits(), 0xc1640000);
-    const_assert!(f32::from_bits(0x3f800000), 1.0);
-    const_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
-    const_assert!(f32::from_bits(0x41480000), 12.5);
-    const_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
-    const_assert!(f32::from_bits(0x44a72000), 1337.0);
-    const_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
-    const_assert!(f32::from_bits(0xc1640000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signalingness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
-    const QUIET_NAN: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
-    const SIGNALING_NAN: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
-
-    const_assert!(f32::from_bits(QUIET_NAN).is_nan());
-    const_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
-    const_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
-    if !has_broken_floats() {
-        const_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
-    }
-}
-
-fn f64() {
-    const_assert!((1f64).to_bits(), 0x3ff0000000000000);
-    const_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
-    const_assert!((12.5f64).to_bits(), 0x4029000000000000);
-    const_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
-    const_assert!((1337f64).to_bits(), 0x4094e40000000000);
-    const_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
-    const_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
-    const_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
-    const_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
-    const_assert!(f64::from_bits(0x4029000000000000), 12.5);
-    const_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
-    const_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
-    const_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
-    const_assert!(f64::from_bits(0xc02c800000000000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signalingness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
-    const QUIET_NAN: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
-    const SIGNALING_NAN: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
-
-    const_assert!(f64::from_bits(QUIET_NAN).is_nan());
-    const_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
-    const_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
-    if !has_broken_floats() {
-        const_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
-    }
-}
-
-#[cfg(target_arch = "x86_64")]
-fn f128() {
-    const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
-    const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
-    const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
-    const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
-    const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
-    const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
-    const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
-    const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
-    const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
-    const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
-    const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
-    const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
-    assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
-    const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signalingness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
-    const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
-    const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
-
-    const_assert!(f128::from_bits(QUIET_NAN).is_nan());
-    const_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
-    const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
-    if !has_broken_floats() {
-        const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
-    }
-}
-
-fn main() {
-    #[cfg(target_arch = "x86_64")]
-    {
-        f16();
-        f128();
-    }
-    f32();
-    f64();
-}
diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs
deleted file mode 100644
index 6e5097f7f2b..00000000000
--- a/tests/ui/consts/const-float-classify.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-//@ compile-flags: -Zmir-opt-level=0 -Znext-solver
-//@ known-bug: #110395
-// FIXME(effects) run-pass
-
-#![feature(const_float_classify)]
-#![feature(const_trait_impl, effects)]
-#![allow(incomplete_features)]
-
-// Don't promote
-const fn nop<T>(x: T) -> T { x }
-
-impl const PartialEq<NonDet> for bool {
-    fn eq(&self, _: &NonDet) -> bool {
-        true
-    }
-}
-
-macro_rules! const_assert {
-    ($a:expr, $b:expr) => {
-        {
-            const _: () = assert!($a == $b);
-            assert!(nop($a) == nop($b));
-        }
-    };
-}
-
-macro_rules! suite {
-    ( $( $tt:tt )* ) => {
-        fn f32() {
-            suite_inner!(f32 $($tt)*);
-        }
-
-        fn f64() {
-            suite_inner!(f64 $($tt)*);
-        }
-    }
-
-}
-
-macro_rules! suite_inner {
-    (
-        $ty:ident [$( $fn:ident ),*]
-        $val:expr => [$($out:ident),*]
-
-        $( $tail:tt )*
-    ) => {
-        $( const_assert!($ty::$fn($val), $out); )*
-        suite_inner!($ty [$($fn),*] $($tail)*)
-    };
-
-    ( $ty:ident [$( $fn:ident ),*]) => {};
-}
-
-#[derive(Debug)]
-struct NonDet;
-
-// The result of the `is_sign` methods are not checked for correctness, since LLVM does not
-// guarantee anything about the signedness of NaNs. See
-// https://github.com/rust-lang/rust/issues/55131.
-
-suite! {
-                   [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
-     -0.0 / 0.0 => [  true,       false,     false,     false,           NonDet,           NonDet]
-      0.0 / 0.0 => [  true,       false,     false,     false,           NonDet,           NonDet]
-            1.0 => [ false,       false,      true,      true,             true,            false]
-           -1.0 => [ false,       false,      true,      true,            false,             true]
-            0.0 => [ false,       false,      true,     false,             true,            false]
-           -0.0 => [ false,       false,      true,     false,            false,             true]
-      1.0 / 0.0 => [ false,        true,     false,     false,             true,            false]
-     -1.0 / 0.0 => [ false,        true,     false,     false,            false,             true]
-}
-
-fn main() {
-    f32();
-    f64();
-}
diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr
deleted file mode 100644
index a35de8ad0ea..00000000000
--- a/tests/ui/consts/const-float-classify.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/const-float-classify.rs:12:12
-   |
-LL | impl const PartialEq<NonDet> for bool {
-   |            ^^^^^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/float/classify-runtime-const.rs b/tests/ui/float/classify-runtime-const.rs
new file mode 100644
index 00000000000..59a232c255e
--- /dev/null
+++ b/tests/ui/float/classify-runtime-const.rs
@@ -0,0 +1,82 @@
+//@ compile-flags: -Zmir-opt-level=0 -Znext-solver
+//@ run-pass
+// ignore-tidy-linelength
+
+// This tests the float classification functions, for regular runtime code and for const evaluation.
+
+#![feature(f16_const)]
+#![feature(f128_const)]
+#![feature(const_float_classify)]
+
+use std::hint::black_box;
+use std::num::FpCategory::*;
+
+macro_rules! both_assert {
+    ($a:expr, NonDet) => {
+        {
+            // Compute `a`, but do not compare with anything as the result is non-deterministic.
+            const _: () = { let _val = $a; };
+            // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
+            // going through LLVM.
+            let _val = black_box($a);
+        }
+    };
+    ($a:expr, $b:ident) => {
+        {
+            const _: () = assert!(matches!($a, $b));
+            assert!(black_box($a) == black_box($b));
+        }
+    };
+}
+
+macro_rules! suite {
+    ( $tyname:ident: $( $tt:tt )* ) => {
+        fn f32() {
+            type $tyname = f32;
+            suite_inner!(f32 $($tt)*);
+        }
+
+        fn f64() {
+            type $tyname = f64;
+            suite_inner!(f64 $($tt)*);
+        }
+    }
+}
+
+macro_rules! suite_inner {
+    (
+        $ty:ident [$( $fn:ident ),*]
+        $val:expr => [$($out:ident),*]
+
+        $( $tail:tt )*
+    ) => {
+        $( both_assert!($ty::$fn($val), $out); )*
+        suite_inner!($ty [$($fn),*] $($tail)*)
+    };
+
+    ( $ty:ident [$( $fn:ident ),*]) => {};
+}
+
+// The result of the `is_sign` methods are not checked for correctness, since we do not
+// guarantee anything about the signedness of NaNs. See
+// https://rust-lang.github.io/rfcs/3514-float-semantics.html.
+
+suite! { T: // type alias for the type we are testing
+                   [ classify, is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative]
+     -0.0 / 0.0 => [      Nan,   true,       false,     false,     false,           NonDet,           NonDet]
+      0.0 / 0.0 => [      Nan,   true,       false,     false,     false,           NonDet,           NonDet]
+            1.0 => [   Normal,  false,       false,      true,      true,             true,            false]
+           -1.0 => [   Normal,  false,       false,      true,      true,            false,             true]
+            0.0 => [     Zero,  false,       false,      true,     false,             true,            false]
+           -0.0 => [     Zero,  false,       false,      true,     false,            false,             true]
+      1.0 / 0.0 => [ Infinite,  false,        true,     false,     false,             true,            false]
+     -1.0 / 0.0 => [ Infinite,  false,        true,     false,     false,            false,             true]
+   1.0 / T::MAX => [Subnormal,  false,       false,      true,     false,             true,            false]
+  -1.0 / T::MAX => [Subnormal,  false,       false,      true,     false,            false,             true]
+}
+
+fn main() {
+    f32();
+    f64();
+    // FIXME(f16_f128): also test f16 and f128
+}
diff --git a/tests/ui/float/conv-bits-runtime-const.rs b/tests/ui/float/conv-bits-runtime-const.rs
new file mode 100644
index 00000000000..e85a889d2c2
--- /dev/null
+++ b/tests/ui/float/conv-bits-runtime-const.rs
@@ -0,0 +1,168 @@
+//@ compile-flags: -Zmir-opt-level=0
+//@ run-pass
+
+// This tests the float classification functions, for regular runtime code and for const evaluation.
+
+#![feature(const_float_classify)]
+#![feature(f16)]
+#![feature(f128)]
+#![feature(f16_const)]
+#![feature(f128_const)]
+#![allow(unused_macro_rules)]
+
+use std::hint::black_box;
+
+macro_rules! both_assert {
+    ($a:expr) => {
+        {
+            const _: () = assert!($a);
+            // `black_box` prevents promotion, and MIR opts are disabled above, so this is truly
+            // going through LLVM.
+            assert!(black_box($a));
+        }
+    };
+    ($a:expr, $b:expr) => {
+        {
+            const _: () = assert!($a == $b);
+            assert_eq!(black_box($a), black_box($b));
+        }
+    };
+}
+
+fn has_broken_floats() -> bool {
+    // i586 targets are broken due to <https://github.com/rust-lang/rust/issues/114479>.
+    cfg!(all(target_arch = "x86", not(target_feature = "sse2")))
+}
+
+#[cfg(target_arch = "x86_64")]
+fn f16(){
+    both_assert!((1f16).to_bits(), 0x3c00);
+    both_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
+    both_assert!((12.5f16).to_bits(), 0x4a40);
+    both_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
+    both_assert!((1337f16).to_bits(), 0x6539);
+    both_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
+    both_assert!((-14.25f16).to_bits(), 0xcb20);
+    both_assert!(f16::from_bits(0x3c00), 1.0);
+    both_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
+    both_assert!(f16::from_bits(0x4a40), 12.5);
+    both_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
+    both_assert!(f16::from_bits(0x5be0), 252.0);
+    both_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
+    both_assert!(f16::from_bits(0xcb20), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
+    const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
+
+    both_assert!(f16::from_bits(QUIET_NAN).is_nan());
+    both_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
+    both_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        both_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
+fn f32() {
+    both_assert!((1f32).to_bits(), 0x3f800000);
+    both_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
+    both_assert!((12.5f32).to_bits(), 0x41480000);
+    both_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000);
+    both_assert!((1337f32).to_bits(), 0x44a72000);
+    both_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000);
+    both_assert!((-14.25f32).to_bits(), 0xc1640000);
+    both_assert!(f32::from_bits(0x3f800000), 1.0);
+    both_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0);
+    both_assert!(f32::from_bits(0x41480000), 12.5);
+    both_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5);
+    both_assert!(f32::from_bits(0x44a72000), 1337.0);
+    both_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0);
+    both_assert!(f32::from_bits(0xc1640000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
+    const SIGNALING_NAN: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
+
+    both_assert!(f32::from_bits(QUIET_NAN).is_nan());
+    both_assert!(f32::from_bits(SIGNALING_NAN).is_nan());
+    both_assert!(f32::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        both_assert!(f32::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
+fn f64() {
+    both_assert!((1f64).to_bits(), 0x3ff0000000000000);
+    both_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000);
+    both_assert!((12.5f64).to_bits(), 0x4029000000000000);
+    both_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000);
+    both_assert!((1337f64).to_bits(), 0x4094e40000000000);
+    both_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000);
+    both_assert!((-14.25f64).to_bits(), 0xc02c800000000000);
+    both_assert!(f64::from_bits(0x3ff0000000000000), 1.0);
+    both_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0);
+    both_assert!(f64::from_bits(0x4029000000000000), 12.5);
+    both_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5);
+    both_assert!(f64::from_bits(0x4094e40000000000), 1337.0);
+    both_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0);
+    both_assert!(f64::from_bits(0xc02c800000000000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
+    const SIGNALING_NAN: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
+
+    both_assert!(f64::from_bits(QUIET_NAN).is_nan());
+    both_assert!(f64::from_bits(SIGNALING_NAN).is_nan());
+    both_assert!(f64::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        both_assert!(f64::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
+#[cfg(target_arch = "x86_64")]
+fn f128() {
+    both_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
+    both_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
+    both_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
+    both_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
+    both_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
+    both_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
+    both_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
+    both_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
+    both_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
+    both_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
+    both_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
+    both_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
+    assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
+    both_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
+    const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
+
+    both_assert!(f128::from_bits(QUIET_NAN).is_nan());
+    both_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
+    both_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        both_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
+fn main() {
+    f32();
+    f64();
+
+    #[cfg(target_arch = "x86_64")]
+    {
+        f16();
+        f128();
+    }
+}
diff --git a/tests/ui/numbers-arithmetic/issue-105626.rs b/tests/ui/numbers-arithmetic/issue-105626.rs
index f942cf1283d..8d4a7c308e7 100644
--- a/tests/ui/numbers-arithmetic/issue-105626.rs
+++ b/tests/ui/numbers-arithmetic/issue-105626.rs
@@ -11,6 +11,7 @@ fn main() {
     assert_ne!((n as f64) as f32, n as f32);
 
     // FIXME: these assertions fail if only x87 is enabled
+    // see also https://github.com/rust-lang/rust/issues/114479
     assert_eq!(n as i64 as f32, r);
     assert_eq!(n as u64 as f32, r);
 }
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 68213a2d661..fe9c4319820 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -44,30 +44,6 @@ 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
    |
 LL |         _ => {}
@@ -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
    |
@@ -157,54 +117,6 @@ 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
    |
 LL |             _ => {}
@@ -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 8f60dad4467..201b0b5c3fd 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -35,30 +35,6 @@ 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
    |
 LL |         _ => {}
@@ -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
    |
@@ -148,54 +108,6 @@ 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
    |
 LL |             _ => {}
@@ -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 d561a0e9c12..9e5f273a390 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 1cfa5212414..f1af7f294cb 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 7023c2775e9..67f83a85175 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 c1cc279f74c..16560a09267 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 34b157f0fc4..f2945fca82b 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 d074e3a6ece..9be37ecf2bb 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 03959ac1606..290f45700b2 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 f68da4aa173..6d7815f7a9e 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 6b3f303eeab..90874760a56 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/issue-65157-repeated-match-arm.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
index 6bee019e897..ca7c5287154 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
@@ -12,7 +12,6 @@ use uninhabited::PartiallyInhabitedVariants;
 pub fn foo(x: PartiallyInhabitedVariants) {
     match x {
         PartiallyInhabitedVariants::Struct { .. } => {}
-        //~^ ERROR unreachable pattern
         PartiallyInhabitedVariants::Struct { .. } => {}
         //~^ ERROR unreachable pattern
         _ => {}
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
index 4fa53101a55..86df9ef9b56 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
@@ -1,23 +1,16 @@
 error: unreachable pattern
-  --> $DIR/issue-65157-repeated-match-arm.rs:14:9
+  --> $DIR/issue-65157-repeated-match-arm.rs:15:9
    |
 LL |         PartiallyInhabitedVariants::Struct { .. } => {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
+   |         ----------------------------------------- matches all the relevant values
+LL |         PartiallyInhabitedVariants::Struct { .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
    |
-   = 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/issue-65157-repeated-match-arm.rs:2:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: unreachable pattern
-  --> $DIR/issue-65157-repeated-match-arm.rs:16:9
-   |
-LL |         PartiallyInhabitedVariants::Struct { .. } => {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
-   |
-   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
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 edc588777eb..088331b0e7f 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
@@ -1,4 +1,5 @@
 //@ aux-build:uninhabited.rs
+#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 
 extern crate uninhabited;
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr
index deaa2ffd927..83300049ea9 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr
@@ -1,18 +1,18 @@
 error: unreachable pattern
-  --> $DIR/patterns.rs:41:9
+  --> $DIR/patterns.rs:42:9
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^ matches no values because `UninhabitedVariants` 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.rs:2:9
+  --> $DIR/patterns.rs:3:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/patterns.rs:46:15
+  --> $DIR/patterns.rs:47:15
    |
 LL |     while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
@@ -20,7 +20,7 @@ LL |     while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inha
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns.rs:48:15
+  --> $DIR/patterns.rs:49:15
    |
 LL |     while let Some(_x) = uninhabited_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
@@ -28,7 +28,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.rs:51:15
+  --> $DIR/patterns.rs:52:15
    |
 LL |     while let Some(_x) = uninhabited_tuple_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is 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 58cced3d23d..3d89ca15d37 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 38524bf5b95..4b107b03645 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:52:9
+  --> $DIR/patterns_same_crate.rs:53: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:57:9
+  --> $DIR/patterns_same_crate.rs:58: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:61:15
+  --> $DIR/patterns_same_crate.rs:62: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:65:15
+  --> $DIR/patterns_same_crate.rs:66: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:68:15
+  --> $DIR/patterns_same_crate.rs:69: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 988383e691b..b7429464fa5 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 0e1c9d31a73..db0166ad5f2 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