about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/assembly/simd-intrinsic-mask-load.rs1
-rw-r--r--tests/assembly/simd-intrinsic-mask-store.rs1
-rw-r--r--tests/codegen/avr/avr-func-addrspace.rs1
-rw-r--r--tests/codegen/cast-optimized.rs35
-rw-r--r--tests/codegen/clone-shims.rs15
-rw-r--r--tests/codegen/emcripten-catch-unwind.rs2
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs1
-rw-r--r--tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs1
-rw-r--r--tests/codegen/try_identity.rs34
-rw-r--r--tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff59
-rw-r--r--tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff59
-rw-r--r--tests/mir-opt/jump_threading.rs12
-rw-r--r--tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff89
-rw-r--r--tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff89
-rw-r--r--tests/mir-opt/simplify_arm.rs50
-rw-r--r--tests/mir-opt/simplify_arm_identity.rs26
-rw-r--r--tests/mir-opt/simplify_try_if_let.rs44
-rw-r--r--tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff104
-rw-r--r--tests/run-make/README.md5
-rw-r--r--tests/run-make/c-unwind-abi-catch-lib-panic/Makefile35
-rw-r--r--tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs36
-rw-r--r--tests/run-make/compiler-rt-works-on-mingw/Makefile9
-rw-r--r--tests/run-make/compiler-rt-works-on-mingw/rmake.rs15
-rw-r--r--tests/run-make/dump-ice-to-disk/Makefile10
-rw-r--r--tests/run-make/dump-ice-to-disk/check.sh64
-rw-r--r--tests/run-make/dump-ice-to-disk/lib.rs (renamed from tests/run-make/dump-ice-to-disk/src/lib.rs)0
-rw-r--r--tests/run-make/dump-ice-to-disk/rmake.rs81
-rw-r--r--tests/run-make/export-executable-symbols/Makefile11
-rw-r--r--tests/run-make/export-executable-symbols/rmake.rs25
-rw-r--r--tests/run-make/extern-flag-disambiguates/Makefile26
-rw-r--r--tests/run-make/extern-flag-disambiguates/rmake.rs30
-rw-r--r--tests/run-make/foreign-rust-exceptions/Makefile13
-rw-r--r--tests/run-make/foreign-rust-exceptions/rmake.rs23
-rw-r--r--tests/run-make/incr-foreign-head-span/Makefile21
-rw-r--r--tests/run-make/incr-foreign-head-span/rmake.rs25
-rw-r--r--tests/run-make/interdependent-c-libraries/Makefile15
-rw-r--r--tests/run-make/interdependent-c-libraries/rmake.rs21
-rw-r--r--tests/run-make/panic-abort-eh_frame/Makefile10
-rw-r--r--tests/run-make/panic-abort-eh_frame/rmake.rs24
-rw-r--r--tests/run-make/sanitizer-cdylib-link/Makefile16
-rw-r--r--tests/run-make/sanitizer-cdylib-link/rmake.rs17
-rw-r--r--tests/run-make/sanitizer-dylib-link/Makefile16
-rw-r--r--tests/run-make/sanitizer-dylib-link/rmake.rs16
-rw-r--r--tests/run-make/sanitizer-staticlib-link/Makefile20
-rw-r--r--tests/run-make/sanitizer-staticlib-link/rmake.rs26
-rw-r--r--tests/run-make/static-dylib-by-default/Makefile17
-rw-r--r--tests/run-make/static-dylib-by-default/rmake.rs35
-rw-r--r--tests/rustdoc-gui/copy-code.goml54
-rw-r--r--tests/rustdoc-gui/run-on-hover.goml8
-rw-r--r--tests/rustdoc-gui/search-title.goml24
-rw-r--r--tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs2
-rw-r--r--tests/ui/asm/aarch64/bad-options.rs12
-rw-r--r--tests/ui/asm/aarch64/bad-options.stderr24
-rw-r--r--tests/ui/asm/aarch64/parse-error.rs2
-rw-r--r--tests/ui/asm/aarch64/parse-error.stderr48
-rw-r--r--tests/ui/asm/naked-functions-inline.rs38
-rw-r--r--tests/ui/asm/naked-functions-inline.stderr35
-rw-r--r--tests/ui/asm/naked-functions-instruction-set.rs30
-rw-r--r--tests/ui/asm/naked-functions-testattrs.rs39
-rw-r--r--tests/ui/asm/naked-functions-testattrs.stderr35
-rw-r--r--tests/ui/asm/naked-functions.rs98
-rw-r--r--tests/ui/asm/naked-functions.stderr44
-rw-r--r--tests/ui/asm/parse-error.rs10
-rw-r--r--tests/ui/asm/parse-error.stderr58
-rw-r--r--tests/ui/asm/unsupported-option.fixed11
-rw-r--r--tests/ui/asm/unsupported-option.rs11
-rw-r--r--tests/ui/asm/unsupported-option.stderr20
-rw-r--r--tests/ui/asm/x86_64/bad-options.rs12
-rw-r--r--tests/ui/asm/x86_64/bad-options.stderr24
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs20
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds.rs29
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds.stderr16
-rw-r--r--tests/ui/associated-type-bounds/type-alias.stderr204
-rw-r--r--tests/ui/associated-types/associated-types-outlives.stderr10
-rw-r--r--tests/ui/async-await/async-closures/clone-closure.rs24
-rw-r--r--tests/ui/async-await/async-closures/clone-closure.run.stdout2
-rw-r--r--tests/ui/async-await/async-closures/move-consuming-capture.stderr9
-rw-r--r--tests/ui/async-await/async-closures/not-clone-closure.rs36
-rw-r--r--tests/ui/async-await/async-closures/not-clone-closure.stderr20
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs2
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr63
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs71
-rw-r--r--tests/ui/consts/const-eval/parse_ints.rs2
-rw-r--r--tests/ui/consts/const-eval/parse_ints.stderr4
-rw-r--r--tests/ui/consts/packed_pattern.stderr4
-rw-r--r--tests/ui/consts/packed_pattern2.stderr4
-rw-r--r--tests/ui/error-codes/E0001.stderr11
-rw-r--r--tests/ui/feature-gates/feature-gate-is_sorted.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-is_sorted.stderr43
-rw-r--r--tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs24
-rw-r--r--tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr71
-rw-r--r--tests/ui/lang-items/missing-clone-for-suggestion.rs20
-rw-r--r--tests/ui/lang-items/missing-clone-for-suggestion.stderr21
-rw-r--r--tests/ui/lint/dead-code/unused-impl-for-non-adts.rs45
-rw-r--r--tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr20
-rw-r--r--tests/ui/macros/issue-118786.rs1
-rw-r--r--tests/ui/macros/issue-118786.stderr6
-rw-r--r--tests/ui/macros/macro-missing-fragment.e2015.stderr (renamed from tests/ui/macros/macro-missing-fragment.stderr)22
-rw-r--r--tests/ui/macros/macro-missing-fragment.e2024.stderr47
-rw-r--r--tests/ui/macros/macro-missing-fragment.rs23
-rw-r--r--tests/ui/maybe-bounds.stderr15
-rw-r--r--tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs5
-rw-r--r--tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr270
-rw-r--r--tests/ui/parser/issues/issue-19398.rs6
-rw-r--r--tests/ui/parser/issues/issue-19398.stderr14
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs16
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr13
-rw-r--r--tests/ui/parser/trait-object-trait-parens.stderr18
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.stderr20
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr17
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr17
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.rs4
-rw-r--r--tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr87
-rw-r--r--tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr87
-rw-r--r--tests/ui/pattern/usefulness/empty-types.never_pats.stderr33
-rw-r--r--tests/ui/pattern/usefulness/empty-types.normal.stderr33
-rw-r--r--tests/ui/pattern/usefulness/explain-unreachable-pats.rs101
-rw-r--r--tests/ui/pattern/usefulness/explain-unreachable-pats.stderr104
-rw-r--r--tests/ui/pattern/usefulness/floats.stderr68
-rw-r--r--tests/ui/pattern/usefulness/impl-trait.stderr27
-rw-r--r--tests/ui/pattern/usefulness/integer-ranges/reachability.stderr155
-rw-r--r--tests/ui/pattern/usefulness/issue-12116.stderr4
-rw-r--r--tests/ui/pattern/usefulness/issue-12369.stderr11
-rw-r--r--tests/ui/pattern/usefulness/issue-13727.stderr4
-rw-r--r--tests/ui/pattern/usefulness/issue-30240-b.stderr4
-rw-r--r--tests/ui/pattern/usefulness/issue-31221.stderr12
-rw-r--r--tests/ui/pattern/usefulness/issue-57472.stderr8
-rw-r--r--tests/ui/pattern/usefulness/match-arm-statics.stderr24
-rw-r--r--tests/ui/pattern/usefulness/match-byte-array-patterns.stderr32
-rw-r--r--tests/ui/pattern/usefulness/match-ref-ice.stderr4
-rw-r--r--tests/ui/pattern/usefulness/match-vec-fixed.stderr8
-rw-r--r--tests/ui/pattern/usefulness/match-vec-unreachable.stderr12
-rw-r--r--tests/ui/pattern/usefulness/slice-pattern-const-2.stderr17
-rw-r--r--tests/ui/pattern/usefulness/slice-pattern-const-3.stderr17
-rw-r--r--tests/ui/pattern/usefulness/slice-pattern-const.stderr39
-rw-r--r--tests/ui/pattern/usefulness/slice-patterns-reachability.stderr27
-rw-r--r--tests/ui/pattern/usefulness/top-level-alternation.stderr53
-rw-r--r--tests/ui/privacy/private-in-public-warn.rs4
-rw-r--r--tests/ui/privacy/private-in-public-warn.stderr34
-rw-r--r--tests/ui/reachable/unreachable-arm.stderr4
-rw-r--r--tests/ui/reachable/unreachable-loop-patterns.stderr1
-rw-r--r--tests/ui/reachable/unreachable-try-pattern.stderr3
-rw-r--r--tests/ui/resolve/issue-118295.rs6
-rw-r--r--tests/ui/resolve/issue-118295.stderr18
-rw-r--r--tests/ui/resolve/issue-55673.stderr2
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr1
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr9
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs4
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr14
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr4
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs17
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed21
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr16
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs21
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed21
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr16
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs21
-rw-r--r--tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs15
-rw-r--r--tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs17
-rw-r--r--tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr17
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed29
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr16
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-adt.rs29
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs24
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed23
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr16
-rw-r--r--tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs23
-rw-r--r--tests/ui/traits/maybe-polarity-pass.rs27
-rw-r--r--tests/ui/traits/maybe-polarity-pass.stderr20
-rw-r--r--tests/ui/traits/maybe-polarity-repeated.rs9
-rw-r--r--tests/ui/traits/maybe-polarity-repeated.stderr21
-rw-r--r--tests/ui/traits/wf-object/maybe-bound.stderr26
-rw-r--r--tests/ui/traits/wf-object/only-maybe-bound.stderr8
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr17
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr36
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr40
-rw-r--r--tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs26
-rw-r--r--tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs2
-rw-r--r--tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr15
-rw-r--r--tests/ui/type/type-alias-bounds.rs21
-rw-r--r--tests/ui/type/type-alias-bounds.stderr163
-rw-r--r--tests/ui/uninhabited/uninhabited-patterns.stderr5
-rw-r--r--tests/ui/unsized/maybe-bounds-where.stderr31
-rw-r--r--tests/ui/variance/variance-issue-20533.stderr10
187 files changed, 3666 insertions, 1487 deletions
diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs
index d537c143d36..b650e1cee30 100644
--- a/tests/assembly/simd-intrinsic-mask-load.rs
+++ b/tests/assembly/simd-intrinsic-mask-load.rs
@@ -18,6 +18,7 @@ pub trait Sized {}
 
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for *const T {}
 
 #[repr(simd)]
 pub struct i8x16([i8; 16]);
diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs
index 5d4c00c3823..95a3b28b967 100644
--- a/tests/assembly/simd-intrinsic-mask-store.rs
+++ b/tests/assembly/simd-intrinsic-mask-store.rs
@@ -18,6 +18,7 @@ pub trait Sized {}
 
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for *mut T {}
 
 #[repr(simd)]
 pub struct i8x16([i8; 16]);
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index 70834707564..7f9a7e6e811 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -17,6 +17,7 @@
 pub trait Sized {}
 #[lang = "copy"]
 pub trait Copy {}
+impl<T: ?Sized> Copy for *const T {}
 #[lang = "receiver"]
 pub trait Receiver {}
 #[lang = "tuple_trait"]
diff --git a/tests/codegen/cast-optimized.rs b/tests/codegen/cast-optimized.rs
new file mode 100644
index 00000000000..313b2b4f0d6
--- /dev/null
+++ b/tests/codegen/cast-optimized.rs
@@ -0,0 +1,35 @@
+//@ compile-flags: -O -Z merge-functions=disabled
+#![crate_type = "lib"]
+
+// This tests that LLVM can optimize based on the niches in the source or
+// destination types for casts.
+
+// CHECK-LABEL: @u32_index
+#[no_mangle]
+pub fn u32_index(c: u32) -> [bool; 22] {
+    let mut array = [false; 22];
+
+    let index = 32 - c.leading_zeros();
+
+    // CHECK: call core::panicking::panic
+    array[index as usize] = true;
+
+    array
+}
+
+// CHECK-LABEL: @char_as_u32_index
+#[no_mangle]
+pub fn char_as_u32_index(c: char) -> [bool; 22] {
+    // CHECK: %[[B:.+]] = icmp ult i32 %c, 1114112
+    // CHECK: call void @llvm.assume(i1 %[[B]])
+    let c = c as u32;
+
+    let mut array = [false; 22];
+
+    let index = 32 - c.leading_zeros();
+
+    // CHECK-NOT: call core::panicking::panic
+    array[index as usize] = true;
+
+    array
+}
diff --git a/tests/codegen/clone-shims.rs b/tests/codegen/clone-shims.rs
new file mode 100644
index 00000000000..06c959f9ee7
--- /dev/null
+++ b/tests/codegen/clone-shims.rs
@@ -0,0 +1,15 @@
+// Clone shims for aggregates are generated by just calling the Clone shims for all their members.
+// Those calls generate a lot of unnecessary IR if the members are Copy. This test ensures that we
+// optimize away those inner calls without needing to inline them.
+
+//@ compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 -Zinline-mir=no
+#![crate_type = "lib"]
+
+pub type Test = (i32, i32, *const i32);
+pub static TEST: fn(&Test) -> Test = <Test as core::clone::Clone>::clone;
+
+// CHECK-NOT: call <i32 as core::clone::Clone>::clone
+// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone
+// CHECK:     ; <(i32, i32, *const i32) as core::clone::Clone>::clone
+// CHECK-NOT: call <i32 as core::clone::Clone>::clone
+// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone
diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs
index 6cda8c6799f..35444db9558 100644
--- a/tests/codegen/emcripten-catch-unwind.rs
+++ b/tests/codegen/emcripten-catch-unwind.rs
@@ -16,6 +16,8 @@ trait Freeze {}
 #[lang = "copy"]
 trait Copy {}
 
