From b8615aa3f5cde84aa7277e549c2a30fa5e4ac5d5 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Tue, 24 Sep 2024 11:32:33 +0200
Subject: [PATCH 01/18] Move existing rfc3627 tests to a dedicated folder

---
 .../auxiliary/migration_lint_macros.rs}       |  0
 .../migration_lint.fixed}                     |  6 ++--
 .../migration_lint.rs}                        |  6 ++--
 .../migration_lint.stderr}                    | 30 +++++++++----------
 4 files changed, 21 insertions(+), 21 deletions(-)
 rename tests/ui/pattern/{auxiliary/match_ergonomics_2024_macros.rs => rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs} (100%)
 rename tests/ui/pattern/{match_ergonomics_2024.fixed => rfc-3627-match-ergonomics-2024/migration_lint.fixed} (91%)
 rename tests/ui/pattern/{match_ergonomics_2024.rs => rfc-3627-match-ergonomics-2024/migration_lint.rs} (91%)
 rename tests/ui/pattern/{match_ergonomics_2024.stderr => rfc-3627-match-ergonomics-2024/migration_lint.stderr} (80%)

diff --git a/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs
similarity index 100%
rename from tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs
diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
similarity index 91%
rename from tests/ui/pattern/match_ergonomics_2024.fixed
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index 1ec2b5a214bfa..253c9589a552a 100644
--- a/tests/ui/pattern/match_ergonomics_2024.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -1,12 +1,12 @@
 //@ edition: 2021
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
-//@ aux-build:match_ergonomics_2024_macros.rs
+//@ aux-build:migration_lint_macros.rs
 #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
-extern crate match_ergonomics_2024_macros;
+extern crate migration_lint_macros;
 
 struct Foo(u8);
 
