From cf34545720986d99712e3b542e8f395360c75095 Mon Sep 17 00:00:00 2001
From: Alan Somers <asomers@gmail.com>
Date: Sun, 27 Oct 2024 11:55:20 -0600
Subject: [PATCH 1/8] CI: build FreeBSD artifacts on FreeBSD 13.4

13.2 is EoL, and 13.3 will be EoL too in about 2 months.  Plus, both
suffer from a bug in LLVM's libunwind.  It causes a segfault inside of
std::backtrace::Backtrace::capture().

Fixes #132185
---
 src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile | 6 +++---
 src/ci/docker/scripts/freebsd-toolchain.sh               | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
index f42e6f770ebe8..fd0f5da8c495a 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -29,9 +29,9 @@ COPY scripts/cmake.sh /scripts/
 RUN /scripts/cmake.sh
 
 ENV \
-    AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-ar \
-    CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang \
-    CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang++
+    AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-ar \
+    CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang \
+    CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd13-clang++
 
 ENV HOSTS=x86_64-unknown-freebsd
 
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 0d02636db9196..b927658b4fdc2 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -5,8 +5,8 @@ set -eux
 
 arch=$1
 binutils_version=2.40
-freebsd_version=12.3
-triple=$arch-unknown-freebsd12
+freebsd_version=13.4
+triple=$arch-unknown-freebsd13
 sysroot=/usr/local/$triple
 
 hide_output() {
@@ -59,7 +59,7 @@ done
 
 # Originally downloaded from:
 # URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz
-URL=https://ci-mirrors.rust-lang.org/rustc/2022-05-06-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
+URL=https://ci-mirrors.rust-lang.org/rustc/2024-09-13-freebsd-${freebsd_version}-${freebsd_arch}-base.txz
 curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}"
 
 # Clang can do cross-builds out of the box, if we give it the right

From 0454d7903b4e5508e5169efdb28e4fa94d2dc64a Mon Sep 17 00:00:00 2001
From: Alan Somers <asomers@gmail.com>
Date: Sun, 12 Jan 2025 14:27:56 -0700
Subject: [PATCH 2/8] Fixup: fix clang command lines in another file

---
 src/ci/docker/host-x86_64/dist-various-2/Dockerfile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index ece5f174d06de..8aabfaafbabbc 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -56,9 +56,9 @@ ENV \
     CFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
     CXX_x86_64_fortanix_unknown_sgx=clang++-11 \
     CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
-    AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \
-    CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \
-    CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \
+    AR_i686_unknown_freebsd=i686-unknown-freebsd13-ar \
+    CC_i686_unknown_freebsd=i686-unknown-freebsd13-clang \
+    CXX_i686_unknown_freebsd=i686-unknown-freebsd13-clang++ \
     CC_aarch64_unknown_uefi=clang-11 \
     CXX_aarch64_unknown_uefi=clang++-11 \
     CC_i686_unknown_uefi=clang-11 \

From b2b12ae0cb6c7e6dd71092aafa14e06b57a290ec Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 19 Jan 2025 16:15:00 -0800
Subject: [PATCH 3/8] Add an example of using `carrying_mul_add` to write wider
 multiplication

Just the basic quadratic version that you wouldn't actually want for a true bigint, but it's nice and short so is useful as an example :)
---
 library/core/src/num/uint_macros.rs | 33 +++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 404e4bcffd379..c8433b3bb168a 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2663,8 +2663,8 @@ macro_rules! uint_impl {
         ///
         /// Basic usage:
         ///
-        /// Please note that this example is shared between integer types.
-        /// Which explains why `u32` is used here.
+        /// Please note that this example is shared between integer types,
+        /// which explains why `u32` is used here.
         ///
         /// ```
         /// #![feature(bigint_helper_methods)]
@@ -2677,6 +2677,35 @@ macro_rules! uint_impl {
             "(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX));"
         )]
         /// ```
+        ///
+        /// This is the core per-digit operation for "grade school" O(n²) multiplication.
+        ///
+        /// Please note that this example is shared between integer types,
+        /// using `u8` for simplicity of the demonstration.
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        ///
+        /// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
+        ///     let mut out = [0; N];
+        ///     for j in 0..N {
+        ///         let mut carry = 0;
+        ///         for i in 0..(N - j) {
+        ///             (out[j + i], carry) = u8::carrying_mul_add(a[i], b[j], out[j + i], carry);
+        ///         }
+        ///     }
+        ///     out
+        /// }
+        ///
+        /// // -1 * -1 == 1
+        /// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
+        ///
+        /// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D);
+        /// assert_eq!(
+        ///     quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
+        ///     u32::to_le_bytes(0xCFFC982D)
+        /// );
+        /// ```
         #[unstable(feature = "bigint_helper_methods", issue = "85532")]
         #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
         #[must_use = "this returns the result of the operation, \