+impl<T> Copy for *mut T {}
+
 #[rustc_intrinsic]
 fn size_of<T>() -> usize {
     loop {}
diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
index ed0af90aaaf..520192b5d59 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
@@ -18,6 +18,7 @@ impl Copy for i64 {}
 impl Copy for u64 {}
 impl Copy for f32 {}
 impl Copy for f64 {}
+impl<T> Copy for *mut T {}
 
 // CHECK: define void @f_void()
 #[no_mangle]
diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
index fc4d570dc2e..c1967e55e75 100644
--- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
+++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs
@@ -15,6 +15,7 @@
 trait Sized {}
 #[lang = "copy"]
 trait Copy {}
+impl<T: ?Sized> Copy for &T {}
 #[lang = "receiver"]
 trait Receiver {}
 #[lang = "dispatch_from_dyn"]
diff --git a/tests/codegen/try_identity.rs b/tests/codegen/try_identity.rs
deleted file mode 100644
index 6a3a8a06e82..00000000000
--- a/tests/codegen/try_identity.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//@ compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=3 -Zunsound-mir-opts
-
-// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
-// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
-
-#![crate_type = "lib"]
-
-type R = Result<u64, i32>;
-
-// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
-// so the relevant desugar is copied inline in order to keep the test testing the same thing.
-// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
-// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
-#[no_mangle]
-pub fn try_identity(x: R) -> R {
-    // CHECK: start:
-    // FIXME(JakobDegen): Broken by deaggregation change CHECK-NOT\: br {{.*}}
-    // CHECK ret void
-    let y = match into_result(x) {
-        Err(e) => return from_error(From::from(e)),
-        Ok(v) => v,
-    };
-    Ok(y)
-}
-
-#[inline]
-fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
-    r
-}
-
-#[inline]
-fn from_error<T, E>(e: E) -> Result<T, E> {
-    Err(e)
-}
diff --git a/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff
new file mode 100644
index 00000000000..6ca37e96d29
--- /dev/null
+++ b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff
@@ -0,0 +1,59 @@
+- // MIR for `floats` before JumpThreading
++ // MIR for `floats` after JumpThreading
+  
+  fn floats() -> u32 {
+      let mut _0: u32;
+      let _1: f64;
+      let mut _2: bool;
+      let mut _3: bool;
+      let mut _4: f64;
+      scope 1 {
+          debug x => _1;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = const true;
+-         switchInt(move _2) -> [0: bb2, otherwise: bb1];
++         goto -> bb1;
+      }
+  
+      bb1: {
+          _1 = const -0f64;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _1 = const 1f64;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = _1;
+          _3 = Eq(move _4, const 0f64);
+          switchInt(move _3) -> [0: bb5, otherwise: bb4];
+      }
+  
+      bb4: {
+          StorageDead(_4);
+          _0 = const 0_u32;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          StorageDead(_4);
+          _0 = const 1_u32;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_3);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff
new file mode 100644
index 00000000000..6ca37e96d29
--- /dev/null
+++ b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff
@@ -0,0 +1,59 @@
+- // MIR for `floats` before JumpThreading
++ // MIR for `floats` after JumpThreading
+  
+  fn floats() -> u32 {
+      let mut _0: u32;
+      let _1: f64;
+      let mut _2: bool;
+      let mut _3: bool;
+      let mut _4: f64;
+      scope 1 {
+          debug x => _1;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = const true;
+-         switchInt(move _2) -> [0: bb2, otherwise: bb1];
++         goto -> bb1;
+      }
+  
+      bb1: {
+          _1 = const -0f64;
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _1 = const 1f64;
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = _1;
+          _3 = Eq(move _4, const 0f64);
+          switchInt(move _3) -> [0: bb5, otherwise: bb4];
+      }
+  
+      bb4: {
+          StorageDead(_4);
+          _0 = const 0_u32;
+          goto -> bb6;
+      }
+  
+      bb5: {
+          StorageDead(_4);
+          _0 = const 1_u32;
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_3);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs
index de290c1ef44..e5d8525dcac 100644
--- a/tests/mir-opt/jump_threading.rs
+++ b/tests/mir-opt/jump_threading.rs
@@ -521,6 +521,16 @@ fn aggregate_copy() -> u32 {
     if c == 2 { b.0 } else { 13 }
 }
 
+fn floats() -> u32 {
+    // CHECK-LABEL: fn floats(
+    // CHECK: switchInt(
+
+    // Test for issue #128243, where float equality was assumed to be bitwise.
+    // When adding float support, it must be ensured that this continues working properly.
+    let x = if true { -0.0 } else { 1.0 };
+    if x == 0.0 { 0 } else { 1 }
+}
+
 fn main() {
     // CHECK-LABEL: fn main(
     too_complex(Ok(0));
@@ -535,6 +545,7 @@ fn main() {
     disappearing_bb(7);
     aggregate(7);
     assume(7, false);
+    floats();
 }
 
 // EMIT_MIR jump_threading.too_complex.JumpThreading.diff
@@ -550,3 +561,4 @@ fn main() {
 // EMIT_MIR jump_threading.aggregate.JumpThreading.diff
 // EMIT_MIR jump_threading.assume.JumpThreading.diff
 // EMIT_MIR jump_threading.aggregate_copy.JumpThreading.diff
+// EMIT_MIR jump_threading.floats.JumpThreading.diff
diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
deleted file mode 100644
index cff9afc38f0..00000000000
--- a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,89 +0,0 @@
-- // MIR for `id_try` before SimplifyArmIdentity
-+ // MIR for `id_try` after SimplifyArmIdentity
-  
-  fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
-      debug r => _1;                       // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
-      let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
-      let _2: u8;                          // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
-      let _10: u8;                         // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-      let mut _11: u8;                     // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
-      scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
-              debug e => _8;               // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
-          }
-      }
-      scope 3 {
-          debug v => _10;                  // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
-          debug r => _4;                   // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-          StorageLive(_4);                 // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-          _4 = _1;                         // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-          _3 = move _4;                    // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
-          StorageDead(_4);                 // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
-      }
-  
-      bb1: {
-          StorageLive(_10);                // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-          _10 = ((_3 as Ok).0: u8);        // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-          _2 = _10;                        // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
-          StorageDead(_10);                // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
-          StorageDead(_3);                 // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
-          StorageLive(_11);                // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
-          _11 = _2;                        // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          ((_0 as Ok).0: u8) = move _11;   // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          StorageDead(_11);                // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
-          StorageDead(_2);                 // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
-          goto -> bb4;                     // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-          _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
-          _9 = _6;                         // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
-          _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
-          ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
-          StorageDead(_3);                 // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
-          StorageDead(_2);                 // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
-          goto -> bb4;                     // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  
-      bb4: {
-          return;                          // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
deleted file mode 100644
index 9d38b93508c..00000000000
--- a/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff
+++ /dev/null
@@ -1,89 +0,0 @@
-- // MIR for `id_try` before SimplifyBranchSame
-+ // MIR for `id_try` after SimplifyBranchSame
-  
-  fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> {
-      debug r => _1;                       // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12
-      let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49
-      let _2: u8;                          // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
-      let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-      let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-      let mut _5: isize;                   // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15
-      let _6: i32;                         // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-      let mut _7: !;                       // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51
-      let mut _8: i32;                     // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50
-      let mut _9: i32;                     // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49
-      let _10: u8;                         // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-      let mut _11: u8;                     // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9
-      scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10
-      }
-      scope 2 {
-          debug e => _6;                   // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14
-          scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50
-              debug t => _9;               // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          }
-          scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51
-              debug e => _8;               // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22
-          }
-      }
-      scope 3 {
-          debug v => _10;                  // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13
-      }
-      scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33
-          debug r => _4;                   // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23
-      }
-  
-      bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-          StorageLive(_4);                 // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-          _4 = _1;                         // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32
-          _3 = move _4;                    // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6
-          StorageDead(_4);                 // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33
-          _5 = discriminant(_3);           // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-          switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33
-      }
-  
-      bb1: {
-          StorageLive(_10);                // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-          _10 = ((_3 as Ok).0: u8);        // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13
-          _2 = _10;                        // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19
-          StorageDead(_10);                // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19
-          StorageDead(_3);                 // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
-          StorageLive(_11);                // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
-          _11 = _2;                        // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9
-          Deinit(_0);                      // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          ((_0 as Ok).0: u8) = move _11;   // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          discriminant(_0) = 0;            // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10
-          StorageDead(_11);                // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10
-          StorageDead(_2);                 // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
-          goto -> bb4;                     // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33
-      }
-  
-      bb3: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-          _6 = ((_3 as Err).0: i32);       // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14
-          StorageLive(_8);                 // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50
-          StorageLive(_9);                 // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
-          _9 = _6;                         // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49
-          _8 = move _9;                    // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50
-          ((_0 as Err).0: i32) = move _8;  // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10
-          Deinit(_0);                      // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
-          discriminant(_0) = 1;            // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11
-          StorageDead(_8);                 // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51
-          StorageDead(_6);                 // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51
-          StorageDead(_3);                 // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7
-          StorageDead(_2);                 // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2
-          goto -> bb4;                     // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  
-      bb4: {
-          return;                          // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2
-      }
-  }
-  
diff --git a/tests/mir-opt/simplify_arm.rs b/tests/mir-opt/simplify_arm.rs
deleted file mode 100644
index 5d9c31121dd..00000000000
--- a/tests/mir-opt/simplify_arm.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// skip-filecheck
-//@ compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
-// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
-// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
-// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
-// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff
-// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff
-// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff
-
-//@ ignore-test This pass is broken since deaggregation changed
-
-fn id(o: Option<u8>) -> Option<u8> {
-    match o {
-        Some(v) => Some(v),
-        None => None,
-    }
-}
-
-fn id_result(r: Result<u8, i32>) -> Result<u8, i32> {
-    match r {
-        Ok(x) => Ok(x),
-        Err(y) => Err(y),
-    }
-}
-
-fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
-    r
-}
-
-fn from_error<T, E>(e: E) -> Result<T, E> {
-    Err(e)
-}
-
-// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
-// so the relevant desugar is copied inline in order to keep the test testing the same thing.
-// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
-// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
-fn id_try(r: Result<u8, i32>) -> Result<u8, i32> {
-    let x = match into_result(r) {
-        Err(e) => return from_error(From::from(e)),
-        Ok(v) => v,
-    };
-    Ok(x)
-}
-
-fn main() {
-    id(None);
-    id_result(Ok(4));
-    id_try(Ok(4));
-}
diff --git a/tests/mir-opt/simplify_arm_identity.rs b/tests/mir-opt/simplify_arm_identity.rs
deleted file mode 100644
index 79395b312ac..00000000000
--- a/tests/mir-opt/simplify_arm_identity.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// skip-filecheck
-// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts.
-// Regression test for issue #66856.
-//
-//@ compile-flags: -Zmir-opt-level=3
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
-
-//@ ignore-test This pass is broken since deaggregation changed
-
-enum Src {
-    Foo(u8),
-    Bar,
-}
-
-enum Dst {
-    Foo(u8),
-}
-
-// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff
-fn main() {
-    let e: Src = Src::Foo(0);
-    let _: Dst = match e {
-        Src::Foo(x) => Dst::Foo(x),
-        Src::Bar => Dst::Foo(0),
-    };
-}
diff --git a/tests/mir-opt/simplify_try_if_let.rs b/tests/mir-opt/simplify_try_if_let.rs
deleted file mode 100644
index 98df9a54abb..00000000000
--- a/tests/mir-opt/simplify_try_if_let.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-// skip-filecheck
-//@ compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts
-//@ ignore-test
-// FIXME: the pass is unsound and causes ICEs in the MIR validator
-
-// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
-
-use std::ptr::NonNull;
-
-pub struct LinkedList {
-    head: Option<NonNull<Node>>,
-    tail: Option<NonNull<Node>>,
-}
-
-pub struct Node {
-    next: Option<NonNull<Node>>,
-}
-
-impl LinkedList {
-    pub fn new() -> Self {
-        Self { head: None, tail: None }
-    }
-
-    pub fn append(&mut self, other: &mut Self) {
-        match self.tail {
-            None => {}
-            Some(mut tail) => {
-                // `as_mut` is okay here because we have exclusive access to the entirety
-                // of both lists.
-                if let Some(other_head) = other.head.take() {
-                    unsafe {
-                        tail.as_mut().next = Some(other_head);
-                    }
-                }
-            }
-        }
-    }
-}
-
-fn main() {
-    let mut one = LinkedList::new();
-    let mut two = LinkedList::new();
-    one.append(&mut two);
-}
diff --git a/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
deleted file mode 100644
index 11f6b533741..00000000000
--- a/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,104 +0,0 @@
-- // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` before SimplifyArmIdentity
-+ // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` after SimplifyArmIdentity
-  
-  fn <impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () {
-      debug self => _1;                    // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28
-      debug other => _2;                   // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35
-      let mut _0: ();                      // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48
-      let mut _3: isize;                   // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
-      let mut _4: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
-      let mut _5: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60
-      let mut _6: &mut std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53
-      let mut _7: isize;                   // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40
-      let mut _9: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62
-      let mut _10: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61
-      let mut _11: &mut Node;              // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38
-      let mut _12: &mut std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29
-      scope 1 {
-          debug tail => _4;                // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26
-          let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
-          scope 2 {
--             debug other_head => _8;      // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
-+             debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
-              scope 3 {
-              }
-          }
-      }
-  
-      bb0: {
-          _3 = discriminant(((*_1).1: std::option::Option<std::ptr::NonNull<Node>>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
-          switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17
-      }
-  
-      bb1: {
-          StorageLive(_4);                 // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
-          _4 = ((((*_1).1: std::option::Option<std::ptr::NonNull<Node>>) as Some).0: std::ptr::NonNull<Node>); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26
-          StorageLive(_5);                 // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
-          StorageLive(_6);                 // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
-          _6 = &mut ((*_2).0: std::option::Option<std::ptr::NonNull<Node>>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53
-          _5 = Option::<NonNull<Node>>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60
-                                           // mir::Constant
-                                           // + span: $DIR/simplify_try_if_let.rs:26:54: 26:58
-                                           // + literal: Const { ty: for<'r> fn(&'r mut std::option::Option<std::ptr::NonNull<Node>>) -> std::option::Option<std::ptr::NonNull<Node>> {std::option::Option::<std::ptr::NonNull<Node>>::take}, val: Value(Scalar(<ZST>)) }
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24
-      }
-  
-      bb3: {
-          _0 = const ();                   // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24
-          goto -> bb9;                     // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
-      }
-  
-      bb4: {
-          StorageDead(_6);                 // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60
-          _7 = discriminant(_5);           // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
-          switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40
-      }
-  
-      bb5: {
-          _0 = const ();                   // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
-          goto -> bb8;                     // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
-      }
-  
-      bb6: {
-          StorageLive(_8);                 // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
-          _8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
-          StorageLive(_9);                 // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
--         StorageLive(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
--         _10 = _8;                        // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
--         ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
--         discriminant(_9) = 1;            // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
--         StorageDead(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
-+         _9 = move _5;                    // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
-          StorageLive(_11);                // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
-          StorageLive(_12);                // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
-          _12 = &mut _4;                   // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
-          _11 = NonNull::<Node>::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
-                                           // mir::Constant
-                                           // + span: $DIR/simplify_try_if_let.rs:28:30: 28:36
-                                           // + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull<Node>) -> &'r mut Node {std::ptr::NonNull::<Node>::as_mut}, val: Value(Scalar(<ZST>)) }
-      }
-  
-      bb7: {
-          StorageDead(_12);                // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38
-          ((*_11).0: std::option::Option<std::ptr::NonNull<Node>>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62
-          StorageDead(_9);                 // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
-          StorageDead(_11);                // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63
-          _0 = const ();                   // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22
-          StorageDead(_8);                 // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18
-          goto -> bb8;                     // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18
-      }
-  
-      bb8: {
-          StorageDead(_5);                 // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14
-          StorageDead(_4);                 // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14
-          goto -> bb9;                     // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10
-      }
-  
-      bb9: {
-          return;                          // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6
-      }
-  }
-  
diff --git a/tests/run-make/README.md b/tests/run-make/README.md
index a6c1b4b7db7..40359903473 100644
--- a/tests/run-make/README.md
+++ b/tests/run-make/README.md
@@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process:
 
 [`run_make_support`]: ../../src/tools/run-make-support
 [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
+
+### Formatting
+
+Note that files under `tests/` are not formatted by `./x fmt`,
+use `rustfmt tests/path/to/file.rs` to format a specific file if desired.
diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile
deleted file mode 100644
index 2bb8d42495d..00000000000
--- a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# Exercise unwinding a panic. This catches a panic across an FFI boundary and downcasts it into an integer. The Rust code that panics is in a separate crate.
-# See https://github.com/rust-lang/rust/commit/baf227ea0c1e07fc54395a51e4b3881d701180cb
-
-# ignore-cross-compile
-# needs-unwind
-include ../tools.mk
-
-all: archive
-	# Compile `main.rs`, which will link into our library, and run it.
-	$(RUSTC) main.rs
-	$(call RUN,main)
-
-ifdef IS_MSVC
-archive: add.o panic.o
-	# Now, create an archive using these two objects.
-	$(AR) crus $(TMPDIR)/add.lib $(TMPDIR)/add.o $(TMPDIR)/panic.o
-else
-archive: add.o panic.o
-	# Now, create an archive using these two objects.
-	$(AR) crus $(TMPDIR)/libadd.a $(TMPDIR)/add.o $(TMPDIR)/panic.o
-endif
-
-# Compile `panic.rs` into an object file.
-#
-# Note that we invoke `rustc` directly, so we may emit an object rather
-# than an archive. We'll do that later.
-panic.o:
-	$(BARE_RUSTC) $(RUSTFLAGS)  \
-		--out-dir $(TMPDIR) \
-		--emit=obj panic.rs
-
-# Compile `add.c` into an object file.
-add.o:
-	$(call COMPILE_OBJ,$(TMPDIR)/add.o,add.c)
-
diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs
new file mode 100644
index 00000000000..62e1748b6fb
--- /dev/null
+++ b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs
@@ -0,0 +1,36 @@
+// Exercise unwinding a panic. This catches a panic across an FFI (foreign function interface)
+// boundary and downcasts it into an integer.
+// The Rust code that panics is in a separate crate.
+// See https://github.com/rust-lang/rust/commit/baf227ea0c1e07fc54395a51e4b3881d701180cb
+
+//@ ignore-cross-compile
+// Reason: the compiled binary is executed
+//@ needs-unwind
+// Reason: this test exercises unwinding a panic
+
+use run_make_support::{cc, is_msvc, llvm_ar, run, rustc, static_lib_name};
+
+fn main() {
+    // Compile `add.c` into an object file.
+    if is_msvc() {
+        cc().arg("-c").out_exe("add").input("add.c").run();
+    } else {
+        cc().arg("-v").arg("-c").out_exe("add.o").input("add.c").run();
+    };
+
+    // Compile `panic.rs` into an object file.
+    // Note that we invoke `rustc` directly, so we may emit an object rather
+    // than an archive. We'll do that later.
+    rustc().emit("obj").input("panic.rs").run();
+
+    // Now, create an archive using these two objects.
+    if is_msvc() {
+        llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.obj", "panic.o"]).run();
+    } else {
+        llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.o", "panic.o"]).run();
+    };
+
+    // Compile `main.rs`, which will link into our library, and run it.
+    rustc().input("main.rs").run();
+    run("main");
+}
diff --git a/tests/run-make/compiler-rt-works-on-mingw/Makefile b/tests/run-make/compiler-rt-works-on-mingw/Makefile
deleted file mode 100644
index 74917570a01..00000000000
--- a/tests/run-make/compiler-rt-works-on-mingw/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include ../tools.mk
-
-# only-windows-gnu
-
-all:
-	$(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
-	$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
-	$(RUSTC) foo.rs -lfoo -lstdc++
-	$(call RUN,foo)
diff --git a/tests/run-make/compiler-rt-works-on-mingw/rmake.rs b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
new file mode 100644
index 00000000000..f1b41f96312
--- /dev/null
+++ b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs
@@ -0,0 +1,15 @@
+// `compiler-rt` ("runtime") is a suite of LLVM features compatible with rustc.
+// After building it was enabled on Windows-gnu in #29874, this test is a basic smoke test to
+// check if building and linking to it can work at all.
+// See https://github.com/rust-lang/rust/pull/29478
+
+//@ only-windows-gnu
+
+use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name};
+
+fn main() {
+    cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run();
+    llvm_ar().obj_to_ar().output_input(static_lib_name("foo"), "foo.o").run();
+    rustc().input("foo.rs").arg("-lfoo").arg("-lstdc++").run();
+    run("foo");
+}
diff --git a/tests/run-make/dump-ice-to-disk/Makefile b/tests/run-make/dump-ice-to-disk/Makefile
deleted file mode 100644
index 23006fc09e2..00000000000
--- a/tests/run-make/dump-ice-to-disk/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include ../tools.mk
-
-# ignore-windows
-
-export RUSTC := $(RUSTC_ORIGINAL)
-export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
-export TMPDIR := $(TMPDIR)
-
-all:
-	bash check.sh
diff --git a/tests/run-make/dump-ice-to-disk/check.sh b/tests/run-make/dump-ice-to-disk/check.sh
deleted file mode 100644
index ff6e4be35af..00000000000
--- a/tests/run-make/dump-ice-to-disk/check.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/sh
-
-# Default nightly behavior (write ICE to current directory)
-# FIXME(estebank): these are failing on CI, but passing locally.
-# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1
-# default=$(cat ./rustc-ice-*.txt | wc -l)
-# rm ./rustc-ice-*.txt
-
-# Explicit directory set
-export RUSTC_ICE=$TMPDIR
-$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1
-default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-content=$(cat $TMPDIR/rustc-ice-*.txt)
-# Ensure that the ICE dump path doesn't contain `:` because they cause problems on Windows
-windows_safe=$(echo rustc-ice-*.txt | grep ':')
-if [ ! -z "$windows_safe" ]; then
-    exit 1
-fi
-
-rm $TMPDIR/rustc-ice-*.txt
-RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1
-short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-rm $TMPDIR/rustc-ice-*.txt
-RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1
-full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
-rm $TMPDIR/rustc-ice-*.txt
-
-# Explicitly disabling ICE dump
-export RUSTC_ICE=0
-$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1
-should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l)
-should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l)
-
-echo "#### ICE Dump content:"
-echo $content
-echo "#### default length:"
-echo $default
-echo "#### short length:"
-echo $short
-echo "#### default_set length:"
-echo $default_set
-echo "#### full length:"
-echo $full
-echo "#### should_be_empty_dot length:"
-echo $should_be_empty_dot
-echo "#### should_be_empty_tmp length:"
-echo $should_be_empty_tmp
-
-## Verify that a the ICE dump file is created in the appropriate directories, that
-## their lengths are the same regardless of other backtrace configuration options,
-## that the file is not created when asked to (RUSTC_ICE=0) and that the file
-## contains at least part of the expected content.
-if [ $short -eq $default_set ] &&
-    #[ $default -eq $short ] &&
-    [ $default_set -eq $full ] &&
-    [[ $content == *"thread 'rustc' panicked at "* ]] &&
-    [[ $content == *"stack backtrace:"* ]] &&
-    #[ $default -gt 0 ] &&
-    [ $should_be_empty_dot -eq 0 ] &&
-    [ $should_be_empty_tmp -eq 0 ]; then
-    exit 0
-else
-    exit 1
-fi
diff --git a/tests/run-make/dump-ice-to-disk/src/lib.rs b/tests/run-make/dump-ice-to-disk/lib.rs
index b23b7f830d7..b23b7f830d7 100644
--- a/tests/run-make/dump-ice-to-disk/src/lib.rs
+++ b/tests/run-make/dump-ice-to-disk/lib.rs
diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs
new file mode 100644
index 00000000000..2fb5c825064
--- /dev/null
+++ b/tests/run-make/dump-ice-to-disk/rmake.rs
@@ -0,0 +1,81 @@
+// This test checks if internal compilation error (ICE) log files work as expected.
+// - Get the number of lines from the log files without any configuration options,
+// then check that the line count doesn't change if the backtrace gets configured to be short
+// or full.
+// - Check that disabling ICE logging results in zero files created.
+// - Check that the ICE files contain some of the expected strings.
+// See https://github.com/rust-lang/rust/pull/108714
+
+use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
+
+fn main() {
+    rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let default = get_text_from_ice(".").lines().count();
+    clear_ice_files();
+
+    rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let ice_text = get_text_from_ice(cwd());
+    let default_set = ice_text.lines().count();
+    let content = ice_text;
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
+    let ice_file_name =
+        ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
+    // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
+    assert!(!ice_file_name.contains(":"), "{ice_file_name}");
+
+    clear_ice_files();
+    rustc()
+        .env("RUSTC_ICE", cwd())
+        .input("lib.rs")
+        .env("RUST_BACKTRACE", "short")
+        .arg("-Ztreat-err-as-bug=1")
+        .run_fail();
+    let short = get_text_from_ice(cwd()).lines().count();
+    clear_ice_files();
+    rustc()
+        .env("RUSTC_ICE", cwd())
+        .input("lib.rs")
+        .env("RUST_BACKTRACE", "full")
+        .arg("-Ztreat-err-as-bug=1")
+        .run_fail();
+    let full = get_text_from_ice(cwd()).lines().count();
+    clear_ice_files();
+
+    // The ICE dump is explicitly disabled. Therefore, this should produce no files.
+    rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    assert!(ice_files.is_empty()); // There should be 0 ICE files.
+
+    // The line count should not change.
+    assert_eq!(short, default_set);
+    assert_eq!(short, default);
+    assert_eq!(full, default_set);
+    assert!(default > 0);
+    // Some of the expected strings in an ICE file should appear.
+    assert!(content.contains("thread 'rustc' panicked at"));
+    assert!(content.contains("stack backtrace:"));
+}
+
+fn clear_ice_files() {
+    let ice_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "rustc-ice") && has_extension(path, "txt")
+    });
+    for file in ice_files {
+        rfs::remove_file(file);
+    }
+}
+
+#[track_caller]
+fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String {
+    let ice_files =
+        shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt"));
+    assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
+    let ice_file = ice_files.get(0).unwrap();
+    let output = rfs::read_to_string(ice_file);
+    output
+}
diff --git a/tests/run-make/export-executable-symbols/Makefile b/tests/run-make/export-executable-symbols/Makefile
deleted file mode 100644
index c4d29aa2bf4..00000000000
--- a/tests/run-make/export-executable-symbols/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-include ../tools.mk
-
-# ignore-wasm32
-# ignore-wasm64
-# ignore-none no-std is not supported
-# only-linux
-
-all:
-	$(RUSTC) -Zexport-executable-symbols  main.rs --target $(TARGET) --crate-type=bin
-	nm $(TMPDIR)/main | $(CGREP) exported_symbol
-
diff --git a/tests/run-make/export-executable-symbols/rmake.rs b/tests/run-make/export-executable-symbols/rmake.rs
new file mode 100644
index 00000000000..77f968189b6
--- /dev/null
+++ b/tests/run-make/export-executable-symbols/rmake.rs
@@ -0,0 +1,25 @@
+// The unstable flag `-Z export-executable-symbols` exports symbols from executables, as if
+// they were dynamic libraries. This test is a simple smoke test to check that this feature
+// works by using it in compilation, then checking that the output binary contains the exported
+// symbol.
+// See https://github.com/rust-lang/rust/pull/85673
+
+//@ only-unix
+// Reason: the export-executable-symbols flag only works on Unix
+// due to hardcoded platform-specific implementation
+// (See #85673)
+//@ ignore-wasm32
+//@ ignore-wasm64
+//@ ignore-none
+// Reason: no-std is not supported
+
+use run_make_support::{bin_name, llvm_readobj, rustc};
+
+fn main() {
+    rustc().arg("-Zexport-executable-symbols").input("main.rs").crate_type("bin").run();
+    llvm_readobj()
+        .symbols()
+        .input(bin_name("main"))
+        .run()
+        .assert_stdout_contains("exported_symbol");
+}
diff --git a/tests/run-make/extern-flag-disambiguates/Makefile b/tests/run-make/extern-flag-disambiguates/Makefile
deleted file mode 100644
index e54a537ecd0..00000000000
--- a/tests/run-make/extern-flag-disambiguates/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Attempt to build this dependency tree:
-#
-#	A.1   A.2
-#	 |\    |
-#	 | \   |
-#        B  \  C
-#         \ | /
-#          \|/
-#           D
-#
-# Note that A.1 and A.2 are crates with the same name.
-
-all:
-	$(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
-	$(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
-	$(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
-	@echo before
-	$(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(call RUN,d)
-	@echo after
-	$(RUSTC) --cfg after  d.rs --extern a=$(TMPDIR)/liba-1.rlib
-	$(call RUN,d)
diff --git a/tests/run-make/extern-flag-disambiguates/rmake.rs b/tests/run-make/extern-flag-disambiguates/rmake.rs
new file mode 100644
index 00000000000..2d7d7f69f66
--- /dev/null
+++ b/tests/run-make/extern-flag-disambiguates/rmake.rs
@@ -0,0 +1,30 @@
+//@ ignore-cross-compile
+
+use run_make_support::{cwd, run, rustc};
+
+// Attempt to build this dependency tree:
+//
+//    A.1   A.2
+//     |\    |
+//     | \   |
+//     B  \  C
+//      \ | /
+//       \|/
+//        D
+//
+// Note that A.1 and A.2 are crates with the same name.
+
+// original Makefile at https://github.com/rust-lang/rust/issues/14469
+
+fn main() {
+    rustc().metadata("1").extra_filename("-1").input("a.rs").run();
+    rustc().metadata("2").extra_filename("-2").input("a.rs").run();
+    rustc().input("b.rs").extern_("a", "liba-1.rlib").run();
+    rustc().input("c.rs").extern_("a", "liba-2.rlib").run();
+    println!("before");
+    rustc().cfg("before").input("d.rs").extern_("a", "liba-1.rlib").run();
+    run("d");
+    println!("after");
+    rustc().cfg("after").input("d.rs").extern_("a", "liba-1.rlib").run();
+    run("d");
+}
diff --git a/tests/run-make/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile
deleted file mode 100644
index 59cee284200..00000000000
--- a/tests/run-make/foreign-rust-exceptions/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# ignore-cross-compile
-# ignore-i686-pc-windows-gnu
-# needs-unwind
-
-# This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder
-# so cross-DLL unwinding does not work.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) bar.rs --crate-type=cdylib
-	$(RUSTC) foo.rs
-	$(call RUN,foo) 2>&1 | $(CGREP) "Rust cannot catch foreign exceptions"
diff --git a/tests/run-make/foreign-rust-exceptions/rmake.rs b/tests/run-make/foreign-rust-exceptions/rmake.rs
new file mode 100644
index 00000000000..9c917078aaa
--- /dev/null
+++ b/tests/run-make/foreign-rust-exceptions/rmake.rs
@@ -0,0 +1,23 @@
+// Rust exceptions can be foreign (from C code, in this test) or local. Foreign
+// exceptions should not be caught, as that can cause undefined behaviour. Instead
+// of catching them, #102721 made it so that the binary panics in execution with a helpful message.
+// This test checks that the correct message appears and that execution fails when trying to catch
+// a foreign exception.
+// See https://github.com/rust-lang/rust/issues/102715
+
+//@ ignore-cross-compile
+// Reason: the compiled binary is executed
+//@ needs-unwind
+// Reason: unwinding panics is exercised in this test
+
+//@ ignore-i686-pc-windows-gnu
+// Reason: This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder
+// so cross-DLL unwinding does not work.
+
+use run_make_support::{run_fail, rustc};
+
+fn main() {
+    rustc().input("bar.rs").crate_type("cdylib").run();
+    rustc().input("foo.rs").run();
+    run_fail("foo").assert_stderr_contains("Rust cannot catch foreign exceptions");
+}
diff --git a/tests/run-make/incr-foreign-head-span/Makefile b/tests/run-make/incr-foreign-head-span/Makefile
deleted file mode 100644
index 9be4b0f601c..00000000000
--- a/tests/run-make/incr-foreign-head-span/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-include ../tools.mk
-
-# ignore-none no-std is not supported
-# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std'
-
-# Ensure that modifying a crate on disk (without recompiling it)
-# does not cause ICEs in downstream crates.
-# Previously, we would call `SourceMap.guess_head_span` on a span
-# from an external crate, which would cause us to read an upstream
-# source file from disk during compilation of a downstream crate
-# See #86480 for more details
-
-INCR=$(TMPDIR)/incr
-
-all:
-	cp first_crate.rs second_crate.rs $(TMPDIR)
-	$(RUSTC) $(TMPDIR)/first_crate.rs  -C incremental=$(INCR) --target $(TARGET) --crate-type lib
-	$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET)  --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib
-	rm $(TMPDIR)/first_crate.rs
-	$(RUSTC) $(TMPDIR)/second_crate.rs  -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib
-
diff --git a/tests/run-make/incr-foreign-head-span/rmake.rs b/tests/run-make/incr-foreign-head-span/rmake.rs
new file mode 100644
index 00000000000..92e2ed5f879
--- /dev/null
+++ b/tests/run-make/incr-foreign-head-span/rmake.rs
@@ -0,0 +1,25 @@
+// Ensure that modifying a crate on disk (without recompiling it)
+// does not cause ICEs (internal compiler errors) in downstream crates.
+// Previously, we would call `SourceMap.guess_head_span` on a span
+// from an external crate, which would cause us to read an upstream
+// source file from disk during compilation of a downstream crate.
+// See https://github.com/rust-lang/rust/issues/86480
+
+//@ ignore-none
+// Reason: no-std is not supported
+//@ ignore-nvptx64-nvidia-cuda
+// Reason: can't find crate for 'std'
+
+use run_make_support::{rfs, rust_lib_name, rustc};
+
+fn main() {
+    rustc().input("first_crate.rs").incremental("incr").crate_type("lib").run();
+    rustc()
+        .input("second_crate.rs")
+        .incremental("incr")
+        .extern_("first_crate", rust_lib_name("first_crate"))
+        .crate_type("lib")
+        .run();
+    rfs::remove_file("first_crate.rs");
+    rustc().input("second_crate.rs").incremental("incr").cfg("second_run").crate_type("lib").run();
+}
diff --git a/tests/run-make/interdependent-c-libraries/Makefile b/tests/run-make/interdependent-c-libraries/Makefile
deleted file mode 100644
index 53a696d82bf..00000000000
--- a/tests/run-make/interdependent-c-libraries/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# The rust crate foo will link to the native library foo, while the rust crate
-# bar will link to the native library bar. There is also a dependency between
-# the native library bar to the natibe library foo.
-#
-# This test ensures that the ordering of -lfoo and -lbar on the command line is
-# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
-# library will be stripped out, and the linkage will fail.
-
-all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar)
-	$(RUSTC) foo.rs
-	$(RUSTC) bar.rs
-	$(RUSTC) main.rs --print link-args
diff --git a/tests/run-make/interdependent-c-libraries/rmake.rs b/tests/run-make/interdependent-c-libraries/rmake.rs
new file mode 100644
index 00000000000..ee8cc76c9cc
--- /dev/null
+++ b/tests/run-make/interdependent-c-libraries/rmake.rs
@@ -0,0 +1,21 @@
+// The rust crate foo will link to the native library foo, while the rust crate
+// bar will link to the native library bar. There is also a dependency between
+// the native library bar to the natibe library foo.
+// This test ensures that the ordering of -lfoo and -lbar on the command line is
+// correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
+// library will be stripped out, and the linkage will fail.
+// See https://github.com/rust-lang/rust/commit/e6072fa0c4c22d62acf3dcb78c8ee260a1368bd7
+
+//@ ignore-cross-compile
+// Reason: linkage still fails as the object files produced are not in the correct
+// format in the `build_native_static_lib` step
+
+use run_make_support::{build_native_static_lib, rustc};
+
+fn main() {
+    build_native_static_lib("foo");
+    build_native_static_lib("bar");
+    rustc().input("foo.rs").run();
+    rustc().input("bar.rs").run();
+    rustc().input("main.rs").print("link-args").run();
+}
diff --git a/tests/run-make/panic-abort-eh_frame/Makefile b/tests/run-make/panic-abort-eh_frame/Makefile
deleted file mode 100644
index 7020455b742..00000000000
--- a/tests/run-make/panic-abort-eh_frame/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# only-linux
-#
-# This test ensures that `panic=abort` code (without `C-unwind`, that is) should not have any
-# unwinding related `.eh_frame` sections emitted.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir
-	objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA'
diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs
new file mode 100644
index 00000000000..23d95dc5774
--- /dev/null
+++ b/tests/run-make/panic-abort-eh_frame/rmake.rs
@@ -0,0 +1,24 @@
+// An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate
+// being inserted, useful for determining whether or not unwinding is necessary.
+// This is useless when panics would NEVER unwind due to -C panic=abort. This section should
+// therefore never appear in the emit file of a -C panic=abort compilation, and this test
+// checks that this is respected.
+// See https://github.com/rust-lang/rust/pull/112403
+
+//@ only-linux
+// FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable
+// is forced to true on Windows targets (see #128136).
+
+use run_make_support::{llvm_objdump, rustc};
+
+fn main() {
+    rustc()
+        .input("foo.rs")
+        .crate_type("lib")
+        .emit("obj=foo.o")
+        .panic("abort")
+        .edition("2021")
+        .arg("-Zvalidate-mir")
+        .run();
+    llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA");
+}
diff --git a/tests/run-make/sanitizer-cdylib-link/Makefile b/tests/run-make/sanitizer-cdylib-link/Makefile
deleted file mode 100644
index 10d94afc39e..00000000000
--- a/tests/run-make/sanitizer-cdylib-link/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# needs-sanitizer-support
-# needs-sanitizer-address
-
-include ../tools.mk
-
-LOG := $(TMPDIR)/log.txt
-
-# This test builds a shared object, then an executable that links it as a native
-# rust library (contrast to an rlib). The shared library and executable both
-# are compiled with address sanitizer, and we assert that a fault in the cdylib
-# is correctly detected.
-
-all:
-	$(RUSTC) -g -Z sanitizer=address --crate-type cdylib --target $(TARGET) library.rs
-	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) program.rs
-	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
diff --git a/tests/run-make/sanitizer-cdylib-link/rmake.rs b/tests/run-make/sanitizer-cdylib-link/rmake.rs
new file mode 100644
index 00000000000..f9d7fd98789
--- /dev/null
+++ b/tests/run-make/sanitizer-cdylib-link/rmake.rs
@@ -0,0 +1,17 @@
+// Identical to sanitizer-dylib-link, but with a cdylib.
+// This test builds a shared object, then an executable that links it as a native
+// rust library (contrast to an rlib). The shared library and executable both
+// are compiled with address sanitizer, and we assert that a fault in the cdylib
+// is correctly detected.
+// See https://github.com/rust-lang/rust/pull/38699
+
+//@ needs-sanitizer-support
+//@ needs-sanitizer-address
+
+use run_make_support::{run_fail, rustc};
+
+fn main() {
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("cdylib").input("library.rs").run();
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run();
+    run_fail("program").assert_stderr_contains("stack-buffer-overflow");
+}
diff --git a/tests/run-make/sanitizer-dylib-link/Makefile b/tests/run-make/sanitizer-dylib-link/Makefile
deleted file mode 100644
index c5a698db3a0..00000000000
--- a/tests/run-make/sanitizer-dylib-link/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# needs-sanitizer-support
-# needs-sanitizer-address
-
-include ../tools.mk
-
-LOG := $(TMPDIR)/log.txt
-
-# This test builds a shared object, then an executable that links it as a native
-# rust library (contrast to an rlib). The shared library and executable both
-# are compiled with address sanitizer, and we assert that a fault in the dylib
-# is correctly detected.
-
-all:
-	$(RUSTC) -g -Z sanitizer=address --crate-type dylib --target $(TARGET) library.rs
-	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) program.rs
-	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
diff --git a/tests/run-make/sanitizer-dylib-link/rmake.rs b/tests/run-make/sanitizer-dylib-link/rmake.rs
new file mode 100644
index 00000000000..b43420adc72
--- /dev/null
+++ b/tests/run-make/sanitizer-dylib-link/rmake.rs
@@ -0,0 +1,16 @@
+// This test builds a shared object, then an executable that links it as a native
+// rust library (contrast to an rlib). The shared library and executable both
+// are compiled with address sanitizer, and we assert that a fault in the dylib
+// is correctly detected.
+// See https://github.com/rust-lang/rust/pull/38699
+
+//@ needs-sanitizer-support
+//@ needs-sanitizer-address
+
+use run_make_support::{run_fail, rustc};
+
+fn main() {
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("dylib").input("library.rs").run();
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run();
+    run_fail("program").assert_stderr_contains("stack-buffer-overflow");
+}
diff --git a/tests/run-make/sanitizer-staticlib-link/Makefile b/tests/run-make/sanitizer-staticlib-link/Makefile
deleted file mode 100644
index 7b1a286ed12..00000000000
--- a/tests/run-make/sanitizer-staticlib-link/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# needs-sanitizer-support
-# needs-sanitizer-address
-
-include ../tools.mk
-
-# This test first builds a staticlib with AddressSanitizer and checks that
-# linking it to an executable fails due to the missing sanitizer runtime.
-# It then builds an executable linking to the staticlib and checks that
-# the fault in the staticlib is detected correctly.
-
-# Note that checking for the link failure actually checks two things at once:
-#   1) That the library has the sanitizer intrumentation
-#   2) and that library does not have the sanitizer runtime
-
-all:
-	$(RUSTC) -g -Z sanitizer=address --crate-type staticlib --target $(TARGET) library.rs
-	! $(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) $(EXTRACFLAGS) $(EXTRACXXFLAGS)
-	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) -L . program.rs
-	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
-
diff --git a/tests/run-make/sanitizer-staticlib-link/rmake.rs b/tests/run-make/sanitizer-staticlib-link/rmake.rs
new file mode 100644
index 00000000000..e38d15a8a3c
--- /dev/null
+++ b/tests/run-make/sanitizer-staticlib-link/rmake.rs
@@ -0,0 +1,26 @@
+// This test first builds a staticlib with AddressSanitizer and checks that
+// linking it to an executable fails due to the missing sanitizer runtime.
+// It then builds an executable linking to the staticlib and checks that
+// the fault in the staticlib is detected correctly.
+
+// Note that checking for the link failure actually checks two things at once:
+//   1) That the library has the sanitizer intrumentation
+//   2) and that library does not have the sanitizer runtime
+// See https://github.com/rust-lang/rust/pull/38699
+
+//@ needs-sanitizer-support
+//@ needs-sanitizer-address
+
+use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run_fail, rustc, static_lib_name};
+
+fn main() {
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("staticlib").input("library.rs").run();
+    cc().input("program.c")
+        .arg(static_lib_name("library"))
+        .out_exe("program")
+        .args(extra_c_flags())
+        .args(extra_cxx_flags())
+        .run_fail();
+    rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run();
+    run_fail("program").assert_stderr_contains("stack-buffer-overflow");
+}
diff --git a/tests/run-make/static-dylib-by-default/Makefile b/tests/run-make/static-dylib-by-default/Makefile
deleted file mode 100644
index cdaab42d06c..00000000000
--- a/tests/run-make/static-dylib-by-default/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-TO_LINK := $(call DYLIB,bar)
-ifdef IS_MSVC
-LINK_ARG = $(TO_LINK:dll=dll.lib)
-else
-LINK_ARG = $(TO_LINK)
-endif
-
-all:
-	$(RUSTC) foo.rs
-	$(RUSTC) bar.rs
-	$(CC) main.c $(call OUT_EXE,main) $(LINK_ARG) $(EXTRACFLAGS)
-	rm $(TMPDIR)/*.rlib
-	rm $(call DYLIB,foo)
-	$(call RUN,main)
diff --git a/tests/run-make/static-dylib-by-default/rmake.rs b/tests/run-make/static-dylib-by-default/rmake.rs
new file mode 100644
index 00000000000..133210c74e7
--- /dev/null
+++ b/tests/run-make/static-dylib-by-default/rmake.rs
@@ -0,0 +1,35 @@
+// If a dylib is being produced, the compiler will first check to see if it can
+// be created entirely statically before falling back to dynamic dependencies. This
+// behavior can be overridden with `-C prefer-dynamic`.
+// In this test, bar depends on foo and is compiled fully statically despite the available
+// `foo` dynamic library. This allows the main binary to be executed in the final step.
+// See https://github.com/rust-lang/rust/commit/3036b001276a6e43409b08b7f2334ce72aeeb036
+
+//@ ignore-cross-compile
+// Reason: the compiled binary is executed
+
+use run_make_support::{
+    cc, cwd, dynamic_lib_name, extra_c_flags, has_extension, is_msvc, rfs, run, rustc,
+    shallow_find_files,
+};
+
+fn main() {
+    rustc().input("foo.rs").run();
+    rustc().input("bar.rs").run();
+    // On msvc, dynamic libraries are compiled by rustc to:
+    // bar.dll     // dylib
+    // bar.dll.lib // import library for the dylib
+    // bar.dll.exp // export library for the dylib
+    // msvc's underlying link.exe requires the import library for the dynamic library as input.
+    // That is why the library is bar.dll.lib, not bar.dll.
+    let library = if is_msvc() { "bar.dll.lib" } else { &dynamic_lib_name("bar") };
+    cc().input("main.c").out_exe("main").arg(library).args(extra_c_flags()).run();
+    for rlib in shallow_find_files(cwd(), |path| has_extension(path, "rlib")) {
+        rfs::remove_file(rlib);
+    }
+    rfs::remove_file(dynamic_lib_name("foo"));
+    if is_msvc() {
+        rfs::remove_file("foo.dll.lib");
+    }
+    run("main");
+}
diff --git a/tests/rustdoc-gui/copy-code.goml b/tests/rustdoc-gui/copy-code.goml
new file mode 100644
index 00000000000..72a5bece175
--- /dev/null
+++ b/tests/rustdoc-gui/copy-code.goml
@@ -0,0 +1,54 @@
+// Checks that the "copy code" button is not triggering JS error and its display
+// isn't broken.
+go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
+
+define-function: (
+    "check-copy-button",
+    [],
+    block {
+        // First we ensure that there are no "copy code" currently existing.
+        assert-count: (".example-wrap .copy-button", 0)
+        move-cursor-to: ".example-wrap"
+        assert-count: (".example-wrap .copy-button", 1)
+        // We now ensure it's only displayed when the example is hovered.
+        assert-css: (".example-wrap .copy-button", { "visibility": "visible" })
+        move-cursor-to: ".search-input"
+        assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })
+        // Checking that the copy button has the same size as the "copy path" button.
+        compare-elements-size: (
+            "#copy-path",
+            ".example-wrap:nth-of-type(1) .copy-button",
+            ["height", "width"],
+        )
+    },
+)
+
+call-function: ("check-copy-button", {})
+// Checking that the run button and the copy button have the same height.
+compare-elements-size: (
+    ".example-wrap:nth-of-type(1) .test-arrow",
+    ".example-wrap:nth-of-type(1) .copy-button",
+    ["height"],
+)
+// ... and the same y position.
+compare-elements-position: (
+    ".example-wrap:nth-of-type(1) .test-arrow",
+    ".example-wrap:nth-of-type(1) .copy-button",
+    ["y"],
+)
+store-size: (".example-wrap:nth-of-type(1) .copy-button", {
+    "height": copy_height,
+    "width": copy_width,
+})
+assert: |copy_height| > 0 && |copy_width| > 0
+
+// Checking same things for the copy button when there is no run button.
+go-to: "file://" + |DOC_PATH| + "/lib2/sub_mod/struct.Foo.html"
+call-function: ("check-copy-button", {})
+// Ensure there is no run button.
+assert-count: (".example-wrap .test-arrow", 0)
+// Check it's the same size without a run button.
+assert-size: (".example-wrap:nth-of-type(1) .copy-button", {
+    "height": |copy_height|,
+    "width": |copy_width|,
+})
diff --git a/tests/rustdoc-gui/run-on-hover.goml b/tests/rustdoc-gui/run-on-hover.goml
index 087dd3374f8..b62da79b780 100644
--- a/tests/rustdoc-gui/run-on-hover.goml
+++ b/tests/rustdoc-gui/run-on-hover.goml
@@ -17,16 +17,16 @@ define-function: (
             "visibility": "visible",
             "color": |color|,
             "background-color": |background|,
-            "font-size": "22px",
-            "border-radius": "5px",
+            "font-size": "16px",
+            "border-radius": "2px",
         })
         move-cursor-to: ".test-arrow"
         assert-css: (".test-arrow:hover", {
             "visibility": "visible",
             "color": |hover_color|,
             "background-color": |hover_background|,
-            "font-size": "22px",
-            "border-radius": "5px",
+            "font-size": "16px",
+            "border-radius": "2px",
         })
     },
 )
diff --git a/tests/rustdoc-gui/search-title.goml b/tests/rustdoc-gui/search-title.goml
new file mode 100644
index 00000000000..95bc36af449
--- /dev/null
+++ b/tests/rustdoc-gui/search-title.goml
@@ -0,0 +1,24 @@
+// Checks that the search changes the title
+include: "utils.goml"
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+
+store-value: (title, "test_docs - Rust")
+assert-document-property: {"title": |title|}
+
+write-into: (".search-input", "test")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "#crate-search"
+
+assert-document-property: {"title": '"test" Search - Rust'}
+
+set-property: (".search-input", {"value": "another one"})
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "#crate-search"
+
+assert-document-property: {"title": '"another one" Search - Rust'}
+
+press-key: "Escape"
+
+assert-document-property: {"title": |title|}
diff --git a/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs b/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
index 31f59f8f724..6ac90953a05 100644
--- a/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
+++ b/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
@@ -1,8 +1,6 @@
 //@ check-pass
 // regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452
 
-#![feature(is_sorted)]
-
 struct A {
     name: String,
 }
diff --git a/tests/ui/asm/aarch64/bad-options.rs b/tests/ui/asm/aarch64/bad-options.rs
index 33b77367a4f..9e721d55b2d 100644
--- a/tests/ui/asm/aarch64/bad-options.rs
+++ b/tests/ui/asm/aarch64/bad-options.rs
@@ -26,14 +26,14 @@ fn main() {
 }
 
 global_asm!("", options(nomem));
-//~^ ERROR expected one of
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
 global_asm!("", options(readonly));
-//~^ ERROR expected one of
+//~^ ERROR the `readonly` option cannot be used with `global_asm!`
 global_asm!("", options(noreturn));
-//~^ ERROR expected one of
+//~^ ERROR the `noreturn` option cannot be used with `global_asm!`
 global_asm!("", options(pure));
-//~^ ERROR expected one of
+//~^ ERROR the `pure` option cannot be used with `global_asm!`
 global_asm!("", options(nostack));
-//~^ ERROR expected one of
+//~^ ERROR the `nostack` option cannot be used with `global_asm!`
 global_asm!("", options(preserves_flags));
-//~^ ERROR expected one of
+//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!`
diff --git a/tests/ui/asm/aarch64/bad-options.stderr b/tests/ui/asm/aarch64/bad-options.stderr
index 21bcc4a9c7b..54ab7cafa49 100644
--- a/tests/ui/asm/aarch64/bad-options.stderr
+++ b/tests/ui/asm/aarch64/bad-options.stderr
@@ -36,41 +36,41 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
    |                    |
    |                    generic outputs
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+error: the `nomem` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:28:25
    |
 LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
+error: the `readonly` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:30:25
    |
 LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
+error: the `noreturn` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:32:25
    |
 LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
+error: the `pure` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:34:25
    |
 LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
+error: the `nostack` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:36:25
    |
 LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
+error: the `preserves_flags` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:38:25
    |
 LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
 
 error: invalid ABI for `clobber_abi`
   --> $DIR/bad-options.rs:20:18
diff --git a/tests/ui/asm/aarch64/parse-error.rs b/tests/ui/asm/aarch64/parse-error.rs
index fbb1e08df91..ac73bbf99c9 100644
--- a/tests/ui/asm/aarch64/parse-error.rs
+++ b/tests/ui/asm/aarch64/parse-error.rs
@@ -98,8 +98,10 @@ global_asm!("", options(FOO));
 //~^ ERROR expected one of
 global_asm!("", options(nomem FOO));
 //~^ ERROR expected one of
+//~| ERROR the `nomem` option cannot be used with `global_asm!`
 global_asm!("", options(nomem, FOO));
 //~^ ERROR expected one of
+//~| ERROR the `nomem` option cannot be used with `global_asm!`
 global_asm!("{}", options(), const FOO);
 global_asm!("", clobber_abi(FOO));
 //~^ ERROR expected string literal
diff --git a/tests/ui/asm/aarch64/parse-error.stderr b/tests/ui/asm/aarch64/parse-error.stderr
index d21a8ab1f85..e2c798c798e 100644
--- a/tests/ui/asm/aarch64/parse-error.stderr
+++ b/tests/ui/asm/aarch64/parse-error.stderr
@@ -218,56 +218,68 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
 LL | global_asm!("", options(FOO));
    |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+error: the `nomem` option cannot be used with `global_asm!`
   --> $DIR/parse-error.rs:99:25
    |
 LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:101:25
+error: expected one of `)` or `,`, found `FOO`
+  --> $DIR/parse-error.rs:99:31
+   |
+LL | global_asm!("", options(nomem FOO));
+   |                               ^^^ expected one of `)` or `,`
+
+error: the `nomem` option cannot be used with `global_asm!`
+  --> $DIR/parse-error.rs:102:25
+   |
+LL | global_asm!("", options(nomem, FOO));
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
+  --> $DIR/parse-error.rs:102:32
    |
 LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                                ^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:104:29
+  --> $DIR/parse-error.rs:106:29
    |
 LL | global_asm!("", clobber_abi(FOO));
    |                             ^^^ not a string literal
 
 error: expected one of `)` or `,`, found `FOO`
-  --> $DIR/parse-error.rs:106:33
+  --> $DIR/parse-error.rs:108:33
    |
 LL | global_asm!("", clobber_abi("C" FOO));
    |                                 ^^^ expected one of `)` or `,`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:108:34
+  --> $DIR/parse-error.rs:110:34
    |
 LL | global_asm!("", clobber_abi("C", FOO));
    |                                  ^^^ not a string literal
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:110:19
+  --> $DIR/parse-error.rs:112:19
    |
 LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:112:28
+  --> $DIR/parse-error.rs:114:28
    |
 LL | global_asm!("", options(), clobber_abi("C"));
    |                            ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:114:30
+  --> $DIR/parse-error.rs:116:30
    |
 LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
    |                              ^^^^^^^^^^^^^^^^
 
 error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:116:35
+  --> $DIR/parse-error.rs:118:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    -------------  ^^^^^^^^^^^^^ duplicate argument
@@ -275,7 +287,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    previously here
 
 error: argument never used
-  --> $DIR/parse-error.rs:116:35
+  --> $DIR/parse-error.rs:118:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                                   ^^^^^^^^^^^^^ argument never used
@@ -283,19 +295,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
-  --> $DIR/parse-error.rs:119:28
+  --> $DIR/parse-error.rs:121:28
    |
 LL | global_asm!("", options(), "");
    |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
-  --> $DIR/parse-error.rs:121:30
+  --> $DIR/parse-error.rs:123:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
    |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:123:13
+  --> $DIR/parse-error.rs:125:13
    |
 LL | global_asm!(format!("{{{}}}", 0), const FOO);
    |             ^^^^^^^^^^^^^^^^^^^^
@@ -303,7 +315,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:125:20
+  --> $DIR/parse-error.rs:127:20
    |
 LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    |                    ^^^^^^^^^^^^^^^^^^^^
@@ -398,6 +410,6 @@ help: consider using `const` instead of `let`
 LL |     const bar: /* Type */ = 0;
    |     ~~~~~    ++++++++++++
 