@@ -47,7 +47,7 @@ fn main() {
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
-        (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
+        (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
             //~^ WARN: the semantics of this pattern will change in edition 2024
             _x = 4;
             _y = &7;
diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
similarity index 91%
rename from tests/ui/pattern/match_ergonomics_2024.rs
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index c9f992c12d4a2..1406db779cc7b 100644
--- a/tests/ui/pattern/match_ergonomics_2024.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -1,12 +1,12 @@
 //@ edition: 2021
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
-//@ aux-build:match_ergonomics_2024_macros.rs
+//@ aux-build:migration_lint_macros.rs
 #![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
-extern crate match_ergonomics_2024_macros;
+extern crate migration_lint_macros;
 
 struct Foo(u8);
 
@@ -47,7 +47,7 @@ fn main() {
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
-        (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
+        (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
             //~^ WARN: the semantics of this pattern will change in edition 2024
             _x = 4;
             _y = &7;
diff --git a/tests/ui/pattern/match_ergonomics_2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
similarity index 80%
rename from tests/ui/pattern/match_ergonomics_2024.stderr
rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 11844434ad214..4d7230120247d 100644
--- a/tests/ui/pattern/match_ergonomics_2024.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -1,5 +1,5 @@
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:14:9
+  --> $DIR/migration_lint.rs:14:9
    |
 LL |     let Foo(mut a) = &Foo(0);
    |         -^^^^^^^^^
@@ -7,13 +7,13 @@ LL |     let Foo(mut a) = &Foo(0);
    |         help: desugar the match ergonomics: `&`
    |
 note: the lint level is defined here
-  --> $DIR/match_ergonomics_2024.rs:7:9
+  --> $DIR/migration_lint.rs:7:9
    |
 LL | #![deny(rust_2024_incompatible_pat)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:18:9
+  --> $DIR/migration_lint.rs:18:9
    |
 LL |     let Foo(mut a) = &mut Foo(0);
    |         -^^^^^^^^^
@@ -21,7 +21,7 @@ LL |     let Foo(mut a) = &mut Foo(0);
    |         help: desugar the match ergonomics: `&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:22:12
+  --> $DIR/migration_lint.rs:22:12
    |
 LL |     if let Some(&_) = &&&&&Some(&0u8) {}
    |            -^^^^^^^
@@ -29,7 +29,7 @@ LL |     if let Some(&_) = &&&&&Some(&0u8) {}
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:25:12
+  --> $DIR/migration_lint.rs:25:12
    |
 LL |     if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
    |            -^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL |     if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:28:12
+  --> $DIR/migration_lint.rs:28:12
    |
 LL |     if let Some(&_) = &&&&&mut Some(&0u8) {}
    |            -^^^^^^^
@@ -45,7 +45,7 @@ LL |     if let Some(&_) = &&&&&mut Some(&0u8) {}
    |            help: desugar the match ergonomics: `&&&&&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:31:12
+  --> $DIR/migration_lint.rs:31:12
    |
 LL |     if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut So
    |            ++++                ++++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:34:12
+  --> $DIR/migration_lint.rs:34:12
    |
 LL |     if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -67,7 +67,7 @@ LL |     if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Som
    |            ++++                ++++      +++++++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:43:9
+  --> $DIR/migration_lint.rs:43:9
    |
 LL |     let Struct { a, mut b, c } = &s;
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -78,20 +78,20 @@ LL |     let &Struct { ref a, mut b, ref c } = &s;
    |         +         +++           +++
 
 warning: the semantics of this pattern will change in edition 2024
-  --> $DIR/match_ergonomics_2024.rs:50:9
+  --> $DIR/migration_lint.rs:50:9
    |
-LL |         (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/match_ergonomics_2024.rs:46:12
+  --> $DIR/migration_lint.rs:46:12
    |
 LL |     #[warn(rust_2024_incompatible_pat)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: desugar the match ergonomics
    |
-LL |         &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
-   |         +                                                                +++
+LL |         &(Some(mut _x), migration_lint_macros::mixed_edition_pat!(ref _y)) => {
+   |         +                                                         +++
 
 error: aborting due to 8 previous errors; 1 warning emitted
 

From c22588b700a62a1d93ff7bc30fd49583efab4ad2 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Fri, 20 Sep 2024 19:47:30 +0200
Subject: [PATCH 02/18] Add `min_match_ergonomics_2024` feature gate

---
 compiler/rustc_feature/src/unstable.rs | 3 +++
 compiler/rustc_span/src/symbol.rs      | 1 +
 2 files changed, 4 insertions(+)

diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index fa3a7049f4a07..5fff81d3e1cd7 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -516,6 +516,9 @@ declare_features! (
     (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)),
     /// Allows `#[marker]` on certain traits allowing overlapping implementations.
     (unstable, marker_trait_attr, "1.30.0", Some(29864)),
+    /// A very restricted form of match ergonomics used over the 2024 edition transition to give
+    /// more time for T-lang to decide the final form of RFC3627.
+    (incomplete, min_match_ergonomics_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
     /// A minimal, sound subset of specialization intended to be used by the
     /// standard library until the soundness issues with specialization
     /// are fixed.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 402232a1720b7..81ae66ccf6807 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1218,6 +1218,7 @@ symbols! {
         min_const_generics,
         min_const_unsafe_fn,
         min_exhaustive_patterns,
+        min_match_ergonomics_2024,
         min_specialization,
         min_type_alias_impl_trait,
         minnumf128,

From 94ab726c7856cd7716d2a33db3e1915faed99008 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= <gabriel@achernar.io>
Date: Wed, 25 Sep 2024 11:35:01 +0200
Subject: [PATCH 03/18] Add 'from_ref' and 'from_mut' constructors to
 'core::ptr::NonNull';

---
 library/core/src/lib.rs                       |  1 +
 library/core/src/ptr/non_null.rs              | 28 ++++++++++---
 ...ated_loop.PreCodegen.after.panic-abort.mir | 40 ++++++++++---------
 ...ted_loop.PreCodegen.after.panic-unwind.mir | 20 +++++-----
 ...ward_loop.PreCodegen.after.panic-abort.mir | 16 ++++----
 ...ard_loop.PreCodegen.after.panic-unwind.mir | 16 ++++----
 ...erse_loop.PreCodegen.after.panic-abort.mir | 22 +++++-----
 ...rse_loop.PreCodegen.after.panic-unwind.mir | 22 +++++-----
 8 files changed, 97 insertions(+), 68 deletions(-)

diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 01cadd78cc09d..53d11ebb5d621 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -174,6 +174,7 @@
 #![feature(isqrt)]
 #![feature(lazy_get)]
 #![feature(link_cfg)]
+#![feature(non_null_from_ref)]
 #![feature(offset_of_enum)]
 #![feature(panic_internals)]
 #![feature(ptr_alignment_type)]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index daa40b3c9d2e5..44936d69bc966 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -230,6 +230,24 @@ impl<T: ?Sized> NonNull<T> {
         }
     }
 
+    /// Converts a reference to a `NonNull` pointer.
+    #[unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[inline]
+    pub const fn from_ref(r: &T) -> Self {
+        // SAFETY: A reference cannot be null.
+        unsafe { NonNull { pointer: r as *const T } }
+    }
+
+    /// Converts a mutable reference to a `NonNull` pointer.
+    #[unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
+    #[inline]
+    pub const fn from_mut(r: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null.
+        unsafe { NonNull { pointer: r as *mut T } }
+    }
+
     /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
     /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer.
     ///
@@ -1753,9 +1771,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
     ///
     /// This conversion is safe and infallible since references cannot be null.
     #[inline]
-    fn from(reference: &mut T) -> Self {
-        // SAFETY: A mutable reference cannot be null.
-        unsafe { NonNull { pointer: reference as *mut T } }
+    fn from(r: &mut T) -> Self {
+        NonNull::from_mut(r)
     }
 }
 
@@ -1765,8 +1782,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
     ///
     /// This conversion is safe and infallible since references cannot be null.
     #[inline]
-    fn from(reference: &T) -> Self {
-        // SAFETY: A reference cannot be null.
-        unsafe { NonNull { pointer: reference as *const T } }
+    fn from(r: &T) -> Self {
+        NonNull::from_ref(r)
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index 3aa483ed1aefa..bd56ab67e0029 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
             debug i => _22;
             debug x => _23;
         }
-        scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
             let mut _15: std::option::Option<&T>;
             let mut _19: (usize, bool);
             let mut _20: (usize, &T);
-            scope 18 {
+            scope 19 {
                 let _18: usize;
-                scope 23 {
+                scope 24 {
                 }
             }
-            scope 19 {
-                scope 20 {
-                    scope 26 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
+            scope 20 {
+                scope 21 {
+                    scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
                     }
                 }
             }
-            scope 21 {
-                scope 22 {
+            scope 22 {
+                scope 23 {
                 }
             }
-            scope 24 (inlined <Option<&T> as Try>::branch) {
+            scope 25 (inlined <Option<&T> as Try>::branch) {
                 let mut _16: isize;
                 let _17: &T;
-                scope 25 {
+                scope 26 {
                 }
             }
         }
@@ -59,29 +59,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 4cc0aa0ed788d..57f09a4631b5d 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -34,29 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 507afa63c6884..4050304f46981 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index a25f12edc28e9..2c3d7ab1e4a89 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 1b397a4e4cdde..a6ccd435c40eb 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index 77689dd9b513e..df11c8e3b4966 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     let _9: *const T;
                     scope 7 {
                     }
-                    scope 11 (inlined without_provenance::<T>) {
+                    scope 12 (inlined without_provenance::<T>) {
                     }
-                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                    scope 13 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
-                    let mut _4: *const [T];
+                    scope 9 (inlined NonNull::<[T]>::from_ref) {
+                        let mut _4: *const [T];
+                    }
                 }
-                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 10 (inlined NonNull::<[T]>::cast::<T>) {
                     let mut _5: *const T;
-                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                    scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
             }
         }
     }
-    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {

From 4abbdfa1c9cd3e2f3181608fb60539755f3a8068 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 6 Oct 2024 20:05:27 +0200
Subject: [PATCH 04/18] Prepare tests

---
 .../migration_lint.fixed                      | 111 ++++++++++++++----
 .../migration_lint.rs                         | 111 ++++++++++++++----
 .../migration_lint.stderr                     | 105 ++++++++++++-----
 3 files changed, 256 insertions(+), 71 deletions(-)

diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index 253c9589a552a..528d274c0ac2a 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -8,49 +8,120 @@
 
 extern crate migration_lint_macros;
 
-struct Foo(u8);
+struct Foo<T>(T);
+
+// Tests type equality in a way that avoids coercing `&&T` to `&T`.
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
 
 fn main() {
-    let &Foo(mut a) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
-    a = 42;
+    let Foo(x) = &Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let Foo(x) = &mut Foo(0);
+    assert_type_eq(x, &mut 0u8);
 
-    let &mut Foo(mut a) = &mut Foo(0);
+    let &Foo(mut x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
-    a = 42;
+    assert_type_eq(x, 0u8);
 
-    if let &&&&&Some(&_) = &&&&&Some(&0u8) {}
+    let &mut Foo(mut x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
+
+    let Foo(ref x) = &Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let Foo(ref x) = &mut Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let &Foo(x) = &Foo(0);
+    assert_type_eq(x, 0u8);
 
-    if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {}
+    let &mut Foo(x) = &mut Foo(0);
+    assert_type_eq(x, 0u8);
+
+    let &Foo(x) = &Foo(&0);
+    assert_type_eq(x, &0u8);
+
+    let &mut Foo(x) = &mut Foo(&0);
+    assert_type_eq(x, &0u8);
+
+    let &Foo(&x) = &Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {}
+    let &Foo(&mut x) = &Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    let &mut Foo(&x) = &mut Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    let &mut Foo(&mut x) = &mut Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
+
+    if let Some(x) = &&&&&Some(&0u8) {
+        assert_type_eq(x, &&0u8);
+    }
+
+    if let &&&&&Some(&x) = &&&&&Some(&0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, &mut 0u8);
+    }
 
-    struct Struct {
-        a: u32,
-        b: u32,
-        c: u32,
+    struct Struct<A, B, C> {
+        a: A,
+        b: B,
+        c: C,
     }
-    let s = Struct { a: 0, b: 0, c: 0 };
-    let &Struct { ref a, mut b, ref c } = &s;
+
+    let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, 0u32);
+
+    let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &&0u32);
+    assert_type_eq(c, &&0u32);
+
+    if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
+    {
+        assert_type_eq(a, &0u32);
+        assert_type_eq(b, 0u32);
+        assert_type_eq(c, &&0u32);
+    }
 
     #[warn(rust_2024_incompatible_pat)]
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
-        (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
+        (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
             //~^ WARN: the semantics of this pattern will change in edition 2024
-            _x = 4;
-            _y = &7;
+            assert_type_eq(x, 0u32);
+            assert_type_eq(y, &0u32);
         }
         _ => {}
     }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index 1406db779cc7b..0c5be2c761d16 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -8,49 +8,120 @@
 
 extern crate migration_lint_macros;
 
-struct Foo(u8);
+struct Foo<T>(T);
+
+// Tests type equality in a way that avoids coercing `&&T` to `&T`.
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
 
 fn main() {
-    let Foo(mut a) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
-    a = 42;
+    let Foo(x) = &Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let Foo(x) = &mut Foo(0);
+    assert_type_eq(x, &mut 0u8);
 
-    let Foo(mut a) = &mut Foo(0);
+    let Foo(mut x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
-    a = 42;
+    assert_type_eq(x, 0u8);
 
-    if let Some(&_) = &&&&&Some(&0u8) {}
+    let Foo(mut x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
+
+    let Foo(ref x) = &Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let Foo(ref x) = &mut Foo(0);
+    assert_type_eq(x, &0u8);
+
+    let &Foo(x) = &Foo(0);
+    assert_type_eq(x, 0u8);
 
-    if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
+    let &mut Foo(x) = &mut Foo(0);
+    assert_type_eq(x, 0u8);
+
+    let &Foo(x) = &Foo(&0);
+    assert_type_eq(x, &0u8);
+
+    let &mut Foo(x) = &mut Foo(&0);
+    assert_type_eq(x, &0u8);
+
+    let Foo(&x) = &Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let Some(&_) = &&&&&mut Some(&0u8) {}
+    let Foo(&mut x) = &Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    let Foo(&x) = &mut Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
 
-    if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    let Foo(&mut x) = &mut Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(x, 0u8);
+
+    if let Some(x) = &&&&&Some(&0u8) {
+        assert_type_eq(x, &&0u8);
+    }
+
+    if let Some(&x) = &&&&&Some(&0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let Some(&mut x) = &&&&&Some(&mut 0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let Some(&x) = &&&&&mut Some(&0u8) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, 0u8);
+    }
+
+    if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        assert_type_eq(x, &mut 0u8);
+    }
 
-    struct Struct {
-        a: u32,
-        b: u32,
-        c: u32,
+    struct Struct<A, B, C> {
+        a: A,
+        b: B,
+        c: C,
     }
-    let s = Struct { a: 0, b: 0, c: 0 };
-    let Struct { a, mut b, c } = &s;
+
+    let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, 0u32);
+
+    let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &&0u32);
+    assert_type_eq(c, &&0u32);
+
+    if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
+        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
+    {
+        assert_type_eq(a, &0u32);
+        assert_type_eq(b, 0u32);
+        assert_type_eq(c, &&0u32);
+    }
 
     #[warn(rust_2024_incompatible_pat)]
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
-        (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
+        (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
             //~^ WARN: the semantics of this pattern will change in edition 2024
-            _x = 4;
-            _y = &7;
+            assert_type_eq(x, 0u32);
+            assert_type_eq(y, &0u32);
         }
         _ => {}
     }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 4d7230120247d..29e9183acc3be 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -1,7 +1,7 @@
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:14:9
+  --> $DIR/migration_lint.rs:25:9
    |
-LL |     let Foo(mut a) = &Foo(0);
+LL |     let Foo(mut x) = &Foo(0);
    |         -^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&`
@@ -13,85 +13,128 @@ LL | #![deny(rust_2024_incompatible_pat)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:18:9
+  --> $DIR/migration_lint.rs:29:9
    |
-LL |     let Foo(mut a) = &mut Foo(0);
+LL |     let Foo(mut x) = &mut Foo(0);
    |         -^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:22:12
+  --> $DIR/migration_lint.rs:51:9
    |
-LL |     if let Some(&_) = &&&&&Some(&0u8) {}
+LL |     let Foo(&x) = &Foo(&0);
+   |         -^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:55:9
+   |
+LL |     let Foo(&mut x) = &Foo(&mut 0);
+   |         -^^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:59:9
+   |
+LL |     let Foo(&x) = &mut Foo(&0);
+   |         -^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&mut`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:63:9
+   |
+LL |     let Foo(&mut x) = &mut Foo(&mut 0);
+   |         -^^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&mut`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:71:12
+   |
+LL |     if let Some(&x) = &&&&&Some(&0u8) {
    |            -^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:25:12
+  --> $DIR/migration_lint.rs:76:12
    |
-LL |     if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
+LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
    |            -^^^^^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:28:12
+  --> $DIR/migration_lint.rs:81:12
    |
-LL |     if let Some(&_) = &&&&&mut Some(&0u8) {}
+LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
    |            -^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:31:12
+  --> $DIR/migration_lint.rs:86:12
    |
-LL |     if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: desugar the match ergonomics
    |
-LL |     if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
-   |            ++++                ++++
+LL |     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
+   |            ++++                ++++      +++++++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:34:12
+  --> $DIR/migration_lint.rs:97:9
    |
-LL |     if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: desugar the match ergonomics
    |
-LL |     if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
-   |            ++++                ++++      +++++++
+LL |     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
+   |         +         +++           +++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:43:9
+  --> $DIR/migration_lint.rs:102:9
    |
-LL |     let Struct { a, mut b, c } = &s;
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: desugar the match ergonomics
    |
-LL |     let &Struct { ref a, mut b, ref c } = &s;
-   |         +         +++           +++
+LL |     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
+   |         +                +++
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:108:12
+   |
+LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: desugar the match ergonomics
+   |
+LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
+   |            +                         +             +     +++
 
 warning: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:50:9
+  --> $DIR/migration_lint.rs:121:9
    |
-LL |         (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/migration_lint.rs:46:12
+  --> $DIR/migration_lint.rs:117:12
    |
 LL |     #[warn(rust_2024_incompatible_pat)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: desugar the match ergonomics
    |
-LL |         &(Some(mut _x), migration_lint_macros::mixed_edition_pat!(ref _y)) => {
-   |         +                                                         +++
+LL |         &(Some(mut x), migration_lint_macros::mixed_edition_pat!(ref y)) => {
+   |         +                                                        +++
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 13 previous errors; 1 warning emitted
 

From 4107322766523afa7d1968acc0dfee4fd06e8ad8 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Sun, 6 Oct 2024 20:47:06 +0200
Subject: [PATCH 05/18] Error on resetted binding mode in edition 2024

---
 compiler/rustc_hir_typeck/src/pat.rs          |  15 +-
 compiler/rustc_hir_typeck/src/writeback.rs    |   6 +-
 compiler/rustc_lint_defs/src/builtin.rs       |   4 +-
 .../rustc_middle/src/ty/typeck_results.rs     |  15 +-
 compiler/rustc_mir_build/src/errors.rs        |   2 +
 .../rustc_mir_build/src/thir/pattern/mod.rs   |  28 +++-
 .../migration_lint.fixed                      |   9 +-
 .../migration_lint.rs                         |   7 +-
 .../migration_lint.stderr                     |  20 +--
 .../min_match_ergonomics_fail.rs              |  49 ++++++
 .../min_match_ergonomics_fail.stderr          | 144 ++++++++++++++++++
 .../min_match_ergonomics_success.rs           |  19 +++
 12 files changed, 270 insertions(+), 48 deletions(-)
 create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
 create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
 create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs

diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 45a6efc7a6a32..8eb3118fb8ad8 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -692,10 +692,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     BindingMode(def_br, Mutability::Mut)
                 } else {
                     // `mut` resets binding mode on edition <= 2021
-                    self.typeck_results
+                    *self
+                        .typeck_results
                         .borrow_mut()
                         .rust_2024_migration_desugared_pats_mut()
-                        .insert(pat_info.top_info.hir_id);
+                        .entry(pat_info.top_info.hir_id)
+                        .or_default() |= pat.span.at_least_rust_2024();
                     BindingMode(ByRef::No, Mutability::Mut)
                 }
             }
@@ -2206,14 +2208,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Reset binding mode on old editions
-
             if pat_info.binding_mode != ByRef::No {
                 pat_info.binding_mode = ByRef::No;
-
-                self.typeck_results
+                *self
+                    .typeck_results
                     .borrow_mut()
                     .rust_2024_migration_desugared_pats_mut()
-                    .insert(pat_info.top_info.hir_id);
+                    .entry(pat_info.top_info.hir_id)
+                    .or_default() |= pat.span.at_least_rust_2024();
             }
         }
 
@@ -2264,6 +2266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (err, err)
             }
         };
+
         self.check_pat(inner, inner_ty, pat_info);
         ref_ty
     }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index c2555d2bb47dc..8164c7377529b 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -640,7 +640,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
-        if self
+        if let Some(is_hard_error) = self
             .fcx
             .typeck_results
             .borrow_mut()
@@ -650,7 +650,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             debug!(
                 "node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
             );
-            self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
+            self.typeck_results
+                .rust_2024_migration_desugared_pats_mut()
+                .insert(hir_id, is_hard_error);
         }
     }
 
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9b6d63c2ef480..06e63bd73411d 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1650,7 +1650,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,edition2021
-    /// #![feature(ref_pat_eat_one_layer_2024)]
+    /// #![feature(min_match_ergonomics_2024)]
     /// #![warn(rust_2024_incompatible_pat)]
     ///
     /// if let Some(&a) = &Some(&0u8) {
@@ -1671,7 +1671,7 @@ declare_lint! {
     pub RUST_2024_INCOMPATIBLE_PAT,
     Allow,
     "detects patterns whose meaning will change in Rust 2024",
-    @feature_gate = ref_pat_eat_one_layer_2024;
+    @feature_gate = min_match_ergonomics_2024;
     // FIXME uncomment below upon stabilization
     /*@future_incompatible = FutureIncompatibleInfo {
         reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index a92bdb2eae0de..c13d229ebdcba 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -79,9 +79,10 @@ pub struct TypeckResults<'tcx> {
     /// Stores the actual binding mode for all instances of [`BindingMode`].
     pat_binding_modes: ItemLocalMap<BindingMode>,
 
-    /// Top-level patterns whose match ergonomics need to be desugared
-    /// by the Rust 2021 -> 2024 migration lint.
-    rust_2024_migration_desugared_pats: ItemLocalSet,
+    /// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
+    /// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error
+    /// (if any of the incompatible pattern elements are in edition 2024).
+    rust_2024_migration_desugared_pats: ItemLocalMap<bool>,
 
     /// Stores the types which were implicitly dereferenced in pattern binding modes
     /// for later usage in THIR lowering. For example,
@@ -437,15 +438,15 @@ impl<'tcx> TypeckResults<'tcx> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
     }
 
-    pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
-        LocalSetInContext {
+    pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> {
+        LocalTableInContext {
             hir_owner: self.hir_owner,
             data: &self.rust_2024_migration_desugared_pats,
         }
     }
 
-    pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
-        LocalSetInContextMut {
+    pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> {
+        LocalTableInContextMut {
             hir_owner: self.hir_owner,
             data: &mut self.rust_2024_migration_desugared_pats,
         }
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 411e9420914da..7f905d5b90b75 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat {
 
 pub(crate) struct Rust2024IncompatiblePatSugg {
     pub(crate) suggestion: Vec<(Span, String)>,
+    /// Whether the incompatibility is a hard error because a relevant span is in edition 2024.
+    pub(crate) is_hard_error: bool,
 }
 
 impl Subdiagnostic for Rust2024IncompatiblePatSugg {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index d78e1f5da09f0..90355d7fce691 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -48,18 +48,30 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
         typeck_results,
         rust_2024_migration_suggestion: typeck_results
             .rust_2024_migration_desugared_pats()
-            .contains(pat.hir_id)
-            .then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
+            .get(pat.hir_id)
+            .map(|&is_hard_error| Rust2024IncompatiblePatSugg {
+                suggestion: Vec::new(),
+                is_hard_error,
+            }),
     };
     let result = pcx.lower_pattern(pat);
     debug!("pat_from_hir({:?}) = {:?}", pat, result);
     if let Some(sugg) = pcx.rust_2024_migration_suggestion {
-        tcx.emit_node_span_lint(
-            lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
-            pat.hir_id,
-            pat.span,
-            Rust2024IncompatiblePat { sugg },
-        );
+        if tcx.features().min_match_ergonomics_2024 && sugg.is_hard_error {
+            let mut err = tcx.dcx().struct_span_err(
+                pat.span,
+                "patterns are not allowed to reset the default binding mode in rust 2024",
+            );
+            err.subdiagnostic(sugg);
+            err.emit();
+        } else {
+            tcx.emit_node_span_lint(
+                lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
+                pat.hir_id,
+                pat.span,
+                Rust2024IncompatiblePat { sugg },
+            );
+        }
     }
     result
 }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index 528d274c0ac2a..63c84ae5b9976 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:migration_lint_macros.rs
-#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
+#![feature(mut_ref, min_match_ergonomics_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
@@ -114,14 +114,13 @@ fn main() {
         assert_type_eq(c, &&0u32);
     }
 
-    #[warn(rust_2024_incompatible_pat)]
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
-        (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-            //~^ WARN: the semantics of this pattern will change in edition 2024
+        &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
+            //~^ ERROR: patterns are not allowed to reset the default binding mode
             assert_type_eq(x, 0u32);
-            assert_type_eq(y, &0u32);
+            assert_type_eq(y, 0u32);
         }
         _ => {}
     }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index 0c5be2c761d16..f2a83c1266bf2 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:migration_lint_macros.rs
-#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
+#![feature(mut_ref, min_match_ergonomics_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
@@ -114,14 +114,13 @@ fn main() {
         assert_type_eq(c, &&0u32);
     }
 
-    #[warn(rust_2024_incompatible_pat)]
     match &(Some(0), Some(0)) {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-            //~^ WARN: the semantics of this pattern will change in edition 2024
+            //~^ ERROR: patterns are not allowed to reset the default binding mode
             assert_type_eq(x, 0u32);
-            assert_type_eq(y, &0u32);
+            assert_type_eq(y, 0u32);
         }
         _ => {}
     }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 29e9183acc3be..5e42e03d6685b 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -120,21 +120,13 @@ help: desugar the match ergonomics
 LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
    |            +                         +             +     +++
 
-warning: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:121:9
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/migration_lint.rs:120:9
    |
 LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/migration_lint.rs:117:12
-   |
-LL |     #[warn(rust_2024_incompatible_pat)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: desugar the match ergonomics
-   |
-LL |         &(Some(mut x), migration_lint_macros::mixed_edition_pat!(ref y)) => {
-   |         +                                                        +++
+   |         -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
 
-error: aborting due to 13 previous errors; 1 warning emitted
+error: aborting due to 14 previous errors
 
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
new file mode 100644
index 0000000000000..283666fdf4cab
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
@@ -0,0 +1,49 @@
+//@ check-fail
+//@ edition: 2024
+//@ compile-flags: -Zunstable-options
+// gate-test-min_match_ergonomics_2024
+#![feature(min_match_ergonomics_2024)]
+#![allow(incomplete_features)]
+#![deny(rust_2024_incompatible_pat)]
+
+fn main() {}
+
+#[derive(Copy, Clone)]
+struct T;
+
+struct Foo {
+    f: &'static (u8,),
+}
+
+macro_rules! test_pat_on_type {
+    ($($tt:tt)*) => {
+        const _: () = {
+            // Define a new function to ensure all cases are tested independently.
+            fn foo($($tt)*) {}
+        };
+    };
+}
+
+test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
+test_pat_on_type![(&x,): &(&T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
+test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types
+test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types
+test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
+test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types
+test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
+test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
+test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode
+test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
+test_pat_on_type![(ref x,): &(T,)];
+test_pat_on_type![(ref mut x,): &mut (T,)];
+
+fn get<X>() -> X {
+    unimplemented!()
+}
+
+// Make sure this works even when the underlying type is inferred. This test passes on rust stable.
+fn infer<X: Copy>() -> X {
+    match &get() {
+        (&x,) => x, //~ ERROR patterns are not allowed to reset the default binding mode
+    }
+}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
new file mode 100644
index 0000000000000..22247847def2d
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -0,0 +1,144 @@
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:27:20
+   |
+LL | test_pat_on_type![(&x,): &(T,)];
+   |                    ^^    ----- expected due to this
+   |                    |
+   |                    expected `T`, found `&_`
+   |
+   = note: expected struct `T`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - test_pat_on_type![(&x,): &(T,)];
+LL + test_pat_on_type![(x,): &(T,)];
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:29:20
+   |
+LL | test_pat_on_type![(&x,): &(&mut T,)];
+   |                    ^^    ---------- expected due to this
+   |                    |
+   |                    types differ in mutability
+   |
+   = note: expected mutable reference `&mut T`
+                      found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - test_pat_on_type![(&x,): &(&mut T,)];
+LL + test_pat_on_type![(x,): &(&mut T,)];
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:30:20
+   |
+LL | test_pat_on_type![(&mut x,): &(&T,)];
+   |                    ^^^^^^    ------ expected due to this
+   |                    |
+   |                    types differ in mutability
+   |
+   = note:      expected reference `&T`
+           found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut x`
+  --> $DIR/min_match_ergonomics_fail.rs:30:20
+   |
+LL | test_pat_on_type![(&mut x,): &(&T,)];
+   |                    ^^^^^^
+help: consider removing `&mut` from the pattern
+   |
+LL - test_pat_on_type![(&mut x,): &(&T,)];
+LL + test_pat_on_type![(x,): &(&T,)];
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:32:20
+   |
+LL | test_pat_on_type![(&x,): &&mut &(T,)];
+   |                    ^^    ----------- expected due to this
+   |                    |
+   |                    expected `T`, found `&_`
+   |
+   = note: expected struct `T`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - test_pat_on_type![(&x,): &&mut &(T,)];
+LL + test_pat_on_type![(x,): &&mut &(T,)];
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:33:29
+   |
+LL | test_pat_on_type![Foo { f: (&x,) }: Foo];
+   |                             ^^      --- expected due to this
+   |                             |
+   |                             expected `u8`, found `&_`
+   |
+   = note:   expected type `u8`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - test_pat_on_type![Foo { f: (&x,) }: Foo];
+LL + test_pat_on_type![Foo { f: (x,) }: Foo];
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/min_match_ergonomics_fail.rs:34:29
+   |
+LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
+   |                             ^^      -------- expected due to this
+   |                             |
+   |                             expected `u8`, found `&_`
+   |
+   = note:   expected type `u8`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
+LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
+   |
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:28:19
+   |
+LL | test_pat_on_type![(&x,): &(&T,)];
+   |                   -^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&`
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:31:19
+   |
+LL | test_pat_on_type![(&mut x,): &(&mut T,)];
+   |                   -^^^^^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&`
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:35:19
+   |
+LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
+   |                   -^^^^^^^^^^^^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&`
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:36:19
+   |
+LL | test_pat_on_type![(mut x,): &(T,)];
+   |                   -^^^^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&`
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:47:9
+   |
+LL |         (&x,) => x,
+   |         -^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs
new file mode 100644
index 0000000000000..8dbbd7cfbb0c8
--- /dev/null
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs
@@ -0,0 +1,19 @@
+//@ revisions: normal min_match_ergonomics
+//@ check-pass
+#![cfg_attr(min_match_ergonomics, feature(min_match_ergonomics_2024))]
+#![allow(incomplete_features)]
+
+fn main() {}
+
+// Tests type equality in a way that avoids coercing `&&T` to `&T`.
+trait Eq<T> {}
+impl<T> Eq<T> for T {}
+fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
+
+#[derive(Copy, Clone)]
+struct T;
+
+fn test() {
+    let (x,) = &(&T,);
+    assert_type_eq(x, &&T);
+}

From 575033c50cf3f530bb054211e3dae968d373037f Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Mon, 7 Oct 2024 23:39:33 +0200
Subject: [PATCH 06/18] Also disallow `ref`/`ref mut` overriding the binding
 mode

---
 compiler/rustc_hir_typeck/src/pat.rs          | 15 ++++++-
 .../migration_lint.fixed                      |  6 ++-
 .../migration_lint.rs                         |  2 +
 .../migration_lint.stderr                     | 42 +++++++++++++------
 .../min_match_ergonomics_fail.rs              |  4 +-
 .../min_match_ergonomics_fail.stderr          | 18 +++++++-
 6 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 8eb3118fb8ad8..9ac5367d5d993 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -691,7 +691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     BindingMode(def_br, Mutability::Mut)
                 } else {
-                    // `mut` resets binding mode on edition <= 2021
+                    // `mut` resets the binding mode on edition <= 2021
                     *self
                         .typeck_results
                         .borrow_mut()
@@ -702,7 +702,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
-            BindingMode(ByRef::Yes(_), _) => user_bind_annot,
+            BindingMode(ByRef::Yes(_), _) => {
+                if matches!(def_br, ByRef::Yes(_)) {
+                    // `ref`/`ref mut` overrides the binding mode on edition <= 2021
+                    *self
+                        .typeck_results
+                        .borrow_mut()
+                        .rust_2024_migration_desugared_pats_mut()
+                        .entry(pat_info.top_info.hir_id)
+                        .or_default() |= pat.span.at_least_rust_2024();
+                }
+                user_bind_annot
+            }
         };
 
         if bm.0 == ByRef::Yes(Mutability::Mut)
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index 63c84ae5b9976..a0fc34826a2f0 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -30,10 +30,12 @@ fn main() {
     //~^ ERROR: the semantics of this pattern will change in edition 2024
     assert_type_eq(x, 0u8);
 
-    let Foo(ref x) = &Foo(0);
+    let &Foo(ref x) = &Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
     assert_type_eq(x, &0u8);
 
-    let Foo(ref x) = &mut Foo(0);
+    let &mut Foo(ref x) = &mut Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
     assert_type_eq(x, &0u8);
 
     let &Foo(x) = &Foo(0);
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index f2a83c1266bf2..6fdea065dc0f2 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -31,9 +31,11 @@ fn main() {
     assert_type_eq(x, 0u8);
 
     let Foo(ref x) = &Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
     assert_type_eq(x, &0u8);
 
     let Foo(ref x) = &mut Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
     assert_type_eq(x, &0u8);
 
     let &Foo(x) = &Foo(0);
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 5e42e03d6685b..f429b96010d70 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -21,7 +21,23 @@ LL |     let Foo(mut x) = &mut Foo(0);
    |         help: desugar the match ergonomics: `&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:51:9
+  --> $DIR/migration_lint.rs:33:9
+   |
+LL |     let Foo(ref x) = &Foo(0);
+   |         -^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:37:9
+   |
+LL |     let Foo(ref x) = &mut Foo(0);
+   |         -^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&mut`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/migration_lint.rs:53:9
    |
 LL |     let Foo(&x) = &Foo(&0);
    |         -^^^^^^
@@ -29,7 +45,7 @@ LL |     let Foo(&x) = &Foo(&0);
    |         help: desugar the match ergonomics: `&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:55:9
+  --> $DIR/migration_lint.rs:57:9
    |
 LL |     let Foo(&mut x) = &Foo(&mut 0);
    |         -^^^^^^^^^^
@@ -37,7 +53,7 @@ LL |     let Foo(&mut x) = &Foo(&mut 0);
    |         help: desugar the match ergonomics: `&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:59:9
+  --> $DIR/migration_lint.rs:61:9
    |
 LL |     let Foo(&x) = &mut Foo(&0);
    |         -^^^^^^
@@ -45,7 +61,7 @@ LL |     let Foo(&x) = &mut Foo(&0);
    |         help: desugar the match ergonomics: `&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:63:9
+  --> $DIR/migration_lint.rs:65:9
    |
 LL |     let Foo(&mut x) = &mut Foo(&mut 0);
    |         -^^^^^^^^^^
@@ -53,7 +69,7 @@ LL |     let Foo(&mut x) = &mut Foo(&mut 0);
    |         help: desugar the match ergonomics: `&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:71:12
+  --> $DIR/migration_lint.rs:73:12
    |
 LL |     if let Some(&x) = &&&&&Some(&0u8) {
    |            -^^^^^^^
@@ -61,7 +77,7 @@ LL |     if let Some(&x) = &&&&&Some(&0u8) {
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:76:12
+  --> $DIR/migration_lint.rs:78:12
    |
 LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
    |            -^^^^^^^^^^^
@@ -69,7 +85,7 @@ LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
    |            help: desugar the match ergonomics: `&&&&&`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:81:12
+  --> $DIR/migration_lint.rs:83:12
    |
 LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
    |            -^^^^^^^
@@ -77,7 +93,7 @@ LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
    |            help: desugar the match ergonomics: `&&&&&mut`
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:86:12
+  --> $DIR/migration_lint.rs:88:12
    |
 LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +104,7 @@ LL |     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some
    |            ++++                ++++      +++++++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:97:9
+  --> $DIR/migration_lint.rs:99:9
    |
 LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +115,7 @@ LL |     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
    |         +         +++           +++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:102:9
+  --> $DIR/migration_lint.rs:104:9
    |
 LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +126,7 @@ LL |     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         +                +++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:108:12
+  --> $DIR/migration_lint.rs:110:12
    |
 LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,12 +137,12 @@ LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
    |            +                         +             +     +++
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/migration_lint.rs:120:9
+  --> $DIR/migration_lint.rs:122:9
    |
 LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
    |         -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&`
 
-error: aborting due to 14 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
index 283666fdf4cab..c5d2199852ba1 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
@@ -34,8 +34,8 @@ test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
 test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
 test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode
 test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
-test_pat_on_type![(ref x,): &(T,)];
-test_pat_on_type![(ref mut x,): &mut (T,)];
+test_pat_on_type![(ref x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
+test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
 
 fn get<X>() -> X {
     unimplemented!()
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
index 22247847def2d..8f189e1cf0793 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -131,6 +131,22 @@ LL | test_pat_on_type![(mut x,): &(T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:37:19
+   |
+LL | test_pat_on_type![(ref x,): &(T,)];
+   |                   -^^^^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&`
+
+error: patterns are not allowed to reset the default binding mode in rust 2024
+  --> $DIR/min_match_ergonomics_fail.rs:38:19
+   |
+LL | test_pat_on_type![(ref mut x,): &mut (T,)];
+   |                   -^^^^^^^^^^^
+   |                   |
+   |                   help: desugar the match ergonomics: `&mut`
+
 error: patterns are not allowed to reset the default binding mode in rust 2024
   --> $DIR/min_match_ergonomics_fail.rs:47:9
    |
@@ -139,6 +155,6 @@ LL |         (&x,) => x,
    |         |
    |         help: desugar the match ergonomics: `&`
 
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
 
 For more information about this error, try `rustc --explain E0308`.

From 4aaada42d0b59c3294908f9996277c60d9e13917 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Mon, 7 Oct 2024 23:47:21 +0200
Subject: [PATCH 07/18] Stabilize `min_match_ergonomics_2024`

---
 compiler/rustc_feature/src/unstable.rs        |  3 -
 compiler/rustc_lint_defs/src/builtin.rs       |  7 +-
 .../rustc_mir_build/src/thir/pattern/mod.rs   |  2 +-
 compiler/rustc_span/src/symbol.rs             |  1 -
 .../migration_lint.fixed                      | 17 ++++-
 .../migration_lint.rs                         | 17 ++++-
 .../migration_lint.stderr                     | 70 +++++++++++++++----
 .../min_match_ergonomics_fail.rs              |  3 -
 .../min_match_ergonomics_fail.stderr          | 28 ++++----
 .../min_match_ergonomics_success.rs           |  2 -
 10 files changed, 104 insertions(+), 46 deletions(-)

diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 5fff81d3e1cd7..fa3a7049f4a07 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -516,9 +516,6 @@ declare_features! (
     (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)),
     /// Allows `#[marker]` on certain traits allowing overlapping implementations.
     (unstable, marker_trait_attr, "1.30.0", Some(29864)),
-    /// A very restricted form of match ergonomics used over the 2024 edition transition to give
-    /// more time for T-lang to decide the final form of RFC3627.
-    (incomplete, min_match_ergonomics_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
     /// A minimal, sound subset of specialization intended to be used by the
     /// standard library until the soundness issues with specialization
     /// are fixed.
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 06e63bd73411d..b73ceb91c400e 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1650,7 +1650,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,edition2021
-    /// #![feature(min_match_ergonomics_2024)]
     /// #![warn(rust_2024_incompatible_pat)]
     ///
     /// if let Some(&a) = &Some(&0u8) {
@@ -1671,12 +1670,10 @@ declare_lint! {
     pub RUST_2024_INCOMPATIBLE_PAT,
     Allow,
     "detects patterns whose meaning will change in Rust 2024",
-    @feature_gate = min_match_ergonomics_2024;
-    // FIXME uncomment below upon stabilization
-    /*@future_incompatible = FutureIncompatibleInfo {
+    @future_incompatible = FutureIncompatibleInfo {
         reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
         reference: "123076",
-    };*/
+    };
 }
 
 declare_lint! {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 90355d7fce691..bb02ee37733c9 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -57,7 +57,7 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
     let result = pcx.lower_pattern(pat);
     debug!("pat_from_hir({:?}) = {:?}", pat, result);
     if let Some(sugg) = pcx.rust_2024_migration_suggestion {
-        if tcx.features().min_match_ergonomics_2024 && sugg.is_hard_error {
+        if sugg.is_hard_error {
             let mut err = tcx.dcx().struct_span_err(
                 pat.span,
                 "patterns are not allowed to reset the default binding mode in rust 2024",
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 81ae66ccf6807..402232a1720b7 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1218,7 +1218,6 @@ symbols! {
         min_const_generics,
         min_const_unsafe_fn,
         min_exhaustive_patterns,
-        min_match_ergonomics_2024,
         min_specialization,
         min_type_alias_impl_trait,
         minnumf128,
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index a0fc34826a2f0..90c35b5a69723 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:migration_lint_macros.rs
-#![feature(mut_ref, min_match_ergonomics_2024)]
+#![feature(mut_ref)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
@@ -24,18 +24,22 @@ fn main() {
 
     let &Foo(mut x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(mut x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &Foo(ref x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let &mut Foo(ref x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let &Foo(x) = &Foo(0);
@@ -52,18 +56,22 @@ fn main() {
 
     let &Foo(&x) = &Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &Foo(&mut x) = &Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&x) = &mut Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&mut x) = &mut Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     if let Some(x) = &&&&&Some(&0u8) {
@@ -72,21 +80,25 @@ fn main() {
 
     if let &&&&&Some(&x) = &&&&&Some(&0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
 
@@ -98,17 +110,20 @@ fn main() {
 
     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
         assert_type_eq(a, &0u32);
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index 6fdea065dc0f2..04d547f301867 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:migration_lint_macros.rs
-#![feature(mut_ref, min_match_ergonomics_2024)]
+#![feature(mut_ref)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
@@ -24,18 +24,22 @@ fn main() {
 
     let Foo(mut x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(mut x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(ref x) = &Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let Foo(ref x) = &mut Foo(0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let &Foo(x) = &Foo(0);
@@ -52,18 +56,22 @@ fn main() {
 
     let Foo(&x) = &Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&x) = &mut Foo(&0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &mut Foo(&mut 0);
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     if let Some(x) = &&&&&Some(&0u8) {
@@ -72,21 +80,25 @@ fn main() {
 
     if let Some(&x) = &&&&&Some(&0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&x) = &&&&&mut Some(&0u8) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
 
@@ -98,17 +110,20 @@ fn main() {
 
     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
     //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
         //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
         assert_type_eq(a, &0u32);
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index f429b96010d70..4881748f71adf 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -6,6 +6,8 @@ LL |     let Foo(mut x) = &Foo(0);
    |         |
    |         help: desugar the match ergonomics: `&`
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 note: the lint level is defined here
   --> $DIR/migration_lint.rs:7:9
    |
@@ -13,131 +15,169 @@ LL | #![deny(rust_2024_incompatible_pat)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:29:9
+  --> $DIR/migration_lint.rs:30:9
    |
 LL |     let Foo(mut x) = &mut Foo(0);
    |         -^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&mut`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:33:9
+  --> $DIR/migration_lint.rs:35:9
    |
 LL |     let Foo(ref x) = &Foo(0);
    |         -^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:37:9
+  --> $DIR/migration_lint.rs:40:9
    |
 LL |     let Foo(ref x) = &mut Foo(0);
    |         -^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&mut`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:53:9
+  --> $DIR/migration_lint.rs:57:9
    |
 LL |     let Foo(&x) = &Foo(&0);
    |         -^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:57:9
+  --> $DIR/migration_lint.rs:62:9
    |
 LL |     let Foo(&mut x) = &Foo(&mut 0);
    |         -^^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:61:9
+  --> $DIR/migration_lint.rs:67:9
    |
 LL |     let Foo(&x) = &mut Foo(&0);
    |         -^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&mut`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:65:9
+  --> $DIR/migration_lint.rs:72:9
    |
 LL |     let Foo(&mut x) = &mut Foo(&mut 0);
    |         -^^^^^^^^^^
    |         |
    |         help: desugar the match ergonomics: `&mut`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:73:12
+  --> $DIR/migration_lint.rs:81:12
    |
 LL |     if let Some(&x) = &&&&&Some(&0u8) {
    |            -^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:78:12
+  --> $DIR/migration_lint.rs:87:12
    |
 LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
    |            -^^^^^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:83:12
+  --> $DIR/migration_lint.rs:93:12
    |
 LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
    |            -^^^^^^^
    |            |
    |            help: desugar the match ergonomics: `&&&&&mut`
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:88:12
+  --> $DIR/migration_lint.rs:99:12
    |
 LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 help: desugar the match ergonomics
    |
 LL |     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ++++                ++++      +++++++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:99:9
+  --> $DIR/migration_lint.rs:111:9
    |
 LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 help: desugar the match ergonomics
    |
 LL |     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
    |         +         +++           +++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:104:9
+  --> $DIR/migration_lint.rs:117:9
    |
 LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 help: desugar the match ergonomics
    |
 LL |     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         +                +++
 
 error: the semantics of this pattern will change in edition 2024
-  --> $DIR/migration_lint.rs:110:12
+  --> $DIR/migration_lint.rs:124:12
    |
 LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see 123076
 help: desugar the match ergonomics
    |
 LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
    |            +                         +             +     +++
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/migration_lint.rs:122:9
+  --> $DIR/migration_lint.rs:137:9
    |
 LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
    |         -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
index c5d2199852ba1..a822c90ab6e5a 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
@@ -1,9 +1,6 @@
 //@ check-fail
 //@ edition: 2024
 //@ compile-flags: -Zunstable-options
-// gate-test-min_match_ergonomics_2024
-#![feature(min_match_ergonomics_2024)]
-#![allow(incomplete_features)]
 #![deny(rust_2024_incompatible_pat)]
 
 fn main() {}
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
index 8f189e1cf0793..ca34ad8d0ece3 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:27:20
+  --> $DIR/min_match_ergonomics_fail.rs:24:20
    |
 LL | test_pat_on_type![(&x,): &(T,)];
    |                    ^^    ----- expected due to this
@@ -15,7 +15,7 @@ LL + test_pat_on_type![(x,): &(T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:29:20
+  --> $DIR/min_match_ergonomics_fail.rs:26:20
    |
 LL | test_pat_on_type![(&x,): &(&mut T,)];
    |                    ^^    ---------- expected due to this
@@ -31,7 +31,7 @@ LL + test_pat_on_type![(x,): &(&mut T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:30:20
+  --> $DIR/min_match_ergonomics_fail.rs:27:20
    |
 LL | test_pat_on_type![(&mut x,): &(&T,)];
    |                    ^^^^^^    ------ expected due to this
@@ -41,7 +41,7 @@ LL | test_pat_on_type![(&mut x,): &(&T,)];
    = note:      expected reference `&T`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/min_match_ergonomics_fail.rs:30:20
+  --> $DIR/min_match_ergonomics_fail.rs:27:20
    |
 LL | test_pat_on_type![(&mut x,): &(&T,)];
    |                    ^^^^^^
@@ -52,7 +52,7 @@ LL + test_pat_on_type![(x,): &(&T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:32:20
+  --> $DIR/min_match_ergonomics_fail.rs:29:20
    |
 LL | test_pat_on_type![(&x,): &&mut &(T,)];
    |                    ^^    ----------- expected due to this
@@ -68,7 +68,7 @@ LL + test_pat_on_type![(x,): &&mut &(T,)];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:33:29
+  --> $DIR/min_match_ergonomics_fail.rs:30:29
    |
 LL | test_pat_on_type![Foo { f: (&x,) }: Foo];
    |                             ^^      --- expected due to this
@@ -84,7 +84,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: Foo];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/min_match_ergonomics_fail.rs:34:29
+  --> $DIR/min_match_ergonomics_fail.rs:31:29
    |
 LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
    |                             ^^      -------- expected due to this
@@ -100,7 +100,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
    |
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:28:19
+  --> $DIR/min_match_ergonomics_fail.rs:25:19
    |
 LL | test_pat_on_type![(&x,): &(&T,)];
    |                   -^^^^
@@ -108,7 +108,7 @@ LL | test_pat_on_type![(&x,): &(&T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:31:19
+  --> $DIR/min_match_ergonomics_fail.rs:28:19
    |
 LL | test_pat_on_type![(&mut x,): &(&mut T,)];
    |                   -^^^^^^^^
@@ -116,7 +116,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:35:19
+  --> $DIR/min_match_ergonomics_fail.rs:32:19
    |
 LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
    |                   -^^^^^^^^^^^^^^^
@@ -124,7 +124,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:36:19
+  --> $DIR/min_match_ergonomics_fail.rs:33:19
    |
 LL | test_pat_on_type![(mut x,): &(T,)];
    |                   -^^^^^^^
@@ -132,7 +132,7 @@ LL | test_pat_on_type![(mut x,): &(T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:37:19
+  --> $DIR/min_match_ergonomics_fail.rs:34:19
    |
 LL | test_pat_on_type![(ref x,): &(T,)];
    |                   -^^^^^^^
@@ -140,7 +140,7 @@ LL | test_pat_on_type![(ref x,): &(T,)];
    |                   help: desugar the match ergonomics: `&`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:38:19
+  --> $DIR/min_match_ergonomics_fail.rs:35:19
    |
 LL | test_pat_on_type![(ref mut x,): &mut (T,)];
    |                   -^^^^^^^^^^^
@@ -148,7 +148,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)];
    |                   help: desugar the match ergonomics: `&mut`
 
 error: patterns are not allowed to reset the default binding mode in rust 2024
-  --> $DIR/min_match_ergonomics_fail.rs:47:9
+  --> $DIR/min_match_ergonomics_fail.rs:44:9
    |
 LL |         (&x,) => x,
    |         -^^^^
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs
index 8dbbd7cfbb0c8..0fb448afca9c7 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs
@@ -1,6 +1,4 @@
-//@ revisions: normal min_match_ergonomics
 //@ check-pass
-#![cfg_attr(min_match_ergonomics, feature(min_match_ergonomics_2024))]
 #![allow(incomplete_features)]
 
 fn main() {}

From 2ef0a8fdfd5142e8a524f4dc9fff8c65d0bd7cc2 Mon Sep 17 00:00:00 2001
From: Nadrieril <nadrieril+git@gmail.com>
Date: Tue, 8 Oct 2024 00:14:35 +0200
Subject: [PATCH 08/18] Change error message

---
 compiler/rustc_mir_build/messages.ftl         |  2 +-
 .../rustc_mir_build/src/thir/pattern/mod.rs   |  7 ++--
 .../migration_lint.fixed                      | 30 ++++++++---------
 .../migration_lint.rs                         | 30 ++++++++---------
 .../migration_lint.stderr                     | 32 +++++++++----------
 .../min_match_ergonomics_fail.stderr          | 14 ++++----
 6 files changed, 57 insertions(+), 58 deletions(-)

diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 1c4e9fd11cbd6..55149570dbc4d 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
 
 mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
 
-mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
+mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024
 
 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
     .attributes = no other attributes may be applied
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index bb02ee37733c9..16b7cac4e4d5d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -25,6 +25,7 @@ use tracing::{debug, instrument};
 
 pub(crate) use self::check_match::check_match;
 use crate::errors::*;
+use crate::fluent_generated as fluent;
 use crate::thir::util::UserAnnotatedTyHelpers;
 
 struct PatCtxt<'a, 'tcx> {
@@ -58,10 +59,8 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
     debug!("pat_from_hir({:?}) = {:?}", pat, result);
     if let Some(sugg) = pcx.rust_2024_migration_suggestion {
         if sugg.is_hard_error {
-            let mut err = tcx.dcx().struct_span_err(
-                pat.span,
-                "patterns are not allowed to reset the default binding mode in rust 2024",
-            );
+            let mut err =
+                tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat);
             err.subdiagnostic(sugg);
             err.emit();
         } else {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index 90c35b5a69723..086671e69cba1 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -23,22 +23,22 @@ fn main() {
     assert_type_eq(x, &mut 0u8);
 
     let &Foo(mut x) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(mut x) = &mut Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &Foo(ref x) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let &mut Foo(ref x) = &mut Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
@@ -55,22 +55,22 @@ fn main() {
     assert_type_eq(x, &0u8);
 
     let &Foo(&x) = &Foo(&0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &Foo(&mut x) = &Foo(&mut 0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&x) = &mut Foo(&0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&mut x) = &mut Foo(&mut 0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
@@ -79,25 +79,25 @@ fn main() {
     }
 
     if let &&&&&Some(&x) = &&&&&Some(&0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
@@ -109,20 +109,20 @@ fn main() {
     }
 
     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index 04d547f301867..acceafdb7ec06 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -23,22 +23,22 @@ fn main() {
     assert_type_eq(x, &mut 0u8);
 
     let Foo(mut x) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(mut x) = &mut Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(ref x) = &Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let Foo(ref x) = &mut Foo(0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
@@ -55,22 +55,22 @@ fn main() {
     assert_type_eq(x, &0u8);
 
     let Foo(&x) = &Foo(&0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &Foo(&mut 0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&x) = &mut Foo(&0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &mut Foo(&mut 0);
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
@@ -79,25 +79,25 @@ fn main() {
     }
 
     if let Some(&x) = &&&&&Some(&0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&x) = &&&&&mut Some(&0u8) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
@@ -109,20 +109,20 @@ fn main() {
     }
 
     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
-    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    //~^ ERROR: patterns are not allowed to reset the default binding mode
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
-        //~^ ERROR: the semantics of this pattern will change in edition 2024
+        //~^ ERROR: patterns are not allowed to reset the default binding mode
         //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 4881748f71adf..1c9a469e6ee0d 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -1,4 +1,4 @@
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:25:9
    |
 LL |     let Foo(mut x) = &Foo(0);
@@ -14,7 +14,7 @@ note: the lint level is defined here
 LL | #![deny(rust_2024_incompatible_pat)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:30:9
    |
 LL |     let Foo(mut x) = &mut Foo(0);
@@ -25,7 +25,7 @@ LL |     let Foo(mut x) = &mut Foo(0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:35:9
    |
 LL |     let Foo(ref x) = &Foo(0);
@@ -36,7 +36,7 @@ LL |     let Foo(ref x) = &Foo(0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:40:9
    |
 LL |     let Foo(ref x) = &mut Foo(0);
@@ -47,7 +47,7 @@ LL |     let Foo(ref x) = &mut Foo(0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:57:9
    |
 LL |     let Foo(&x) = &Foo(&0);
@@ -58,7 +58,7 @@ LL |     let Foo(&x) = &Foo(&0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:62:9
    |
 LL |     let Foo(&mut x) = &Foo(&mut 0);
@@ -69,7 +69,7 @@ LL |     let Foo(&mut x) = &Foo(&mut 0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:67:9
    |
 LL |     let Foo(&x) = &mut Foo(&0);
@@ -80,7 +80,7 @@ LL |     let Foo(&x) = &mut Foo(&0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:72:9
    |
 LL |     let Foo(&mut x) = &mut Foo(&mut 0);
@@ -91,7 +91,7 @@ LL |     let Foo(&mut x) = &mut Foo(&mut 0);
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:81:12
    |
 LL |     if let Some(&x) = &&&&&Some(&0u8) {
@@ -102,7 +102,7 @@ LL |     if let Some(&x) = &&&&&Some(&0u8) {
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:87:12
    |
 LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
@@ -113,7 +113,7 @@ LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:93:12
    |
 LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
@@ -124,7 +124,7 @@ LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
    = warning: this changes meaning in Rust 2024
    = note: for more information, see 123076
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:99:12
    |
 LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
@@ -137,7 +137,7 @@ help: desugar the match ergonomics
 LL |     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ++++                ++++      +++++++
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:111:9
    |
 LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
@@ -150,7 +150,7 @@ help: desugar the match ergonomics
 LL |     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
    |         +         +++           +++
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:117:9
    |
 LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
@@ -163,7 +163,7 @@ help: desugar the match ergonomics
 LL |     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         +                +++
 
-error: the semantics of this pattern will change in edition 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:124:12
    |
 LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
@@ -176,7 +176,7 @@ help: desugar the match ergonomics
 LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
    |            +                         +             +     +++
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/migration_lint.rs:137:9
    |
 LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
index ca34ad8d0ece3..33e4f0021b7ba 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -99,7 +99,7 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
 LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
    |
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:25:19
    |
 LL | test_pat_on_type![(&x,): &(&T,)];
@@ -107,7 +107,7 @@ LL | test_pat_on_type![(&x,): &(&T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:28:19
    |
 LL | test_pat_on_type![(&mut x,): &(&mut T,)];
@@ -115,7 +115,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:32:19
    |
 LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
@@ -123,7 +123,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:33:19
    |
 LL | test_pat_on_type![(mut x,): &(T,)];
@@ -131,7 +131,7 @@ LL | test_pat_on_type![(mut x,): &(T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:34:19
    |
 LL | test_pat_on_type![(ref x,): &(T,)];
@@ -139,7 +139,7 @@ LL | test_pat_on_type![(ref x,): &(T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:35:19
    |
 LL | test_pat_on_type![(ref mut x,): &mut (T,)];
@@ -147,7 +147,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)];
    |                   |
    |                   help: desugar the match ergonomics: `&mut`
 
-error: patterns are not allowed to reset the default binding mode in rust 2024
+error: patterns are not allowed to reset the default binding mode in edition 2024
   --> $DIR/min_match_ergonomics_fail.rs:44:9
    |
 LL |         (&x,) => x,

From 67b85e2a1f4e7632e5805fcc6e6a6f53501dd357 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Mon, 14 Oct 2024 16:37:54 +0200
Subject: [PATCH 09/18] Add fast-path when computing the default visibility

---
 compiler/rustc_monomorphize/src/partitioning.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 5bd484d7bb002..9bf7e67417eff 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -119,6 +119,7 @@ use rustc_middle::util::Providers;
 use rustc_session::CodegenUnits;
 use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
 use rustc_span::symbol::Symbol;
+use rustc_target::spec::SymbolVisibility;
 use tracing::debug;
 
 use crate::collector::{self, MonoItemCollectionStrategy, UsageMap};
@@ -904,6 +905,11 @@ fn mono_item_visibility<'tcx>(
 }
 
 fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
+    // Fast-path to avoid expensive query call below
+    if tcx.sess.default_visibility() == SymbolVisibility::Interposable {
+        return Visibility::Default;
+    }
+
     let export_level = if is_generic {
         // Generic functions never have export-level C.
         SymbolExportLevel::Rust
@@ -913,6 +919,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
             _ => SymbolExportLevel::Rust,
         }
     };
+
     match export_level {
         // C-export level items remain at `Default` to allow C code to
         // access and interpose them.

From 50b8029ce143aa5ed67aab9d3c05533330df97d6 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 14 Oct 2024 12:40:08 -0400
Subject: [PATCH 10/18] Always recurse on predicates in BestObligation

---
 compiler/rustc_trait_selection/src/solve/fulfill.rs | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 081d7a6a769a1..0e2b081448e58 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -465,13 +465,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                     polarity: ty::PredicatePolarity::Positive,
                 }))
             }
-            ty::PredicateKind::Clause(
-                ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
-            )
-            | ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
-            _ => {
-                return ControlFlow::Break(self.obligation.clone());
-            }
+            _ => ChildMode::PassThrough,
         };
 
         let mut impl_where_bound_count = 0;

From fd2038d344c3abb34a0a7812c49f1730c3cee3b2 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 14 Oct 2024 10:52:34 -0400
Subject: [PATCH 11/18] Make sure the alias is actually rigid

---
 .../src/solve/normalizes_to/mod.rs            | 53 ++++++++++++++-
 .../defaults-unsound-62211-1.next.stderr      | 21 ++++--
 .../defaults-unsound-62211-2.next.stderr      | 21 ++++--
 .../associated-types/issue-54108.next.stderr  | 21 ++++--
 tests/ui/for/issue-20605.next.stderr          | 11 +--
 ...mbig-hr-projection-issue-93340.next.stderr | 12 +++-
 .../in-trait/alias-bounds-when-not-wf.stderr  | 28 ++++++--
 .../impl-trait/method-resolution4.next.stderr | 50 +++++++++++---
 .../recursive-coroutine-boxed.next.stderr     | 68 +++++++++++++++----
 .../impl-trait/unsized_coercion.next.stderr   | 35 +++++++---
 .../impl-trait/unsized_coercion3.next.stderr  | 43 ++++++------
 .../opaque-type-unsatisfied-bound.stderr      | 62 +++++++++++++++--
 .../opaque-type-unsatisfied-fn-bound.stderr   | 28 +++++++-
 .../traits/next-solver/coroutine.fail.stderr  | 41 ++++++++++-
 .../diagnostics/projection-trait-ref.stderr   | 33 ++++++++-
 .../next-solver/dyn-incompatibility.stderr    | 15 +++-
 tests/ui/traits/next-solver/fn-trait.stderr   | 61 ++++++++++++++++-
 .../issue-118950-root-region.stderr           | 18 ++---
 ...ution_trait_method_from_opaque.next.stderr | 19 +++++-
 ...hod_resolution_trait_method_from_opaque.rs |  2 +
 20 files changed, 530 insertions(+), 112 deletions(-)

diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 005b293621afc..bf1d2bf08b788 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
-    NoSolution, QueryResult,
+    NoSolution, QueryResult, Reveal,
 };
 
 impl<D, I> EvalCtxt<'_, D>
@@ -39,11 +39,58 @@ where
             Err(NoSolution) => {
                 let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
                 self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
+                self.add_rigid_constraints(param_env, alias)?;
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
         }
     }
 
+    /// Register any obligations that are used to validate that an alias should be
+    /// treated as rigid.
+    ///
+    /// An alias may be considered rigid if it fails normalization, but we also don't
+    /// want to consider aliases that are not well-formed to be rigid simply because
+    /// they fail normalization.
+    ///
+    /// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
+    /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
+    fn add_rigid_constraints(
+        &mut self,
+        param_env: I::ParamEnv,
+        rigid_alias: ty::AliasTerm<I>,
+    ) -> Result<(), NoSolution> {
+        match rigid_alias.kind(self.cx()) {
+            // Projections are rigid only if their trait ref holds.
+            ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
+                let trait_ref = rigid_alias.trait_ref(self.cx());
+                self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref));
+                Ok(())
+            }
+            ty::AliasTermKind::OpaqueTy => {
+                match param_env.reveal() {
+                    // In user-facing mode, paques are only rigid if we may not define it.
+                    Reveal::UserFacing => {
+                        if rigid_alias
+                            .def_id
+                            .as_local()
+                            .is_some_and(|def_id| self.can_define_opaque_ty(def_id))
+                        {
+                            Err(NoSolution)
+                        } else {
+                            Ok(())
+                        }
+                    }
+                    // Opaques are never rigid in reveal-all mode.
+                    Reveal::All => Err(NoSolution),
+                }
+            }
+            // FIXME(generic_const_exprs): we would need to support generic consts here
+            ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
+            // Inherent and weak types are never rigid. This type must not be well-formed.
+            ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
+        }
+    }
+
     /// Normalize the given alias by at least one step. If the alias is rigid, this
     /// returns `NoSolution`.
     #[instrument(level = "trace", skip(self), ret)]
@@ -124,6 +171,7 @@ where
                     ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
 
                     // Add GAT where clauses from the trait's definition
+                    // FIXME: We don't need these, since these are the type's own WF obligations.
                     ecx.add_goals(
                         GoalSource::Misc,
                         cx.own_predicates_of(goal.predicate.def_id())
@@ -179,7 +227,8 @@ where
                 .map(|pred| goal.with(cx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
-            // Add GAT where clauses from the trait's definition
+            // Add GAT where clauses from the trait's definition.
+            // FIXME: We don't need these, since these are the type's own WF obligations.
             ecx.add_goals(
                 GoalSource::Misc,
                 cx.own_predicates_of(goal.predicate.def_id())
diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
index 010f51df15ad3..4523fc3e037e8 100644
--- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
+++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
@@ -31,17 +31,29 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
    |                            +++++++++++++++++++++++++
 
-error[E0277]: the trait bound `Self: Deref` is not satisfied
+error[E0271]: type mismatch resolving `<Self as Deref>::Target normalizes-to <Self as Deref>::Target`
   --> $DIR/defaults-unsound-62211-1.rs:24:96
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
+   |                                                                                                ^^^^ types differ
    |
 note: required by a bound in `UncheckedCopy::Output`
   --> $DIR/defaults-unsound-62211-1.rs:24:31
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
    |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+
+error[E0277]: the trait bound `Self: Deref` is not satisfied
+  --> $DIR/defaults-unsound-62211-1.rs:24:96
+   |
+LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+   |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
+   |
+note: required by a bound in `UncheckedCopy::Output`
+  --> $DIR/defaults-unsound-62211-1.rs:24:25
+   |
+LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+   |                         ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
 help: consider further restricting `Self`
    |
 LL | trait UncheckedCopy: Sized + Deref {
@@ -63,6 +75,7 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + Copy {
    |                            ++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
index 9347894657078..7a68f1ac8cc47 100644
--- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
+++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
@@ -31,17 +31,29 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
    |                            +++++++++++++++++++++++++
 
-error[E0277]: the trait bound `Self: Deref` is not satisfied
+error[E0271]: type mismatch resolving `<Self as Deref>::Target normalizes-to <Self as Deref>::Target`
   --> $DIR/defaults-unsound-62211-2.rs:24:96
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
+   |                                                                                                ^^^^ types differ
    |
 note: required by a bound in `UncheckedCopy::Output`
   --> $DIR/defaults-unsound-62211-2.rs:24:31
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
    |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+
+error[E0277]: the trait bound `Self: Deref` is not satisfied
+  --> $DIR/defaults-unsound-62211-2.rs:24:96
+   |
+LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+   |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
+   |
+note: required by a bound in `UncheckedCopy::Output`
+  --> $DIR/defaults-unsound-62211-2.rs:24:25
+   |
+LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+   |                         ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
 help: consider further restricting `Self`
    |
 LL | trait UncheckedCopy: Sized + Deref {
@@ -63,6 +75,7 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + Copy {
    |                            ++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr
index 5e2fa551afe30..0866ed054514b 100644
--- a/tests/ui/associated-types/issue-54108.next.stderr
+++ b/tests/ui/associated-types/issue-54108.next.stderr
@@ -1,3 +1,15 @@
+error[E0271]: type mismatch resolving `<<T as SubEncoder>::ActualSize as Add>::Output normalizes-to <<T as SubEncoder>::ActualSize as Add>::Output`
+  --> $DIR/issue-54108.rs:23:17
+   |
+LL |     type Size = <Self as SubEncoder>::ActualSize;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |
+note: required by a bound in `Encoder::Size`
+  --> $DIR/issue-54108.rs:8:20
+   |
+LL |     type Size: Add<Output = Self::Size>;
+   |                    ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
+
 error[E0277]: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
   --> $DIR/issue-54108.rs:23:17
    |
@@ -6,15 +18,16 @@ LL |     type Size = <Self as SubEncoder>::ActualSize;
    |
    = help: the trait `Add` is not implemented for `<T as SubEncoder>::ActualSize`
 note: required by a bound in `Encoder::Size`
-  --> $DIR/issue-54108.rs:8:20
+  --> $DIR/issue-54108.rs:8:16
    |
 LL |     type Size: Add<Output = Self::Size>;
-   |                    ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
 help: consider further restricting the associated type
    |
 LL |     T: SubEncoder, <T as SubEncoder>::ActualSize: Add
    |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr
index 98609211865c4..1a66cb4146495 100644
--- a/tests/ui/for/issue-20605.next.stderr
+++ b/tests/ui/for/issue-20605.next.stderr
@@ -11,13 +11,6 @@ help: consider mutably borrowing here
 LL |     for item in &mut *things { *item = 0 }
    |                 ++++
 
-error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
-  --> $DIR/issue-20605.rs:6:27
-   |
-LL |     for item in *things { *item = 0 }
-   |                           ^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0614.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
index d913b2e91ca0e..bc57874bf850a 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
@@ -15,6 +15,14 @@ help: consider specifying the generic arguments
 LL |     cmp_eq::<A, B, O>
    |           +++++++++++
 
-error: aborting due to 1 previous error
+error[E0271]: type mismatch resolving `build_expression<A, B, O>::{opaque#0} normalizes-to _`
+  --> $DIR/ambig-hr-projection-issue-93340.rs:14:1
+   |
+LL | / fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
+LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+   | |_________________________________________________^ types differ
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0283`.
+Some errors have detailed explanations: E0271, E0283.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
index 9663fab3d8c39..cab6163803a4e 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -7,14 +7,32 @@ LL | #![feature(lazy_type_alias)]
    = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0277]: the size for values of type `A<usize>` cannot be known at compilation time
+error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
   --> $DIR/alias-bounds-when-not-wf.rs:16:13
    |
 LL | fn hello(_: W<A<usize>>) {}
-   |             ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             ^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+  --> $DIR/alias-bounds-when-not-wf.rs:16:10
    |
-   = help: the trait `Sized` is not implemented for `A<usize>`
+LL | fn hello(_: W<A<usize>>) {}
+   |          ^ types differ
+
+error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+  --> $DIR/alias-bounds-when-not-wf.rs:16:10
+   |
+LL | fn hello(_: W<A<usize>>) {}
+   |          ^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+  --> $DIR/alias-bounds-when-not-wf.rs:16:1
+   |
+LL | fn hello(_: W<A<usize>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 4 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr
index b48de0af3579d..5aa6931d371e2 100644
--- a/tests/ui/impl-trait/method-resolution4.next.stderr
+++ b/tests/ui/impl-trait/method-resolution4.next.stderr
@@ -4,19 +4,51 @@ error[E0282]: type annotations needed
 LL |         foo(false).next().unwrap();
    |         ^^^^^^^^^^ cannot infer type
 
-error[E0308]: mismatched types
-  --> $DIR/method-resolution4.rs:16:5
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/method-resolution4.rs:13:9
+   |
+LL |         foo(false).next().unwrap();
+   |         ^^^^^^^^^^ types differ
+
+error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
+  --> $DIR/method-resolution4.rs:11:20
    |
 LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
-   |                    ------------------------ the expected opaque type
-...
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/method-resolution4.rs:16:5
+   |
 LL |     std::iter::empty()
    |     ^^^^^^^^^^^^^^^^^^ types differ
+
+error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
+  --> $DIR/method-resolution4.rs:13:9
    |
-   = note: expected opaque type `impl Iterator<Item = ()>`
-                   found struct `std::iter::Empty<_>`
+LL |         foo(false).next().unwrap();
+   |         ^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/method-resolution4.rs:13:9
+   |
+LL |         foo(false).next().unwrap();
+   |         ^^^^^^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/method-resolution4.rs:11:1
+   |
+LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 2 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0271, E0277, E0282.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
index 96db2030a405c..5feef0b44b53b 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
@@ -12,15 +12,9 @@ help: consider specifying the generic argument
 LL |         let mut gen = Box::<T>::pin(foo());
    |                          +++++
 
-error[E0308]: mismatched types
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
   --> $DIR/recursive-coroutine-boxed.rs:14:18
    |
-LL |   fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-   |               ---------------------------------------
-   |               |
-   |               the expected opaque type
-   |               expected `impl Coroutine<Yield = (), Return = ()>` because of return type
-...
 LL |       #[coroutine] || {
    |  __________________^
 LL | |         let mut gen = Box::pin(foo());
@@ -30,11 +24,61 @@ LL | |         let mut r = gen.as_mut().resume(());
 LL | |         }
 LL | |     }
    | |_____^ types differ
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/recursive-coroutine-boxed.rs:15:32
+   |
+LL |         let mut gen = Box::pin(foo());
+   |                                ^^^^^ types differ
+
+error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
+  --> $DIR/recursive-coroutine-boxed.rs:9:13
+   |
+LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/recursive-coroutine-boxed.rs:14:18
+   |
+LL |       #[coroutine] || {
+   |  __________________^
+LL | |         let mut gen = Box::pin(foo());
+LL | |
+LL | |         let mut r = gen.as_mut().resume(());
+...  |
+LL | |         }
+LL | |     }
+   | |_____^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
+  --> $DIR/recursive-coroutine-boxed.rs:15:32
+   |
+LL |         let mut gen = Box::pin(foo());
+   |                                ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/recursive-coroutine-boxed.rs:15:32
+   |
+LL |         let mut gen = Box::pin(foo());
+   |                                ^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
+  --> $DIR/recursive-coroutine-boxed.rs:9:1
    |
-   = note: expected opaque type `impl Coroutine<Yield = (), Return = ()>`
-                found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}`
+LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 2 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0282, E0308.
-For more information about an error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0271, E0277, E0282.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr
index 49ac3f1845fb3..f31a2a806674b 100644
--- a/tests/ui/impl-trait/unsized_coercion.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion.next.stderr
@@ -1,26 +1,39 @@
-error[E0271]: type mismatch resolving `impl Trait <: dyn Trait`
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
   --> $DIR/unsized_coercion.rs:14:17
    |
 LL |         let x = hello();
    |                 ^^^^^^^ types differ
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion.rs:18:14
+  --> $DIR/unsized_coercion.rs:18:5
    |
 LL | fn hello() -> Box<impl Trait> {
-   |                   ---------- the expected opaque type
+   |               ---------------
+   |               |   |
+   |               |   the expected opaque type
+   |               expected `Box<impl Trait>` because of return type
 ...
 LL |     Box::new(1u32)
-   |     -------- ^^^^ types differ
-   |     |
-   |     arguments to this function are incorrect
+   |     ^^^^^^^^^^^^^^ types differ
    |
-   = note: expected opaque type `impl Trait`
-                     found type `u32`
-note: associated function defined here
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: expected struct `Box<impl Trait>`
+              found struct `Box<u32>`
 
-error: aborting due to 2 previous errors
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+  --> $DIR/unsized_coercion.rs:14:17
+   |
+LL |         let x = hello();
+   |                 ^^^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+  --> $DIR/unsized_coercion.rs:12:1
+   |
+LL | fn hello() -> Box<impl Trait> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0271, E0308.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr
index 586ae07602821..f5187a6256efa 100644
--- a/tests/ui/impl-trait/unsized_coercion3.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr
@@ -1,38 +1,39 @@
-error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
   --> $DIR/unsized_coercion3.rs:13:17
    |
 LL |         let x = hello();
    |                 ^^^^^^^ types differ
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion3.rs:18:14
+  --> $DIR/unsized_coercion3.rs:18:5
    |
 LL | fn hello() -> Box<impl Trait + ?Sized> {
-   |                   ------------------- the expected opaque type
+   |               ------------------------
+   |               |   |
+   |               |   the expected opaque type
+   |               expected `Box<impl Trait + ?Sized>` because of return type
 ...
 LL |     Box::new(1u32)
-   |     -------- ^^^^ types differ
-   |     |
-   |     arguments to this function are incorrect
+   |     ^^^^^^^^^^^^^^ types differ
    |
-   = note: expected opaque type `impl Trait + ?Sized`
-                     found type `u32`
-note: associated function defined here
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: expected struct `Box<impl Trait + ?Sized>`
+              found struct `Box<u32>`
 
-error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
-  --> $DIR/unsized_coercion3.rs:18:14
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+  --> $DIR/unsized_coercion3.rs:13:17
    |
-LL |     Box::new(1u32)
-   |     -------- ^^^^ doesn't have a size known at compile-time
-   |     |
-   |     required by a bound introduced by this call
+LL |         let x = hello();
+   |                 ^^^^^^^ types differ
    |
-   = help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
-note: required by a bound in `Box::<T>::new`
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+  --> $DIR/unsized_coercion3.rs:11:1
+   |
+LL | fn hello() -> Box<impl Trait + ?Sized> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277, E0308.
+Some errors have detailed explanations: E0271, E0308.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 3dd2b27b55b67..561bf8eee2283 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,21 +1,69 @@
-error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
+error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
+error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
+   |
+LL | fn weird0() -> impl Sized + !Sized {}
+   |                                    ^^ types differ
+
+error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
+   |
+LL | fn weird0() -> impl Sized + !Sized {}
+   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
+   |
+LL | fn weird0() -> impl Sized + !Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
   --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ types differ
 
-error[E0271]: type mismatch resolving `impl !Sized == ()`
+error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:17:36
+   |
+LL | fn weird1() -> impl !Sized + Sized {}
+   |                                    ^^ types differ
+
+error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
+   |
+LL | fn weird1() -> impl !Sized + Sized {}
+   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:17:1
+   |
+LL | fn weird1() -> impl !Sized + Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird2() -> impl !Sized {}
    |                ^^^^^^^^^^^ types differ
 
+error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:28
+   |
+LL | fn weird2() -> impl !Sized {}
+   |                            ^^ types differ
+
 error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
@@ -25,6 +73,12 @@ LL | fn weird2() -> impl !Sized {}
    = help: the trait `Sized` is not implemented for `impl !Sized`
    = note: the return type of a function must have a statically known size
 
+error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
+   |
+LL | fn weird2() -> impl !Sized {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
    |
@@ -39,7 +93,7 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 5 previous errors
+error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0271, E0277.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index e1b84e0df7a54..a7a83cf1d69cc 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -1,9 +1,31 @@
-error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
+error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
    |                 ^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 1 previous error
+error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
+   |
+LL | fn produce() -> impl !Fn<(u32,)> {}
+   |                                  ^^ types differ
+
+error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
+   |
+LL | fn produce() -> impl !Fn<(u32,)> {}
+   |                 ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>`
+   = note: the return type of a function must have a statically known size
+
+error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
+  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
+   |
+LL | fn produce() -> impl !Fn<(u32,)> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr
index 8c263e8644bd0..b37dbc0e579eb 100644
--- a/tests/ui/traits/next-solver/coroutine.fail.stderr
+++ b/tests/ui/traits/next-solver/coroutine.fail.stderr
@@ -16,6 +16,43 @@ note: required by a bound in `needs_coroutine`
 LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine`
 
-error: aborting due to 1 previous error
+error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Yield`
+  --> $DIR/coroutine.rs:20:9
+   |
+LL |       needs_coroutine(
+   |       --------------- required by a bound introduced by this call
+LL |           #[coroutine]
+LL | /         || {
+LL | |
+LL | |             yield ();
+LL | |         },
+   | |_________^ types differ
+   |
+note: required by a bound in `needs_coroutine`
+  --> $DIR/coroutine.rs:14:41
+   |
+LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
+   |                                         ^^^^^^^^^ required by this bound in `needs_coroutine`
+
+error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Return`
+  --> $DIR/coroutine.rs:20:9
+   |
+LL |       needs_coroutine(
+   |       --------------- required by a bound introduced by this call
+LL |           #[coroutine]
+LL | /         || {
+LL | |
+LL | |             yield ();
+LL | |         },
+   | |_________^ types differ
+   |
+note: required by a bound in `needs_coroutine`
+  --> $DIR/coroutine.rs:14:52
+   |
+LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
+   |                                                    ^^^^^^^^^^ required by this bound in `needs_coroutine`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
index cd8d8b3ffcd38..dbd2880943c97 100644
--- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
+++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
@@ -9,6 +9,20 @@ help: consider restricting type parameter `T`
 LL | fn test_poly<T: Trait>() {
    |               +++++++
 
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc normalizes-to <T as Trait>::Assoc`
+  --> $DIR/projection-trait-ref.rs:8:12
+   |
+LL |     let x: <T as Trait>::Assoc = ();
+   |            ^^^^^^^^^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `<T as Trait>::Assoc normalizes-to <T as Trait>::Assoc`
+  --> $DIR/projection-trait-ref.rs:8:12
+   |
+LL |     let x: <T as Trait>::Assoc = ();
+   |            ^^^^^^^^^^^^^^^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0277]: the trait bound `i32: Trait` is not satisfied
   --> $DIR/projection-trait-ref.rs:13:12
    |
@@ -21,6 +35,21 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait {
    | ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0271]: type mismatch resolving `<i32 as Trait>::Assoc normalizes-to <i32 as Trait>::Assoc`
+  --> $DIR/projection-trait-ref.rs:13:12
+   |
+LL |     let x: <i32 as Trait>::Assoc = ();
+   |            ^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `<i32 as Trait>::Assoc normalizes-to <i32 as Trait>::Assoc`
+  --> $DIR/projection-trait-ref.rs:13:12
+   |
+LL |     let x: <i32 as Trait>::Assoc = ();
+   |            ^^^^^^^^^^^^^^^^^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr
index 7f2c0646ef501..adf46686e081a 100644
--- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr
+++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr
@@ -43,7 +43,20 @@ help: consider restricting type parameter `T`
 LL | pub fn copy_any<T: std::marker::Copy>(t: &T) -> T {
    |                  +++++++++++++++++++
 
-error: aborting due to 3 previous errors
+error[E0277]: the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
+  --> $DIR/dyn-incompatibility.rs:12:5
+   |
+LL |     copy::<dyn Setup<From=T>>(t)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `<dyn Setup<From = T> as Setup>::From`
+   = note: the return type of a function must have a statically known size
+help: consider further restricting the associated type
+   |
+LL | pub fn copy_any<T>(t: &T) -> T where <dyn Setup<From = T> as Setup>::From: Sized {
+   |                                +++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr
index 00243fd905950..0dee26d467271 100644
--- a/tests/ui/traits/next-solver/fn-trait.stderr
+++ b/tests/ui/traits/next-solver/fn-trait.stderr
@@ -15,6 +15,20 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
+error[E0271]: type mismatch resolving `<unsafe fn() -> i32 as FnOnce<()>>::Output normalizes-to <unsafe fn() -> i32 as FnOnce<()>>::Output`
+  --> $DIR/fn-trait.rs:20:16
+   |
+LL |     require_fn(f as unsafe fn() -> i32);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `require_fn`
+  --> $DIR/fn-trait.rs:3:31
+   |
+LL | fn require_fn(_: impl Fn() -> i32) {}
+   |                               ^^^ required by this bound in `require_fn`
+
 error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}`
   --> $DIR/fn-trait.rs:22:16
    |
@@ -31,6 +45,20 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
+error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 {g} as FnOnce<()>>::Output normalizes-to <extern "C" fn() -> i32 {g} as FnOnce<()>>::Output`
+  --> $DIR/fn-trait.rs:22:16
+   |
+LL |     require_fn(g);
+   |     ---------- ^ types differ
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `require_fn`
+  --> $DIR/fn-trait.rs:3:31
+   |
+LL | fn require_fn(_: impl Fn() -> i32) {}
+   |                               ^^^ required by this bound in `require_fn`
+
 error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32`
   --> $DIR/fn-trait.rs:24:16
    |
@@ -47,6 +75,20 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
+error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 as FnOnce<()>>::Output normalizes-to <extern "C" fn() -> i32 as FnOnce<()>>::Output`
+  --> $DIR/fn-trait.rs:24:16
+   |
+LL |     require_fn(g as extern "C" fn() -> i32);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `require_fn`
+  --> $DIR/fn-trait.rs:3:31
+   |
+LL | fn require_fn(_: impl Fn() -> i32) {}
+   |                               ^^^ required by this bound in `require_fn`
+
 error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}`
   --> $DIR/fn-trait.rs:26:16
    |
@@ -64,6 +106,21 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
-error: aborting due to 4 previous errors
+error[E0271]: type mismatch resolving `<unsafe fn() -> i32 {h} as FnOnce<()>>::Output normalizes-to <unsafe fn() -> i32 {h} as FnOnce<()>>::Output`
+  --> $DIR/fn-trait.rs:26:16
+   |
+LL |     require_fn(h);
+   |     ---------- ^ types differ
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `require_fn`
+  --> $DIR/fn-trait.rs:3:31
+   |
+LL | fn require_fn(_: impl Fn() -> i32) {}
+   |                               ^^^ required by this bound in `require_fn`
+
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index 7c3e22fb4014a..82ec9e3a22f75 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -26,21 +26,13 @@ LL | trait ToUnit<'a> {
    | ^^^^^^^^^^^^^^^^
 
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
-error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
-  --> $DIR/issue-118950-root-region.rs:19:1
+error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _`
+  --> $DIR/issue-118950-root-region.rs:19:17
    |
-LL | impl<T> Overlap<T> for T {}
-   | ------------------------ first implementation here
-LL |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
-   |
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
 error: aborting due to 3 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0119, E0277, E0412.
-For more information about an error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0271, E0277, E0412.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
index 2617ce124c105..f953111aef025 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
@@ -4,6 +4,21 @@ error[E0282]: type annotations needed
 LL |         self.bar.next().unwrap();
    |         ^^^^^^^^ cannot infer type
 
-error: aborting due to 1 previous error
+error[E0271]: type mismatch resolving `Tait normalizes-to _`
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
+   |
+LL |         self.bar.next().unwrap();
+   |         ^^^^^^^^ types differ
+
+error[E0271]: type mismatch resolving `Tait normalizes-to _`
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
+   |
+LL |         self.bar.next().unwrap();
+   |         ^^^^^^^^ types differ
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0271, E0282.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
index b6adf08853f2f..5c9a3b7c2d296 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
@@ -25,6 +25,8 @@ impl Foo {
         //[current]~^ ERROR: item does not constrain
         self.bar.next().unwrap();
         //[next]~^ ERROR: type annotations needed
+        //[next]~| ERROR type mismatch resolving `Tait normalizes-to _`
+        //[next]~| ERROR type mismatch resolving `Tait normalizes-to _`
     }
 }
 

From 8528387743709360f1cb2d3b5538342ec71bd03a Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 14 Oct 2024 13:04:10 -0400
Subject: [PATCH 12/18] Be better at reporting alias errors

---
 .../src/solve/eval_ctxt/mod.rs                |  2 +-
 .../src/solve/normalizes_to/mod.rs            | 20 +++--
 .../src/solve/fulfill.rs                      | 17 ++++-
 .../src/solve/inspect/analyse.rs              |  6 +-
 .../rustc_trait_selection/src/solve/select.rs |  3 +-
 compiler/rustc_type_ir/src/solve/inspect.rs   |  2 +
 compiler/rustc_type_ir/src/solve/mod.rs       |  4 +
 .../defaults-unsound-62211-1.next.stderr      | 21 +-----
 .../defaults-unsound-62211-2.next.stderr      | 21 +-----
 .../associated-types/issue-54108.next.stderr  | 21 +-----
 tests/ui/for/issue-20605.rs                   |  7 +-
 ...mbig-hr-projection-issue-93340.next.stderr | 12 +--
 ...ambig-hr-projection-issue-93340.old.stderr |  2 +-
 .../ambig-hr-projection-issue-93340.rs        |  1 +
 .../in-trait/alias-bounds-when-not-wf.rs      |  4 +-
 .../in-trait/alias-bounds-when-not-wf.stderr  | 38 ++++++----
 .../impl-trait/method-resolution4.next.stderr | 36 ++-------
 tests/ui/impl-trait/method-resolution4.rs     |  3 +-
 .../recursive-coroutine-boxed.next.stderr     | 60 ++-------------
 .../impl-trait/recursive-coroutine-boxed.rs   |  6 +-
 .../impl-trait/unsized_coercion.next.stderr   | 30 ++++----
 tests/ui/impl-trait/unsized_coercion.rs       |  3 +-
 .../impl-trait/unsized_coercion3.next.stderr  | 30 ++++----
 .../impl-trait/unsized_coercion3.old.stderr   |  2 +-
 tests/ui/impl-trait/unsized_coercion3.rs      |  4 +-
 .../opaque-type-unsatisfied-bound.rs          | 16 +++-
 .../opaque-type-unsatisfied-bound.stderr      | 73 ++++++++++++-------
 .../opaque-type-unsatisfied-fn-bound.rs       |  5 +-
 .../opaque-type-unsatisfied-fn-bound.stderr   | 21 ++++--
 .../traits/next-solver/coroutine.fail.stderr  | 41 +----------
 .../diagnostics/projection-trait-ref.stderr   | 33 +--------
 .../traits/next-solver/dyn-incompatibility.rs |  1 +
 tests/ui/traits/next-solver/fn-trait.stderr   | 61 +---------------
 .../next-solver/issue-118950-root-region.rs   |  4 +-
 .../issue-118950-root-region.stderr           | 14 +++-
 .../normalize/normalize-region-obligations.rs |  2 +-
 ...ution_trait_method_from_opaque.next.stderr | 19 +----
 ...hod_resolution_trait_method_from_opaque.rs |  2 -
 tests/ui/typeck/issue-103899.rs               | 10 +--
 39 files changed, 237 insertions(+), 420 deletions(-)

diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index daacc6691182d..0f8b796d602a7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -983,7 +983,7 @@ where
             hidden_ty,
             &mut goals,
         );
-        self.add_goals(GoalSource::Misc, goals);
+        self.add_goals(GoalSource::AliasWellFormed, goals);
     }
 
     // Do something for each opaque/hidden pair defined with `def_id` in the
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index bf1d2bf08b788..4d8b193ee4911 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -37,10 +37,12 @@ where
         match normalize_result {
             Ok(res) => Ok(res),
             Err(NoSolution) => {
-                let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
-                self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
-                self.add_rigid_constraints(param_env, alias)?;
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
+                    let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
+                    this.add_rigid_constraints(param_env, alias)?;
+                    this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
+                    this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                })
             }
         }
     }
@@ -59,11 +61,13 @@ where
         param_env: I::ParamEnv,
         rigid_alias: ty::AliasTerm<I>,
     ) -> Result<(), NoSolution> {
-        match rigid_alias.kind(self.cx()) {
-            // Projections are rigid only if their trait ref holds.
+        let cx = self.cx();
+        match rigid_alias.kind(cx) {
+            // Projections are rigid only if their trait ref holds,
+            // and the GAT where-clauses hold.
             ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
-                let trait_ref = rigid_alias.trait_ref(self.cx());
-                self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref));
+                let trait_ref = rigid_alias.trait_ref(cx);
+                self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
                 Ok(())
             }
             ty::AliasTermKind::OpaqueTy => {
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 0e2b081448e58..0f977beb85a91 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -13,7 +13,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
-use tracing::instrument;
+use tracing::{instrument, trace};
 
 use super::Certainty;
 use super::delegate::SolverDelegate;
@@ -402,6 +402,7 @@ impl<'tcx> BestObligation<'tcx> {
                                         nested_goal.source(),
                                         GoalSource::ImplWhereBound
                                             | GoalSource::InstantiateHigherRanked
+                                            | GoalSource::AliasWellFormed
                                     ) && match self.consider_ambiguities {
                                         true => {
                                             matches!(
@@ -416,6 +417,13 @@ impl<'tcx> BestObligation<'tcx> {
                         })
                     });
                 }
+
+                // Prefer a non-rigid candidate if there is one.
+                if candidates.len() > 1 {
+                    candidates.retain(|candidate| {
+                        !matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. })
+                    });
+                }
             }
         }
 
@@ -430,8 +438,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
         self.obligation.cause.span
     }
 
+    #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
     fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
         let candidates = self.non_trivial_candidates(goal);
+        trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
+
         let [candidate] = candidates.as_slice() else {
             return ControlFlow::Break(self.obligation.clone());
         };
@@ -470,6 +481,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
 
         let mut impl_where_bound_count = 0;
         for nested_goal in candidate.instantiate_nested_goals(self.span()) {
+            trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
+
             let make_obligation = |cause| Obligation {
                 cause,
                 param_env: nested_goal.goal().param_env,
@@ -496,7 +509,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                 (_, GoalSource::InstantiateHigherRanked) => {
                     obligation = self.obligation.clone();
                 }
-                (ChildMode::PassThrough, _) => {
+                (ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
                     obligation = make_obligation(self.obligation.cause.clone());
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 254620e0b597f..4975a9ce0c757 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                         | inspect::ProbeKind::Root { .. }
                         | inspect::ProbeKind::TryNormalizeNonRigid { .. }
                         | inspect::ProbeKind::TraitCandidate { .. }
-                        | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
+                        | inspect::ProbeKind::OpaqueTypeStorageLookup { .. }
+                        | inspect::ProbeKind::RigidAlias { .. } => {
                             // Nested probes have to prove goals added in their parent
                             // but do not leak them, so we truncate the added goals
                             // afterwards.
@@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
             inspect::ProbeKind::Root { result }
             | inspect::ProbeKind::TryNormalizeNonRigid { result }
             | inspect::ProbeKind::TraitCandidate { source: _, result }
-            | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
+            | inspect::ProbeKind::OpaqueTypeStorageLookup { result }
+            | inspect::ProbeKind::RigidAlias { result } => {
                 // We only add a candidate if `shallow_certainty` was set, which means
                 // that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
                 if let Some(shallow_certainty) = shallow_certainty {
diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs
index 257fd263b9447..1661852903c48 100644
--- a/compiler/rustc_trait_selection/src/solve/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/select.rs
@@ -177,7 +177,8 @@ fn to_selection<'tcx>(
         | ProbeKind::UpcastProjectionCompatibility
         | ProbeKind::OpaqueTypeStorageLookup { result: _ }
         | ProbeKind::Root { result: _ }
-        | ProbeKind::ShadowedEnvProbing => {
+        | ProbeKind::ShadowedEnvProbing
+        | ProbeKind::RigidAlias { result: _ } => {
             span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
         }
     })
diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs
index 099c66f6bdc81..138ba8bac8871 100644
--- a/compiler/rustc_type_ir/src/solve/inspect.rs
+++ b/compiler/rustc_type_ir/src/solve/inspect.rs
@@ -135,4 +135,6 @@ pub enum ProbeKind<I: Interner> {
     ShadowedEnvProbing,
     /// Try to unify an opaque type with an existing key in the storage.
     OpaqueTypeStorageLookup { result: QueryResult<I> },
+    /// Checking that a rigid alias is well-formed.
+    RigidAlias { result: QueryResult<I> },
 }
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index a0f7658212f4b..f02c7a3207193 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -130,6 +130,10 @@ pub enum GoalSource {
     ImplWhereBound,
     /// Instantiating a higher-ranked goal and re-proving it.
     InstantiateHigherRanked,
+    /// Predicate required for an alias projection to be well-formed.
+    /// This is used in two places: projecting to an opaque whose hidden type
+    /// is already registered in the opaque type storage, and for rigid projections.
+    AliasWellFormed,
 }
 
 #[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
index 4523fc3e037e8..010f51df15ad3 100644
--- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
+++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr
@@ -31,18 +31,6 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
    |                            +++++++++++++++++++++++++
 
-error[E0271]: type mismatch resolving `<Self as Deref>::Target normalizes-to <Self as Deref>::Target`
-  --> $DIR/defaults-unsound-62211-1.rs:24:96
-   |
-LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                                                                                                ^^^^ types differ
-   |
-note: required by a bound in `UncheckedCopy::Output`
-  --> $DIR/defaults-unsound-62211-1.rs:24:31
-   |
-LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
-
 error[E0277]: the trait bound `Self: Deref` is not satisfied
   --> $DIR/defaults-unsound-62211-1.rs:24:96
    |
@@ -50,10 +38,10 @@ LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + Fro
    |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
    |
 note: required by a bound in `UncheckedCopy::Output`
-  --> $DIR/defaults-unsound-62211-1.rs:24:25
+  --> $DIR/defaults-unsound-62211-1.rs:24:31
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                         ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+   |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
 help: consider further restricting `Self`
    |
 LL | trait UncheckedCopy: Sized + Deref {
@@ -75,7 +63,6 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + Copy {
    |                            ++++++
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
index 7a68f1ac8cc47..9347894657078 100644
--- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
+++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr
@@ -31,18 +31,6 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
    |                            +++++++++++++++++++++++++
 
-error[E0271]: type mismatch resolving `<Self as Deref>::Target normalizes-to <Self as Deref>::Target`
-  --> $DIR/defaults-unsound-62211-2.rs:24:96
-   |
-LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                                                                                                ^^^^ types differ
-   |
-note: required by a bound in `UncheckedCopy::Output`
-  --> $DIR/defaults-unsound-62211-2.rs:24:31
-   |
-LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
-
 error[E0277]: the trait bound `Self: Deref` is not satisfied
   --> $DIR/defaults-unsound-62211-2.rs:24:96
    |
@@ -50,10 +38,10 @@ LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + Fro
    |                                                                                                ^^^^ the trait `Deref` is not implemented for `Self`
    |
 note: required by a bound in `UncheckedCopy::Output`
-  --> $DIR/defaults-unsound-62211-2.rs:24:25
+  --> $DIR/defaults-unsound-62211-2.rs:24:31
    |
 LL |     type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
-   |                         ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+   |                               ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
 help: consider further restricting `Self`
    |
 LL | trait UncheckedCopy: Sized + Deref {
@@ -75,7 +63,6 @@ help: consider further restricting `Self`
 LL | trait UncheckedCopy: Sized + Copy {
    |                            ++++++
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr
index 0866ed054514b..5e2fa551afe30 100644
--- a/tests/ui/associated-types/issue-54108.next.stderr
+++ b/tests/ui/associated-types/issue-54108.next.stderr
@@ -1,15 +1,3 @@
-error[E0271]: type mismatch resolving `<<T as SubEncoder>::ActualSize as Add>::Output normalizes-to <<T as SubEncoder>::ActualSize as Add>::Output`
-  --> $DIR/issue-54108.rs:23:17
-   |
-LL |     type Size = <Self as SubEncoder>::ActualSize;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-   |
-note: required by a bound in `Encoder::Size`
-  --> $DIR/issue-54108.rs:8:20
-   |
-LL |     type Size: Add<Output = Self::Size>;
-   |                    ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
-
 error[E0277]: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
   --> $DIR/issue-54108.rs:23:17
    |
@@ -18,16 +6,15 @@ LL |     type Size = <Self as SubEncoder>::ActualSize;
    |
    = help: the trait `Add` is not implemented for `<T as SubEncoder>::ActualSize`
 note: required by a bound in `Encoder::Size`
-  --> $DIR/issue-54108.rs:8:16
+  --> $DIR/issue-54108.rs:8:20
    |
 LL |     type Size: Add<Output = Self::Size>;
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
+   |                    ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
 help: consider further restricting the associated type
    |
 LL |     T: SubEncoder, <T as SubEncoder>::ActualSize: Add
    |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs
index 647dc84028c33..5c56e64a01727 100644
--- a/tests/ui/for/issue-20605.rs
+++ b/tests/ui/for/issue-20605.rs
@@ -4,12 +4,7 @@
 
 fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
     for item in *things { *item = 0 }
-    //[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
-    //[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
-    //[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
-
-    // FIXME(-Znext-solver): these error messages are horrible and have to be
-    // improved before we stabilize the new solver.
+    //~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
index bc57874bf850a..d624fb1e42b6f 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
+  --> $DIR/ambig-hr-projection-issue-93340.rs:17:5
    |
 LL |     cmp_eq
    |     ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
@@ -15,14 +15,16 @@ help: consider specifying the generic arguments
 LL |     cmp_eq::<A, B, O>
    |           +++++++++++
 
-error[E0271]: type mismatch resolving `build_expression<A, B, O>::{opaque#0} normalizes-to _`
+error[E0277]: expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
   --> $DIR/ambig-hr-projection-issue-93340.rs:14:1
    |
 LL | / fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
 LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
-   | |_________________________________________________^ types differ
+   | |_________________________________________________^ expected an `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
+   |
+   = help: the trait `for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0271, E0283.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0283.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
index d913b2e91ca0e..4a293d44e0e3d 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
+  --> $DIR/ambig-hr-projection-issue-93340.rs:17:5
    |
 LL |     cmp_eq
    |     ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
index acfebad38db0c..5f2e134109e22 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
@@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
 
 fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
 ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+    //[next]~^^ expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure
     cmp_eq
     //~^ ERROR type annotations needed
 }
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
index 5a6bf9bfaef24..351cdad4ee115 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
@@ -14,6 +14,8 @@ struct W<T>(T);
 // `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
 // encounter weak types in `assemble_alias_bound_candidates_recur`.
 fn hello(_: W<A<usize>>) {}
-//~^ ERROR the size for values of type `A<usize>` cannot be known at compilation time
+//~^ ERROR the trait bound `usize: Foo` is not satisfied
+//~| ERROR the trait bound `usize: Foo` is not satisfied
+//~| ERROR the trait bound `usize: Foo` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
index cab6163803a4e..79581066a3a32 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -7,32 +7,42 @@ LL | #![feature(lazy_type_alias)]
    = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+error[E0277]: the trait bound `usize: Foo` is not satisfied
   --> $DIR/alias-bounds-when-not-wf.rs:16:13
    |
 LL | fn hello(_: W<A<usize>>) {}
-   |             ^^^^^^^^^^^ types differ
-
-error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
-  --> $DIR/alias-bounds-when-not-wf.rs:16:10
+   |             ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
    |
-LL | fn hello(_: W<A<usize>>) {}
-   |          ^ types differ
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
 
-error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+error[E0277]: the trait bound `usize: Foo` is not satisfied
   --> $DIR/alias-bounds-when-not-wf.rs:16:10
    |
 LL | fn hello(_: W<A<usize>>) {}
-   |          ^ types differ
+   |          ^ the trait `Foo` is not implemented for `usize`
    |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
 
-error[E0271]: type mismatch resolving `A<usize> normalizes-to _`
+error[E0277]: the trait bound `usize: Foo` is not satisfied
   --> $DIR/alias-bounds-when-not-wf.rs:16:1
    |
 LL | fn hello(_: W<A<usize>>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/alias-bounds-when-not-wf.rs:6:1
+   |
+LL | trait Foo {}
+   | ^^^^^^^^^
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr
index 5aa6931d371e2..8eacfd3e44d40 100644
--- a/tests/ui/impl-trait/method-resolution4.next.stderr
+++ b/tests/ui/impl-trait/method-resolution4.next.stderr
@@ -1,15 +1,9 @@
 error[E0282]: type annotations needed
-  --> $DIR/method-resolution4.rs:13:9
+  --> $DIR/method-resolution4.rs:14:9
    |
 LL |         foo(false).next().unwrap();
    |         ^^^^^^^^^^ cannot infer type
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/method-resolution4.rs:13:9
-   |
-LL |         foo(false).next().unwrap();
-   |         ^^^^^^^^^^ types differ
-
 error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
   --> $DIR/method-resolution4.rs:11:20
    |
@@ -19,14 +13,8 @@ LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
    = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/method-resolution4.rs:16:5
-   |
-LL |     std::iter::empty()
-   |     ^^^^^^^^^^^^^^^^^^ types differ
-
 error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
-  --> $DIR/method-resolution4.rs:13:9
+  --> $DIR/method-resolution4.rs:14:9
    |
 LL |         foo(false).next().unwrap();
    |         ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -34,21 +22,7 @@ LL |         foo(false).next().unwrap();
    = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/method-resolution4.rs:13:9
-   |
-LL |         foo(false).next().unwrap();
-   |         ^^^^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/method-resolution4.rs:11:1
-   |
-LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-
-error: aborting due to 7 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0277, E0282.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0282.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs
index 91884eb59fd63..8eeedf04cbeb1 100644
--- a/tests/ui/impl-trait/method-resolution4.rs
+++ b/tests/ui/impl-trait/method-resolution4.rs
@@ -9,12 +9,13 @@
 //@[current] check-pass
 
 fn foo(b: bool) -> impl Iterator<Item = ()> {
+    //[next]~^ ERROR the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
     if b {
         foo(false).next().unwrap();
         //[next]~^ type annotations needed
+        //[next]~| ERROR the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
     }
     std::iter::empty()
-    //[next]~^ mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
index 5feef0b44b53b..b38850c9214e4 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
@@ -1,9 +1,9 @@
 error[E0282]: type annotations needed
-  --> $DIR/recursive-coroutine-boxed.rs:15:23
+  --> $DIR/recursive-coroutine-boxed.rs:16:23
    |
 LL |         let mut gen = Box::pin(foo());
    |                       ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
-LL |
+...
 LL |         let mut r = gen.as_mut().resume(());
    |                         ------ type must be known at this point
    |
@@ -12,25 +12,6 @@ help: consider specifying the generic argument
 LL |         let mut gen = Box::<T>::pin(foo());
    |                          +++++
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-coroutine-boxed.rs:14:18
-   |
-LL |       #[coroutine] || {
-   |  __________________^
-LL | |         let mut gen = Box::pin(foo());
-LL | |
-LL | |         let mut r = gen.as_mut().resume(());
-...  |
-LL | |         }
-LL | |     }
-   | |_____^ types differ
-
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-coroutine-boxed.rs:15:32
-   |
-LL |         let mut gen = Box::pin(foo());
-   |                                ^^^^^ types differ
-
 error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
   --> $DIR/recursive-coroutine-boxed.rs:9:13
    |
@@ -40,23 +21,8 @@ LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
    = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-coroutine-boxed.rs:14:18
-   |
-LL |       #[coroutine] || {
-   |  __________________^
-LL | |         let mut gen = Box::pin(foo());
-LL | |
-LL | |         let mut r = gen.as_mut().resume(());
-...  |
-LL | |         }
-LL | |     }
-   | |_____^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
-  --> $DIR/recursive-coroutine-boxed.rs:15:32
+  --> $DIR/recursive-coroutine-boxed.rs:16:32
    |
 LL |         let mut gen = Box::pin(foo());
    |                                ^^^^^ doesn't have a size known at compile-time
@@ -64,21 +30,7 @@ LL |         let mut gen = Box::pin(foo());
    = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-coroutine-boxed.rs:15:32
-   |
-LL |         let mut gen = Box::pin(foo());
-   |                                ^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-coroutine-boxed.rs:9:1
-   |
-LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-
-error: aborting due to 8 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0277, E0282.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0282.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
index 24a77d7311419..8e670dd78ecb5 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
@@ -7,13 +7,15 @@
 use std::ops::{Coroutine, CoroutineState};
 
 fn foo() -> impl Coroutine<Yield = (), Return = ()> {
+    //[next]~^ ERROR the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
+
     // FIXME(-Znext-solver): this fails with a mismatched types as the
     // hidden type of the opaque ends up as {type error}. We should not
     // emit errors for such goals.
-
-    #[coroutine] || { //[next]~ ERROR mismatched types
+    #[coroutine] || {
         let mut gen = Box::pin(foo());
         //[next]~^ ERROR type annotations needed
+        //[next]~| ERROR the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
         let mut r = gen.as_mut().resume(());
         while let CoroutineState::Yielded(v) = r {
             yield v;
diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr
index f31a2a806674b..4cebd26a5bee6 100644
--- a/tests/ui/impl-trait/unsized_coercion.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion.next.stderr
@@ -1,11 +1,13 @@
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
-  --> $DIR/unsized_coercion.rs:14:17
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
+  --> $DIR/unsized_coercion.rs:15:17
    |
 LL |         let x = hello();
-   |                 ^^^^^^^ types differ
+   |                 ^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Trait`
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion.rs:18:5
+  --> $DIR/unsized_coercion.rs:19:5
    |
 LL | fn hello() -> Box<impl Trait> {
    |               ---------------
@@ -19,21 +21,15 @@ LL |     Box::new(1u32)
    = note: expected struct `Box<impl Trait>`
               found struct `Box<u32>`
 
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
-  --> $DIR/unsized_coercion.rs:14:17
-   |
-LL |         let x = hello();
-   |                 ^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
   --> $DIR/unsized_coercion.rs:12:1
    |
 LL | fn hello() -> Box<impl Trait> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Trait`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0308.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs
index 46e040c1428a4..b3791b38abc2d 100644
--- a/tests/ui/impl-trait/unsized_coercion.rs
+++ b/tests/ui/impl-trait/unsized_coercion.rs
@@ -10,9 +10,10 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait> {
+    //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
     if true {
         let x = hello();
-        //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
+        //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
         let y: Box<dyn Trait> = x;
     }
     Box::new(1u32) //[next]~ ERROR: mismatched types
diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr
index f5187a6256efa..d1e1809cf1656 100644
--- a/tests/ui/impl-trait/unsized_coercion3.next.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr
@@ -1,11 +1,13 @@
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
-  --> $DIR/unsized_coercion3.rs:13:17
+error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
+  --> $DIR/unsized_coercion3.rs:14:17
    |
 LL |         let x = hello();
-   |                 ^^^^^^^ types differ
+   |                 ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
+   |
+   = help: the trait `Trait` is implemented for `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/unsized_coercion3.rs:18:5
+  --> $DIR/unsized_coercion3.rs:19:5
    |
 LL | fn hello() -> Box<impl Trait + ?Sized> {
    |               ------------------------
@@ -19,21 +21,15 @@ LL |     Box::new(1u32)
    = note: expected struct `Box<impl Trait + ?Sized>`
               found struct `Box<u32>`
 
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
-  --> $DIR/unsized_coercion3.rs:13:17
-   |
-LL |         let x = hello();
-   |                 ^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _`
+error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
   --> $DIR/unsized_coercion3.rs:11:1
    |
 LL | fn hello() -> Box<impl Trait + ?Sized> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
+   |
+   = help: the trait `Trait` is implemented for `u32`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0271, E0308.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr
index 52a72b84a8dd6..3bb9f9c209510 100644
--- a/tests/ui/impl-trait/unsized_coercion3.old.stderr
+++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
-  --> $DIR/unsized_coercion3.rs:15:32
+  --> $DIR/unsized_coercion3.rs:16:32
    |
 LL |         let y: Box<dyn Send> = x;
    |                                ^ doesn't have a size known at compile-time
diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs
index 7e862de2157d9..c1dd5350e229a 100644
--- a/tests/ui/impl-trait/unsized_coercion3.rs
+++ b/tests/ui/impl-trait/unsized_coercion3.rs
@@ -9,15 +9,15 @@ trait Trait {}
 impl Trait for u32 {}
 
 fn hello() -> Box<impl Trait + ?Sized> {
+    //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
     if true {
         let x = hello();
-        //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
+        //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
         let y: Box<dyn Send> = x;
         //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
     }
     Box::new(1u32)
     //[next]~^ ERROR: mismatched types
-    //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
 }
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index 35757f2339dbf..70cc47bb0225f 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -13,9 +13,17 @@ fn main() {
 }
 
 fn weird0() -> impl Sized + !Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
+//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 fn weird1() -> impl !Sized + Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
+//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 fn weird2() -> impl !Sized {}
-//~^ ERROR type mismatch resolving `impl !Sized == ()`
-//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time
+//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277]
+//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 561bf8eee2283..366baf26dea94 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,14 +1,18 @@
-error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
+error[E0277]: the size for values of type `()` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ types differ
+   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
+error[E0277]: the size for values of type `()` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                                    ^^ types differ
+   |                                    ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
@@ -19,26 +23,32 @@ LL | fn weird0() -> impl Sized + !Sized {}
    = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _`
+error[E0277]: the size for values of type `()` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:20:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ types differ
+   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:17:36
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:20:36
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   |                                    ^^ types differ
+   |                                    ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:20:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -46,26 +56,32 @@ LL | fn weird1() -> impl !Sized + Sized {}
    = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:17:1
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:20:1
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:25:16
    |
 LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ types differ
+   |                ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:28
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:25:28
    |
 LL | fn weird2() -> impl !Sized {}
-   |                            ^^ types differ
+   |                            ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:25:16
    |
 LL | fn weird2() -> impl !Sized {}
    |                ^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -73,11 +89,13 @@ LL | fn weird2() -> impl !Sized {}
    = help: the trait `Sized` is not implemented for `impl !Sized`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _`
-  --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
+error[E0277]: the size for values of type `()` cannot be known at compilation time
+  --> $DIR/opaque-type-unsatisfied-bound.rs:25:1
    |
 LL | fn weird2() -> impl !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
@@ -95,5 +113,4 @@ LL | fn consume(_: impl Trait) {}
 
 error: aborting due to 13 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index 9951826a8466d..3633e9f3f481c 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -3,6 +3,9 @@
 #![feature(negative_bounds, unboxed_closures)]
 
 fn produce() -> impl !Fn<(u32,)> {}
-//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
+//~^ ERROR expected a `Fn(u32)` closure, found `()`
+//~| ERROR expected a `Fn(u32)` closure, found `()`
+//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time
+//~| ERROR expected a `Fn(u32)` closure, found `()`
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index a7a83cf1d69cc..cdd89de0d888e 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -1,14 +1,18 @@
-error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
+error[E0277]: expected a `Fn(u32)` closure, found `()`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ^^^^^^^^^^^^^^^^ types differ
+   |                 ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()`
+   |
+   = help: the trait bound `(): !Fn(u32)` is not satisfied
 
-error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
+error[E0277]: expected a `Fn(u32)` closure, found `()`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                                  ^^ types differ
+   |                                  ^^ expected an `Fn(u32)` closure, found `()`
+   |
+   = help: the trait bound `(): !Fn(u32)` is not satisfied
 
 error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
@@ -19,13 +23,14 @@ LL | fn produce() -> impl !Fn<(u32,)> {}
    = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>`
    = note: the return type of a function must have a statically known size
 
-error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _`
+error[E0277]: expected a `Fn(u32)` closure, found `()`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()`
+   |
+   = help: the trait bound `(): !Fn(u32)` is not satisfied
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr
index b37dbc0e579eb..8c263e8644bd0 100644
--- a/tests/ui/traits/next-solver/coroutine.fail.stderr
+++ b/tests/ui/traits/next-solver/coroutine.fail.stderr
@@ -16,43 +16,6 @@ note: required by a bound in `needs_coroutine`
 LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine`
 
-error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Yield`
-  --> $DIR/coroutine.rs:20:9
-   |
-LL |       needs_coroutine(
-   |       --------------- required by a bound introduced by this call
-LL |           #[coroutine]
-LL | /         || {
-LL | |
-LL | |             yield ();
-LL | |         },
-   | |_________^ types differ
-   |
-note: required by a bound in `needs_coroutine`
-  --> $DIR/coroutine.rs:14:41
-   |
-LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
-   |                                         ^^^^^^^^^ required by this bound in `needs_coroutine`
-
-error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine<A>>::Return`
-  --> $DIR/coroutine.rs:20:9
-   |
-LL |       needs_coroutine(
-   |       --------------- required by a bound introduced by this call
-LL |           #[coroutine]
-LL | /         || {
-LL | |
-LL | |             yield ();
-LL | |         },
-   | |_________^ types differ
-   |
-note: required by a bound in `needs_coroutine`
-  --> $DIR/coroutine.rs:14:52
-   |
-LL | fn needs_coroutine(_: impl Coroutine<A, Yield = B, Return = C>) {}
-   |                                                    ^^^^^^^^^^ required by this bound in `needs_coroutine`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
index dbd2880943c97..cd8d8b3ffcd38 100644
--- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
+++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr
@@ -9,20 +9,6 @@ help: consider restricting type parameter `T`
 LL | fn test_poly<T: Trait>() {
    |               +++++++
 
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc normalizes-to <T as Trait>::Assoc`
-  --> $DIR/projection-trait-ref.rs:8:12
-   |
-LL |     let x: <T as Trait>::Assoc = ();
-   |            ^^^^^^^^^^^^^^^^^^^ types differ
-
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc normalizes-to <T as Trait>::Assoc`
-  --> $DIR/projection-trait-ref.rs:8:12
-   |
-LL |     let x: <T as Trait>::Assoc = ();
-   |            ^^^^^^^^^^^^^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0277]: the trait bound `i32: Trait` is not satisfied
   --> $DIR/projection-trait-ref.rs:13:12
    |
@@ -35,21 +21,6 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait {
    | ^^^^^^^^^^^
 
-error[E0271]: type mismatch resolving `<i32 as Trait>::Assoc normalizes-to <i32 as Trait>::Assoc`
-  --> $DIR/projection-trait-ref.rs:13:12
-   |
-LL |     let x: <i32 as Trait>::Assoc = ();
-   |            ^^^^^^^^^^^^^^^^^^^^^ types differ
-
-error[E0271]: type mismatch resolving `<i32 as Trait>::Assoc normalizes-to <i32 as Trait>::Assoc`
-  --> $DIR/projection-trait-ref.rs:13:12
-   |
-LL |     let x: <i32 as Trait>::Assoc = ();
-   |            ^^^^^^^^^^^^^^^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs
index a347984daf6a6..b53a6543c90a4 100644
--- a/tests/ui/traits/next-solver/dyn-incompatibility.rs
+++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs
@@ -13,6 +13,7 @@ pub fn copy_any<T>(t: &T) -> T {
     //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup<From = T>`
     //~| ERROR mismatched types
     //~| ERROR the trait bound `T: Copy` is not satisfied
+    //~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
 
     // FIXME(-Znext-solver): These error messages are horrible and some of them
     // are even simple fallout from previous error.
diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr
index 0dee26d467271..00243fd905950 100644
--- a/tests/ui/traits/next-solver/fn-trait.stderr
+++ b/tests/ui/traits/next-solver/fn-trait.stderr
@@ -15,20 +15,6 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
-error[E0271]: type mismatch resolving `<unsafe fn() -> i32 as FnOnce<()>>::Output normalizes-to <unsafe fn() -> i32 as FnOnce<()>>::Output`
-  --> $DIR/fn-trait.rs:20:16
-   |
-LL |     require_fn(f as unsafe fn() -> i32);
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `require_fn`
-  --> $DIR/fn-trait.rs:3:31
-   |
-LL | fn require_fn(_: impl Fn() -> i32) {}
-   |                               ^^^ required by this bound in `require_fn`
-
 error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}`
   --> $DIR/fn-trait.rs:22:16
    |
@@ -45,20 +31,6 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
-error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 {g} as FnOnce<()>>::Output normalizes-to <extern "C" fn() -> i32 {g} as FnOnce<()>>::Output`
-  --> $DIR/fn-trait.rs:22:16
-   |
-LL |     require_fn(g);
-   |     ---------- ^ types differ
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `require_fn`
-  --> $DIR/fn-trait.rs:3:31
-   |
-LL | fn require_fn(_: impl Fn() -> i32) {}
-   |                               ^^^ required by this bound in `require_fn`
-
 error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32`
   --> $DIR/fn-trait.rs:24:16
    |
@@ -75,20 +47,6 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
-error[E0271]: type mismatch resolving `<extern "C" fn() -> i32 as FnOnce<()>>::Output normalizes-to <extern "C" fn() -> i32 as FnOnce<()>>::Output`
-  --> $DIR/fn-trait.rs:24:16
-   |
-LL |     require_fn(g as extern "C" fn() -> i32);
-   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `require_fn`
-  --> $DIR/fn-trait.rs:3:31
-   |
-LL | fn require_fn(_: impl Fn() -> i32) {}
-   |                               ^^^ required by this bound in `require_fn`
-
 error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}`
   --> $DIR/fn-trait.rs:26:16
    |
@@ -106,21 +64,6 @@ note: required by a bound in `require_fn`
 LL | fn require_fn(_: impl Fn() -> i32) {}
    |                       ^^^^^^^^^^^ required by this bound in `require_fn`
 
-error[E0271]: type mismatch resolving `<unsafe fn() -> i32 {h} as FnOnce<()>>::Output normalizes-to <unsafe fn() -> i32 {h} as FnOnce<()>>::Output`
-  --> $DIR/fn-trait.rs:26:16
-   |
-LL |     require_fn(h);
-   |     ---------- ^ types differ
-   |     |
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `require_fn`
-  --> $DIR/fn-trait.rs:3:31
-   |
-LL | fn require_fn(_: impl Fn() -> i32) {}
-   |                               ^^^ required by this bound in `require_fn`
-
-error: aborting due to 8 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0271, E0277.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
index 9f6dea5d5bf86..e1bd234a275a6 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.rs
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -17,7 +17,7 @@ type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
 impl<T> Overlap<T> for T {}
 
 impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
-//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
-//~| ERROR cannot find type `Missing` in this scope
+//~^ ERROR cannot find type `Missing` in this scope
+//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index 82ec9e3a22f75..f6545c6ebf9de 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -26,13 +26,19 @@ LL | trait ToUnit<'a> {
    | ^^^^^^^^^^^^^^^^
 
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
-error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _`
+error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
   --> $DIR/issue-118950-root-region.rs:19:17
    |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/issue-118950-root-region.rs:8:1
+   |
+LL | trait ToUnit<'a> {
+   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0271, E0277, E0412.
-For more information about an error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
index 7bf3274f9c634..c4c2e695a1df5 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
+++ b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs
@@ -15,7 +15,7 @@ trait Mirror { type Assoc: ?Sized; }
 impl<T: ?Sized> Mirror for T { type Assoc = T; }
 
 trait MirrorRegion<'a> { type Assoc: ?Sized; }
-impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
+impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; }
 
 impl<T> Foo for T {
     #[cfg(normalize_param_env)]
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
index f953111aef025..2617ce124c105 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
@@ -4,21 +4,6 @@ error[E0282]: type annotations needed
 LL |         self.bar.next().unwrap();
    |         ^^^^^^^^ cannot infer type
 
-error[E0271]: type mismatch resolving `Tait normalizes-to _`
-  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
-   |
-LL |         self.bar.next().unwrap();
-   |         ^^^^^^^^ types differ
-
-error[E0271]: type mismatch resolving `Tait normalizes-to _`
-  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
-   |
-LL |         self.bar.next().unwrap();
-   |         ^^^^^^^^ types differ
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0271, E0282.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
index 5c9a3b7c2d296..b6adf08853f2f 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
@@ -25,8 +25,6 @@ impl Foo {
         //[current]~^ ERROR: item does not constrain
         self.bar.next().unwrap();
         //[next]~^ ERROR: type annotations needed
-        //[next]~| ERROR type mismatch resolving `Tait normalizes-to _`
-        //[next]~| ERROR type mismatch resolving `Tait normalizes-to _`
     }
 }
 
diff --git a/tests/ui/typeck/issue-103899.rs b/tests/ui/typeck/issue-103899.rs
index 38882e9dc54da..81ab92a8994c4 100644
--- a/tests/ui/typeck/issue-103899.rs
+++ b/tests/ui/typeck/issue-103899.rs
@@ -1,11 +1,9 @@
 //@ revisions: current next
-//@[next] compile-flags: -Znext-solver
-//@[next] check-pass
 //@ ignore-compare-mode-next-solver (explicit revisions)
-//@[current] check-fail
-//@[current] failure-status: 101
-//@[current] dont-check-compiler-stderr
-//@[current] known-bug: #103899
+//@ check-fail
+//@ failure-status: 101
+//@ dont-check-compiler-stderr
+//@ known-bug: #103899
 
 trait BaseWithAssoc {
     type Assoc;

From 0ead25c4a99242a526ef1076c52fa420c65b667a Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Mon, 14 Oct 2024 13:49:31 -0400
Subject: [PATCH 13/18] Register a dummy candidate for failed structural
 normalization during candiate assembly

---
 .../src/solve/assembly/mod.rs                 | 20 +++++++++
 .../impl-trait/method-resolution4.next.stderr | 25 ++---------
 tests/ui/impl-trait/method-resolution4.rs     |  2 -
 .../recursive-coroutine-boxed.next.stderr     | 27 ++----------
 .../impl-trait/recursive-coroutine-boxed.rs   |  3 --
 .../opaque-type-unsatisfied-bound.rs          |  3 --
 .../opaque-type-unsatisfied-bound.stderr      | 41 ++++---------------
 .../opaque-type-unsatisfied-fn-bound.rs       |  1 -
 .../opaque-type-unsatisfied-fn-bound.stderr   | 11 +----
 .../traits/next-solver/dyn-incompatibility.rs |  1 -
 .../next-solver/dyn-incompatibility.stderr    | 15 +------
 11 files changed, 36 insertions(+), 113 deletions(-)

diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index cebeef76bfc03..c9c0d6391fc81 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -6,6 +6,7 @@ use derive_where::derive_where;
 use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
+use rustc_type_ir::solve::inspect;
 use rustc_type_ir::visit::TypeVisitableExt as _;
 use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
 use tracing::{debug, instrument};
@@ -288,6 +289,25 @@ where
         let Ok(normalized_self_ty) =
             self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
         else {
+            // FIXME: We register a fake candidate when normalization fails so that
+            // we can point at the reason for *why*. I'm tempted to say that this
+            // is the wrong way to do this, though.
+            let result =
+                self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
+                    let normalized_ty = this.next_ty_infer();
+                    let alias_relate_goal = Goal::new(
+                        this.cx(),
+                        goal.param_env,
+                        ty::PredicateKind::AliasRelate(
+                            goal.predicate.self_ty().into(),
+                            normalized_ty.into(),
+                            ty::AliasRelationDirection::Equate,
+                        ),
+                    );
+                    this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
+                    this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                });
+            assert_eq!(result, Err(NoSolution));
             return vec![];
         };
 
diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr
index 8eacfd3e44d40..0524f49f98e58 100644
--- a/tests/ui/impl-trait/method-resolution4.next.stderr
+++ b/tests/ui/impl-trait/method-resolution4.next.stderr
@@ -1,28 +1,9 @@
 error[E0282]: type annotations needed
-  --> $DIR/method-resolution4.rs:14:9
+  --> $DIR/method-resolution4.rs:13:9
    |
 LL |         foo(false).next().unwrap();
    |         ^^^^^^^^^^ cannot infer type
 
-error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
-  --> $DIR/method-resolution4.rs:11:20
-   |
-LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
-   = note: the return type of a function must have a statically known size
-
-error[E0277]: the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
-  --> $DIR/method-resolution4.rs:14:9
-   |
-LL |         foo(false).next().unwrap();
-   |         ^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl Iterator<Item = ()>`
-   = note: the return type of a function must have a statically known size
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0282.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs
index 8eeedf04cbeb1..5c8813ed79224 100644
--- a/tests/ui/impl-trait/method-resolution4.rs
+++ b/tests/ui/impl-trait/method-resolution4.rs
@@ -9,11 +9,9 @@
 //@[current] check-pass
 
 fn foo(b: bool) -> impl Iterator<Item = ()> {
-    //[next]~^ ERROR the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
     if b {
         foo(false).next().unwrap();
         //[next]~^ type annotations needed
-        //[next]~| ERROR the size for values of type `impl Iterator<Item = ()>` cannot be known at compilation time
     }
     std::iter::empty()
 }
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
index b38850c9214e4..132f7de4ef230 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
@@ -1,9 +1,9 @@
 error[E0282]: type annotations needed
-  --> $DIR/recursive-coroutine-boxed.rs:16:23
+  --> $DIR/recursive-coroutine-boxed.rs:14:23
    |
 LL |         let mut gen = Box::pin(foo());
    |                       ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
-...
+LL |
 LL |         let mut r = gen.as_mut().resume(());
    |                         ------ type must be known at this point
    |
@@ -12,25 +12,6 @@ help: consider specifying the generic argument
 LL |         let mut gen = Box::<T>::pin(foo());
    |                          +++++
 
-error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
-  --> $DIR/recursive-coroutine-boxed.rs:9:13
-   |
-LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
-   = note: the return type of a function must have a statically known size
-
-error[E0277]: the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
-  --> $DIR/recursive-coroutine-boxed.rs:16:32
-   |
-LL |         let mut gen = Box::pin(foo());
-   |                                ^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
-   = note: the return type of a function must have a statically known size
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0282.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
index 8e670dd78ecb5..8d38e6aed1246 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
@@ -7,15 +7,12 @@
 use std::ops::{Coroutine, CoroutineState};
 
 fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-    //[next]~^ ERROR the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
-
     // FIXME(-Znext-solver): this fails with a mismatched types as the
     // hidden type of the opaque ends up as {type error}. We should not
     // emit errors for such goals.
     #[coroutine] || {
         let mut gen = Box::pin(foo());
         //[next]~^ ERROR type annotations needed
-        //[next]~| ERROR the size for values of type `impl Coroutine<Yield = (), Return = ()>` cannot be known at compilation time
         let mut r = gen.as_mut().resume(());
         while let CoroutineState::Yielded(v) = r {
             yield v;
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index 70cc47bb0225f..25034b67e35b8 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -15,15 +15,12 @@ fn main() {
 fn weird0() -> impl Sized + !Sized {}
 //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 fn weird1() -> impl !Sized + Sized {}
 //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 fn weird2() -> impl !Sized {}
 //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277]
 //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 366baf26dea94..3e803a1c24fa3 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -14,15 +14,6 @@ LL | fn weird0() -> impl Sized + !Sized {}
    |
    = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
-   |
-LL | fn weird0() -> impl Sized + !Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
-   = note: the return type of a function must have a statically known size
-
 error[E0277]: the size for values of type `()` cannot be known at compilation time
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
    |
@@ -32,7 +23,7 @@ LL | fn weird0() -> impl Sized + !Sized {}
    = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:20:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -40,24 +31,15 @@ LL | fn weird1() -> impl !Sized + Sized {}
    = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:20:36
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:36
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    |                                    ^^ doesn't have a size known at compile-time
    |
    = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:20:16
-   |
-LL | fn weird1() -> impl !Sized + Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl !Sized + Sized`
-   = note: the return type of a function must have a statically known size
-
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:20:1
+  --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
    |
 LL | fn weird1() -> impl !Sized + Sized {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -65,7 +47,7 @@ LL | fn weird1() -> impl !Sized + Sized {}
    = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:25:16
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:16
    |
 LL | fn weird2() -> impl !Sized {}
    |                ^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -73,24 +55,15 @@ LL | fn weird2() -> impl !Sized {}
    = help: the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:25:28
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:28
    |
 LL | fn weird2() -> impl !Sized {}
    |                            ^^ doesn't have a size known at compile-time
    |
    = help: the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:25:16
-   |
-LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl !Sized`
-   = note: the return type of a function must have a statically known size
-
 error[E0277]: the size for values of type `()` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-bound.rs:25:1
+  --> $DIR/opaque-type-unsatisfied-bound.rs:23:1
    |
 LL | fn weird2() -> impl !Sized {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -111,6 +84,6 @@ note: required by a bound in `consume`
 LL | fn consume(_: impl Trait) {}
    |                    ^^^^^ required by this bound in `consume`
 
-error: aborting due to 13 previous errors
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index 3633e9f3f481c..7538e3c0d2bba 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -5,7 +5,6 @@
 fn produce() -> impl !Fn<(u32,)> {}
 //~^ ERROR expected a `Fn(u32)` closure, found `()`
 //~| ERROR expected a `Fn(u32)` closure, found `()`
-//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time
 //~| ERROR expected a `Fn(u32)` closure, found `()`
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index cdd89de0d888e..57a423741b394 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -14,15 +14,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {}
    |
    = help: the trait bound `(): !Fn(u32)` is not satisfied
 
-error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time
-  --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
-   |
-LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>`
-   = note: the return type of a function must have a statically known size
-
 error[E0277]: expected a `Fn(u32)` closure, found `()`
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
    |
@@ -31,6 +22,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {}
    |
    = help: the trait bound `(): !Fn(u32)` is not satisfied
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs
index b53a6543c90a4..a347984daf6a6 100644
--- a/tests/ui/traits/next-solver/dyn-incompatibility.rs
+++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs
@@ -13,7 +13,6 @@ pub fn copy_any<T>(t: &T) -> T {
     //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup<From = T>`
     //~| ERROR mismatched types
     //~| ERROR the trait bound `T: Copy` is not satisfied
-    //~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
 
     // FIXME(-Znext-solver): These error messages are horrible and some of them
     // are even simple fallout from previous error.
diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr
index adf46686e081a..7f2c0646ef501 100644
--- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr
+++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr
@@ -43,20 +43,7 @@ help: consider restricting type parameter `T`
 LL | pub fn copy_any<T: std::marker::Copy>(t: &T) -> T {
    |                  +++++++++++++++++++
 
-error[E0277]: the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time
-  --> $DIR/dyn-incompatibility.rs:12:5
-   |
-LL |     copy::<dyn Setup<From=T>>(t)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `<dyn Setup<From = T> as Setup>::From`
-   = note: the return type of a function must have a statically known size
-help: consider further restricting the associated type
-   |
-LL | pub fn copy_any<T>(t: &T) -> T where <dyn Setup<From = T> as Setup>::From: Sized {
-   |                                +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.

From f956dc2e779ae5ca14c882998d308609648025e9 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 15 Oct 2024 20:38:43 -0400
Subject: [PATCH 14/18] Bless tests

---
 .../structually-relate-aliases.rs             |  3 +-
 .../structually-relate-aliases.stderr         | 32 ++++++-----
 .../opaque-type-unsatisfied-bound.rs          | 18 +++----
 .../opaque-type-unsatisfied-bound.stderr      | 54 +++++++------------
 .../opaque-type-unsatisfied-fn-bound.rs       |  6 +--
 .../opaque-type-unsatisfied-fn-bound.stderr   | 18 +++----
 6 files changed, 58 insertions(+), 73 deletions(-)

diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs
index 6988245096136..73c2cd23d86e3 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.rs
+++ b/tests/ui/higher-ranked/structually-relate-aliases.rs
@@ -11,6 +11,7 @@ type Assoc<'a, T> = <T as ToUnit<'a>>::Unit;
 impl<T> Overlap<T> for T {}
 
 impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-//~^ ERROR conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>`
+//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr
index 4ecd5829bc352..e9d91e45e217b 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.stderr
+++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr
@@ -1,18 +1,26 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
-error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
-  --> $DIR/structually-relate-aliases.rs:13:1
+error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+  --> $DIR/structually-relate-aliases.rs:13:36
    |
-LL | impl<T> Overlap<T> for T {}
-   | ------------------------ first implementation here
-LL |
 LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)`
+   |                                    ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |       ++++++++++++++++++++
+
+error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
+  --> $DIR/structually-relate-aliases.rs:13:17
+   |
+LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
    |
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
+   |       ++++++++++++++++++++
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
index 25034b67e35b8..1260cca510680 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs
@@ -13,14 +13,14 @@ fn main() {
 }
 
 fn weird0() -> impl Sized + !Sized {}
-//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird1() -> impl !Sized + Sized {}
-//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
 fn weird2() -> impl !Sized {}
-//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
-//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277]
+//~^ ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
+//~| ERROR the trait bound `(): !Sized` is not satisfied
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
index 3e803a1c24fa3..4ec578a3b7bc2 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr
@@ -1,74 +1,56 @@
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:36
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   |                                    ^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                                    ^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:15:1
    |
 LL | fn weird0() -> impl Sized + !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:36
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   |                                    ^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                                    ^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:19:1
    |
 LL | fn weird1() -> impl !Sized + Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:23:16
    |
 LL | fn weird2() -> impl !Sized {}
-   |                ^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:23:28
    |
 LL | fn weird2() -> impl !Sized {}
-   |                            ^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   |                            ^^ the trait bound `(): !Sized` is not satisfied
 
-error[E0277]: the size for values of type `()` cannot be known at compilation time
+error[E0277]: the trait bound `(): !Sized` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:23:1
    |
 LL | fn weird2() -> impl !Sized {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait bound `(): !Sized` is not satisfied
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
 
 error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
   --> $DIR/opaque-type-unsatisfied-bound.rs:12:13
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
index 7538e3c0d2bba..c6826578658fd 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs
@@ -3,8 +3,8 @@
 #![feature(negative_bounds, unboxed_closures)]
 
 fn produce() -> impl !Fn<(u32,)> {}
-//~^ ERROR expected a `Fn(u32)` closure, found `()`
-//~| ERROR expected a `Fn(u32)` closure, found `()`
-//~| ERROR expected a `Fn(u32)` closure, found `()`
+//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
+//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
+//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
index 57a423741b394..f81f0a23ac315 100644
--- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
+++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr
@@ -1,26 +1,20 @@
-error[E0277]: expected a `Fn(u32)` closure, found `()`
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                 ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()`
-   |
-   = help: the trait bound `(): !Fn(u32)` is not satisfied
+   |                 ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
 
-error[E0277]: expected a `Fn(u32)` closure, found `()`
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   |                                  ^^ expected an `Fn(u32)` closure, found `()`
-   |
-   = help: the trait bound `(): !Fn(u32)` is not satisfied
+   |                                  ^^ the trait bound `(): !Fn(u32)` is not satisfied
 
-error[E0277]: expected a `Fn(u32)` closure, found `()`
+error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
   --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
    |
 LL | fn produce() -> impl !Fn<(u32,)> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()`
-   |
-   = help: the trait bound `(): !Fn(u32)` is not satisfied
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
 
 error: aborting due to 3 previous errors
 

From b2b4ad4cc94077eba1331acc534b5e36ae3e2603 Mon Sep 17 00:00:00 2001
From: Michal Piotrowski <practicalrs.com@gmail.com>
Date: Wed, 16 Oct 2024 15:44:16 +0200
Subject: [PATCH 15/18] Fix explicit_iter_loop in rustc_serialize

---
 compiler/rustc_serialize/src/serialize.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index bae5f259fccf4..db8555edd0f8f 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -288,7 +288,7 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> {
 impl<S: Encoder, T: Encodable<S>> Encodable<S> for [T] {
     default fn encode(&self, s: &mut S) {
         s.emit_usize(self.len());
-        for e in self.iter() {
+        for e in self {
             e.encode(s);
         }
     }
@@ -527,7 +527,7 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for ThinVec<T> {
 impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
     fn encode(&self, s: &mut S) {
         s.emit_usize(self.len());
-        for e in self.iter() {
+        for e in self {
             e.encode(s);
         }
     }
@@ -547,7 +547,7 @@ where
 {
     fn encode(&self, e: &mut S) {
         e.emit_usize(self.len());
-        for (key, val) in self.iter() {
+        for (key, val) in self {
             key.encode(e);
             val.encode(e);
         }
@@ -571,7 +571,7 @@ where
 {
     fn encode(&self, s: &mut S) {
         s.emit_usize(self.len());
-        for e in self.iter() {
+        for e in self {
             e.encode(s);
         }
     }
@@ -595,7 +595,7 @@ where
 {
     fn encode(&self, e: &mut E) {
         e.emit_usize(self.len());
-        for (key, val) in self.iter() {
+        for (key, val) in self {
             key.encode(e);
             val.encode(e);
         }
@@ -621,7 +621,7 @@ where
 {
     fn encode(&self, s: &mut E) {
         s.emit_usize(self.len());
-        for e in self.iter() {
+        for e in self {
             e.encode(s);
         }
     }
@@ -646,7 +646,7 @@ where
 {
     fn encode(&self, e: &mut E) {
         e.emit_usize(self.len());
-        for (key, val) in self.iter() {
+        for (key, val) in self {
             key.encode(e);
             val.encode(e);
         }
@@ -672,7 +672,7 @@ where
 {
     fn encode(&self, s: &mut E) {
         s.emit_usize(self.len());
-        for e in self.iter() {
+        for e in self {
             e.encode(s);
         }
     }

From 6d82559bc1d5e02705cec0726a25704882c79365 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= <me@fmease.dev>
Date: Sat, 12 Oct 2024 12:34:58 +0200
Subject: [PATCH 16/18] rustdoc: Rename "object safe" to "dyn compatible"

---
 src/librustdoc/clean/types.rs            |  2 +-
 src/librustdoc/html/markdown.rs          |  2 +-
 src/librustdoc/html/render/print_item.rs | 14 ++++++------
 src/librustdoc/html/render/sidebar.rs    |  6 +++---
 src/librustdoc/json/conversions.rs       |  2 +-
 tests/rustdoc/dyn-compatibility.rs       | 27 ++++++++++++++++++++++++
 tests/rustdoc/sidebar/sidebar-items.rs   |  6 +++---
 tests/rustdoc/trait-object-safe.rs       | 27 ------------------------
 8 files changed, 44 insertions(+), 42 deletions(-)
 create mode 100644 tests/rustdoc/dyn-compatibility.rs
 delete mode 100644 tests/rustdoc/trait-object-safe.rs

diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index bc5bf4c05838a..44295fa0cd940 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1450,7 +1450,7 @@ impl Trait {
     pub(crate) fn safety(&self, tcx: TyCtxt<'_>) -> hir::Safety {
         tcx.trait_def(self.def_id).safety
     }
-    pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool {
+    pub(crate) fn is_dyn_compatible(&self, tcx: TyCtxt<'_>) -> bool {
         tcx.is_dyn_compatible(self.def_id)
     }
 }
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 5dacabd031e06..315b7742a4cf8 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -2002,7 +2002,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     map.insert("required-associated-consts".into(), 1);
     map.insert("required-methods".into(), 1);
     map.insert("provided-methods".into(), 1);
-    map.insert("object-safety".into(), 1);
+    map.insert("dyn-compatibility".into(), 1);
     map.insert("implementors".into(), 1);
     map.insert("synthetic-implementors".into(), 1);
     map.insert("implementations-list".into(), 1);
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 3c96f8736814e..5e9cbef99a950 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -934,16 +934,18 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
     let cache = &cloned_shared.cache;
     let mut extern_crates = FxIndexSet::default();
 
-    if !t.is_object_safe(cx.tcx()) {
+    if !t.is_dyn_compatible(cx.tcx()) {
+        // FIXME(dyn_compat_renaming): Update the URL once the Reference is updated.
         write_section_heading(
             w,
-            "Object Safety",
-            "object-safety",
+            "Dyn Compatibility",
+            "dyn-compatibility",
             None,
             &format!(
-                "<div class=\"object-safety-info\">This trait is <b>not</b> \
-                <a href=\"{base}/reference/items/traits.html#object-safety\">\
-                object safe</a>.</div>",
+                "<div class=\"dyn-compatibility-info\"><p>This trait is <b>not</b> \
+                <a href=\"{base}/reference/items/traits.html#object-safety\">dyn compatible</a>.</p>\
+                <p><i>In older versions of Rust, dyn compatibility was called \"object safety\", \
+                so this trait is not object safe.</i></p></div>",
                 base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
             ),
         );
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index e7706e7fdeaec..6df9486e65809 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -315,10 +315,10 @@ fn sidebar_trait<'a>(
     );
     sidebar_assoc_items(cx, it, blocks);
 
-    if !t.is_object_safe(cx.tcx()) {
+    if !t.is_dyn_compatible(cx.tcx()) {
         blocks.push(LinkBlock::forced(
-            Link::new("object-safety", "Object Safety"),
-            "object-safety-note",
+            Link::new("dyn-compatibility", "Dyn Compatibility"),
+            "dyn-compatibility-note",
         ));
     }
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index b8791c9918b12..77e7d83090b94 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -672,7 +672,7 @@ impl FromClean<clean::Trait> for Trait {
         let tcx = renderer.tcx;
         let is_auto = trait_.is_auto(tcx);
         let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe;
-        let is_object_safe = trait_.is_object_safe(tcx);
+        let is_object_safe = trait_.is_dyn_compatible(tcx);
         let clean::Trait { items, generics, bounds, .. } = trait_;
         Trait {
             is_auto,
diff --git a/tests/rustdoc/dyn-compatibility.rs b/tests/rustdoc/dyn-compatibility.rs
new file mode 100644
index 0000000000000..9115f93bc3bac
--- /dev/null
+++ b/tests/rustdoc/dyn-compatibility.rs
@@ -0,0 +1,27 @@
+#![crate_name = "foo"]
+
+//@ has 'foo/trait.DynIncompatible.html'
+//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.'
+//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility'
+pub trait DynIncompatible {
+    fn foo() -> Self;
+}
+
+//@ has 'foo/trait.DynIncompatible2.html'
+//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.'
+//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility'
+pub trait DynIncompatible2<T> {
+    fn foo(i: T);
+}
+
+//@ has 'foo/trait.DynCompatible.html'
+//@ !has - '//*[@class="dyn-compatibility-info"]' ''
+//@ !has - '//*[@id="dyn-compatibility"]' ''
+pub trait DynCompatible {
+    fn foo(&self);
+}
+
+//@ has 'foo/struct.Foo.html'
+//@ count - '//*[@class="dyn-compatibility-info"]' 0
+//@ count - '//*[@id="dyn-compatibility"]' 0
+pub struct Foo;
diff --git a/tests/rustdoc/sidebar/sidebar-items.rs b/tests/rustdoc/sidebar/sidebar-items.rs
index f3812143a7da6..57c2eee91a92a 100644
--- a/tests/rustdoc/sidebar/sidebar-items.rs
+++ b/tests/rustdoc/sidebar/sidebar-items.rs
@@ -14,7 +14,7 @@
 //@ has - '//*[@class="sidebar-elems"]//section//a' 'Output'
 //@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
 //@ has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
-//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
+//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#dyn-compatibility"]' 'Dyn Compatibility'
 pub trait Foo {
     const FOO: usize;
     const BAR: u32 = 0;
@@ -25,9 +25,9 @@ pub trait Foo {
     fn bar() -> Self::Output;
 }
 
-//@ has foo/trait.Safe.html
+//@ has foo/trait.DynCompatible.html
 //@ !has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
-pub trait Safe {
+pub trait DynCompatible {
     fn access(&self);
 }
 
diff --git a/tests/rustdoc/trait-object-safe.rs b/tests/rustdoc/trait-object-safe.rs
deleted file mode 100644
index b4e986c8f69cd..0000000000000
--- a/tests/rustdoc/trait-object-safe.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-#![crate_name = "foo"]
-
-//@ has 'foo/trait.Unsafe.html'
-//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
-//@ has - '//*[@id="object-safety"]' 'Object Safety'
-pub trait Unsafe {
-    fn foo() -> Self;
-}
-
-//@ has 'foo/trait.Unsafe2.html'
-//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
-//@ has - '//*[@id="object-safety"]' 'Object Safety'
-pub trait Unsafe2<T> {
-    fn foo(i: T);
-}
-
-//@ has 'foo/trait.Safe.html'
-//@ !has - '//*[@class="object-safety-info"]' ''
-//@ !has - '//*[@id="object-safety"]' ''
-pub trait Safe {
-    fn foo(&self);
-}
-
-//@ has 'foo/struct.Foo.html'
-//@ count - '//*[@class="object-safety-info"]' 0
-//@ count - '//*[@id="object-safety"]' 0
-pub struct Foo;

From 8991fd4bed6583757c5df3f37b7c17fd58963f09 Mon Sep 17 00:00:00 2001
From: Charles Celerier <chcl@google.com>
Date: Tue, 15 Oct 2024 15:47:10 -0400
Subject: [PATCH 17/18] Ignore lint-non-snake-case-crate#proc_macro_ on targets
 without unwind

The lint-non-snake-case-crate test may emit a warning in stderr if the
target does not support unwinding

```
warning: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
```

Consequently, the test will fail on targets that don't support unwinding
as written.

This change prevents lint-non-snake-case-crate#proc_macro_ from running
on targets that don't support unwind by using the needs-unwind
directive.
---
 .../non-snake-case/lint-non-snake-case-crate.cdylib_.stderr   | 4 ++--
 .../non-snake-case/lint-non-snake-case-crate.dylib_.stderr    | 4 ++--
 .../lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr | 4 ++--
 .../lint-non-snake-case-crate.proc_macro_.stderr              | 4 ++--
 .../non-snake-case/lint-non-snake-case-crate.rlib_.stderr     | 4 ++--
 tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs     | 4 ++++
 .../lint-non-snake-case-crate.staticlib_.stderr               | 4 ++--
 7 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
index 57604d99a07b1..097b246c16502 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs
@@ -22,6 +22,10 @@
 //@[rlib_] compile-flags: --crate-type=rlib
 //@[staticlib_] compile-flags: --crate-type=staticlib
 
+// The compiler may emit a warning that causes stderr output
+// that contains a warning this test does not wish to check.
+//@[proc_macro_] needs-unwind
+
 #![crate_name = "NonSnakeCase"]
 //[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name
 #![deny(non_snake_case)]
diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
index 9bccb270627d8..140d72b974219 100644
--- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
+++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
-  --> $DIR/lint-non-snake-case-crate.rs:25:18
+  --> $DIR/lint-non-snake-case-crate.rs:29:18
    |
 LL | #![crate_name = "NonSnakeCase"]
    |                  ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
    |
 note: the lint level is defined here
-  --> $DIR/lint-non-snake-case-crate.rs:27:9
+  --> $DIR/lint-non-snake-case-crate.rs:31:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^

From 682bca30ccbfe1dc94e8c1abbd458d7f7be18077 Mon Sep 17 00:00:00 2001
From: dufucun <dufuchun@sohu.com>
Date: Thu, 17 Oct 2024 00:16:19 +0800
Subject: [PATCH 18/18] Fix mismatched quotation mark

---
 tests/ui/mir/mir-inlining/always-encode-mirs.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/ui/mir/mir-inlining/always-encode-mirs.rs b/tests/ui/mir/mir-inlining/always-encode-mirs.rs
index 9029ff6499b07..4553560baaa64 100644
--- a/tests/ui/mir/mir-inlining/always-encode-mirs.rs
+++ b/tests/ui/mir/mir-inlining/always-encode-mirs.rs
@@ -1,6 +1,6 @@
 // Regression test for MIR inlining with -Zalways-encode-mir enabled in the auxiliary crate.
 // Previously we inlined function not eligible for inlining which lead to linking error:
-// undefined reference to `internal::S'
+// undefined reference to `internal::S`
 //
 //@ aux-build:internal.rs
 //@ build-pass