From 9d88b82b99cdd43c79e5fb5d031e522347863db2 Mon Sep 17 00:00:00 2001
From: jyn <github@jyn.dev>
Date: Mon, 20 Jan 2025 16:08:08 -0500
Subject: [PATCH 4/8] Ignore `mermaid.min.js`

It is very long and tends to match a lot of search queries. It's not useful to show with ripgrep.

Note that this does not actually untrack the file; changes can still be committed (although I suspect it may not have been intentional to commit originally?). This just changes how it interacts with tools that use `.gitignore` as a default filter.
---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index f84a3704ca900..ddc8dad95e809 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,6 +83,7 @@ __pycache__/
 node_modules
 package-lock.json
 package.json
+/src/doc/rustc-dev-guide/mermaid.min.js
 
 ## Rustdoc GUI tests
 tests/rustdoc-gui/src/**.lock

From 51af4d6d228490bb97cc53f9eea50647e0443513 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= <berykubik@gmail.com>
Date: Tue, 21 Jan 2025 10:23:14 +0100
Subject: [PATCH 5/8] Add Kobzol on vacation

---
 triagebot.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/triagebot.toml b/triagebot.toml
index 5ee52bbf435c9..4a09fe116a572 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1025,6 +1025,7 @@ users_on_vacation = [
     "nnethercote",
     "spastorino",
     "workingjubilee",
+    "kobzol"
 ]
 
 [[assign.warn_non_default_branch.exceptions]]

From fdc80af5c5ef65159d086e55a21419ead24a3c21 Mon Sep 17 00:00:00 2001
From: Marijn Schouten <hkBst@users.noreply.github.com>
Date: Tue, 21 Jan 2025 14:36:18 +0100
Subject: [PATCH 6/8] fix OsString::from_encoded_bytes_unchecked description

---
 library/std/src/ffi/os_str.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 7fb57d410431e..c4c8dbccd7a44 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -203,8 +203,8 @@ impl OsString {
         self
     }
 
-    /// Converts the `OsString` into a byte slice.  To convert the byte slice back into an
-    /// `OsString`, use the [`OsStr::from_encoded_bytes_unchecked`] function.
+    /// Converts the `OsString` into a byte vector.  To convert the byte vector back into an
+    /// `OsString`, use the [`OsString::from_encoded_bytes_unchecked`] function.
     ///
     /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
     /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit

From a0a061d782f221c06a5e8ef0b34c4406431ca85f Mon Sep 17 00:00:00 2001
From: Boxy <rust@boxyuwu.dev>
Date: Tue, 21 Jan 2025 11:10:02 +0000
Subject: [PATCH 7/8] Use `structurally_normalize` instead of manual
 `normalizes-to` goals

---
 .../rustc_next_trait_solver/src/solve/mod.rs  | 42 +++++------
 .../traits/fulfillment_errors.rs              | 21 +++---
 .../src/traits/engine.rs                      | 11 +++
 .../src/traits/structural_normalize.rs        | 71 +++++++------------
 src/tools/tidy/src/ui_tests.rs                |  2 +-
 ...not-fn.stderr => is-not-fn.current.stderr} |  8 +--
 .../async-closures/is-not-fn.next.stderr      | 19 +++++
 .../async-await/async-closures/is-not-fn.rs   |  5 +-
 ...stituting-in-region-112823.current.stderr} |  6 +-
 ...nsubstituting-in-region-112823.next.stderr | 29 ++++++++
 ...-type-whensubstituting-in-region-112823.rs |  8 ++-
 ...3941.stderr => issue-33941.current.stderr} |  6 +-
 tests/ui/issues/issue-33941.next.stderr       | 25 +++++++
 tests/ui/issues/issue-33941.rs                |  6 +-
 ...rg-type-mismatch-issue-45727.current.fixed | 12 ++++
 ...-type-mismatch-issue-45727.current.stderr} |  4 +-
 ...losure-arg-type-mismatch-issue-45727.fixed |  5 --
 ...-arg-type-mismatch-issue-45727.next.stderr | 24 +++++++
 .../closure-arg-type-mismatch-issue-45727.rs  | 13 +++-
 ...elate_error_uses_structurally_normalize.rs | 28 ++++++++
 ...e_error_uses_structurally_normalize.stderr | 17 +++++
 21 files changed, 254 insertions(+), 108 deletions(-)
 rename tests/ui/async-await/async-closures/{is-not-fn.stderr => is-not-fn.current.stderr} (77%)
 create mode 100644 tests/ui/async-await/async-closures/is-not-fn.next.stderr
 rename tests/ui/impl-trait/{ice-unexpected-param-type-whensubstituting-in-region-112823.stderr => ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr} (96%)
 create mode 100644 tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
 rename tests/ui/issues/{issue-33941.stderr => issue-33941.current.stderr} (93%)
 create mode 100644 tests/ui/issues/issue-33941.next.stderr
 create mode 100644 tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
 rename tests/ui/mismatched_types/{closure-arg-type-mismatch-issue-45727.stderr => closure-arg-type-mismatch-issue-45727.current.stderr} (92%)
 delete mode 100644 tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed
 create mode 100644 tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
 create mode 100644 tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs
 create mode 100644 tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.stderr

diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 37678bfd8805f..8d1194ee53980 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -277,23 +277,7 @@ where
         param_env: I::ParamEnv,
         ty: I::Ty,
     ) -> Result<I::Ty, NoSolution> {
-        if let ty::Alias(..) = ty.kind() {
-            let normalized_ty = self.next_ty_infer();
-            let alias_relate_goal = Goal::new(
-                self.cx(),
-                param_env,
-                ty::PredicateKind::AliasRelate(
-                    ty.into(),
-                    normalized_ty.into(),
-                    ty::AliasRelationDirection::Equate,
-                ),
-            );
-            self.add_goal(GoalSource::Misc, alias_relate_goal);
-            self.try_evaluate_added_goals()?;
-            Ok(self.resolve_vars_if_possible(normalized_ty))
-        } else {
-            Ok(ty)
-        }
+        self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty())
     }
 
     /// Normalize a const for when it is structurally matched on, or more likely
@@ -308,22 +292,34 @@ where
         param_env: I::ParamEnv,
         ct: I::Const,
     ) -> Result<I::Const, NoSolution> {
-        if let ty::ConstKind::Unevaluated(..) = ct.kind() {
-            let normalized_ct = self.next_const_infer();
+        self.structurally_normalize_term(param_env, ct.into()).map(|term| term.expect_const())
+    }
+
+    /// Normalize a term for when it is structurally matched on.
+    ///
+    /// This function is necessary in nearly all cases before matching on a ty/const.
+    /// Not doing so is likely to be incomplete and therefore unsound during coherence.
+    fn structurally_normalize_term(
+        &mut self,
+        param_env: I::ParamEnv,
+        term: I::Term,
+    ) -> Result<I::Term, NoSolution> {
+        if let Some(_) = term.to_alias_term() {
+            let normalized_term = self.next_term_infer_of_kind(term);
             let alias_relate_goal = Goal::new(
                 self.cx(),
                 param_env,
                 ty::PredicateKind::AliasRelate(
-                    ct.into(),
-                    normalized_ct.into(),
+                    term,
+                    normalized_term,
                     ty::AliasRelationDirection::Equate,
                 ),
             );
             self.add_goal(GoalSource::Misc, alias_relate_goal);
             self.try_evaluate_added_goals()?;
-            Ok(self.resolve_vars_if_possible(normalized_ct))
+            Ok(self.resolve_vars_if_possible(normalized_term))
         } else {
-            Ok(ct)
+            Ok(term)
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index c40ba33084569..bcd3b0109b709 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1338,20 +1338,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     let derive_better_type_error =
                         |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {
                             let ocx = ObligationCtxt::new(self);
-                            let normalized_term = match expected_term.unpack() {
-                                ty::TermKind::Ty(_) => self.next_ty_var(DUMMY_SP).into(),
-                                ty::TermKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
-                            };
-                            ocx.register_obligation(Obligation::new(
-                                self.tcx,
-                                ObligationCause::dummy(),
+
+                            let Ok(normalized_term) = ocx.structurally_normalize_term(
+                                &ObligationCause::dummy(),
                                 obligation.param_env,
-                                ty::PredicateKind::NormalizesTo(ty::NormalizesTo {
-                                    alias: alias_term,
-                                    term: normalized_term,
-                                }),
-                            ));
-                            let _ = ocx.select_where_possible();
+                                alias_term.to_term(self.tcx),
+                            ) else {
+                                return None;
+                            };
+
                             if let Err(terr) = ocx.eq(
                                 &ObligationCause::dummy(),
                                 obligation.param_env,
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 5e270b62b0081..48b26ee19d4dc 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -340,4 +340,15 @@ where
             .at(cause, param_env)
             .structurally_normalize_const(value, &mut **self.engine.borrow_mut())
     }
+
+    pub fn structurally_normalize_term(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        value: ty::Term<'tcx>,
+    ) -> Result<ty::Term<'tcx>, Vec<E>> {
+        self.infcx
+            .at(cause, param_env)
+            .structurally_normalize_term(value, &mut **self.engine.borrow_mut())
+    }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index f8e8f2176c182..458791df66fd6 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -12,39 +12,7 @@ impl<'tcx> At<'_, 'tcx> {
         ty: Ty<'tcx>,
         fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
     ) -> Result<Ty<'tcx>, Vec<E>> {
-        assert!(!ty.is_ty_var(), "should have resolved vars before calling");
-
-        if self.infcx.next_trait_solver() {
-            let ty::Alias(..) = *ty.kind() else {
-                return Ok(ty);
-            };
-
-            let new_infer_ty = self.infcx.next_ty_var(self.cause.span);
-
-            // We simply emit an `alias-eq` goal here, since that will take care of
-            // normalizing the LHS of the projection until it is a rigid projection
-            // (or a not-yet-defined opaque in scope).
-            let obligation = Obligation::new(
-                self.infcx.tcx,
-                self.cause.clone(),
-                self.param_env,
-                ty::PredicateKind::AliasRelate(
-                    ty.into(),
-                    new_infer_ty.into(),
-                    ty::AliasRelationDirection::Equate,
-                ),
-            );
-
-            fulfill_cx.register_predicate_obligation(self.infcx, obligation);
-            let errors = fulfill_cx.select_where_possible(self.infcx);
-            if !errors.is_empty() {
-                return Err(errors);
-            }
-
-            Ok(self.infcx.resolve_vars_if_possible(new_infer_ty))
-        } else {
-            Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx))
-        }
+        self.structurally_normalize_term(ty.into(), fulfill_cx).map(|term| term.expect_type())
     }
 
     fn structurally_normalize_const<E: 'tcx>(
@@ -52,14 +20,29 @@ impl<'tcx> At<'_, 'tcx> {
         ct: ty::Const<'tcx>,
         fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
     ) -> Result<ty::Const<'tcx>, Vec<E>> {
-        assert!(!ct.is_ct_infer(), "should have resolved vars before calling");
+        if self.infcx.tcx.features().generic_const_exprs() {
+            return Ok(super::evaluate_const(&self.infcx, ct, self.param_env));
+        }
+
+        self.structurally_normalize_term(ct.into(), fulfill_cx).map(|term| term.expect_const())
+    }
+
+    fn structurally_normalize_term<E: 'tcx>(
+        &self,
+        term: ty::Term<'tcx>,
+        fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
+    ) -> Result<ty::Term<'tcx>, Vec<E>> {
+        assert!(!term.is_infer(), "should have resolved vars before calling");
 
         if self.infcx.next_trait_solver() {
-            let ty::ConstKind::Unevaluated(..) = ct.kind() else {
-                return Ok(ct);
-            };
+            if let None = term.to_alias_term() {
+                return Ok(term);
+            }
 
-            let new_infer_ct = self.infcx.next_const_var(self.cause.span);
+            let new_infer = match term.unpack() {
+                ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
+                ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
+            };
 
             // We simply emit an `alias-eq` goal here, since that will take care of
             // normalizing the LHS of the projection until it is a rigid projection
@@ -68,11 +51,7 @@ impl<'tcx> At<'_, 'tcx> {
                 self.infcx.tcx,
                 self.cause.clone(),
                 self.param_env,
-                ty::PredicateKind::AliasRelate(
-                    ct.into(),
-                    new_infer_ct.into(),
-                    ty::AliasRelationDirection::Equate,
-                ),
+                ty::PredicateKind::AliasRelate(term, new_infer, ty::AliasRelationDirection::Equate),
             );
 
             fulfill_cx.register_predicate_obligation(self.infcx, obligation);
@@ -81,11 +60,9 @@ impl<'tcx> At<'_, 'tcx> {
                 return Err(errors);
             }
 
-            Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
-        } else if self.infcx.tcx.features().generic_const_exprs() {
-            Ok(super::evaluate_const(&self.infcx, ct, self.param_env))
+            Ok(self.infcx.resolve_vars_if_possible(new_infer))
         } else {
-            Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
+            Ok(self.normalize(term).into_value_registering_obligations(self.infcx, fulfill_cx))
         }
     }
 }
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 401169c838f71..7c1b16dc7143b 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use ignore::Walk;
 const ENTRY_LIMIT: u32 = 901;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1667;
+const ISSUES_ENTRY_LIMIT: u32 = 1668;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/ui/async-await/async-closures/is-not-fn.stderr b/tests/ui/async-await/async-closures/is-not-fn.current.stderr
similarity index 77%
rename from tests/ui/async-await/async-closures/is-not-fn.stderr
rename to tests/ui/async-await/async-closures/is-not-fn.current.stderr
index bc1d5e6e9d112..e7be1d5b10efe 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.stderr
+++ b/tests/ui/async-await/async-closures/is-not-fn.current.stderr
@@ -1,5 +1,5 @@
-error[E0271]: expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
-  --> $DIR/is-not-fn.rs:5:14
+error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
+  --> $DIR/is-not-fn.rs:8:14
    |
 LL |     needs_fn(async || {});
    |     -------- ^^^^^^^^^^^ expected `()`, found `async` closure body
@@ -7,9 +7,9 @@ LL |     needs_fn(async || {});
    |     required by a bound introduced by this call
    |
    = note:         expected unit type `()`
-           found `async` closure body `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
+           found `async` closure body `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
 note: required by a bound in `needs_fn`
-  --> $DIR/is-not-fn.rs:4:25
+  --> $DIR/is-not-fn.rs:7:25
    |
 LL |     fn needs_fn(x: impl FnOnce()) {}
    |                         ^^^^^^^^ required by this bound in `needs_fn`
diff --git a/tests/ui/async-await/async-closures/is-not-fn.next.stderr b/tests/ui/async-await/async-closures/is-not-fn.next.stderr
new file mode 100644
index 0000000000000..e7be1d5b10efe
--- /dev/null
+++ b/tests/ui/async-await/async-closures/is-not-fn.next.stderr
@@ -0,0 +1,19 @@
+error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
+  --> $DIR/is-not-fn.rs:8:14
+   |
+LL |     needs_fn(async || {});
+   |     -------- ^^^^^^^^^^^ expected `()`, found `async` closure body
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note:         expected unit type `()`
+           found `async` closure body `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}`
+note: required by a bound in `needs_fn`
+  --> $DIR/is-not-fn.rs:7:25
+   |
+LL |     fn needs_fn(x: impl FnOnce()) {}
+   |                         ^^^^^^^^ required by this bound in `needs_fn`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs
index 4acaa5d9809a1..eacd07b7cdd86 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.rs
+++ b/tests/ui/async-await/async-closures/is-not-fn.rs
@@ -1,7 +1,10 @@
 //@ edition:2021
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 
 fn main() {
     fn needs_fn(x: impl FnOnce()) {}
     needs_fn(async || {});
-    //~^ ERROR expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`
+    //~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to be a closure that returns `()`
 }
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
similarity index 96%
rename from tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.stderr
rename to tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
index 28a0f7461e2d5..146a3d21068cd 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.stderr
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
@@ -1,11 +1,11 @@
 error[E0407]: method `line_stream` is not a member of trait `X`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:5
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
 
 error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:22:21
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
    |
 LL |     type LineStream<'a, Repr>
    |                     --  ----
@@ -18,7 +18,7 @@ LL |     type LineStream<'c, 'd> = impl Stream;
    |                     found 0 type parameters
 
 error[E0277]: `()` is not a future
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:43
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
new file mode 100644
index 0000000000000..3c24eb9adbee7
--- /dev/null
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
@@ -0,0 +1,29 @@
+error[E0407]: method `line_stream` is not a member of trait `X`
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
+   |
+LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
+
+error[E0049]: type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:21
+   |
+LL |     type LineStream<'a, Repr>
+   |                     --  ----
+   |                     |
+   |                     expected 1 type parameter
+...
+LL |     type LineStream<'c, 'd> = impl Stream;
+   |                     ^^  ^^
+   |                     |
+   |                     found 0 type parameters
+
+error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43
+   |
+LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0049, E0271, E0407.
+For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
index d6fa56663a3f0..c97bd1799436f 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
@@ -1,3 +1,6 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 // test for ICE #112823
 // Unexpected parameter Type(Repr) when substituting in region
 
@@ -23,8 +26,9 @@ impl X for Y {
     //~^ ERROR type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
     type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
-    //~^ ERROR `()` is not a future
-    //~^^ method `line_stream` is not a member of trait `X`
+    //[current]~^ ERROR `()` is not a future
+    //[next]~^^ ERROR type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
+    //~^^^ method `line_stream` is not a member of trait `X`
 }
 
 pub fn main() {}
diff --git a/tests/ui/issues/issue-33941.stderr b/tests/ui/issues/issue-33941.current.stderr
similarity index 93%
rename from tests/ui/issues/issue-33941.stderr
rename to tests/ui/issues/issue-33941.current.stderr
index 9535ea57430d0..d653bbd327427 100644
--- a/tests/ui/issues/issue-33941.stderr
+++ b/tests/ui/issues/issue-33941.current.stderr
@@ -1,5 +1,5 @@
 error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-  --> $DIR/issue-33941.rs:6:36
+  --> $DIR/issue-33941.rs:9:36
    |
 LL |     for _ in HashMap::new().iter().cloned() {}
    |                                    ^^^^^^ expected `&_`, found `(&_, &_)`
@@ -7,7 +7,7 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    = note: expected reference `&_`
                   found tuple `(&_, &_)`
 note: the method call chain might not have had the expected associated types
-  --> $DIR/issue-33941.rs:6:29
+  --> $DIR/issue-33941.rs:9:29
    |
 LL |     for _ in HashMap::new().iter().cloned() {}
    |              -------------- ^^^^^^ `Iterator::Item` is `(&_, &_)` here
@@ -17,7 +17,7 @@ note: required by a bound in `cloned`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
 error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-  --> $DIR/issue-33941.rs:6:14
+  --> $DIR/issue-33941.rs:9:14
    |
 LL |     for _ in HashMap::new().iter().cloned() {}
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)`
diff --git a/tests/ui/issues/issue-33941.next.stderr b/tests/ui/issues/issue-33941.next.stderr
new file mode 100644
index 0000000000000..a5a6e51545a58
--- /dev/null
+++ b/tests/ui/issues/issue-33941.next.stderr
@@ -0,0 +1,25 @@
+error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+  --> $DIR/issue-33941.rs:9:36
+   |
+LL |     for _ in HashMap::new().iter().cloned() {}
+   |                                    ^^^^^^ expected `&_`, found `(&_, &_)`
+   |
+   = note: expected reference `&_`
+                  found tuple `(&_, &_)`
+note: required by a bound in `cloned`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+  --> $DIR/issue-33941.rs:9:14
+   |
+LL |     for _ in HashMap::new().iter().cloned() {}
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)`
+   |
+   = note: expected reference `&_`
+                  found tuple `(&_, &_)`
+   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
+   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/issues/issue-33941.rs
index 7b5be30834b9d..b0736204a0811 100644
--- a/tests/ui/issues/issue-33941.rs
+++ b/tests/ui/issues/issue-33941.rs
@@ -1,8 +1,12 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 //@ compile-flags: -Zdeduplicate-diagnostics=yes
 
 use std::collections::HashMap;
 
 fn main() {
-    for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+    for _ in HashMap::new().iter().cloned() {}
     //~^ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
+    //~| ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
 }
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
new file mode 100644
index 0000000000000..7383ab177dc31
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.fixed
@@ -0,0 +1,12 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@[current] run-rustfix
+fn main() {
+    let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
+    //[current]~^ ERROR type mismatch in closure arguments
+    //[next]~^^ ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
+    //[current]~^ ERROR type mismatch in closure arguments
+    //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
+}
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.stderr
similarity index 92%
rename from tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr
rename to tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.stderr
index e52e095e9f729..c35d70a635cbd 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.current.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:3:24
+  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:6:24
    |
 LL |     let _ = (-10..=10).find(|x: i32| x.signum() == 0);
    |                        ^^^^ -------- found signature defined here
@@ -16,7 +16,7 @@ LL |     let _ = (-10..=10).find(|x: &i32| x.signum() == 0);
    |                                 +
 
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:4:24
+  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:24
    |
 LL |     let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
    |                        ^^^^ ----------- found signature defined here
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed
deleted file mode 100644
index e6e3e1551e959..0000000000000
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ run-rustfix
-fn main() {
-    let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
-    let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
-}
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
new file mode 100644
index 0000000000000..6104a08933737
--- /dev/null
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.next.stderr
@@ -0,0 +1,24 @@
+error[E0277]: expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:6:29
+   |
+LL |     let _ = (-10..=10).find(|x: i32| x.signum() == 0);
+   |                        ---- ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+   |                        |
+   |                        required by a bound introduced by this call
+   |
+   = help: the trait `for<'a> FnMut(&'a <RangeInclusive<{integer}> as Iterator>::Item)` is not implemented for closure `{closure@$DIR/closure-arg-type-mismatch-issue-45727.rs:6:29: 6:37}`
+   = note: expected a closure with arguments `(i32,)`
+              found a closure with arguments `(&<RangeInclusive<{integer}> as Iterator>::Item,)`
+note: required by a bound in `find`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error[E0271]: expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
+  --> $DIR/closure-arg-type-mismatch-issue-45727.rs:9:33
+   |
+LL |     let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
+   |                                 ^^^^^^ expected `&&i32`, found integer
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
index 64e815606d427..668a1a7a29c6f 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs
@@ -1,5 +1,12 @@
-//@ run-rustfix
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@[current] run-rustfix
 fn main() {
-    let _ = (-10..=10).find(|x: i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
-    let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments
+    let _ = (-10..=10).find(|x: i32| x.signum() == 0);
+    //[current]~^ ERROR type mismatch in closure arguments
+    //[next]~^^ ERROR expected a `FnMut(&<RangeInclusive<{integer}> as Iterator>::Item)` closure, found
+    let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
+    //[current]~^ ERROR type mismatch in closure arguments
+    //[next]~^^ ERROR expected `RangeInclusive<{integer}>` to be an iterator that yields `&&i32`, but it yields `{integer}`
 }
diff --git a/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs b/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs
new file mode 100644
index 0000000000000..5cea9bb74d793
--- /dev/null
+++ b/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs
@@ -0,0 +1,28 @@
+//@ compile-flags: -Znext-solver
+
+// When encountering a fulfillment error from an `alias-relate` goal failing, we
+// would previously manually construct a `normalizes-to` goal involving the alias
+// and an infer var. This would then ICE as normalization would return a nested
+// goal (the `T: Sized` from the `Trait` impl for `Foo<T>` below) from the root goal
+// which is not supported.
+
+struct Foo<T>(T);
+
+trait Trait {
+    type Assoc;
+}
+
+// `T: Sized` being explicit is not required, but the bound being present *is*.
+impl<T: Sized> Trait for Foo<T> {
+    type Assoc = u64;
+}
+
+fn bar<T: Trait<Assoc = u32>>(_: T) {}
+
+fn main() {
+    let foo = Foo(Default::default());
+    bar(foo);
+    //~^ ERROR: type mismatch resolving `<Foo<_> as Trait>::Assoc == u32`
+    // Here diagnostics would manually construct a `<Foo<?y> as Trait>::Assoc normalizes-to ?x` goal
+    // which would return a nested goal of `?y: Sized` from the impl.
+}
diff --git a/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.stderr b/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.stderr
new file mode 100644
index 0000000000000..ff3cbdb2c7841
--- /dev/null
+++ b/tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.stderr
@@ -0,0 +1,17 @@
+error[E0271]: type mismatch resolving `<Foo<_> as Trait>::Assoc == u32`
+  --> $DIR/alias_relate_error_uses_structurally_normalize.rs:24:9
+   |
+LL |     bar(foo);
+   |     --- ^^^ expected `u32`, found `u64`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `bar`
+  --> $DIR/alias_relate_error_uses_structurally_normalize.rs:20:17
+   |
+LL | fn bar<T: Trait<Assoc = u32>>(_: T) {}
+   |                 ^^^^^^^^^^^ required by this bound in `bar`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.

From d6c42a831c4ebe5fa5c70d1a64ac0ada83ba88b0 Mon Sep 17 00:00:00 2001
From: Boxy <rust@boxyuwu.dev>
Date: Tue, 21 Jan 2025 11:22:30 +0000
Subject: [PATCH 8/8] Rename `structurally_normalize` to
 `structurally_normalize_ty`

---
 compiler/rustc_borrowck/src/type_check/canonical.rs       | 4 ++--
 compiler/rustc_hir_analysis/src/autoderef.rs              | 8 ++++----
 compiler/rustc_hir_analysis/src/coherence/orphan.rs       | 2 +-
 compiler/rustc_hir_typeck/src/coercion.rs                 | 2 +-
 compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs            | 2 +-
 compiler/rustc_trait_selection/src/traits/coherence.rs    | 2 +-
 compiler/rustc_trait_selection/src/traits/engine.rs       | 4 ++--
 .../src/traits/structural_normalize.rs                    | 2 +-
 8 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index 3903c45fda529..bffd9f383343d 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -185,7 +185,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 CustomTypeOp::new(
                     |ocx| {
                         let structurally_normalize = |ty| {
-                            ocx.structurally_normalize(
+                            ocx.structurally_normalize_ty(
                                 &ObligationCause::misc(
                                     location.to_locations().span(body),
                                     body.source.def_id().expect_local(),
@@ -230,7 +230,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 ConstraintCategory::Boring,
                 CustomTypeOp::new(
                     |ocx| {
-                        ocx.structurally_normalize(
+                        ocx.structurally_normalize_ty(
                             &ObligationCause::misc(
                                 location.to_locations().span(body),
                                 body.source.def_id().expect_local(),
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index d8e9227a87c86..b3eade8c8ae47 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -86,7 +86,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
                 if self.infcx.next_trait_solver()
                     && let ty::Alias(..) = ty.kind()
                 {
-                    let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
+                    let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?;
                     self.state.obligations.extend(obligations);
                     (AutoderefKind::Builtin, normalized_ty)
                 } else {
@@ -166,7 +166,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
         }
 
         let (normalized_ty, obligations) =
-            self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
+            self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
         debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
         self.state.obligations.extend(obligations);
 
@@ -174,12 +174,12 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self), ret)]
-    pub fn structurally_normalize(
+    pub fn structurally_normalize_ty(
         &self,
         ty: Ty<'tcx>,
     ) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> {
         let ocx = ObligationCtxt::new(self.infcx);
-        let Ok(normalized_ty) = ocx.structurally_normalize(
+        let Ok(normalized_ty) = ocx.structurally_normalize_ty(
             &traits::ObligationCause::misc(self.span, self.body_id),
             self.param_env,
             ty,
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 7d651155781a1..d17ee86ba667c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -320,7 +320,7 @@ fn orphan_check<'tcx>(
         }
 
         let ty = if infcx.next_trait_solver() {
-            ocx.structurally_normalize(
+            ocx.structurally_normalize_ty(
                 &cause,
                 ty::ParamEnv::empty(),
                 infcx.resolve_vars_if_possible(ty),
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 6945dbc321697..3c25f4a8b7cc2 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1124,7 +1124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if self.next_trait_solver()
                     && let ty::Alias(..) = ty.kind()
                 {
-                    ocx.structurally_normalize(&cause, self.param_env, ty)
+                    ocx.structurally_normalize_ty(&cause, self.param_env, ty)
                 } else {
                     Ok(ty)
                 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index be6d9570e35b4..e26c09e3601cb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1433,7 +1433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // in a reentrant borrow, causing an ICE.
             let result = self
                 .at(&self.misc(sp), self.param_env)
-                .structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut());
+                .structurally_normalize_ty(ty, &mut **self.fulfillment_cx.borrow_mut());
             match result {
                 Ok(normalized_ty) => normalized_ty,
                 Err(errors) => {
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index e27143f139641..50d47d20e1a4e 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -709,7 +709,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
             if matches!(ty.kind(), ty::Alias(..)) {
                 let ocx = ObligationCtxt::new(infcx);
                 ty = ocx
-                    .structurally_normalize(&ObligationCause::dummy(), param_env, ty)
+                    .structurally_normalize_ty(&ObligationCause::dummy(), param_env, ty)
                     .map_err(|_| ())?;
                 if !ocx.select_where_possible().is_empty() {
                     return Err(());
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 48b26ee19d4dc..4a3983fca31ce 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -319,7 +319,7 @@ where
         self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
     }
 
-    pub fn structurally_normalize(
+    pub fn structurally_normalize_ty(
         &self,
         cause: &ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -327,7 +327,7 @@ where
     ) -> Result<Ty<'tcx>, Vec<E>> {
         self.infcx
             .at(cause, param_env)
-            .structurally_normalize(value, &mut **self.engine.borrow_mut())
+            .structurally_normalize_ty(value, &mut **self.engine.borrow_mut())
     }
 
     pub fn structurally_normalize_const(
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 458791df66fd6..e6d5d336b8d55 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -7,7 +7,7 @@ use crate::traits::{NormalizeExt, Obligation};
 
 #[extension(pub trait StructurallyNormalizeExt<'tcx>)]
 impl<'tcx> At<'_, 'tcx> {
-    fn structurally_normalize<E: 'tcx>(
+    fn structurally_normalize_ty<E: 'tcx>(
         &self,
         ty: Ty<'tcx>,
         fulfill_cx: &mut dyn TraitEngine<'tcx, E>,