-error: aborting due to 57 previous errors
+error: aborting due to 59 previous errors
 
 For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs
new file mode 100644
index 00000000000..cfb38f2e738
--- /dev/null
+++ b/tests/ui/asm/naked-functions-inline.rs
@@ -0,0 +1,38 @@
+//@ needs-asm-support
+#![feature(naked_functions)]
+#![crate_type = "lib"]
+
+use std::arch::asm;
+
+#[naked]
+pub unsafe extern "C" fn inline_none() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline]
+//~^ ERROR [E0736]
+pub unsafe extern "C" fn inline_hint() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline(always)]
+//~^ ERROR [E0736]
+pub unsafe extern "C" fn inline_always() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline(never)]
+//~^ ERROR [E0736]
+pub unsafe extern "C" fn inline_never() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[cfg_attr(all(), inline(never))]
+//~^ ERROR [E0736]
+pub unsafe extern "C" fn conditional_inline_never() {
+    asm!("", options(noreturn));
+}
diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr
new file mode 100644
index 00000000000..84a688f6f53
--- /dev/null
+++ b/tests/ui/asm/naked-functions-inline.stderr
@@ -0,0 +1,35 @@
+error[E0736]: attribute incompatible with `#[naked]`
+  --> $DIR/naked-functions-inline.rs:13:1
+   |
+LL | #[naked]
+   | -------- function marked with `#[naked]` here
+LL | #[inline]
+   | ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+
+error[E0736]: attribute incompatible with `#[naked]`
+  --> $DIR/naked-functions-inline.rs:20:1
+   |
+LL | #[naked]
+   | -------- function marked with `#[naked]` here
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+
+error[E0736]: attribute incompatible with `#[naked]`
+  --> $DIR/naked-functions-inline.rs:27:1
+   |
+LL | #[naked]
+   | -------- function marked with `#[naked]` here
+LL | #[inline(never)]
+   | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+
+error[E0736]: attribute incompatible with `#[naked]`
+  --> $DIR/naked-functions-inline.rs:34:19
+   |
+LL | #[naked]
+   | -------- function marked with `#[naked]` here
+LL | #[cfg_attr(all(), inline(never))]
+   |                   ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0736`.
diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs
new file mode 100644
index 00000000000..b81b65cff74
--- /dev/null
+++ b/tests/ui/asm/naked-functions-instruction-set.rs
@@ -0,0 +1,30 @@
+//@ compile-flags: --target armv5te-unknown-linux-gnueabi
+//@ needs-llvm-components: arm
+//@ needs-asm-support
+//@ build-pass
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[no_mangle]
+#[naked]
+#[instruction_set(arm::t32)]
+unsafe extern "C" fn test_thumb() {
+    asm!("bx lr", options(noreturn));
+}
+
+#[no_mangle]
+#[naked]
+#[instruction_set(arm::t32)]
+unsafe extern "C" fn test_arm() {
+    asm!("bx lr", options(noreturn));
+}
diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs
new file mode 100644
index 00000000000..12943ac0378
--- /dev/null
+++ b/tests/ui/asm/naked-functions-testattrs.rs
@@ -0,0 +1,39 @@
+//@ needs-asm-support
+//@ compile-flags: --test
+
+#![allow(undefined_naked_function_abi)]
+#![feature(naked_functions)]
+#![feature(test)]
+#![crate_type = "lib"]
+
+use std::arch::asm;
+
+#[test]
+#[naked]
+//~^ ERROR [E0736]
+fn test_naked() {
+    unsafe { asm!("", options(noreturn)) };
+}
+
+#[should_panic]
+#[test]
+#[naked]
+//~^ ERROR [E0736]
+fn test_naked_should_panic() {
+    unsafe { asm!("", options(noreturn)) };
+}
+
+#[ignore]
+#[test]
+#[naked]
+//~^ ERROR [E0736]
+fn test_naked_ignore() {
+    unsafe { asm!("", options(noreturn)) };
+}
+
+#[bench]
+#[naked]
+//~^ ERROR [E0736]
+fn bench_naked() {
+    unsafe { asm!("", options(noreturn)) };
+}
diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr
new file mode 100644
index 00000000000..4dabe41964a
--- /dev/null
+++ b/tests/ui/asm/naked-functions-testattrs.stderr
@@ -0,0 +1,35 @@
+error[E0736]: cannot use `#[naked]` with testing attributes
+  --> $DIR/naked-functions-testattrs.rs:12:1
+   |
+LL | #[test]
+   | ------- function marked with testing attribute here
+LL | #[naked]
+   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+
+error[E0736]: cannot use `#[naked]` with testing attributes
+  --> $DIR/naked-functions-testattrs.rs:20:1
+   |
+LL | #[test]
+   | ------- function marked with testing attribute here
+LL | #[naked]
+   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+
+error[E0736]: cannot use `#[naked]` with testing attributes
+  --> $DIR/naked-functions-testattrs.rs:28:1
+   |
+LL | #[test]
+   | ------- function marked with testing attribute here
+LL | #[naked]
+   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+
+error[E0736]: cannot use `#[naked]` with testing attributes
+  --> $DIR/naked-functions-testattrs.rs:35:1
+   |
+LL | #[bench]
+   | -------- function marked with testing attribute here
+LL | #[naked]
+   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0736`.
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 6b2d2aea238..6d335ac2def 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -3,7 +3,7 @@
 //@ ignore-spirv
 
 #![feature(naked_functions)]
-#![feature(asm_const, asm_unwind)]
+#![feature(asm_const, asm_unwind, linkage)]
 #![crate_type = "lib"]
 
 use std::arch::asm;
@@ -163,57 +163,89 @@ pub unsafe extern "C" fn valid_att_syntax() {
 }
 
 #[naked]
-pub unsafe extern "C" fn inline_none() {
-    asm!("", options(noreturn));
+#[naked]
+pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
+    compile_error!("this is a user specified error")
+    //~^ ERROR this is a user specified error
 }
 
 #[naked]
-#[inline]
-//~^ ERROR naked functions cannot be inlined
-pub unsafe extern "C" fn inline_hint() {
-    asm!("", options(noreturn));
+pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
+    compile_error!("this is a user specified error");
+    //~^ ERROR this is a user specified error
+    asm!("", options(noreturn))
 }
 
 #[naked]
-#[inline(always)]
-//~^ ERROR naked functions cannot be inlined
-pub unsafe extern "C" fn inline_always() {
-    asm!("", options(noreturn));
+pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
+    asm!(invalid_syntax)
+    //~^ ERROR asm template must be a string literal
 }
 
+#[cfg(target_arch = "x86_64")]
+#[cfg_attr(target_pointer_width = "64", no_mangle)]
 #[naked]
-#[inline(never)]
-//~^ ERROR naked functions cannot be inlined
-pub unsafe extern "C" fn inline_never() {
-    asm!("", options(noreturn));
+pub unsafe extern "C" fn compatible_cfg_attributes() {
+    asm!("", options(noreturn, att_syntax));
 }
 
+#[allow(dead_code)]
+#[warn(dead_code)]
+#[deny(dead_code)]
+#[forbid(dead_code)]
 #[naked]
-#[inline]
-//~^ ERROR naked functions cannot be inlined
-#[inline(always)]
-//~^ ERROR naked functions cannot be inlined
-#[inline(never)]
-//~^ ERROR naked functions cannot be inlined
-pub unsafe extern "C" fn inline_all() {
-    asm!("", options(noreturn));
+pub unsafe extern "C" fn compatible_diagnostic_attributes() {
+    asm!("", options(noreturn, raw));
 }
 
+#[deprecated = "test"]
 #[naked]
-pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
-    compile_error!("this is a user specified error")
-    //~^ ERROR this is a user specified error
+pub unsafe extern "C" fn compatible_deprecated_attributes() {
+    asm!("", options(noreturn, raw));
 }
 
+#[cfg(target_arch = "x86_64")]
+#[must_use]
 #[naked]
-pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
-    compile_error!("this is a user specified error");
-    //~^ ERROR this is a user specified error
-    asm!("", options(noreturn))
+pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
+    asm!(
+        "
+        mov rax, 42
+        ret
+        ",
+        options(noreturn)
+    )
 }
 
+#[export_name = "exported_function_name"]
+#[link_section = ".custom_section"]
+#[no_mangle]
 #[naked]
-pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
-    asm!(invalid_syntax)
-    //~^ ERROR asm template must be a string literal
+pub unsafe extern "C" fn compatible_ffi_attributes_1() {
+    asm!("", options(noreturn, raw));
+}
+
+#[cold]
+#[naked]
+pub unsafe extern "C" fn compatible_codegen_attributes() {
+    asm!("", options(noreturn, raw));
+}
+
+#[cfg(target_arch = "x86_64")]
+#[target_feature(enable = "sse2")]
+#[naked]
+pub unsafe extern "C" fn compatible_target_feature() {
+    asm!("", options(noreturn));
+}
+
+#[doc = "foo bar baz"]
+#[naked]
+pub unsafe extern "C" fn compatible_doc_attributes() {
+    asm!("", options(noreturn, raw));
+}
+
+#[linkage = "external"]
+#[naked]
+pub unsafe extern "C" fn compatible_linkage() {
+    asm!("", options(noreturn, raw));
 }
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index 4dd9e29bdc6..93c02e2fbef 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -5,19 +5,19 @@ LL |     asm!("", options(readonly, nostack), options(pure));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:204:5
+  --> $DIR/naked-functions.rs:168:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:210:5
+  --> $DIR/naked-functions.rs:174:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:217:10
+  --> $DIR/naked-functions.rs:181:10
    |
 LL |     asm!(invalid_syntax)
    |          ^^^^^^^^^^^^^^
@@ -249,42 +249,6 @@ warning: Rust ABI is unsupported in naked functions
 LL | pub unsafe fn rust_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:171:1
-   |
-LL | #[inline]
-   | ^^^^^^^^^
-
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:178:1
-   |
-LL | #[inline(always)]
-   | ^^^^^^^^^^^^^^^^^
-
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:185:1
-   |
-LL | #[inline(never)]
-   | ^^^^^^^^^^^^^^^^
-
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:192:1
-   |
-LL | #[inline]
-   | ^^^^^^^^^
-
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:194:1
-   |
-LL | #[inline(always)]
-   | ^^^^^^^^^^^^^^^^^
-
-error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:196:1
-   |
-LL | #[inline(never)]
-   | ^^^^^^^^^^^^^^^^
-
-error: aborting due to 33 previous errors; 2 warnings emitted
+error: aborting due to 27 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0787`.
diff --git a/tests/ui/asm/parse-error.rs b/tests/ui/asm/parse-error.rs
index a0251c6763b..9dec3a1c394 100644
--- a/tests/ui/asm/parse-error.rs
+++ b/tests/ui/asm/parse-error.rs
@@ -111,11 +111,15 @@ global_asm!("{}", const);
 global_asm!("{}", const(reg) FOO);
 //~^ ERROR expected one of
 global_asm!("", options(FOO));
-//~^ ERROR expected one of
+//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
+global_asm!("", options(FOO,));
+//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
 global_asm!("", options(nomem FOO));
-//~^ ERROR expected one of
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
+//~| ERROR expected one of `)` or `,`, found `FOO`
 global_asm!("", options(nomem, FOO));
-//~^ ERROR expected one of
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
+//~| ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
 global_asm!("{}", options(), const FOO);
 global_asm!("", clobber_abi(FOO));
 //~^ ERROR expected string literal
diff --git a/tests/ui/asm/parse-error.stderr b/tests/ui/asm/parse-error.stderr
index 1999cd09aa3..e9ecd712bc3 100644
--- a/tests/ui/asm/parse-error.stderr
+++ b/tests/ui/asm/parse-error.stderr
@@ -264,62 +264,80 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
 LL | global_asm!("", options(FOO));
    |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
   --> $DIR/parse-error.rs:115:25
    |
-LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+LL | global_asm!("", options(FOO,));
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+error: the `nomem` option cannot be used with `global_asm!`
   --> $DIR/parse-error.rs:117:25
    |
+LL | global_asm!("", options(nomem FOO));
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
+
+error: expected one of `)` or `,`, found `FOO`
+  --> $DIR/parse-error.rs:117:31
+   |
+LL | global_asm!("", options(nomem FOO));
+   |                               ^^^ expected one of `)` or `,`
+
+error: the `nomem` option cannot be used with `global_asm!`
+  --> $DIR/parse-error.rs:120:25
+   |
+LL | global_asm!("", options(nomem, FOO));
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
+
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
+  --> $DIR/parse-error.rs:120:32
+   |
 LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                                ^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:120:29
+  --> $DIR/parse-error.rs:124:29
    |
 LL | global_asm!("", clobber_abi(FOO));
    |                             ^^^ not a string literal
 
 error: expected one of `)` or `,`, found `FOO`
-  --> $DIR/parse-error.rs:122:33
+  --> $DIR/parse-error.rs:126:33
    |
 LL | global_asm!("", clobber_abi("C" FOO));
    |                                 ^^^ expected one of `)` or `,`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:124:34
+  --> $DIR/parse-error.rs:128:34
    |
 LL | global_asm!("", clobber_abi("C", FOO));
    |                                  ^^^ not a string literal
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:126:19
+  --> $DIR/parse-error.rs:130:19
    |
 LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:128:28
+  --> $DIR/parse-error.rs:132:28
    |
 LL | global_asm!("", options(), clobber_abi("C"));
    |                            ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:130:30
+  --> $DIR/parse-error.rs:134:30
    |
 LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
    |                              ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:132:17
+  --> $DIR/parse-error.rs:136:17
    |
 LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
    |                 ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^
 
 error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:134:35
+  --> $DIR/parse-error.rs:138:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    -------------  ^^^^^^^^^^^^^ duplicate argument
@@ -327,7 +345,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    previously here
 
 error: argument never used
-  --> $DIR/parse-error.rs:134:35
+  --> $DIR/parse-error.rs:138:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                                   ^^^^^^^^^^^^^ argument never used
@@ -335,19 +353,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
-  --> $DIR/parse-error.rs:137:28
+  --> $DIR/parse-error.rs:141:28
    |
 LL | global_asm!("", options(), "");
    |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
-  --> $DIR/parse-error.rs:139:30
+  --> $DIR/parse-error.rs:143:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
    |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:141:13
+  --> $DIR/parse-error.rs:145:13
    |
 LL | global_asm!(format!("{{{}}}", 0), const FOO);
    |             ^^^^^^^^^^^^^^^^^^^^
@@ -355,7 +373,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:143:20
+  --> $DIR/parse-error.rs:147:20
    |
 LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    |                    ^^^^^^^^^^^^^^^^^^^^
@@ -363,7 +381,7 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected operand, options, or additional template string
-  --> $DIR/parse-error.rs:145:19
+  --> $DIR/parse-error.rs:149:19
    |
 LL | global_asm!("{}", label {});
    |                   ^^^^^^^^ expected operand, options, or additional template string
@@ -423,6 +441,6 @@ help: consider using `const` instead of `let`
 LL |     const bar: /* Type */ = 0;
    |     ~~~~~    ++++++++++++
 
-error: aborting due to 64 previous errors
+error: aborting due to 67 previous errors
 
 For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/asm/unsupported-option.fixed b/tests/ui/asm/unsupported-option.fixed
new file mode 100644
index 00000000000..d313d8028b6
--- /dev/null
+++ b/tests/ui/asm/unsupported-option.fixed
@@ -0,0 +1,11 @@
+//@ needs-asm-support
+//@ run-rustfix
+
+use std::arch::global_asm;
+
+fn main() {}
+
+global_asm!("", options(   raw));
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
+//~| ERROR the `readonly` option cannot be used with `global_asm!`
+//~| ERROR the `noreturn` option cannot be used with `global_asm!`
diff --git a/tests/ui/asm/unsupported-option.rs b/tests/ui/asm/unsupported-option.rs
new file mode 100644
index 00000000000..d75f8e7f569
--- /dev/null
+++ b/tests/ui/asm/unsupported-option.rs
@@ -0,0 +1,11 @@
+//@ needs-asm-support
+//@ run-rustfix
+
+use std::arch::global_asm;
+
+fn main() {}
+
+global_asm!("", options(nomem, readonly, noreturn, raw));
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
+//~| ERROR the `readonly` option cannot be used with `global_asm!`
+//~| ERROR the `noreturn` option cannot be used with `global_asm!`
diff --git a/tests/ui/asm/unsupported-option.stderr b/tests/ui/asm/unsupported-option.stderr
new file mode 100644
index 00000000000..7a6927152b6
--- /dev/null
+++ b/tests/ui/asm/unsupported-option.stderr
@@ -0,0 +1,20 @@
+error: the `nomem` option cannot be used with `global_asm!`
+  --> $DIR/unsupported-option.rs:8:25
+   |
+LL | global_asm!("", options(nomem, readonly, noreturn, raw));
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
+
+error: the `readonly` option cannot be used with `global_asm!`
+  --> $DIR/unsupported-option.rs:8:32
+   |
+LL | global_asm!("", options(nomem, readonly, noreturn, raw));
+   |                                ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
+
+error: the `noreturn` option cannot be used with `global_asm!`
+  --> $DIR/unsupported-option.rs:8:42
+   |
+LL | global_asm!("", options(nomem, readonly, noreturn, raw));
+   |                                          ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/asm/x86_64/bad-options.rs b/tests/ui/asm/x86_64/bad-options.rs
index f9cc13cfc5a..6424a1b1d42 100644
--- a/tests/ui/asm/x86_64/bad-options.rs
+++ b/tests/ui/asm/x86_64/bad-options.rs
@@ -33,14 +33,14 @@ fn main() {
 }
 
 global_asm!("", options(nomem));
-//~^ ERROR expected one of
+//~^ ERROR the `nomem` option cannot be used with `global_asm!`
 global_asm!("", options(readonly));
-//~^ ERROR expected one of
+//~^ ERROR the `readonly` option cannot be used with `global_asm!`
 global_asm!("", options(noreturn));
-//~^ ERROR expected one of
+//~^ ERROR the `noreturn` option cannot be used with `global_asm!`
 global_asm!("", options(pure));
-//~^ ERROR expected one of
+//~^ ERROR the `pure` option cannot be used with `global_asm!`
 global_asm!("", options(nostack));
-//~^ ERROR expected one of
+//~^ ERROR the `nostack` option cannot be used with `global_asm!`
 global_asm!("", options(preserves_flags));
-//~^ ERROR expected one of
+//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!`
diff --git a/tests/ui/asm/x86_64/bad-options.stderr b/tests/ui/asm/x86_64/bad-options.stderr
index aa167e7913c..366eb7cb90f 100644
--- a/tests/ui/asm/x86_64/bad-options.stderr
+++ b/tests/ui/asm/x86_64/bad-options.stderr
@@ -51,41 +51,41 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
    |                    |             clobber_abi
    |                    generic outputs
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
+error: the `nomem` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:35:25
    |
 LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
+error: the `readonly` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:37:25
    |
 LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
+error: the `noreturn` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:39:25
    |
 LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
+error: the `pure` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:41:25
    |
 LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
+error: the `nostack` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:43:25
    |
 LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
 
-error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
+error: the `preserves_flags` option cannot be used with `global_asm!`
   --> $DIR/bad-options.rs:45:25
    |
 LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
+   |                         ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
 
 error: invalid ABI for `clobber_abi`
   --> $DIR/bad-options.rs:24:18
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
deleted file mode 100644
index 5ac7e1e58b8..00000000000
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ compile-flags: --crate-type=lib
-//@ check-pass
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-// Bounds on the self type play a major role in the resolution of inherent associated types (*).
-// As a result of that, if a type alias contains any then its bounds have to be respected and the
-// lint `type_alias_bounds` should not fire.
-
-#![deny(type_alias_bounds)]
-
-pub type Alias<T: Bound> = (Source<T>::Assoc,);
-
-pub struct Source<T>(T);
-pub trait Bound {}
-
-impl<T: Bound> Source<T> {
-    pub type Assoc = ();
-}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs
new file mode 100644
index 00000000000..61641a83994
--- /dev/null
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs
@@ -0,0 +1,29 @@
+//@ compile-flags: --crate-type=lib
+//@ check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// FIXME(inherent_associated_types):
+// While we currently do take some clauses of the ParamEnv into consideration
+// when performing IAT selection, we do not perform full well-formedness checking
+// for (eager) type alias definition and usage sites.
+//
+// Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the
+// fact that removing `Bound` from `T` in `Alias` would lead to an error!
+//
+// Obviously, the present situation isn't ideal and we should fix it in one way
+// or another. Either we somehow delay IAT selection until after HIR ty lowering
+// to avoid the need to specify any bounds inside (eager) type aliases or we
+// force the overarching type alias to be *lazy* (similar to TAITs) which would
+// automatically lead to full wfchecking and lint TAB getting suppressed.
+
+pub type Alias<T: Bound> = (Source<T>::Assoc,);
+//~^ WARN bounds on generic parameters in type aliases are not enforced
+
+pub struct Source<T>(T);
+pub trait Bound {}
+
+impl<T: Bound> Source<T> {
+    pub type Assoc = ();
+}
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.stderr b/tests/ui/associated-inherent-types/type-alias-bounds.stderr
new file mode 100644
index 00000000000..c56dd498f77
--- /dev/null
+++ b/tests/ui/associated-inherent-types/type-alias-bounds.stderr
@@ -0,0 +1,16 @@
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:21:19
+   |
+LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
+   |                 --^^^^^
+   |                 | |
+   |                 | will not be checked at usage sites of the type alias
+   |                 help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+   = note: `#[warn(type_alias_bounds)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/type-alias.stderr b/tests/ui/associated-type-bounds/type-alias.stderr
index 072c471467c..d59952b4a14 100644
--- a/tests/ui/associated-type-bounds/type-alias.stderr
+++ b/tests/ui/associated-type-bounds/type-alias.stderr
@@ -1,147 +1,159 @@
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:3:25
    |
 LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
-LL + type _TaWhere1<T>  = T;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:4:25
    |
 LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
-LL + type _TaWhere2<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:5:25
    |
 LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
-LL + type _TaWhere3<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:6:25
    |
 LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
-LL + type _TaWhere4<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:7:25
    |
 LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
-LL + type _TaWhere5<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias.rs:8:25
    |
 LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
-LL + type _TaWhere6<T>  = T;
-   |
+   |                   ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |     |
+   |                   |     will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:10:20
    |
 LL | type _TaInline1<T: Iterator<Item: Copy>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline1<T: Iterator<Item: Copy>> = T;
-LL + type _TaInline1<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:11:20
    |
 LL | type _TaInline2<T: Iterator<Item: 'static>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline2<T: Iterator<Item: 'static>> = T;
-LL + type _TaInline2<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:12:20
    |
 LL | type _TaInline3<T: Iterator<Item: 'static>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline3<T: Iterator<Item: 'static>> = T;
-LL + type _TaInline3<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:13:20
    |
 LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
-LL + type _TaInline4<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:14:20
    |
 LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
-LL + type _TaInline5<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias.rs:15:20
    |
 LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
-LL + type _TaInline6<T> = T;
-   |
+   |                  --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  | |
+   |                  | will not be checked at usage sites of the type alias
+   |                  help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 warning: 12 warnings emitted
 
diff --git a/tests/ui/associated-types/associated-types-outlives.stderr b/tests/ui/associated-types/associated-types-outlives.stderr
index c97af672c33..1164869bf19 100644
--- a/tests/ui/associated-types/associated-types-outlives.stderr
+++ b/tests/ui/associated-types/associated-types-outlives.stderr
@@ -11,10 +11,14 @@ LL |         drop(x);
 LL |         return f(y);
    |                  - borrow later used here
    |
-help: consider cloning the value if the performance cost is acceptable
+help: if `T` implemented `Clone`, you could clone the value
+  --> $DIR/associated-types-outlives.rs:17:21
    |
-LL |         's: loop { y = denormalise(&x).clone(); break }
-   |                                       ++++++++
+LL | pub fn free_and_use<T: for<'a> Foo<'a>,
+   |                     ^ consider constraining this type parameter with `Clone`
+...
+LL |         's: loop { y = denormalise(&x); break }
+   |                                    -- you could clone this value
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/async-closures/clone-closure.rs b/tests/ui/async-await/async-closures/clone-closure.rs
new file mode 100644
index 00000000000..807897e3e03
--- /dev/null
+++ b/tests/ui/async-await/async-closures/clone-closure.rs
@@ -0,0 +1,24 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ run-pass
+//@ check-run-results
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+async fn for_each(f: impl async FnOnce(&str) + Clone) {
+    f.clone()("world").await;
+    f.clone()("world2").await;
+}
+
+fn main() {
+    block_on::block_on(async_main());
+}
+
+async fn async_main() {
+    let x = String::from("Hello,");
+    for_each(async move |s| {
+        println!("{x} {s}");
+    }).await;
+}
diff --git a/tests/ui/async-await/async-closures/clone-closure.run.stdout b/tests/ui/async-await/async-closures/clone-closure.run.stdout
new file mode 100644
index 00000000000..0cfcf1923da
--- /dev/null
+++ b/tests/ui/async-await/async-closures/clone-closure.run.stdout
@@ -0,0 +1,2 @@
+Hello, world
+Hello, world2
diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.stderr b/tests/ui/async-await/async-closures/move-consuming-capture.stderr
index 45c1eac8f8f..4ce71ec49d6 100644
--- a/tests/ui/async-await/async-closures/move-consuming-capture.stderr
+++ b/tests/ui/async-await/async-closures/move-consuming-capture.stderr
@@ -11,6 +11,15 @@ LL |         x().await;
    |
 note: `async_call_once` takes ownership of the receiver `self`, which moves `x`
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
+help: you could `clone` the value and consume it, if the `NoCopy: Clone` trait bound could be satisfied
+   |
+LL |         x.clone()().await;
+   |          ++++++++
+help: consider annotating `NoCopy` with `#[derive(Clone)]`
+   |
+LL + #[derive(Clone)]
+LL | struct NoCopy;
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/async-closures/not-clone-closure.rs b/tests/ui/async-await/async-closures/not-clone-closure.rs
new file mode 100644
index 00000000000..2776ce4690f
--- /dev/null
+++ b/tests/ui/async-await/async-closures/not-clone-closure.rs
@@ -0,0 +1,36 @@
+//@ edition: 2021
+
+#![feature(async_closure)]
+
+struct NotClonableArg;
+#[derive(Default)]
+struct NotClonableReturnType;
+
+// Verify that the only components that we care about are the upvars, not the signature.
+fn we_are_okay_with_not_clonable_signature() {
+    let x = async |x: NotClonableArg| -> NotClonableReturnType { Default::default() };
+    x.clone(); // Okay
+}
+
+#[derive(Debug)]
+struct NotClonableUpvar;
+
+fn we_only_care_about_clonable_upvars() {
+    let x = NotClonableUpvar;
+    // Notably, this is clone because we capture `&x`.
+    let yes_clone = async || {
+        println!("{x:?}");
+    };
+    yes_clone.clone(); // Okay
+
+    let z = NotClonableUpvar;
+    // However, this is not because the closure captures `z` by move.
+    // (Even though the future that is lent out captures `z by ref!)
+    let not_clone = async move || {
+        println!("{z:?}");
+    };
+    not_clone.clone();
+    //~^ ERROR the trait bound `NotClonableUpvar: Clone` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/async-closures/not-clone-closure.stderr b/tests/ui/async-await/async-closures/not-clone-closure.stderr
new file mode 100644
index 00000000000..aea48a455c2
--- /dev/null
+++ b/tests/ui/async-await/async-closures/not-clone-closure.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`
+  --> $DIR/not-clone-closure.rs:32:15
+   |
+LL |     not_clone.clone();
+   |               ^^^^^ within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`, which is required by `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}: Clone`
+   |
+note: required because it's used within this closure
+  --> $DIR/not-clone-closure.rs:29:21
+   |
+LL |     let not_clone = async move || {
+   |                     ^^^^^^^^^^^^^
+help: consider annotating `NotClonableUpvar` with `#[derive(Clone)]`
+   |
+LL + #[derive(Clone)]
+LL | struct NotClonableUpvar;
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
index 17681161e20..18f16ca4b2d 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
@@ -19,7 +19,7 @@ fn simple<'a>(x: &'a i32) {
 
     let c = async move || { println!("{}", *x); };
     outlives::<'a>(c()); //~ ERROR `c` does not live long enough
-    outlives::<'a>(call_once(c)); //~ ERROR cannot move out of `c`
+    outlives::<'a>(call_once(c));
 }
 
 struct S<'a>(&'a i32);
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
index 569028934cb..1df5abdbb18 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
@@ -29,22 +29,6 @@ LL |     outlives::<'a>(call_once(c));
 LL | }
    | - `c` dropped here while still borrowed
 
-error[E0505]: cannot move out of `c` because it is borrowed
-  --> $DIR/without-precise-captures-we-are-powerless.rs:22:30
-   |
-LL | fn simple<'a>(x: &'a i32) {
-   |           -- lifetime `'a` defined here
-...
-LL |     let c = async move || { println!("{}", *x); };
-   |         - binding `c` declared here
-LL |     outlives::<'a>(c());
-   |                    ---
-   |                    |
-   |                    borrow of `c` occurs here
-   |                    argument requires that `c` is borrowed for `'a`
-LL |     outlives::<'a>(call_once(c));
-   |                              ^ move out of `c` occurs here
-
 error[E0597]: `x` does not live long enough
   --> $DIR/without-precise-captures-we-are-powerless.rs:28:13
    |
@@ -146,7 +130,7 @@ LL |     // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out w
 LL | }
    | - `c` dropped here while still borrowed
 
-error: aborting due to 10 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0505, E0597, E0621.
 For more information about an error, try `rustc --explain E0505`.
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
new file mode 100644
index 00000000000..fa12dd14753
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
@@ -0,0 +1,63 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:23:12
+   |
+LL |     let _: AliasConstUnused<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `ct_unused_0::AliasConstUnused`
+  --> $DIR/type-alias-bounds.rs:20:30
+   |
+LL |     type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
+   |                              ^^^^ required by this bound in `AliasConstUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:31:12
+   |
+LL |     let _: AliasConstUnused;
+   |            ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `ct_unused_1::AliasConstUnused`
+  --> $DIR/type-alias-bounds.rs:29:41
+   |
+LL |     type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+   |                                         ^^^^ required by this bound in `AliasConstUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:39:12
+   |
+LL |     let _: AliasFnUnused<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasFnUnused`
+  --> $DIR/type-alias-bounds.rs:36:27
+   |
+LL |     type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
+   |                           ^^^^ required by this bound in `AliasFnUnused`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:57:12
+   |
+LL |     let _: AliasAssocConstUsed<String>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasAssocConstUsed`
+  --> $DIR/type-alias-bounds.rs:55:41
+   |
+LL |     type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
+   |                                         ^^^^ required by this bound in `AliasAssocConstUsed`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/type-alias-bounds.rs:65:12
+   |
+LL |     let _: AliasFnUsed<String>;
+   |            ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+note: required by a bound in `AliasFnUsed`
+  --> $DIR/type-alias-bounds.rs:62:33
+   |
+LL |     type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
+   |                                 ^^^^ required by this bound in `AliasFnUsed`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
new file mode 100644
index 00000000000..f16e646129c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
@@ -0,0 +1,71 @@
+//@ revisions: pos neg
+//@[pos] check-pass
+
+#![feature(generic_const_exprs)]
+#![feature(trivial_bounds)] // only used in test case `ct_unused_1`
+#![allow(incomplete_features)]
+
+// FIXME(generic_const_exprs): Revisit this before stabilization.
+// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases
+// whose RHS contains a const projection (aka uneval'ed const).
+// Since anon consts inherit the parent generics and predicates and we effectively
+// check them before and after instantiaton for well-formedness, the type alias
+// bounds are in every sense "enforced".
+// Note that the test cases whose name ends in "unused" just demonstrate that this
+// holds even if the const projections don't "visibly" capture any generics and/or
+// predicates.
+#![deny(type_alias_bounds)]
+
+fn ct_unused_0() {
+    type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
+    const DATA: i32 = 0;
+    #[cfg(neg)]
+    let _: AliasConstUnused<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn ct_unused_1() {
+    #[allow(trivial_bounds)]
+    type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+    #[cfg(neg)]
+    let _: AliasConstUnused;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn fn_unused() {
+    type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
+    const fn code() -> i32 { 0 }
+    #[cfg(neg)]
+    let _: AliasFnUnused<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+trait Trait {
+    type Proj;
+    const DATA: i32;
+}
+
+impl Trait for String {
+    type Proj = i32;
+    const DATA: i32 = 0;
+}
+
+// Regression test for issue #94398.
+fn assoc_ct_used() {
+    type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
+    #[cfg(neg)]
+    let _: AliasAssocConstUsed<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn fn_used() {
+    type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
+    const fn code<T: Trait>() -> i32 { T::DATA }
+    #[cfg(neg)]
+    let _: AliasFnUsed<String>;
+    //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+struct I32<const N: i32>;
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/parse_ints.rs b/tests/ui/consts/const-eval/parse_ints.rs
index ff9fc47e65c..cb9a3eb4312 100644
--- a/tests/ui/consts/const-eval/parse_ints.rs
+++ b/tests/ui/consts/const-eval/parse_ints.rs
@@ -1,5 +1,3 @@
-#![feature(const_int_from_str)]
-
 const _OK: () = match i32::from_str_radix("-1234", 10) {
     Ok(x) => assert!(x == -1234),
     Err(_) => panic!(),
diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr
index 9e49fe433a1..ec9249ece8e 100644
--- a/tests/ui/consts/const-eval/parse_ints.stderr
+++ b/tests/ui/consts/const-eval/parse_ints.stderr
@@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed
 note: inside `core::num::<impl u64>::from_str_radix`
   --> $SRC_DIR/core/src/num/mod.rs:LL:COL
 note: inside `_TOO_LOW`
-  --> $DIR/parse_ints.rs:7:24
+  --> $DIR/parse_ints.rs:5:24
    |
 LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); };
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed
 note: inside `core::num::<impl u64>::from_str_radix`
   --> $SRC_DIR/core/src/num/mod.rs:LL:COL
 note: inside `_TOO_HIGH`
-  --> $DIR/parse_ints.rs:8:25
+  --> $DIR/parse_ints.rs:6:25
    |
 LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); };
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/consts/packed_pattern.stderr b/tests/ui/consts/packed_pattern.stderr
index 9ca50a95e4e..a0b434b2d78 100644
--- a/tests/ui/consts/packed_pattern.stderr
+++ b/tests/ui/consts/packed_pattern.stderr
@@ -1,8 +1,10 @@
 warning: unreachable pattern
   --> $DIR/packed_pattern.rs:16:9
    |
+LL |         Foo { field: (5, 6, 7, 8) } => {},
+   |         --------------------------- matches all the values already
 LL |         FOO => unreachable!(),
-   |         ^^^
+   |         ^^^ unreachable pattern
    |
    = note: `#[warn(unreachable_patterns)]` on by default
 
diff --git a/tests/ui/consts/packed_pattern2.stderr b/tests/ui/consts/packed_pattern2.stderr
index 4dc54461eeb..4785f4d0297 100644
--- a/tests/ui/consts/packed_pattern2.stderr
+++ b/tests/ui/consts/packed_pattern2.stderr
@@ -1,8 +1,10 @@
 warning: unreachable pattern
   --> $DIR/packed_pattern2.rs:24:9
    |
+LL |         Bar { a: Foo { field: (5, 6) } } => {},
+   |         -------------------------------- matches all the values already
 LL |         FOO => unreachable!(),
-   |         ^^^
+   |         ^^^ unreachable pattern
    |
    = note: `#[warn(unreachable_patterns)]` on by default
 
diff --git a/tests/ui/error-codes/E0001.stderr b/tests/ui/error-codes/E0001.stderr
index 49bb73e7ba8..40008230ec8 100644
--- a/tests/ui/error-codes/E0001.stderr
+++ b/tests/ui/error-codes/E0001.stderr
@@ -2,8 +2,17 @@ error: unreachable pattern
   --> $DIR/E0001.rs:8:9
    |
 LL |         _ => {/* ... */}
-   |         ^
+   |         ^ unreachable pattern
    |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/E0001.rs:8:9
+   |
+LL |         Some(_) => {/* ... */}
+   |         ------- matches some of the same values
+LL |         None => {/* ... */}
+   |         ---- matches some of the same values
+LL |         _ => {/* ... */}
+   |         ^ collectively making this unreachable
 note: the lint level is defined here
   --> $DIR/E0001.rs:1:9
    |
diff --git a/tests/ui/feature-gates/feature-gate-is_sorted.rs b/tests/ui/feature-gates/feature-gate-is_sorted.rs
deleted file mode 100644
index 359ed835bcb..00000000000
--- a/tests/ui/feature-gates/feature-gate-is_sorted.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-fn main() {
-    // Assert `Iterator` methods are unstable
-    assert!([1, 2, 2, 9].iter().is_sorted());
-    //~^ ERROR: use of unstable library feature 'is_sorted': new API
-    assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
-    //~^ ERROR: use of unstable library feature 'is_sorted': new API
-
-    // Assert `[T]` methods are unstable
-    assert!([1, 2, 2, 9].is_sorted());
-    //~^ ERROR: use of unstable library feature 'is_sorted': new API
-    assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
-    //~^ ERROR: use of unstable library feature 'is_sorted': new API
-}
diff --git a/tests/ui/feature-gates/feature-gate-is_sorted.stderr b/tests/ui/feature-gates/feature-gate-is_sorted.stderr
deleted file mode 100644
index f3e87659b02..00000000000
--- a/tests/ui/feature-gates/feature-gate-is_sorted.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0658]: use of unstable library feature 'is_sorted': new API
-  --> $DIR/feature-gate-is_sorted.rs:3:33
-   |
-LL |     assert!([1, 2, 2, 9].iter().is_sorted());
-   |                                 ^^^^^^^^^
-   |
-   = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
-   = help: add `#![feature(is_sorted)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: use of unstable library feature 'is_sorted': new API
-  --> $DIR/feature-gate-is_sorted.rs:5:39
-   |
-LL |     assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
-   |                                       ^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
-   = help: add `#![feature(is_sorted)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: use of unstable library feature 'is_sorted': new API
-  --> $DIR/feature-gate-is_sorted.rs:9:26
-   |
-LL |     assert!([1, 2, 2, 9].is_sorted());
-   |                          ^^^^^^^^^
-   |
-   = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
-   = help: add `#![feature(is_sorted)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: use of unstable library feature 'is_sorted': new API
-  --> $DIR/feature-gate-is_sorted.rs:11:32
-   |
-LL |     assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
-   |                                ^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information
-   = help: add `#![feature(is_sorted)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
new file mode 100644
index 00000000000..debe143b091
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs
@@ -0,0 +1,24 @@
+#![feature(auto_traits)]
+
+trait Trait1 {}
+auto trait Trait2 {}
+trait Trait3: ?Trait1 {}
+//~^  ERROR `?Trait` is not permitted in supertraits
+trait Trait4 where Self: ?Trait1 {}
+//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared
+
+fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
+//~^  ERROR `?Trait` is not permitted in trait object types
+fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+trait Trait {}
+// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
+fn baz<T: ?Trait + ?Trait>(_ : T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
new file mode 100644
index 00000000000..e6d65e05997
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr
@@ -0,0 +1,71 @@
+error[E0658]: `?Trait` is not permitted in supertraits
+  --> $DIR/feature-gate-more-maybe-bounds.rs:5:15
+   |
+LL | trait Trait3: ?Trait1 {}
+   |               ^^^^^^^
+   |
+   = note: traits are `?Trait1` by default
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` is not permitted in trait object types
+  --> $DIR/feature-gate-more-maybe-bounds.rs:10:28
+   |
+LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
+   |                            ^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
+  --> $DIR/feature-gate-more-maybe-bounds.rs:7:26
+   |
+LL | trait Trait4 where Self: ?Trait1 {}
+   |                          ^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+  --> $DIR/feature-gate-more-maybe-bounds.rs:12:11
+   |
+LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
+   |           ^^^^^^^   ^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:12:11
+   |
+LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
+   |           ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:12:21
+   |
+LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
+   |                     ^^^^^^^
+
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:11
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |           ^^^^^^   ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:11
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |           ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/feature-gate-more-maybe-bounds.rs:19:20
+   |
+LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
+   |                    ^^^^^^
+
+error: aborting due to 5 previous errors; 4 warnings emitted
+
+Some errors have detailed explanations: E0203, E0658.
+For more information about an error, try `rustc --explain E0203`.
diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.rs b/tests/ui/lang-items/missing-clone-for-suggestion.rs
deleted file mode 100644
index e8290c0098a..00000000000
--- a/tests/ui/lang-items/missing-clone-for-suggestion.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Avoid panicking if the Clone trait is not found while building error suggestions
-// See #104870
-
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-trait Sized {}
-
-#[lang = "copy"]
-trait Copy {}
-
-fn g<T>(x: T) {}
-
-fn f(x: *mut u8) {
-    g(x);
-    g(x); //~ ERROR use of moved value: `x`
-}
-
-fn main() {}
diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.stderr b/tests/ui/lang-items/missing-clone-for-suggestion.stderr
deleted file mode 100644
index 0187f965b5c..00000000000
--- a/tests/ui/lang-items/missing-clone-for-suggestion.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0382]: use of moved value: `x`
-  --> $DIR/missing-clone-for-suggestion.rs:17:7
-   |
-LL | fn f(x: *mut u8) {
-   |      - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait
-LL |     g(x);
-   |       - value moved here
-LL |     g(x);
-   |       ^ value used here after move
-   |
-note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary
-  --> $DIR/missing-clone-for-suggestion.rs:13:12
-   |
-LL | fn g<T>(x: T) {}
-   |    -       ^ this parameter takes ownership of the value
-   |    |
-   |    in this function
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs
new file mode 100644
index 00000000000..46065dcee81
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs
@@ -0,0 +1,45 @@
+#![deny(dead_code)]
+
+struct Foo; //~ ERROR struct `Foo` is never constructed
+
+trait Trait { //~ ERROR trait `Trait` is never used
+    fn foo(&self) {}
+}
+
+impl Trait for Foo {}
+
+impl Trait for [Foo] {}
+impl<const N: usize> Trait for [Foo; N] {}
+
+impl Trait for *const Foo {}
+impl Trait for *mut Foo {}
+
+impl Trait for &Foo {}
+impl Trait for &&Foo {}
+impl Trait for &mut Foo {}
+
+impl Trait for [&Foo] {}
+impl Trait for &[Foo] {}
+impl Trait for &*const Foo {}
+
+pub trait Trait2 {
+    fn foo(&self) {}
+}
+
+impl Trait2 for Foo {}
+
+impl Trait2 for [Foo] {}
+impl<const N: usize> Trait2 for [Foo; N] {}
+
+impl Trait2 for *const Foo {}
+impl Trait2 for *mut Foo {}
+
+impl Trait2 for &Foo {}
+impl Trait2 for &&Foo {}
+impl Trait2 for &mut Foo {}
+
+impl Trait2 for [&Foo] {}
+impl Trait2 for &[Foo] {}
+impl Trait2 for &*const Foo {}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr
new file mode 100644
index 00000000000..e61fc403e81
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr
@@ -0,0 +1,20 @@
+error: struct `Foo` is never constructed
+  --> $DIR/unused-impl-for-non-adts.rs:3:8
+   |
+LL | struct Foo;
+   |        ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused-impl-for-non-adts.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: trait `Trait` is never used
+  --> $DIR/unused-impl-for-non-adts.rs:5:7
+   |
+LL | trait Trait {
+   |       ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs
index 97454c9de07..a41372e4ea8 100644
--- a/tests/ui/macros/issue-118786.rs
+++ b/tests/ui/macros/issue-118786.rs
@@ -7,6 +7,7 @@ macro_rules! make_macro {
         macro_rules! $macro_name {
         //~^ ERROR macro expansion ignores token `{` and any following
         //~| ERROR cannot find macro `macro_rules` in this scope
+        //~| put a macro name here
             () => {}
         }
     }
diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr
index 03e65c94ba7..256b742ee16 100644
--- a/tests/ui/macros/issue-118786.stderr
+++ b/tests/ui/macros/issue-118786.stderr
@@ -1,5 +1,5 @@
 error: macros that expand to items must be delimited with braces or followed by a semicolon
-  --> $DIR/issue-118786.rs:15:13
+  --> $DIR/issue-118786.rs:16:13
    |
 LL | make_macro!((meow));
    |             ^^^^^^
@@ -34,10 +34,10 @@ LL | make_macro!((meow));
    | ------------------- in this macro invocation
    |
 note: maybe you have forgotten to define a name for this `macro_rules!`
-  --> $DIR/issue-118786.rs:7:9
+  --> $DIR/issue-118786.rs:7:20
    |
 LL |         macro_rules! $macro_name {
-   |         ^^^^^^^^^^^
+   |                    ^ put a macro name here
 ...
 LL | make_macro!((meow));
    | ------------------- in this macro invocation
diff --git a/tests/ui/macros/macro-missing-fragment.stderr b/tests/ui/macros/macro-missing-fragment.e2015.stderr
index abe4d4cd68a..a068dc5c054 100644
--- a/tests/ui/macros/macro-missing-fragment.stderr
+++ b/tests/ui/macros/macro-missing-fragment.e2015.stderr
@@ -1,11 +1,11 @@
 error: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:4:20
+  --> $DIR/macro-missing-fragment.rs:9:20
    |
 LL |     ( $( any_token $field_rust_type )* ) => {};
    |                    ^^^^^^^^^^^^^^^^
 
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:4:20
+  --> $DIR/macro-missing-fragment.rs:9:20
    |
 LL |     ( $( any_token $field_rust_type )* ) => {};
    |                    ^^^^^^^^^^^^^^^^
@@ -13,13 +13,13 @@ LL |     ( $( any_token $field_rust_type )* ) => {};
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
-  --> $DIR/macro-missing-fragment.rs:1:9
+  --> $DIR/macro-missing-fragment.rs:6:9
    |
 LL | #![warn(missing_fragment_specifier)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:12:7
+  --> $DIR/macro-missing-fragment.rs:19:7
    |
 LL |     ( $name ) => {};
    |       ^^^^^
@@ -28,7 +28,7 @@ LL |     ( $name ) => {};
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:18:7
+  --> $DIR/macro-missing-fragment.rs:26:7
    |
 LL |     ( $name ) => {};
    |       ^^^^^
@@ -40,7 +40,7 @@ error: aborting due to 1 previous error; 3 warnings emitted
 
 Future incompatibility report: Future breakage diagnostic:
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:4:20
+  --> $DIR/macro-missing-fragment.rs:9:20
    |
 LL |     ( $( any_token $field_rust_type )* ) => {};
    |                    ^^^^^^^^^^^^^^^^
@@ -48,14 +48,14 @@ LL |     ( $( any_token $field_rust_type )* ) => {};
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
-  --> $DIR/macro-missing-fragment.rs:1:9
+  --> $DIR/macro-missing-fragment.rs:6:9
    |
 LL | #![warn(missing_fragment_specifier)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Future breakage diagnostic:
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:12:7
+  --> $DIR/macro-missing-fragment.rs:19:7
    |
 LL |     ( $name ) => {};
    |       ^^^^^
@@ -63,14 +63,14 @@ LL |     ( $name ) => {};
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
-  --> $DIR/macro-missing-fragment.rs:1:9
+  --> $DIR/macro-missing-fragment.rs:6:9
    |
 LL | #![warn(missing_fragment_specifier)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Future breakage diagnostic:
 warning: missing fragment specifier
-  --> $DIR/macro-missing-fragment.rs:18:7
+  --> $DIR/macro-missing-fragment.rs:26:7
    |
 LL |     ( $name ) => {};
    |       ^^^^^
@@ -78,7 +78,7 @@ LL |     ( $name ) => {};
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
-  --> $DIR/macro-missing-fragment.rs:1:9
+  --> $DIR/macro-missing-fragment.rs:6:9
    |
 LL | #![warn(missing_fragment_specifier)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/macros/macro-missing-fragment.e2024.stderr b/tests/ui/macros/macro-missing-fragment.e2024.stderr
new file mode 100644
index 00000000000..3afa069c170
--- /dev/null
+++ b/tests/ui/macros/macro-missing-fragment.e2024.stderr
@@ -0,0 +1,47 @@
+error: missing fragment specifier
+  --> $DIR/macro-missing-fragment.rs:9:20
+   |
+LL |     ( $( any_token $field_rust_type )* ) => {};
+   |                    ^^^^^^^^^^^^^^^^
+   |
+   = note: fragment specifiers must be specified in the 2024 edition
+   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+help: try adding a specifier here
+   |
+LL |     ( $( any_token $field_rust_type:spec )* ) => {};
+   |                                    +++++
+
+error: missing fragment specifier
+  --> $DIR/macro-missing-fragment.rs:19:7
+   |
+LL |     ( $name ) => {};
+   |       ^^^^^
+   |
+   = note: fragment specifiers must be specified in the 2024 edition
+   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+help: try adding a specifier here
+   |
+LL |     ( $name:spec ) => {};
+   |            +++++
+
+error: missing fragment specifier
+  --> $DIR/macro-missing-fragment.rs:26:7
+   |
+LL |     ( $name ) => {};
+   |       ^^^^^
+   |
+   = note: fragment specifiers must be specified in the 2024 edition
+   = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
+help: try adding a specifier here
+   |
+LL |     ( $name:spec ) => {};
+   |            +++++
+
+error: missing fragment specifier
+  --> $DIR/macro-missing-fragment.rs:9:20
+   |
+LL |     ( $( any_token $field_rust_type )* ) => {};
+   |                    ^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/macros/macro-missing-fragment.rs b/tests/ui/macros/macro-missing-fragment.rs
index 210c85ebbf2..b7da87ae610 100644
--- a/tests/ui/macros/macro-missing-fragment.rs
+++ b/tests/ui/macros/macro-missing-fragment.rs
@@ -1,23 +1,32 @@
+//@ revisions: e2015 e2024
+//@[e2015] edition:2015
+//@[e2024] edition:2024
+//@[e2024] compile-flags: -Zunstable-options
+
 #![warn(missing_fragment_specifier)]
 
 macro_rules! used_arm {
     ( $( any_token $field_rust_type )* ) => {};
-    //~^ ERROR missing fragment
-    //~| WARN missing fragment
-    //~| WARN this was previously accepted
+    //[e2015]~^ ERROR missing fragment
+    //[e2015]~| WARN missing fragment
+    //[e2015]~| WARN this was previously accepted
+    //[e2024]~^^^^ ERROR missing fragment
+    //[e2024]~| ERROR missing fragment
 }
 
 macro_rules! used_macro_unused_arm {
     () => {};
     ( $name ) => {};
-    //~^ WARN missing fragment
-    //~| WARN this was previously accepted
+    //[e2015]~^ WARN missing fragment
+    //[e2015]~| WARN this was previously accepted
+    //[e2024]~^^^ ERROR missing fragment
 }
 
 macro_rules! unused_macro {
     ( $name ) => {};
-    //~^ WARN missing fragment
-    //~| WARN this was previously accepted
+    //[e2015]~^ WARN missing fragment
+    //[e2015]~| WARN this was previously accepted
+    //[e2024]~^^^ ERROR missing fragment
 }
 
 fn main() {
diff --git a/tests/ui/maybe-bounds.stderr b/tests/ui/maybe-bounds.stderr
index 1d823b6acb2..230d11fd0ae 100644
--- a/tests/ui/maybe-bounds.stderr
+++ b/tests/ui/maybe-bounds.stderr
@@ -1,22 +1,31 @@
-error: `?Trait` is not permitted in supertraits
+error[E0658]: `?Trait` is not permitted in supertraits
   --> $DIR/maybe-bounds.rs:1:11
    |
 LL | trait Tr: ?Sized {}
    |           ^^^^^^
    |
    = note: traits are `?Sized` by default
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bounds.rs:4:20
    |
 LL | type A1 = dyn Tr + (?Sized);
    |                    ^^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bounds.rs:6:28
    |
 LL | type A2 = dyn for<'a> Tr + (?Sized);
    |                            ^^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
index 1ad335bf394..afdcff0346b 100644
--- a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
+++ b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
@@ -29,6 +29,11 @@ fn main() {
         (1, 4 | 5) => {} //~ ERROR unreachable pattern
         _ => {}
     }
+    match (0u8, 0u8, 0u8) {
+        (0, 0, 0) => {}
+        (0, 0 | 1, 0) => {} //~ ERROR unreachable pattern
+        _ => {}
+    }
     match (true, true) {
         (false | true, false | true) => (),
     }
diff --git a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
index 336530d1b32..5570390b21c 100644
--- a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
+++ b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:8:9
    |
+LL |         (1 | 2,) => {}
+   |         -------- matches all the values already
 LL |         (1,) => {}
-   |         ^^^^
+   |         ^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/exhaustiveness-unreachable-pattern.rs:1:9
@@ -13,212 +15,354 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:13:9
    |
+LL |         (1 | 2,) => {}
+   |         -------- matches all the values already
 LL |         (2,) => {}
-   |         ^^^^
+   |         ^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9
    |
 LL |         (1 | 2,) => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9
+   |
+LL |         (1,) => {}
+   |         ---- matches some of the same values
+LL |         (2,) => {}
+   |         ---- matches some of the same values
+LL |         (1 | 2,) => {}
+   |         ^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:24:9
    |
+LL |         (1 | 2, 3 | 4) => {}
+   |         -------------- matches all the values already
 LL |         (1, 3) => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:25:9
    |
+LL |         (1 | 2, 3 | 4) => {}
+   |         -------------- matches all the values already
+LL |         (1, 3) => {}
 LL |         (1, 4) => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:26:9
    |
+LL |         (1 | 2, 3 | 4) => {}
+   |         -------------- matches all the values already
+...
 LL |         (2, 4) => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:27:9
    |
+LL |         (1 | 2, 3 | 4) => {}
+   |         -------------- matches all the values already
+...
 LL |         (2 | 1, 4) => {}
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9
    |
 LL |         (1, 4 | 5) => {}
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9
+   |
+LL |         (1 | 2, 3 | 4) => {}
+   |         -------------- matches some of the same values
+...
+LL |         (1, 5 | 6) => {}
+   |         ---------- matches some of the same values
+LL |         (1, 4 | 5) => {}
+   |         ^^^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:37:9
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:34:13
    |
+LL |         (0, 0, 0) => {}
+   |             - matches all the values already
+LL |         (0, 0 | 1, 0) => {}
+   |             ^ unreachable pattern
+
+error: unreachable pattern
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:42:9
+   |
+LL |         (None | Some(1 | 2),) => {}
+   |         --------------------- matches all the values already
 LL |         (Some(1),) => {}
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:38:9
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:43:9
    |
+LL |         (None | Some(1 | 2),) => {}
+   |         --------------------- matches all the values already
+LL |         (Some(1),) => {}
 LL |         (None,) => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:43:9
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:48:9
    |
+LL |         ((1 | 2,) | (3 | 4,),) => {}
+   |         ---------------------- matches all the values already
 LL |         ((1..=4,),) => {}
-   |         ^^^^^^^^^^^
+   |         ^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:48:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:53:14
    |
 LL |         (1 | 1,) => {}
-   |              ^
+   |          -   ^ unreachable pattern
+   |          |
+   |          matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:52:19
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:57:19
    |
 LL |         (0 | 1) | 1 => {}
-   |                   ^
+   |              -    ^ unreachable pattern
+   |              |
+   |              matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:58:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:63:14
    |
 LL |         0 | (0 | 0) => {}
-   |              ^
+   |         -    ^ unreachable pattern
+   |         |
+   |         matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:58:18
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:63:18
    |
 LL |         0 | (0 | 0) => {}
-   |                  ^
+   |         -        ^ unreachable pattern
+   |         |
+   |         matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:66:13
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:71:13
    |
+LL |           Some(0) |
+   |           ------- matches all the values already
 LL | /             Some(
 LL | |                 0 | 0) => {}
-   | |______________________^
+   | |______________________^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:72:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:77:15
    |
+LL |         [0
+   |          - matches all the values already
 LL |             | 0
-   |               ^
+   |               ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:74:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:79:15
    |
+LL |         , 0
+   |           - matches all the values already
 LL |             | 0] => {}
-   |               ^
+   |               ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:78:20
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:83:20
    |
 LL |         (true, 0 | 0) => {}
-   |                    ^
+   |                -   ^ unreachable pattern
+   |                |
+   |                matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:79:17
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17
    |
 LL |         (_, 0 | 0) => {}
-   |                 ^
+   |                 ^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17
+   |
+LL |         (true, 0 | 0) => {}
+   |                - matches some of the same values
+LL |         (_, 0 | 0) => {}
+   |             -   ^ collectively making this unreachable
+   |             |
+   |             matches some of the same values
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:87:10
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:92:10
    |
+LL |         [1, ..] => {}
+   |          - matches all the values already
 LL |         [1
-   |          ^
+   |          ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:99:10
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:104:10
    |
+LL |         [true, ..] => {}
+   |          ---- matches all the values already
 LL |         [true
-   |          ^^^^
+   |          ^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:106:36
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36
    |
 LL |         (true | false, None | Some(true
-   |                                    ^^^^
+   |                                    ^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36
+   |
+LL |         (true, Some(_)) => {}
+   |                     - matches some of the same values
+LL |         (false, Some(true)) => {}
+   |                      ---- matches some of the same values
+LL |         (true | false, None | Some(true
+   |                                    ^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:111:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14
    |
 LL |             (true
-   |              ^^^^
+   |              ^^^^ unreachable pattern
 ...
 LL |         (true | false, None | Some(t_or_f!())) => {}
    |                                    --------- in this macro invocation
    |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14
+   |
+LL |             (true
+   |              ^^^^ collectively making this unreachable
+...
+LL |         (true, Some(_)) => {}
+   |                     - matches some of the same values
+LL |         (false, Some(true)) => {}
+   |                      ---- matches some of the same values
+LL |         (true | false, None | Some(t_or_f!())) => {}
+   |                                    --------- in this macro invocation
    = note: this error originates in the macro `t_or_f` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:122:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:127:14
    |
+LL |         Some(0) => {}
+   |              - matches all the values already
 LL |         Some(0
-   |              ^
+   |              ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:141:19
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:146:19
    |
+LL |         Some(false) => {}
+   |              ----- matches all the values already
+LL |         None | Some(true
 LL |                 | false) => {}
-   |                   ^^^^^
+   |                   ^^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:149:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15
    |
 LL |             | true) => {}
-   |               ^^^^
+   |               ^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15
+   |
+LL |         (false, true) => {}
+   |                 ---- matches some of the same values
+LL |         (true, true) => {}
+   |                ---- matches some of the same values
+LL |         (false | true, false
+LL |             | true) => {}
+   |               ^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:155:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15
    |
 LL |             | true,
-   |               ^^^^
+   |               ^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15
+   |
+LL |         (true, false) => {}
+   |          ---- matches some of the same values
+LL |         (true, true) => {}
+   |          ---- matches some of the same values
+LL |         (false
+LL |             | true,
+   |               ^^^^ collectively making this unreachable
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:165:15
    |
+LL |         (x, y)
+   |         ------ matches any value
 LL |             | (y, x) => {}
-   |               ^^^^^^
+   |               ^^^^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:164:30
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:169:30
    |
 LL | fn unreachable_in_param((_ | (_, _)): (bool, bool)) {}
-   |                              ^^^^^^
+   |                          -   ^^^^^^ unreachable pattern
+   |                          |
+   |                          matches any value
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:171:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:176:14
    |
 LL |     let (_ | (_, _)) = bool_pair;
-   |              ^^^^^^
+   |          -   ^^^^^^ unreachable pattern
+   |          |
+   |          matches any value
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:173:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:178:14
    |
 LL |     for (_ | (_, _)) in [bool_pair] {}
-   |              ^^^^^^
+   |          -   ^^^^^^ unreachable pattern
+   |          |
+   |          matches any value
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:176:20
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:181:20
    |
 LL |     let (Some(_) | Some(true)) = bool_option else { return };
-   |                    ^^^^^^^^^^
+   |          -------   ^^^^^^^^^^ unreachable pattern
+   |          |
+   |          matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:178:22
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:183:22
    |
 LL |     if let Some(_) | Some(true) = bool_option {}
-   |                      ^^^^^^^^^^
+   |            -------   ^^^^^^^^^^ unreachable pattern
+   |            |
+   |            matches all the values already
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:180:25
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:185:25
    |
 LL |     while let Some(_) | Some(true) = bool_option {}
-   |                         ^^^^^^^^^^
+   |               -------   ^^^^^^^^^^ unreachable pattern
+   |               |
+   |               matches all the values already
 
-error: aborting due to 35 previous errors
+error: aborting due to 36 previous errors
 
diff --git a/tests/ui/parser/issues/issue-19398.rs b/tests/ui/parser/issues/issue-19398.rs
index 46eb320a172..358f65f1da5 100644
--- a/tests/ui/parser/issues/issue-19398.rs
+++ b/tests/ui/parser/issues/issue-19398.rs
@@ -1,6 +1,10 @@
 trait T {
     extern "Rust" unsafe fn foo();
-    //~^ ERROR expected `{`, found keyword `unsafe`
+    //~^ ERROR expected `fn`, found keyword `unsafe`
+    //~| NOTE expected `fn`
+    //~| HELP `unsafe` must come before `extern "Rust"`
+    //~| SUGGESTION unsafe extern "Rust"
+    //~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 }
 
 fn main() {}
diff --git a/tests/ui/parser/issues/issue-19398.stderr b/tests/ui/parser/issues/issue-19398.stderr
index 236fac673b6..2b97ec50c91 100644
--- a/tests/ui/parser/issues/issue-19398.stderr
+++ b/tests/ui/parser/issues/issue-19398.stderr
@@ -1,13 +1,13 @@
-error: expected `{`, found keyword `unsafe`
+error: expected `fn`, found keyword `unsafe`
   --> $DIR/issue-19398.rs:2:19
    |
-LL | trait T {
-   |         - while parsing this item list starting here
 LL |     extern "Rust" unsafe fn foo();
-   |                   ^^^^^^ expected `{`
-LL |
-LL | }
-   | - the item list ends here
+   |     --------------^^^^^^
+   |     |             |
+   |     |             expected `fn`
+   |     help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"`
+   |
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs
new file mode 100644
index 00000000000..794ac635c76
--- /dev/null
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs
@@ -0,0 +1,16 @@
+//@ edition:2018
+
+// There is an order to respect for keywords before a function:
+// `<visibility>, const, async, unsafe, extern, "<ABI>"`
+//
+// This test ensures the compiler is helpful about them being misplaced.
+// Visibilities are tested elsewhere.
+
+extern "C" unsafe fn test() {}
+//~^ ERROR expected `fn`, found keyword `unsafe`
+//~| NOTE expected `fn`
+//~| HELP `unsafe` must come before `extern "C"`
+//~| SUGGESTION unsafe extern "C"
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+fn main() {}
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr
new file mode 100644
index 00000000000..8ed037869c8
--- /dev/null
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr
@@ -0,0 +1,13 @@
+error: expected `fn`, found keyword `unsafe`
+  --> $DIR/wrong-unsafe-abi.rs:9:12
+   |
+LL | extern "C" unsafe fn test() {}
+   | -----------^^^^^^
+   | |          |
+   | |          expected `fn`
+   | help: `unsafe` must come before `extern "C"`: `unsafe extern "C"`
+   |
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr
index 3134746b930..ff32b173d49 100644
--- a/tests/ui/parser/trait-object-trait-parens.stderr
+++ b/tests/ui/parser/trait-object-trait-parens.stderr
@@ -1,20 +1,29 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/trait-object-trait-parens.rs:8:24
    |
 LL |     let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    |                        ^^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/trait-object-trait-parens.rs:13:16
    |
 LL |     let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |                ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/trait-object-trait-parens.rs:18:44
    |
 LL |     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |                                            ^^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 warning: trait objects without an explicit `dyn` are deprecated
   --> $DIR/trait-object-trait-parens.rs:8:16
@@ -91,4 +100,5 @@ LL |     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
 
 error: aborting due to 6 previous errors; 3 warnings emitted
 
-For more information about this error, try `rustc --explain E0225`.
+Some errors have detailed explanations: E0225, E0658.
+For more information about an error, try `rustc --explain E0225`.
diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr
index d057309e420..9d3a35321ca 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.stderr
+++ b/tests/ui/pattern/usefulness/consts-opaque.stderr
@@ -106,20 +106,34 @@ LL |         _ => {} // should not be emitting unreachable warning
 error: unreachable pattern
   --> $DIR/consts-opaque.rs:72:9
    |
+LL |         BAZ => {}
+   |         --- matches all the values already
 LL |         Baz::Baz1 => {} // should not be emitting unreachable warning
-   |         ^^^^^^^^^
+   |         ^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/consts-opaque.rs:79:9
    |
+LL |         Baz::Baz1 => {}
+   |         --------- matches all the values already
 LL |         BAZ => {}
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/consts-opaque.rs:87:9
    |
 LL |         _ => {} // should not be emitting unreachable warning
-   |         ^
+   |         ^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/consts-opaque.rs:87:9
+   |
+LL |         BAZ => {}
+   |         --- matches some of the same values
+LL |         Baz::Baz2 => {}
+   |         --------- matches some of the same values
+LL |         _ => {} // should not be emitting unreachable warning
+   |         ^ collectively making this unreachable
 
 error: aborting due to 17 previous errors
 
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
index 4c434192431..9e700ee55ef 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `EmptyEnum` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-match-check-notes.rs:7:9
    |
@@ -11,25 +12,31 @@ LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:20:9
+  --> $DIR/empty-match-check-notes.rs:21:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyEnum` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:27:9
+  --> $DIR/empty-match-check-notes.rs:29:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:30:9
+  --> $DIR/empty-match-check-notes.rs:33:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-match-check-notes.rs:35:9
+  --> $DIR/empty-match-check-notes.rs:39:9
    |
 LL |     let None = x;
    |         ^^^^ pattern `Some(_)` not covered
@@ -44,7 +51,7 @@ LL |     if let None = x { todo!() };
    |     ++              +++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
-  --> $DIR/empty-match-check-notes.rs:45:11
+  --> $DIR/empty-match-check-notes.rs:49:11
    |
 LL |     match 0u8 {
    |           ^^^ pattern `0_u8..=u8::MAX` not covered
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
index 45f715dc7b2..480ae7095a6 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `EmptyEnum` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-match-check-notes.rs:7:9
    |
@@ -11,25 +12,31 @@ LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:20:9
+  --> $DIR/empty-match-check-notes.rs:21:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyEnum` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:27:9
+  --> $DIR/empty-match-check-notes.rs:29:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-match-check-notes.rs:30:9
+  --> $DIR/empty-match-check-notes.rs:33:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-match-check-notes.rs:35:9
+  --> $DIR/empty-match-check-notes.rs:39:9
    |
 LL |     let None = x;
    |         ^^^^ pattern `Some(_)` not covered
@@ -43,7 +50,7 @@ LL |     if let None = x { todo!() };
    |     ++              +++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
-  --> $DIR/empty-match-check-notes.rs:45:11
+  --> $DIR/empty-match-check-notes.rs:49:11
    |
 LL |     match 0u8 {
    |           ^^^ pattern `0_u8..=u8::MAX` not covered
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.rs b/tests/ui/pattern/usefulness/empty-match-check-notes.rs
index ea797bc7dd5..2eef283a21e 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.rs
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.rs
@@ -15,9 +15,11 @@ fn empty_enum(x: EmptyEnum) {
     match x {} // ok
     match x {
         _ => {} //~ ERROR unreachable pattern
+                //~^ NOTE matches no values
     }
     match x {
         _ if false => {} //~ ERROR unreachable pattern
+                         //~^ NOTE matches no values
     }
 }
 
@@ -25,9 +27,11 @@ fn empty_foreign_enum(x: empty::EmptyForeignEnum) {
     match x {} // ok
     match x {
         _ => {} //~ ERROR unreachable pattern
+                //~^ NOTE matches no values
     }
     match x {
         _ if false => {} //~ ERROR unreachable pattern
+                         //~^ NOTE matches no values
     }
 }
 
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
index 45bdba94d78..416a50b87b5 100644
--- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `!` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-types.rs:17:9
    |
@@ -15,6 +16,8 @@ error: unreachable pattern
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
   --> $DIR/empty-types.rs:58:11
@@ -36,24 +39,32 @@ error: unreachable pattern
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(u32, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:80:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:83:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:87:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
   --> $DIR/empty-types.rs:91:11
@@ -79,12 +90,16 @@ error: unreachable pattern
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:104:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
   --> $DIR/empty-types.rs:101:11
@@ -123,114 +138,152 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:123:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:126:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:127:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:130:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:131:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:140:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:143:13
    |
 LL |             _ if false => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:152:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:156:13
    |
+LL |             None => {}
+   |             ---- matches all the values already
 LL |             _ => {}
-   |             ^
+   |             ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:208:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:213:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:218:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:223:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:229:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:288:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:291:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:294:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:295:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
   --> $DIR/empty-types.rs:327:11
@@ -292,18 +345,24 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:372:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:375:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
   --> $DIR/empty-types.rs:389:11
@@ -322,8 +381,10 @@ LL +     }
 error: unreachable pattern
   --> $DIR/empty-types.rs:396:9
    |
+LL |         [] => {}
+   |         -- matches all the values already
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/empty-types.rs:398:11
@@ -344,48 +405,66 @@ error: unreachable pattern
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:422:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:427:9
    |
+LL |         None => {}
+   |         ---- matches all the values already
+LL |         // !useful, !reachable
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:432:9
    |
+LL |         None => {}
+   |         ---- matches all the values already
+LL |         // !useful, !reachable
 LL |         _a => {}
-   |         ^^
+   |         ^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:604:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:607:9
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:610:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:613:9
    |
 LL |         _x if false => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: aborting due to 49 previous errors
 
diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
index 9b57c895eea..2e5511527d5 100644
--- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `!` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-types.rs:17:9
    |
@@ -15,6 +16,8 @@ error: unreachable pattern
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
   --> $DIR/empty-types.rs:58:11
@@ -36,24 +39,32 @@ error: unreachable pattern
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(u32, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:80:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:83:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:87:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
   --> $DIR/empty-types.rs:91:11
@@ -79,12 +90,16 @@ error: unreachable pattern
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:104:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
   --> $DIR/empty-types.rs:101:11
@@ -137,60 +152,80 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:123:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:126:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:127:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:130:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:131:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:140:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:143:13
    |
 LL |             _ if false => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:152:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:156:13
    |
+LL |             None => {}
+   |             ---- matches all the values already
 LL |             _ => {}
-   |             ^
+   |             ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
   --> $DIR/empty-types.rs:165:15
@@ -216,54 +251,72 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:213:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:218:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:223:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:229:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:288:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:291:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:294:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:295:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
+   |
+   = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
   --> $DIR/empty-types.rs:316:11
@@ -403,18 +456,24 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:372:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:375:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
+   |
+   = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
   --> $DIR/empty-types.rs:389:11
@@ -433,8 +492,10 @@ LL +     }
 error: unreachable pattern
   --> $DIR/empty-types.rs:396:9
    |
+LL |         [] => {}
+   |         -- matches all the values already
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/empty-types.rs:398:11
@@ -455,24 +516,34 @@ error: unreachable pattern
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:422:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:427:9
    |
+LL |         None => {}
+   |         ---- matches all the values already
+LL |         // !useful, !reachable
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:432:9
    |
+LL |         None => {}
+   |         ---- matches all the values already
+LL |         // !useful, !reachable
 LL |         _a => {}
-   |         ^^
+   |         ^^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
   --> $DIR/empty-types.rs:452:11
@@ -569,24 +640,32 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:607:9
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:610:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:613:9
    |
 LL |         _x if false => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
   --> $DIR/empty-types.rs:638:11
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 0ff2472922e..4856a2f8e08 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -13,6 +13,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `!` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-types.rs:17:9
    |
@@ -24,6 +25,8 @@ error: unreachable pattern
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
   --> $DIR/empty-types.rs:58:11
@@ -73,6 +76,8 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(!)` not covered
   --> $DIR/empty-types.rs:91:11
@@ -218,12 +223,16 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:143:13
    |
 LL |             _ if false => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Some(!)` not covered
   --> $DIR/empty-types.rs:146:15
@@ -266,36 +275,48 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:213:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:218:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:223:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:229:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:288:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
   --> $DIR/empty-types.rs:316:11
@@ -460,8 +481,10 @@ LL +     }
 error: unreachable pattern
   --> $DIR/empty-types.rs:396:9
    |
+LL |         [] => {}
+   |         -- matches all the values already
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/empty-types.rs:398:11
@@ -568,24 +591,32 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:607:9
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:610:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:613:9
    |
 LL |         _x if false => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `&!` not covered
   --> $DIR/empty-types.rs:638:11
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index 1d13802a2bd..78db9ee349b 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `!` is uninhabited
 note: the lint level is defined here
   --> $DIR/empty-types.rs:17:9
    |
@@ -15,6 +16,8 @@ error: unreachable pattern
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
   --> $DIR/empty-types.rs:58:11
@@ -64,6 +67,8 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
   --> $DIR/empty-types.rs:91:11
@@ -209,12 +214,16 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:143:13
    |
 LL |             _ if false => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
   --> $DIR/empty-types.rs:146:15
@@ -257,36 +266,48 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:213:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:218:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:223:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:229:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:288:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
   --> $DIR/empty-types.rs:316:11
@@ -451,8 +472,10 @@ LL +     }
 error: unreachable pattern
   --> $DIR/empty-types.rs:396:9
    |
+LL |         [] => {}
+   |         -- matches all the values already
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
   --> $DIR/empty-types.rs:398:11
@@ -559,24 +582,32 @@ error: unreachable pattern
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:607:9
    |
 LL |         _x => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:610:9
    |
 LL |         _ if false => {}
    |         ^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/empty-types.rs:613:9
    |
 LL |         _x if false => {}
    |         ^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
   --> $DIR/empty-types.rs:638:11
diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs
new file mode 100644
index 00000000000..98f781b6a09
--- /dev/null
+++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs
@@ -0,0 +1,101 @@
+#![feature(never_type)]
+#![feature(min_exhaustive_patterns)]
+#![deny(unreachable_patterns)]
+//~^ NOTE lint level is defined here
+
+#[rustfmt::skip]
+fn main() {
+    match (0u8,) {
+        (1 | 2,) => {}
+        //~^ NOTE matches all the values already
+        (2,) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+        _ => {}
+    }
+
+    match (0u8,) {
+        (1,) => {}
+        //~^ NOTE matches some of the same values
+        (2,) => {}
+        //~^ NOTE matches some of the same values
+        (1 | 2,) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+        //~| NOTE these patterns collectively make the last one unreachable
+        //~| NOTE collectively making this unreachable
+        _ => {}
+    }
+
+    let res: Result<(),!> = Ok(());
+    match res {
+        Ok(_) => {}
+        Err(_) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE this pattern matches no values because `!` is uninhabited
+    }
+
+    #[derive(Copy, Clone)]
+    enum Void1 {}
+    #[derive(Copy, Clone)]
+    enum Void2 {}
+    // Only an empty type matched _by value_ can make an arm unreachable. We must get the right one.
+    let res1: Result<(), Void1> = Ok(());
+    let res2: Result<(), Void2> = Ok(());
+    match (&res1, res2) {
+        (Err(_), Err(_)) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE this pattern matches no values because `Void2` is uninhabited
+        _ => {}
+    }
+    match (res1, &res2) {
+        (Err(_), Err(_)) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE this pattern matches no values because `Void1` is uninhabited
+        _ => {}
+    }
+
+
+    if let (0
+        //~^ NOTE matches all the values already
+        | 0, _) = (0, 0) {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+
+    match (true, true) {
+        (_, true) if false => {} // Guarded patterns don't cover others
+        (true, _) => {}
+        //~^ NOTE matches some of the same values
+        (false, _) => {}
+        //~^ NOTE matches some of the same values
+        (_, true) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+        //~| NOTE these patterns collectively make the last one unreachable
+        //~| NOTE collectively making this unreachable
+    }
+
+    match (true, true) {
+        (true, _) => {}
+        //~^ NOTE matches all the values already
+        (false, _) => {}
+        #[allow(unreachable_patterns)]
+        (_, true) => {} // Doesn't cover below because it's already unreachable.
+        (true, true) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+    }
+
+    // Despite skipping some irrelevant cases, we still report a set of rows that covers the
+    // unreachable one.
+    match (true, true, 0) {
+        (true, _, _) => {}
+        (_, true, 0..10) => {}
+        //~^ NOTE matches all the values already
+        (_, true, 10..) => {}
+        (_, true, 3) => {}
+        //~^ ERROR unreachable pattern
+        //~| NOTE unreachable pattern
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr
new file mode 100644
index 00000000000..e2eecf4a9f3
--- /dev/null
+++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr
@@ -0,0 +1,104 @@
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:11:9
+   |
+LL |         (1 | 2,) => {}
+   |         -------- matches all the values already
+LL |
+LL |         (2,) => {}
+   |         ^^^^ unreachable pattern
+   |
+note: the lint level is defined here
+  --> $DIR/explain-unreachable-pats.rs:3:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:22:9
+   |
+LL |         (1 | 2,) => {}
+   |         ^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/explain-unreachable-pats.rs:22:9
+   |
+LL |         (1,) => {}
+   |         ---- matches some of the same values
+LL |
+LL |         (2,) => {}
+   |         ---- matches some of the same values
+LL |
+LL |         (1 | 2,) => {}
+   |         ^^^^^^^^ collectively making this unreachable
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:33:9
+   |
+LL |         Err(_) => {}
+   |         ^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:46:9
+   |
+LL |         (Err(_), Err(_)) => {}
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern matches no values because `Void2` is uninhabited
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:52:9
+   |
+LL |         (Err(_), Err(_)) => {}
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern matches no values because `Void1` is uninhabited
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:61:11
+   |
+LL |     if let (0
+   |             - matches all the values already
+LL |
+LL |         | 0, _) = (0, 0) {}
+   |           ^ unreachable pattern
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:71:9
+   |
+LL |         (_, true) => {}
+   |         ^^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/explain-unreachable-pats.rs:71:9
+   |
+LL |         (true, _) => {}
+   |         --------- matches some of the same values
+LL |
+LL |         (false, _) => {}
+   |         ---------- matches some of the same values
+LL |
+LL |         (_, true) => {}
+   |         ^^^^^^^^^ collectively making this unreachable
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:84:9
+   |
+LL |         (true, _) => {}
+   |         --------- matches all the values already
+...
+LL |         (true, true) => {}
+   |         ^^^^^^^^^^^^ unreachable pattern
+
+error: unreachable pattern
+  --> $DIR/explain-unreachable-pats.rs:96:9
+   |
+LL |         (_, true, 0..10) => {}
+   |         ---------------- matches all the values already
+...
+LL |         (_, true, 3) => {}
+   |         ^^^^^^^^^^^^ unreachable pattern
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/pattern/usefulness/floats.stderr b/tests/ui/pattern/usefulness/floats.stderr
index 684f6c93a16..d0a8841d6a8 100644
--- a/tests/ui/pattern/usefulness/floats.stderr
+++ b/tests/ui/pattern/usefulness/floats.stderr
@@ -14,8 +14,10 @@ LL +         _ => todo!()
 error: unreachable pattern
   --> $DIR/floats.rs:18:9
    |
+LL |         0.01f16..=6.5f16 => {}
+   |         ---------------- matches all the values already
 LL |         0.01f16 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/floats.rs:1:9
@@ -26,80 +28,118 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/floats.rs:19:9
    |
+LL |         0.01f16..=6.5f16 => {}
+   |         ---------------- matches all the values already
+LL |         0.01f16 => {}
 LL |         0.02f16 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:20:9
    |
+LL |         0.01f16..=6.5f16 => {}
+   |         ---------------- matches all the values already
+...
 LL |         6.5f16 => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:31:9
    |
+LL |         0.01f32..=6.5f32 => {}
+   |         ---------------- matches all the values already
 LL |         0.01f32 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:32:9
    |
+LL |         0.01f32..=6.5f32 => {}
+   |         ---------------- matches all the values already
+LL |         0.01f32 => {}
 LL |         0.02f32 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:33:9
    |
+LL |         0.01f32..=6.5f32 => {}
+   |         ---------------- matches all the values already
+...
 LL |         6.5f32 => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:45:9
    |
+LL |         0.01f64..=6.5f64 => {}
+   |         ---------------- matches all the values already
+LL |         0.005f64 => {}
 LL |         0.01f64 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:46:9
    |
+LL |         0.01f64..=6.5f64 => {}
+   |         ---------------- matches all the values already
+...
 LL |         0.02f64 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:47:9
    |
+LL |         0.01f64..=6.5f64 => {}
+   |         ---------------- matches all the values already
+...
 LL |         6.5f64 => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:49:9
    |
+LL |         0.01f64..=6.5f64 => {}
+   |         ---------------- matches all the values already
+...
 LL |         1.0f64..=4.0f64 => {}
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:62:9
    |
+LL |         0.01f128..=6.5f128 => {}
+   |         ------------------ matches all the values already
+LL |         0.005f128 => {}
 LL |         0.01f128 => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:63:9
    |
+LL |         0.01f128..=6.5f128 => {}
+   |         ------------------ matches all the values already
+...
 LL |         0.02f128 => {}
-   |         ^^^^^^^^
+   |         ^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:64:9
    |
+LL |         0.01f128..=6.5f128 => {}
+   |         ------------------ matches all the values already
+...
 LL |         6.5f128 => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/floats.rs:66:9
    |
+LL |         0.01f128..=6.5f128 => {}
+   |         ------------------ matches all the values already
+...
 LL |         1.0f128..=4.0f128 => {}
-   |         ^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: aborting due to 15 previous errors
 
diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr
index ba8b12f9f66..c079f5a259d 100644
--- a/tests/ui/pattern/usefulness/impl-trait.stderr
+++ b/tests/ui/pattern/usefulness/impl-trait.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |             _ => {}
    |             ^
    |
+   = note: this pattern matches no values because `Void` is uninhabited
 note: the lint level is defined here
   --> $DIR/impl-trait.rs:5:9
    |
@@ -15,36 +16,48 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:45:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:49:13
    |
+LL |             None => {}
+   |             ---- matches all the values already
 LL |             _ => {}
-   |             ^
+   |             ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:59:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:63:13
    |
+LL |             None => {}
+   |             ---- matches all the values already
 LL |             _ => {}
-   |             ^
+   |             ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:76:9
    |
 LL |         _ => {}
    |         ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:86:9
@@ -59,12 +72,16 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:105:9
    |
+LL |         Some((a, b)) => {}
+   |         ------------ matches all the values already
 LL |         Some((mut x, mut y)) => {
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:124:13
@@ -79,12 +96,16 @@ error: unreachable pattern
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `SecretelyVoid` is uninhabited
 
 error: unreachable pattern
   --> $DIR/impl-trait.rs:151:13
    |
 LL |             _ => {}
    |             ^
+   |
+   = note: this pattern matches no values because `SecretelyDoubleVoid` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
   --> $DIR/impl-trait.rs:23:11
diff --git a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr
index c5b028d2038..5d86007a853 100644
--- a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr
+++ b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/reachability.rs:18:17
    |
 LL |     m!(0u8, 42, 42);
-   |                 ^^
+   |             --  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
    |
 note: the lint level is defined here
   --> $DIR/reachability.rs:3:9
@@ -14,121 +16,211 @@ error: unreachable pattern
   --> $DIR/reachability.rs:22:22
    |
 LL |     m!(0u8, 20..=30, 20);
-   |                      ^^
+   |             -------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:23:22
    |
 LL |     m!(0u8, 20..=30, 21);
-   |                      ^^
+   |             -------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:24:22
    |
 LL |     m!(0u8, 20..=30, 25);
-   |                      ^^
+   |             -------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:25:22
    |
 LL |     m!(0u8, 20..=30, 29);
-   |                      ^^
+   |             -------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:26:22
    |
 LL |     m!(0u8, 20..=30, 30);
-   |                      ^^
+   |             -------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:29:21
    |
 LL |     m!(0u8, 20..30, 20);
-   |                     ^^
+   |             ------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:30:21
    |
 LL |     m!(0u8, 20..30, 21);
-   |                     ^^
+   |             ------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:31:21
    |
 LL |     m!(0u8, 20..30, 25);
-   |                     ^^
+   |             ------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:32:21
    |
 LL |     m!(0u8, 20..30, 29);
-   |                     ^^
+   |             ------  ^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:36:22
    |
 LL |     m!(0u8, 20..=30, 20..=30);
-   |                      ^^^^^^^
+   |             -------  ^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:37:22
    |
 LL |     m!(0u8, 20.. 30, 20.. 30);
-   |                      ^^^^^^^
+   |             -------  ^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:38:22
    |
 LL |     m!(0u8, 20..=30, 20.. 30);
-   |                      ^^^^^^^
+   |             -------  ^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:40:22
    |
 LL |     m!(0u8, 20..=30, 21..=30);
-   |                      ^^^^^^^
+   |             -------  ^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:41:22
    |
 LL |     m!(0u8, 20..=30, 20..=29);
-   |                      ^^^^^^^
+   |             -------  ^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:43:24
    |
 LL |     m!('a', 'A'..='z', 'a'..='z');
-   |                        ^^^^^^^^^
+   |             ---------  ^^^^^^^^^ unreachable pattern
+   |             |
+   |             matches all the values already
 
 error: unreachable pattern
   --> $DIR/reachability.rs:50:9
    |
 LL |         5..=8 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:50:9
+   |
+LL |         5 => {},
+   |         - matches some of the same values
+LL |         6 => {},
+   |         - matches some of the same values
+LL |         7 => {},
+   |         - matches some of the same values
+LL |         8 => {},
+   |         - matches some of the same values
+LL |         5..=8 => {},
+   |         ^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:56:9
    |
 LL |         5..15 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:56:9
+   |
+LL |         0..10 => {},
+   |         ----- matches some of the same values
+LL |         10..20 => {},
+   |         ------ matches some of the same values
+LL |         5..15 => {},
+   |         ^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:63:9
    |
 LL |         5..25 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:63:9
+   |
+LL |         0..10 => {},
+   |         ----- matches some of the same values
+LL |         10..20 => {},
+   |         ------ matches some of the same values
+LL |         20..30 => {},
+   |         ------ matches some of the same values
+LL |         5..25 => {},
+   |         ^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:71:9
    |
 LL |         5..25 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:71:9
+   |
+LL |         0..10 => {},
+   |         ----- matches some of the same values
+LL |         10 => {},
+   |         -- matches some of the same values
+LL |         11..=23 => {},
+   |         ------- matches some of the same values
+LL |         19..30 => {},
+   |         ------ matches some of the same values
+LL |         5..25 => {},
+   |         ^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:77:9
    |
 LL |         5..15 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:77:9
+   |
+LL |         0..10 => {},
+   |         ----- matches some of the same values
+LL |         10..20 => {},
+   |         ------ matches some of the same values
+LL |         5..15 => {},
+   |         ^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:84:9
@@ -142,19 +234,34 @@ error: unreachable pattern
   --> $DIR/reachability.rs:89:9
    |
 LL |         '\u{D7FF}'..='\u{E000}' => {},
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/reachability.rs:89:9
+   |
+LL |         '\u{0}'..='\u{D7FF}' => {},
+   |         -------------------- matches some of the same values
+LL |         '\u{E000}'..='\u{10_FFFF}' => {},
+   |         -------------------------- matches some of the same values
+LL |         '\u{D7FF}'..='\u{E000}' => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/reachability.rs:105:9
    |
+LL |         &42 => {}
+   |         --- matches all the values already
 LL |         &FOO => {}
-   |         ^^^^
+   |         ^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/reachability.rs:106:9
    |
+LL |         &42 => {}
+   |         --- matches all the values already
+LL |         &FOO => {}
 LL |         BAR => {}
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: aborting due to 25 previous errors
 
diff --git a/tests/ui/pattern/usefulness/issue-12116.stderr b/tests/ui/pattern/usefulness/issue-12116.stderr
index 199bdc6ac97..b2c2be97563 100644
--- a/tests/ui/pattern/usefulness/issue-12116.stderr
+++ b/tests/ui/pattern/usefulness/issue-12116.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/issue-12116.rs:15:9
    |
+LL |         &IntList::Cons(val, box ref next_list) => tail(next_list),
+   |         -------------------------------------- matches all the values already
 LL |         &IntList::Cons(val, box IntList::Nil)  => IntList::Cons(val, Box::new(IntList::Nil)),
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/issue-12116.rs:4:9
diff --git a/tests/ui/pattern/usefulness/issue-12369.stderr b/tests/ui/pattern/usefulness/issue-12369.stderr
index 2b6e2e14b7c..7754cbc2484 100644
--- a/tests/ui/pattern/usefulness/issue-12369.stderr
+++ b/tests/ui/pattern/usefulness/issue-12369.stderr
@@ -2,8 +2,17 @@ error: unreachable pattern
   --> $DIR/issue-12369.rs:9:9
    |
 LL |         &[10,a, ref rest @ ..] => 10
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/issue-12369.rs:9:9
+   |
+LL |         &[a,b,c] => 3,
+   |         -------- matches some of the same values
+LL |         &[a, ref rest @ ..] => a,
+   |         ------------------- matches some of the same values
+LL |         &[10,a, ref rest @ ..] => 10
+   |         ^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable
 note: the lint level is defined here
   --> $DIR/issue-12369.rs:1:9
    |
diff --git a/tests/ui/pattern/usefulness/issue-13727.stderr b/tests/ui/pattern/usefulness/issue-13727.stderr
index ab80c56ea88..ca8533b33a4 100644
--- a/tests/ui/pattern/usefulness/issue-13727.stderr
+++ b/tests/ui/pattern/usefulness/issue-13727.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/issue-13727.rs:7:5
    |
+LL |     256 => print!("0b1110\n"),
+   |     --- matches all the values already
 LL |     512 => print!("0b1111\n"),
-   |     ^^^
+   |     ^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/issue-13727.rs:2:9
diff --git a/tests/ui/pattern/usefulness/issue-30240-b.stderr b/tests/ui/pattern/usefulness/issue-30240-b.stderr
index 74d39eba98c..749515fc94b 100644
--- a/tests/ui/pattern/usefulness/issue-30240-b.stderr
+++ b/tests/ui/pattern/usefulness/issue-30240-b.stderr
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/issue-30240-b.rs:12:9
    |
 LL |         "hello" => {}
-   |         ^^^^^^^
+   |         ------- matches all the values already
+LL |         "hello" => {}
+   |         ^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/issue-30240-b.rs:1:9
diff --git a/tests/ui/pattern/usefulness/issue-31221.stderr b/tests/ui/pattern/usefulness/issue-31221.stderr
index 7d349144456..596f4d8096d 100644
--- a/tests/ui/pattern/usefulness/issue-31221.stderr
+++ b/tests/ui/pattern/usefulness/issue-31221.stderr
@@ -23,10 +23,18 @@ LL |         &Var2 => (),
 error: unreachable pattern
   --> $DIR/issue-31221.rs:31:9
    |
-LL |         (c, d) => (),
-   |         ------ matches any value
 LL |         anything => ()
    |         ^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/issue-31221.rs:31:9
+   |
+LL |         (Var1, b) => (),
+   |         --------- matches some of the same values
+LL |         (c, d) => (),
+   |         ------ matches some of the same values
+LL |         anything => ()
+   |         ^^^^^^^^ collectively making this unreachable
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/usefulness/issue-57472.stderr b/tests/ui/pattern/usefulness/issue-57472.stderr
index c814eaec0d1..68b5b7cb791 100644
--- a/tests/ui/pattern/usefulness/issue-57472.stderr
+++ b/tests/ui/pattern/usefulness/issue-57472.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/issue-57472.rs:15:13
    |
+LL |             Punned { foo: [_], .. } => println!("foo"),
+   |             ----------------------- matches all the values already
 LL |             Punned { bar: [_], .. } => println!("bar"),
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/issue-57472.rs:2:9
@@ -13,8 +15,10 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/issue-57472.rs:32:17
    |
+LL |                 Punned { foo: [_] } => println!("foo"),
+   |                 ------------------- matches all the values already
 LL |                 Punned { bar: [_] } => println!("bar"),
-   |                 ^^^^^^^^^^^^^^^^^^^
+   |                 ^^^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/pattern/usefulness/match-arm-statics.stderr b/tests/ui/pattern/usefulness/match-arm-statics.stderr
index a5dffebf699..b6f2b47047d 100644
--- a/tests/ui/pattern/usefulness/match-arm-statics.stderr
+++ b/tests/ui/pattern/usefulness/match-arm-statics.stderr
@@ -1,8 +1,11 @@
 error: unreachable pattern
   --> $DIR/match-arm-statics.rs:25:9
    |
+LL |         TRUE_TRUE => (),
+   |         --------- matches all the values already
+...
 LL |         (true, true) => ()
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/match-arm-statics.rs:2:9
@@ -13,14 +16,29 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/match-arm-statics.rs:40:9
    |
+LL |         Some(Some(EAST)) => (),
+   |         ---------------- matches all the values already
+...
 LL |         Some(Some(East)) => (),
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-arm-statics.rs:60:9
    |
 LL |         Foo { bar: Some(EAST), baz: NewBool(false) } => ()
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/match-arm-statics.rs:60:9
+   |
+LL |         Foo { bar: _, baz: NEW_FALSE } => (),
+   |         ------------------------------ matches some of the same values
+...
+LL |         Foo { bar: Some(EAST), .. } => (),
+   |         --------------------------- matches some of the same values
+LL |         Foo { bar: Some(North), baz: NewBool(true) } => (),
+LL |         Foo { bar: Some(EAST), baz: NewBool(false) } => ()
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr b/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr
index 0c582be8df8..39675e2bdd4 100644
--- a/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr
+++ b/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:8:9
    |
+LL |         b"AAAA" => {},
+   |         ------- matches all the values already
 LL |         &[0x41, 0x41, 0x41, 0x41] => {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/match-byte-array-patterns.rs:1:9
@@ -13,44 +15,58 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:14:9
    |
+LL |         &[0x41, 0x41, 0x41, 0x41] => {}
+   |         ------------------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:20:9
    |
+LL |         &[_, 0x41, 0x41, 0x41] => {},
+   |         ---------------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:26:9
    |
+LL |         &[0x41, .., 0x41] => {}
+   |         ----------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:34:9
    |
+LL |         b"AAAA" => {},
+   |         ------- matches all the values already
 LL |         &[0x41, 0x41, 0x41, 0x41] => {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:40:9
    |
+LL |         &[0x41, 0x41, 0x41, 0x41] => {}
+   |         ------------------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:46:9
    |
+LL |         &[_, 0x41, 0x41, 0x41] => {},
+   |         ---------------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-byte-array-patterns.rs:52:9
    |
+LL |         &[0x41, .., 0x41] => {}
+   |         ----------------- matches all the values already
 LL |         b"AAAA" => {},
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/pattern/usefulness/match-ref-ice.stderr b/tests/ui/pattern/usefulness/match-ref-ice.stderr
index 0dbfa776f69..9c5af47cc1e 100644
--- a/tests/ui/pattern/usefulness/match-ref-ice.stderr
+++ b/tests/ui/pattern/usefulness/match-ref-ice.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/match-ref-ice.rs:13:9
    |
+LL |         [1, ref _madoka, 3] => (),
+   |         ------------------- matches all the values already
 LL |         [1, 2, 3] => (),
-   |         ^^^^^^^^^
+   |         ^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/match-ref-ice.rs:1:9
diff --git a/tests/ui/pattern/usefulness/match-vec-fixed.stderr b/tests/ui/pattern/usefulness/match-vec-fixed.stderr
index e388a06cb9a..04507a22856 100644
--- a/tests/ui/pattern/usefulness/match-vec-fixed.stderr
+++ b/tests/ui/pattern/usefulness/match-vec-fixed.stderr
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/match-vec-fixed.rs:7:9
    |
 LL |         [_, _, _] => {}
-   |         ^^^^^^^^^
+   |         --------- matches all the values already
+LL |         [_, _, _] => {}
+   |         ^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/match-vec-fixed.rs:1:9
@@ -14,7 +16,9 @@ error: unreachable pattern
   --> $DIR/match-vec-fixed.rs:11:9
    |
 LL |         [_, 1, _] => {}
-   |         ^^^^^^^^^
+   |         --------- matches all the values already
+LL |         [_, 1, _] => {}
+   |         ^^^^^^^^^ unreachable pattern
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/pattern/usefulness/match-vec-unreachable.stderr b/tests/ui/pattern/usefulness/match-vec-unreachable.stderr
index 672fd92fb5e..865f5b319a7 100644
--- a/tests/ui/pattern/usefulness/match-vec-unreachable.stderr
+++ b/tests/ui/pattern/usefulness/match-vec-unreachable.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/match-vec-unreachable.rs:8:9
    |
+LL |         [a, (2, 3), _] => (),
+   |         -------------- matches all the values already
 LL |         [(1, 2), (2, 3), b] => (),
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/match-vec-unreachable.rs:1:9
@@ -13,14 +15,18 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/match-vec-unreachable.rs:18:9
    |
+LL |         [ref a, _, _, ..] => { println!("{}", a); }
+   |         ----------------- matches all the values already
 LL |         [_, _, _, _, _] => { }
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/match-vec-unreachable.rs:26:9
    |
+LL |         ['a', 'b', 'c', ref _tail @ ..] => {}
+   |         ------------------------------- matches all the values already
 LL |         ['a', 'b', 'c'] => {}
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ unreachable pattern
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr b/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr
index dcad11a38a7..12db48590a4 100644
--- a/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr
+++ b/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr
@@ -1,8 +1,11 @@
 error: unreachable pattern
   --> $DIR/slice-pattern-const-2.rs:9:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
+LL |         [0x00, 0x00, 0x00, 0x00] => (),
 LL |         [4, 5, 6, 7] => (),
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/slice-pattern-const-2.rs:1:9
@@ -13,20 +16,26 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/slice-pattern-const-2.rs:15:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
 LL |         [4, 5, 6, 7] => (),
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const-2.rs:21:9
    |
+LL |         [4, 5, 6, 7] => (),
+   |         ------------ matches all the values already
 LL |         MAGIC_TEST => (),
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const-2.rs:28:9
    |
+LL |         [4] => (),
+   |         --- matches all the values already
 LL |         FOO => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr b/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr
index b90b3a88a18..5a66799d9c9 100644
--- a/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr
+++ b/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr
@@ -1,8 +1,11 @@
 error: unreachable pattern
   --> $DIR/slice-pattern-const-3.rs:9:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
+LL |         ["0x00", "0x00", "0x00", "0x00"] => (),
 LL |         ["4", "5", "6", "7"] => (),
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/slice-pattern-const-3.rs:1:9
@@ -13,20 +16,26 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/slice-pattern-const-3.rs:15:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
 LL |         ["4", "5", "6", "7"] => (),
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const-3.rs:21:9
    |
+LL |         ["4", "5", "6", "7"] => (),
+   |         -------------------- matches all the values already
 LL |         MAGIC_TEST => (),
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const-3.rs:28:9
    |
+LL |         ["boo"] => (),
+   |         ------- matches all the values already
 LL |         FOO => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/pattern/usefulness/slice-pattern-const.stderr b/tests/ui/pattern/usefulness/slice-pattern-const.stderr
index 1fffb9fedbf..87a85acc4c5 100644
--- a/tests/ui/pattern/usefulness/slice-pattern-const.stderr
+++ b/tests/ui/pattern/usefulness/slice-pattern-const.stderr
@@ -1,8 +1,11 @@
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:9:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
+LL |         [0x00, 0x00, 0x00, 0x00] => (),
 LL |         [84, 69, 83, 84] => (),
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/slice-pattern-const.rs:1:9
@@ -13,50 +16,68 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:15:9
    |
+LL |         MAGIC_TEST => (),
+   |         ---------- matches all the values already
 LL |         [84, 69, 83, 84] => (),
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:21:9
    |
+LL |         [84, 69, 83, 84] => (),
+   |         ---------------- matches all the values already
 LL |         MAGIC_TEST => (),
-   |         ^^^^^^^^^^
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:28:9
    |
+LL |         [4] => (),
+   |         --- matches all the values already
 LL |         FOO => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:35:9
    |
+LL |         [4] => (),
+   |         --- matches all the values already
 LL |         BAR => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:43:9
    |
+LL |         [] => (),
+   |         -- matches all the values already
 LL |         BOO => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:44:9
    |
+LL |         [] => (),
+   |         -- matches all the values already
+LL |         BOO => (),
 LL |         b"" => (),
-   |         ^^^
+   |         ^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:45:9
    |
+LL |         [] => (),
+   |         -- matches all the values already
+...
 LL |         _ => (),
-   |         ^
+   |         ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-pattern-const.rs:51:9
    |
+LL |         CONST1 => {}
+   |         ------ matches all the values already
 LL |         [true] => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr b/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr
index 607ffb76595..40fbb00de1f 100644
--- a/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr
+++ b/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:8:9
    |
 LL |         [true, ..] => {}
-   |         ^^^^^^^^^^
+   |         ---------- matches all the values already
+LL |         [true, ..] => {}
+   |         ^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/slice-patterns-reachability.rs:1:9
@@ -13,32 +15,45 @@ LL | #![deny(unreachable_patterns)]
 error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:9:9
    |
+LL |         [true, ..] => {}
+   |         ---------- matches all the values already
+LL |         [true, ..] => {}
 LL |         [true] => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:14:9
    |
 LL |         [.., true] => {}
-   |         ^^^^^^^^^^
+   |         ---------- matches all the values already
+LL |         [.., true] => {}
+   |         ^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:15:9
    |
+LL |         [.., true] => {}
+   |         ---------- matches all the values already
+LL |         [.., true] => {}
 LL |         [true] => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:20:9
    |
 LL |         [false, .., true] => {}
-   |         ^^^^^^^^^^^^^^^^^
+   |         ----------------- matches all the values already
+LL |         [false, .., true] => {}
+   |         ^^^^^^^^^^^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/slice-patterns-reachability.rs:21:9
    |
+LL |         [false, .., true] => {}
+   |         ----------------- matches all the values already
+LL |         [false, .., true] => {}
 LL |         [false, true] => {}
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^ unreachable pattern
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/pattern/usefulness/top-level-alternation.stderr b/tests/ui/pattern/usefulness/top-level-alternation.stderr
index 17fa951c539..ad846f23155 100644
--- a/tests/ui/pattern/usefulness/top-level-alternation.stderr
+++ b/tests/ui/pattern/usefulness/top-level-alternation.stderr
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/top-level-alternation.rs:4:23
    |
 LL |     while let 0..=2 | 1 = 0 {}
-   |                       ^
+   |               -----   ^ unreachable pattern
+   |               |
+   |               matches all the values already
    |
 note: the lint level is defined here
   --> $DIR/top-level-alternation.rs:1:9
@@ -14,61 +16,90 @@ error: unreachable pattern
   --> $DIR/top-level-alternation.rs:5:20
    |
 LL |     if let 0..=2 | 1 = 0 {}
-   |                    ^
+   |            -----   ^ unreachable pattern
+   |            |
+   |            matches all the values already
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:9:15
    |
+LL |         0
+   |         - matches all the values already
 LL |             | 0 => {}
-   |               ^
+   |               ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:14:15
    |
+LL |         Some(0)
+   |         ------- matches all the values already
 LL |             | Some(0) => {}
-   |               ^^^^^^^
+   |               ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:19:9
    |
+LL |         (0, _) | (_, 0) => {}
+   |         --------------- matches all the values already
 LL |         (0, 0) => {}
-   |         ^^^^^^
+   |         ^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:39:9
    |
+LL |         None | Some(_) => {}
+   |         -------------- matches all the values already
 LL |         _ => {}
-   |         ^
+   |         ^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:43:9
    |
+LL |         None | Some(_) => {}
+   |         -------------- matches all the values already
 LL |         Some(_) => {}
-   |         ^^^^^^^
+   |         ^^^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:44:9
    |
+LL |         None | Some(_) => {}
+   |         -------------- matches all the values already
+LL |         Some(_) => {}
 LL |         None => {}
-   |         ^^^^
+   |         ^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:49:9
    |
 LL |         None | Some(_) => {}
-   |         ^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^ unreachable pattern
+   |
+note: these patterns collectively make the last one unreachable
+  --> $DIR/top-level-alternation.rs:49:9
+   |
+LL |         Some(_) => {}
+   |         ------- matches some of the same values
+LL |         None => {}
+   |         ---- matches some of the same values
+LL |         None | Some(_) => {}
+   |         ^^^^^^^^^^^^^^ collectively making this unreachable
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:53:9
    |
+LL |         1 | 2 => {},
+   |         ----- matches all the values already
 LL |         1..=2 => {},
-   |         ^^^^^
+   |         ^^^^^ unreachable pattern
 
 error: unreachable pattern
   --> $DIR/top-level-alternation.rs:56:14
    |
 LL |     let (0 | 0) = 0 else { return };
-   |              ^
+   |          -   ^ unreachable pattern
+   |          |
+   |          matches all the values already
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs
index 99d318e36be..746b98fbd07 100644
--- a/tests/ui/privacy/private-in-public-warn.rs
+++ b/tests/ui/privacy/private-in-public-warn.rs
@@ -39,7 +39,7 @@ mod traits {
     pub trait PubTr {}
 
     pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`
-    //~^ WARNING bounds on generic parameters are not enforced in type aliases
+    //~^ WARNING bounds on generic parameters in type aliases are not enforced
     pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`
     pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`
     pub trait Tr3 {
@@ -58,7 +58,7 @@ mod traits_where {
 
     pub type Alias<T> where T: PrivTr = T;
         //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
-        //~| WARNING where clauses are not enforced in type aliases
+        //~| WARNING where clauses on type aliases are not enforced
     pub trait Tr2<T> where T: PrivTr {}
         //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
     pub trait Tr3 {
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr
index ac7e5547de9..3f7b8c281e7 100644
--- a/tests/ui/privacy/private-in-public-warn.stderr
+++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
 LL |     struct Priv2;
    |     ^^^^^^^^^^^^
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/private-in-public-warn.rs:41:23
    |
 LL |     pub type Alias<T: PrivTr> = T;
-   |                       ^^^^^^
-   |
+   |                     --^^^^^^
+   |                     | |
+   |                     | will not be checked at usage sites of the type alias
+   |                     help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL -     pub type Alias<T: PrivTr> = T;
-LL +     pub type Alias<T> = T;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/private-in-public-warn.rs:59:29
    |
 LL |     pub type Alias<T> where T: PrivTr = T;
-   |                             ^^^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL -     pub type Alias<T> where T: PrivTr = T;
-LL +     pub type Alias<T>  = T;
-   |
+   |                       ------^^^^^^^^^
+   |                       |     |
+   |                       |     will not be checked at usage sites of the type alias
+   |                       help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 error: aborting due to 34 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/reachable/unreachable-arm.stderr b/tests/ui/reachable/unreachable-arm.stderr
index 60db8217640..79627404030 100644
--- a/tests/ui/reachable/unreachable-arm.stderr
+++ b/tests/ui/reachable/unreachable-arm.stderr
@@ -1,8 +1,10 @@
 error: unreachable pattern
   --> $DIR/unreachable-arm.rs:11:9
    |
+LL |         Foo::B(_) | Foo::A(box _, 1) => { }
+   |         ---------------------------- matches all the values already
 LL |         Foo::A(_, 1) => { }
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/unreachable-arm.rs:4:9
diff --git a/tests/ui/reachable/unreachable-loop-patterns.stderr b/tests/ui/reachable/unreachable-loop-patterns.stderr
index 1dea9d813f9..bdd9b5ee411 100644
--- a/tests/ui/reachable/unreachable-loop-patterns.stderr
+++ b/tests/ui/reachable/unreachable-loop-patterns.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |     for _ in unimplemented!() as Void {}
    |         ^
    |
+   = note: this pattern matches no values because `Void` is uninhabited
 note: the lint level is defined here
   --> $DIR/unreachable-loop-patterns.rs:5:9
    |
diff --git a/tests/ui/reachable/unreachable-try-pattern.stderr b/tests/ui/reachable/unreachable-try-pattern.stderr
index 8f3e23119fb..bc1a6fffda6 100644
--- a/tests/ui/reachable/unreachable-try-pattern.stderr
+++ b/tests/ui/reachable/unreachable-try-pattern.stderr
@@ -19,6 +19,7 @@ warning: unreachable pattern
 LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
    |                        ^^^^^
    |
+   = note: this pattern matches no values because `!` is uninhabited
 note: the lint level is defined here
   --> $DIR/unreachable-try-pattern.rs:4:9
    |
@@ -30,6 +31,8 @@ warning: unreachable pattern
    |
 LL |     let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
    |                                        ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 warning: 3 warnings emitted
 
diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs
index b97681d9563..37a49baee80 100644
--- a/tests/ui/resolve/issue-118295.rs
+++ b/tests/ui/resolve/issue-118295.rs
@@ -1,5 +1,11 @@
 macro_rules! {}
 //~^ ERROR cannot find macro `macro_rules` in this scope
 //~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
+//~| put a macro name here
+
+macro_rules!{}
+//~^ ERROR cannot find macro `macro_rules` in this scope
+//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
+//~| put a macro name here
 
 fn main() {}
diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr
index d60d7d9185d..06a37e81d6c 100644
--- a/tests/ui/resolve/issue-118295.stderr
+++ b/tests/ui/resolve/issue-118295.stderr
@@ -1,14 +1,26 @@
 error: cannot find macro `macro_rules` in this scope
-  --> $DIR/issue-118295.rs:1:1
+  --> $DIR/issue-118295.rs:6:1
    |
-LL | macro_rules! {}
+LL | macro_rules!{}
    | ^^^^^^^^^^^
    |
 note: maybe you have forgotten to define a name for this `macro_rules!`
+  --> $DIR/issue-118295.rs:6:12
+   |
+LL | macro_rules!{}
+   |            ^ put a macro name here
+
+error: cannot find macro `macro_rules` in this scope
   --> $DIR/issue-118295.rs:1:1
    |
 LL | macro_rules! {}
    | ^^^^^^^^^^^
+   |
+note: maybe you have forgotten to define a name for this `macro_rules!`
+  --> $DIR/issue-118295.rs:1:12
+   |
+LL | macro_rules! {}
+   |            ^ put a macro name here
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/issue-55673.stderr b/tests/ui/resolve/issue-55673.stderr
index ffc3252230a..4069b35a998 100644
--- a/tests/ui/resolve/issue-55673.stderr
+++ b/tests/ui/resolve/issue-55673.stderr
@@ -19,7 +19,7 @@ help: consider further restricting type parameter `T`
    |
 LL |     T::Baa: std::fmt::Debug, T: Foo
    |                            ~~~~~~~~
-help: and also change the associated type name
+help: ...and changing the associated type name
    |
 LL |     T::Bar: std::fmt::Debug,
    |        ~~~
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr
index fe2a72d2a31..a875041d89c 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         Err(!),
    |         ^^^^^^
    |
+   = note: this pattern matches no values because `Void` is uninhabited
 note: the lint level is defined here
   --> $DIR/unreachable.rs:7:9
    |
@@ -15,30 +16,40 @@ error: unreachable pattern
    |
 LL |     let (Ok(_x) | Err(!)) = res_void;
    |                   ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/unreachable.rs:22:12
    |
 LL |     if let Err(!) = res_void {}
    |            ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/unreachable.rs:24:24
    |
 LL |     if let (Ok(true) | Err(!)) = res_void {}
    |                        ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/unreachable.rs:26:23
    |
 LL |     for (Ok(mut _x) | Err(!)) in [res_void] {}
    |                       ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: unreachable pattern
   --> $DIR/unreachable.rs:30:18
    |
 LL | fn foo((Ok(_x) | Err(!)): Result<bool, Void>) {}
    |                  ^^^^^^
+   |
+   = note: this pattern matches no values because `Void` is uninhabited
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
index 7386f10a6fb..d5f58e436c5 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         _ => {}
    |         ^
    |
+   = note: this pattern matches no values because `EmptyNonExhaustiveEnum` is uninhabited
 note: the lint level is defined here
   --> $DIR/enum_same_crate_empty_match.rs:1:9
    |
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 3034a67dc43..4ec4ec9705a 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
@@ -2,7 +2,9 @@ error: unreachable pattern
   --> $DIR/issue-65157-repeated-match-arm.rs:15:9
    |
 LL |         PartiallyInhabitedVariants::Struct { .. } => {},
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ----------------------------------------- matches all the values already
+LL |         PartiallyInhabitedVariants::Struct { .. } => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern
    |
 note: the lint level is defined here
   --> $DIR/issue-65157-repeated-match-arm.rs:2:9
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 8bfd6e91f4d..d5192a70ed5 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
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         Some(_x) => (),
    |         ^^^^^^^^
    |
+   = note: this pattern matches no values because `UninhabitedEnum` is uninhabited
 note: the lint level is defined here
   --> $DIR/patterns_same_crate.rs:1:9
    |
@@ -15,24 +16,32 @@ error: unreachable pattern
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^
+   |
+   = note: this pattern matches no values because `UninhabitedVariants` is uninhabited
 
 error: unreachable pattern
   --> $DIR/patterns_same_crate.rs:61:15
    |
 LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
   --> $DIR/patterns_same_crate.rs:65:15
    |
 LL |     while let Some(_x) = uninhabited_struct() {
    |               ^^^^^^^^
+   |
+   = note: this pattern matches no values because `UninhabitedStruct` is uninhabited
 
 error: unreachable pattern
   --> $DIR/patterns_same_crate.rs:68:15
    |
 LL |     while let Some(_x) = uninhabited_tuple_struct() {
    |               ^^^^^^^^
+   |
+   = note: this pattern matches no values because `UninhabitedTupleStruct` is uninhabited
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
index 6eaa7d4d9bc..0c73b9abf35 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
@@ -3,7 +3,7 @@
 
 use std::arch::asm;
 
-#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
+#[track_caller] //~ ERROR [E0736]
 //~^ ERROR `#[track_caller]` requires Rust ABI
 #[naked]
 extern "C" fn f() {
@@ -15,7 +15,7 @@ extern "C" fn f() {
 struct S;
 
 impl S {
-    #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
+    #[track_caller] //~ ERROR [E0736]
     //~^ ERROR `#[track_caller]` requires Rust ABI
     #[naked]
     extern "C" fn g() {
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
index 04c5c649d7f..0625ed1183b 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
@@ -1,14 +1,20 @@
-error[E0736]: cannot use `#[track_caller]` with `#[naked]`
+error[E0736]: attribute incompatible with `#[naked]`
   --> $DIR/error-with-naked.rs:6:1
    |
 LL | #[track_caller]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
+LL |
+LL | #[naked]
+   | -------- function marked with `#[naked]` here
 
-error[E0736]: cannot use `#[track_caller]` with `#[naked]`
+error[E0736]: attribute incompatible with `#[naked]`
   --> $DIR/error-with-naked.rs:18:5
    |
 LL |     #[track_caller]
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
+LL |
+LL |     #[naked]
+   |     -------- function marked with `#[naked]` here
 
 error[E0737]: `#[track_caller]` requires Rust ABI
   --> $DIR/error-with-naked.rs:6:1
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr
index eed5dbb88de..8d0874fa900 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr
@@ -16,7 +16,9 @@ error: unreachable pattern
   --> $DIR/warns.rs:15:25
    |
 LL |         x if let None | None = x => {}
-   |                         ^^^^
+   |                  ----   ^^^^ unreachable pattern
+   |                  |
+   |                  matches all the values already
    |
 note: the lint level is defined here
   --> $DIR/warns.rs:12:8
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs
new file mode 100644
index 00000000000..7bf5118c340
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs
@@ -0,0 +1,17 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+
+use std::future::Future;
+
+fn main() {
+    core::pin::pin!(async {}).poll(&mut context());
+}
+
+fn context() -> core::task::Context<'static> {
+    loop {}
+}
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed
new file mode 100644
index 00000000000..44850c8c45b
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed
@@ -0,0 +1,21 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    Meow::poll(&core::pin::pin!(async {}), &mut context());
+    //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
+
+fn context() -> core::task::Context<'static> {
+    loop {}
+}
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr
new file mode 100644
index 00000000000..496b3197c34
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr
@@ -0,0 +1,16 @@
+error: trait method `poll` will become ambiguous in Rust 2024
+  --> $DIR/future-poll-async-block.rs:14:5
+   |
+LL |     core::pin::pin!(async {}).poll(&mut context());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
+   |
+   = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+note: the lint level is defined here
+  --> $DIR/future-poll-async-block.rs:8:9
+   |
+LL | #![deny(rust_2024_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs
new file mode 100644
index 00000000000..614e4c786c5
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs
@@ -0,0 +1,21 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    core::pin::pin!(async {}).poll(&mut context());
+    //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
+
+fn context() -> core::task::Context<'static> {
+    loop {}
+}
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed
new file mode 100644
index 00000000000..c96d1dcecc2
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed
@@ -0,0 +1,21 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn poll(&self) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    // This is a deliberate false positive.
+    // While `()` does not implement `Future` and can therefore not be ambiguous, we
+    // do not check that in the lint, as that introduces additional complexities.
+    // Just checking whether the self type is `Pin<&mut _>` is enough.
+    Meow::poll(&core::pin::pin!(()));
+    //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr
new file mode 100644
index 00000000000..020a00ccdec
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr
@@ -0,0 +1,16 @@
+error: trait method `poll` will become ambiguous in Rust 2024
+  --> $DIR/future-poll-not-future-pinned.rs:18:5
+   |
+LL |     core::pin::pin!(()).poll();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(()))`
+   |
+   = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+note: the lint level is defined here
+  --> $DIR/future-poll-not-future-pinned.rs:8:9
+   |
+LL | #![deny(rust_2024_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs
new file mode 100644
index 00000000000..21b170a5f1d
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs
@@ -0,0 +1,21 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn poll(&self) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    // This is a deliberate false positive.
+    // While `()` does not implement `Future` and can therefore not be ambiguous, we
+    // do not check that in the lint, as that introduces additional complexities.
+    // Just checking whether the self type is `Pin<&mut _>` is enough.
+    core::pin::pin!(()).poll();
+    //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs
new file mode 100644
index 00000000000..899b69ebfc2
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs
@@ -0,0 +1,15 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn poll(&self) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    // As the self type here is not `Pin<&mut _>`, the lint does not fire.
+    ().poll();
+}
diff --git a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs
new file mode 100644
index 00000000000..b6a5d278720
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs
@@ -0,0 +1,17 @@
+//@ edition: 2021
+
+#![deny(rust_2024_compatibility)]
+
+trait Meow {
+    fn poll(&self, _ctx: &mut core::task::Context<'_>) {}
+}
+impl<T> Meow for T {}
+fn main() {
+    core::pin::pin!(async {}).poll(&mut context());
+    //~^ ERROR trait method `poll` will become ambiguous in Rust 2024
+    //~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
+
+fn context() -> core::task::Context<'static> {
+    loop {}
+}
diff --git a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr
new file mode 100644
index 00000000000..5865029d65d
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr
@@ -0,0 +1,17 @@
+error: trait method `poll` will become ambiguous in Rust 2024
+  --> $DIR/in_2024_compatibility.rs:10:5
+   |
+LL |     core::pin::pin!(async {}).poll(&mut context());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
+   |
+   = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+note: the lint level is defined here
+  --> $DIR/in_2024_compatibility.rs:3:9
+   |
+LL | #![deny(rust_2024_compatibility)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(rust_2024_prelude_collisions)]` implied by `#[deny(rust_2024_compatibility)]`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed
new file mode 100644
index 00000000000..0b0873eb238
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed
@@ -0,0 +1,29 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn into_future(&self) {}
+}
+impl Meow for Cat {}
+
+struct Cat;
+
+impl core::future::IntoFuture for Cat {
+    type Output = ();
+    type IntoFuture = core::future::Ready<()>;
+
+    fn into_future(self) -> Self::IntoFuture {
+        core::future::ready(())
+    }
+}
+
+fn main() {
+    Meow::into_future(&Cat);
+    //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr
new file mode 100644
index 00000000000..b74e80e2a4a
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr
@@ -0,0 +1,16 @@
+error: trait method `into_future` will become ambiguous in Rust 2024
+  --> $DIR/into-future-adt.rs:26:5
+   |
+LL |     Cat.into_future();
+   |     ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
+   |
+   = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+note: the lint level is defined here
+  --> $DIR/into-future-adt.rs:8:9
+   |
+LL | #![deny(rust_2024_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.rs b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs
new file mode 100644
index 00000000000..0db70930bc7
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs
@@ -0,0 +1,29 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn into_future(&self) {}
+}
+impl Meow for Cat {}
+
+struct Cat;
+
+impl core::future::IntoFuture for Cat {
+    type Output = ();
+    type IntoFuture = core::future::Ready<()>;
+
+    fn into_future(self) -> Self::IntoFuture {
+        core::future::ready(())
+    }
+}
+
+fn main() {
+    Cat.into_future();
+    //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs
new file mode 100644
index 00000000000..6bc2ea31705
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs
@@ -0,0 +1,24 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+
+use core::future::IntoFuture;
+
+struct Cat;
+
+impl IntoFuture for Cat {
+    type Output = ();
+    type IntoFuture = core::future::Ready<()>;
+
+    fn into_future(self) -> Self::IntoFuture {
+        core::future::ready(())
+    }
+}
+
+fn main() {
+    let _ = Cat.into_future();
+}
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed
new file mode 100644
index 00000000000..a798014d93d
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed
@@ -0,0 +1,23 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn into_future(&self) {}
+}
+impl Meow for Cat {}
+
+struct Cat;
+
+fn main() {
+    // This is a false positive, but it should be rare enough to not matter, and checking whether
+    // it implements the trait can have other nontrivial consequences, so it was decided to accept
+    // this.
+    Meow::into_future(&Cat);
+    //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr
new file mode 100644
index 00000000000..6ea4580ca72
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr
@@ -0,0 +1,16 @@
+error: trait method `into_future` will become ambiguous in Rust 2024
+  --> $DIR/into-future-not-into-future.rs:20:5
+   |
+LL |     Cat.into_future();
+   |     ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
+   |
+   = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+note: the lint level is defined here
+  --> $DIR/into-future-not-into-future.rs:8:9
+   |
+LL | #![deny(rust_2024_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs
new file mode 100644
index 00000000000..23e81cfe6b4
--- /dev/null
+++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs
@@ -0,0 +1,23 @@
+//@ revisions: e2021 e2024
+//@[e2021] edition: 2021
+//@[e2021] run-rustfix
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//@[e2024] check-pass
+
+#![deny(rust_2024_prelude_collisions)]
+trait Meow {
+    fn into_future(&self) {}
+}
+impl Meow for Cat {}
+
+struct Cat;
+
+fn main() {
+    // This is a false positive, but it should be rare enough to not matter, and checking whether
+    // it implements the trait can have other nontrivial consequences, so it was decided to accept
+    // this.
+    Cat.into_future();
+    //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024
+    //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
+}
diff --git a/tests/ui/traits/maybe-polarity-pass.rs b/tests/ui/traits/maybe-polarity-pass.rs
new file mode 100644
index 00000000000..075a0d8dcac
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-pass.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+
+#![feature(auto_traits)]
+#![feature(more_maybe_bounds)]
+#![feature(negative_impls)]
+
+trait Trait1 {}
+auto trait Trait2 {}
+
+trait Trait3 : ?Trait1 {}
+trait Trait4 where Self: Trait1 {}
+
+fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
+fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
+//~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+struct S;
+impl !Trait2 for S {}
+impl Trait1 for S {}
+impl Trait3 for S {}
+
+fn main() {
+    foo(Box::new(S));
+    bar(&S);
+}
diff --git a/tests/ui/traits/maybe-polarity-pass.stderr b/tests/ui/traits/maybe-polarity-pass.stderr
new file mode 100644
index 00000000000..09ed52f5b0d
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-pass.stderr
@@ -0,0 +1,20 @@
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-pass.rs:14:20
+   |
+LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
+   |                    ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-pass.rs:14:30
+   |
+LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
+   |                              ^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-pass.rs:14:40
+   |
+LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
+   |                                        ^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/traits/maybe-polarity-repeated.rs b/tests/ui/traits/maybe-polarity-repeated.rs
new file mode 100644
index 00000000000..4b5ec83fffa
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-repeated.rs
@@ -0,0 +1,9 @@
+#![feature(more_maybe_bounds)]
+
+trait Trait {}
+fn foo<T: ?Trait + ?Trait>(_: T) {}
+//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+
+fn main() {}
diff --git a/tests/ui/traits/maybe-polarity-repeated.stderr b/tests/ui/traits/maybe-polarity-repeated.stderr
new file mode 100644
index 00000000000..610c484fbec
--- /dev/null
+++ b/tests/ui/traits/maybe-polarity-repeated.stderr
@@ -0,0 +1,21 @@
+error[E0203]: type parameter has more than one relaxed default bound, only one is supported
+  --> $DIR/maybe-polarity-repeated.rs:4:11
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |           ^^^^^^   ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-repeated.rs:4:11
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |           ^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-polarity-repeated.rs:4:20
+   |
+LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
+   |                    ^^^^^^
+
+error: aborting due to 1 previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0203`.
diff --git a/tests/ui/traits/wf-object/maybe-bound.stderr b/tests/ui/traits/wf-object/maybe-bound.stderr
index 2fe3f0fc39f..be7afabd0d0 100644
--- a/tests/ui/traits/wf-object/maybe-bound.stderr
+++ b/tests/ui/traits/wf-object/maybe-bound.stderr
@@ -1,32 +1,48 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bound.rs:5:15
    |
 LL | type _0 = dyn ?Sized + Foo;
    |               ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bound.rs:8:21
    |
 LL | type _1 = dyn Foo + ?Sized;
    |                     ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bound.rs:11:21
    |
 LL | type _2 = dyn Foo + ?Sized + ?Sized;
    |                     ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bound.rs:11:30
    |
 LL | type _2 = dyn Foo + ?Sized + ?Sized;
    |                              ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/maybe-bound.rs:15:15
    |
 LL | type _3 = dyn ?Sized + Foo;
    |               ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr
index cbc41feec1e..26269476eaa 100644
--- a/tests/ui/traits/wf-object/only-maybe-bound.stderr
+++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr
@@ -1,8 +1,11 @@
-error: `?Trait` is not permitted in trait object types
+error[E0658]: `?Trait` is not permitted in trait object types
   --> $DIR/only-maybe-bound.rs:3:15
    |
 LL | type _0 = dyn ?Sized;
    |               ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0224]: at least one trait is required for an object type
   --> $DIR/only-maybe-bound.rs:3:11
@@ -12,4 +15,5 @@ LL | type _0 = dyn ?Sized;
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0224`.
+Some errors have detailed explanations: E0224, E0658.
+For more information about an error, try `rustc --explain E0224`.
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
index d66e468873b..0eae68bfcf0 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
@@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters
 LL | union U where i32: Foo { f: i32 }
    |                    ^^^
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/trivial-bounds-inconsistent.rs:22:14
    |
 LL | type Y where i32: Foo = ();
-   |              ^^^^^^^^
-   |
+   |        ------^^^^^^^^
+   |        |     |
+   |        |     will not be checked at usage sites of the type alias
+   |        help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type Y where i32: Foo = ();
-LL + type Y  = ();
-   |
 
 warning: trait bound i32: Foo does not depend on any type or lifetime parameters
   --> $DIR/trivial-bounds-inconsistent.rs:22:19
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr
new file mode 100644
index 00000000000..e891ff10fda
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr
@@ -0,0 +1,36 @@
+error[E0220]: associated type `Assoc` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
+   |
+LL | type AssocOf<T> = T::Assoc;
+   |                      ^^^^^ there is an associated type `Assoc` in the trait `Trait`
+   |
+help: consider fully qualifying the associated type
+   |
+LL | type AssocOf<T> = <T as Trait>::Assoc;
+   |                   +  +++++++++
+
+error[E0220]: associated type `Assok` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
+   |
+LL | type AssokOf<T> = T::Assok;
+   |                      ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
+   |
+help: consider fully qualifying and renaming the associated type
+   |
+LL | type AssokOf<T> = <T as Trait>::Assoc;
+   |                   +  +++++++++  ~~~~~
+
+error[E0220]: associated type `Proj` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
+   |
+LL | type ProjOf<T> = T::Proj;
+   |                     ^^^^ there is an associated type `Proj` in the trait `Parametrized`
+   |
+help: consider fully qualifying the associated type
+   |
+LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
+   |                  +  ++++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr
new file mode 100644
index 00000000000..96179a7b484
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr
@@ -0,0 +1,40 @@
+error[E0220]: associated type `Assoc` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
+   |
+LL | type AssocOf<T> = T::Assoc;
+   |                      ^^^^^ there is an associated type `Assoc` in the trait `Trait`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type AssocOf<T: Trait> = T::Assoc;
+   |               +++++++
+
+error[E0220]: associated type `Assok` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
+   |
+LL | type AssokOf<T> = T::Assok;
+   |                      ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type AssokOf<T: Trait> = T::Assok;
+   |               +++++++
+help: ...and changing the associated type name
+   |
+LL | type AssokOf<T> = T::Assoc;
+   |                      ~~~~~
+
+error[E0220]: associated type `Proj` not found for `T`
+  --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
+   |
+LL | type ProjOf<T> = T::Proj;
+   |                     ^^^^ there is an associated type `Proj` in the trait `Parametrized`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
+   |              ++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs
new file mode 100644
index 00000000000..2c8d448f308
--- /dev/null
+++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs
@@ -0,0 +1,26 @@
+// Ensure that we don't suggest *type alias bounds* for **eager** type aliases.
+// issue: rust-lang/rust#125789
+
+//@ revisions: eager lazy
+#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
+
+trait Trait { type Assoc; }
+
+type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
+//[eager]~^ HELP consider fully qualifying the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+
+type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
+//[eager]~^ HELP consider fully qualifying and renaming the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+//[lazy]~| HELP and changing the associated type name
+
+trait Parametrized<'a, T, const N: usize> {
+    type Proj;
+}
+
+type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
+//[eager]~^ HELP consider fully qualifying the associated type
+//[lazy]~| HELP consider restricting type parameter `T`
+
+fn main() {}
diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
index 5ee3c027f40..52e0887175d 100644
--- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
+++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
@@ -3,6 +3,6 @@
 
 //@ check-pass
 pub type T<P: Send + Send + Send> = P;
-//~^ WARN bounds on generic parameters are not enforced in type aliases
+//~^ WARN bounds on generic parameters in type aliases are not enforced
 
 fn main() {}
diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
index 125ffbbb417..9fd0fe4913b 100644
--- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
+++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr
@@ -1,15 +1,16 @@
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15
    |
 LL | pub type T<P: Send + Send + Send> = P;
-   |               ^^^^   ^^^^   ^^^^
+   |             --^^^^---^^^^---^^^^
+   |             |               |
+   |             |               will not be checked at usage sites of the type alias
+   |             help: remove this bound
    |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - pub type T<P: Send + Send + Send> = P;
-LL + pub type T<P> = P;
-   |
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/type/type-alias-bounds.rs b/tests/ui/type/type-alias-bounds.rs
index 6d63c0c7e1b..37c073fe1f9 100644
--- a/tests/ui/type/type-alias-bounds.rs
+++ b/tests/ui/type/type-alias-bounds.rs
@@ -6,15 +6,15 @@
 use std::rc::Rc;
 
 type SVec<T: Send + Send> = Vec<T>;
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type S2Vec<T> where T: Send = Vec<T>;
-//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
 type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
+//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
 type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
+//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
 
 static STATIC: u32 = 0;
 
@@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) {
 struct Sendable<T: Send>(T);
 type MySendable<T> = Sendable<T>; // no error here!
 
-// However, bounds *are* taken into account when accessing associated types
+// Bounds on type params do enable shorthand type alias paths.
+// However, that doesn't actually mean that they are properly enforced.
 trait Bound { type Assoc; }
-type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
-type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
+type T1<U: Bound> = U::Assoc; //~ WARN are not enforced
+type T2<U> where U: Bound = U::Assoc;  //~ WARN are not enforced
 
 // This errors:
 // `type T3<U> = U::Assoc;`
@@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc;  //~ WARN not enforced in type aliases
 type T4<U> = <U as Bound>::Assoc;
 
 // Make sure the help about associated types is not shown incorrectly
-type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN not enforced in type aliases
-type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN not enforced in type aliases
+type T5<U: Bound> = <U as Bound>::Assoc;  //~ WARN are not enforced
+type T6<U: Bound> = ::std::vec::Vec<U>;  //~ WARN are not enforced
 
 fn main() {}
diff --git a/tests/ui/type/type-alias-bounds.stderr b/tests/ui/type/type-alias-bounds.stderr
index 92e573393c9..15c00901066 100644
--- a/tests/ui/type/type-alias-bounds.stderr
+++ b/tests/ui/type/type-alias-bounds.stderr
@@ -1,121 +1,132 @@
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:8:14
    |
 LL | type SVec<T: Send + Send> = Vec<T>;
-   |              ^^^^   ^^^^
-   |
+   |            --^^^^---^^^^
+   |            |        |
+   |            |        will not be checked at usage sites of the type alias
+   |            help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
    = note: `#[warn(type_alias_bounds)]` on by default
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type SVec<T: Send + Send> = Vec<T>;
-LL + type SVec<T> = Vec<T>;
-   |
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:10:21
    |
 LL | type S2Vec<T> where T: Send = Vec<T>;
-   |                     ^^^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type S2Vec<T> where T: Send = Vec<T>;
-LL + type S2Vec<T>  = Vec<T>;
-   |
+   |               ------^^^^^^^
+   |               |     |
+   |               |     will not be checked at usage sites of the type alias
+   |               help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:12:19
    |
 LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-   |                   ^^   ^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
-LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>);
-   |
+   |                 --^^---^^
+   |                 |      |
+   |                 |      will not be checked at usage sites of the type alias
+   |                 help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
+warning: bounds on generic parameters in type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:14:18
    |
 LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-   |                  ^^   ^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
-LL + type WVec<'b, T> = (&'b u32, Vec<T>);
-   |
+   |                --^^---^^
+   |                |      |
+   |                |      will not be checked at usage sites of the type alias
+   |                help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: where clauses are not enforced in type aliases
+warning: where clauses on type aliases are not enforced
   --> $DIR/type-alias-bounds.rs:16:25
    |
 LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-   |                         ^^^^^  ^^^^^
-   |
-help: the clause will not be checked when the type alias is used, and should be removed
-   |
-LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
-LL + type W2Vec<'b, T>  = (&'b u32, Vec<T>);
-   |
+   |                   ------^^^^^--^^^^^
+   |                   |            |
+   |                   |            will not be checked at usage sites of the type alias
+   |                   help: remove this where clause
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:47:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:48:12
    |
 LL | type T1<U: Bound> = U::Assoc;
-   |            ^^^^^
+   |            ^^^^^ will not be checked at usage sites of the type alias
    |
-help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-  --> $DIR/type-alias-bounds.rs:47:21
-   |
-LL | type T1<U: Bound> = U::Assoc;
-   |                     ^^^^^^^^
-help: the bound will not be checked when the type alias is used, and should be removed
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+help: remove this bound
    |
 LL - type T1<U: Bound> = U::Assoc;
 LL + type T1<U> = U::Assoc;
    |
+help: fully qualify this associated type
+   |
+LL | type T1<U: Bound> = <U as /* Trait */>::Assoc;
+   |                     +  +++++++++++++++
 
-warning: where clauses are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:48:18
+warning: where clauses on type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:49:18
    |
 LL | type T2<U> where U: Bound = U::Assoc;
-   |                  ^^^^^^^^
+   |                  ^^^^^^^^ will not be checked at usage sites of the type alias
    |
-help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
-  --> $DIR/type-alias-bounds.rs:48:29
-   |
-LL | type T2<U> where U: Bound = U::Assoc;
-   |                             ^^^^^^^^
-help: the clause will not be checked when the type alias is used, and should be removed
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
+help: remove this where clause
    |
 LL - type T2<U> where U: Bound = U::Assoc;
 LL + type T2<U>  = U::Assoc;
    |
+help: fully qualify this associated type
+   |
+LL | type T2<U> where U: Bound = <U as /* Trait */>::Assoc;
+   |                             +  +++++++++++++++
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:56:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:57:12
    |
 LL | type T5<U: Bound> = <U as Bound>::Assoc;
-   |            ^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type T5<U: Bound> = <U as Bound>::Assoc;
-LL + type T5<U> = <U as Bound>::Assoc;
-   |
+   |          --^^^^^
+   |          | |
+   |          | will not be checked at usage sites of the type alias
+   |          help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
-warning: bounds on generic parameters are not enforced in type aliases
-  --> $DIR/type-alias-bounds.rs:57:12
+warning: bounds on generic parameters in type aliases are not enforced
+  --> $DIR/type-alias-bounds.rs:58:12
    |
 LL | type T6<U: Bound> = ::std::vec::Vec<U>;
-   |            ^^^^^
-   |
-help: the bound will not be checked when the type alias is used, and should be removed
-   |
-LL - type T6<U: Bound> = ::std::vec::Vec<U>;
-LL + type T6<U> = ::std::vec::Vec<U>;
-   |
+   |          --^^^^^
+   |          | |
+   |          | will not be checked at usage sites of the type alias
+   |          help: remove this bound
+   |
+   = note: this is a known limitation of the type checker that may be lifted in a future edition.
+           see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
 
 warning: 9 warnings emitted
 
diff --git a/tests/ui/uninhabited/uninhabited-patterns.stderr b/tests/ui/uninhabited/uninhabited-patterns.stderr
index a6fda88f032..ca62386d7ef 100644
--- a/tests/ui/uninhabited/uninhabited-patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-patterns.stderr
@@ -4,6 +4,7 @@ error: unreachable pattern
 LL |         Ok(box _) => (),
    |         ^^^^^^^^^
    |
+   = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited
 note: the lint level is defined here
   --> $DIR/uninhabited-patterns.rs:4:9
    |
@@ -15,12 +16,16 @@ error: unreachable pattern
    |
 LL |         Err(Ok(_y)) => (),
    |         ^^^^^^^^^^^
+   |
+   = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited
 
 error: unreachable pattern
   --> $DIR/uninhabited-patterns.rs:42:15
    |
 LL |     while let Some(_y) = foo() {
    |               ^^^^^^^^
+   |
+   = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/unsized/maybe-bounds-where.stderr b/tests/ui/unsized/maybe-bounds-where.stderr
index 683bd387bb2..f7851261667 100644
--- a/tests/ui/unsized/maybe-bounds-where.stderr
+++ b/tests/ui/unsized/maybe-bounds-where.stderr
@@ -1,32 +1,47 @@
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
   --> $DIR/maybe-bounds-where.rs:1:28
    |
 LL | struct S1<T>(T) where (T): ?Sized;
    |                            ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
   --> $DIR/maybe-bounds-where.rs:4:27
    |
 LL | struct S2<T>(T) where u8: ?Sized;
    |                           ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
   --> $DIR/maybe-bounds-where.rs:7:35
    |
 LL | struct S3<T>(T) where &'static T: ?Sized;
    |                                   ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
   --> $DIR/maybe-bounds-where.rs:12:34
    |
 LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
    |                                  ^^^^^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: `?Trait` bounds are only permitted at the point where a type parameter is declared
+error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
   --> $DIR/maybe-bounds-where.rs:21:21
    |
 LL |     fn f() where T: ?Sized {}
    |                     ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
   --> $DIR/maybe-bounds-where.rs:12:34
@@ -39,6 +54,9 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i
    |
 LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
    |                                 ^^^^^^^^^^^^^^^   ^^^^^^
+   |
+   = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
   --> $DIR/maybe-bounds-where.rs:16:33
@@ -48,4 +66,5 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
 
 error: aborting due to 6 previous errors; 2 warnings emitted
 
-For more information about this error, try `rustc --explain E0203`.
+Some errors have detailed explanations: E0203, E0658.
+For more information about an error, try `rustc --explain E0203`.
diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr
index 03cada07a9e..0a810b7222e 100644
--- a/tests/ui/variance/variance-issue-20533.stderr
+++ b/tests/ui/variance/variance-issue-20533.stderr
@@ -73,10 +73,14 @@ LL |         drop(a);
 LL |         drop(x);
    |              - borrow later used here
    |
-help: consider cloning the value if the performance cost is acceptable
+note: if `AffineU32` implemented `Clone`, you could clone the value
+  --> $DIR/variance-issue-20533.rs:26:1
    |
-LL |         let x = bat(&a).clone();
-   |                        ++++++++
+LL | struct AffineU32(u32);
+   | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |         let x = bat(&a);
+   |                     -- you could clone this value
 
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/variance-issue-20533.rs:59:14