about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-17 15:43:17 +0000
committerbors <bors@rust-lang.org>2023-06-17 15:43:17 +0000
commit5f81d83ddef72816c824909d9f77eb7c3306d496 (patch)
treeb95862aa9f90c4103b873905c729d3364e280bc5
parent20a2a24e11270bd90feb54cd7fde7b4aeacba76a (diff)
parent14155e95b14495e1713da596cef337c64e1e9f3e (diff)
downloadrust-5f81d83ddef72816c824909d9f77eb7c3306d496.tar.gz
rust-5f81d83ddef72816c824909d9f77eb7c3306d496.zip
Auto merge of #2933 - RalfJung:rustup, r=RalfJung
Rustup
-rw-r--r--.github/workflows/ci.yml36
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs13
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs4
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs124
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs134
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs40
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs55
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_lint/src/builtin.rs4
-rw-r--r--compiler/rustc_lint/src/types.rs2
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs41
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs159
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs82
-rw-r--r--compiler/rustc_middle/src/ty/context.rs1
-rw-r--r--compiler/rustc_middle/src/ty/error.rs1
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs66
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs1
-rw-r--r--compiler/rustc_mir_transform/src/check_alignment.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs9
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs85
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs9
-rw-r--r--compiler/rustc_privacy/src/lib.rs3
-rw-r--r--compiler/rustc_span/src/hygiene.rs13
-rw-r--r--compiler/rustc_span/src/lib.rs14
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs43
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs21
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs9
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs12
-rw-r--r--compiler/rustc_trait_selection/src/solve/weak_types.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs118
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs79
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs5
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs34
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs145
-rw-r--r--compiler/rustc_type_ir/src/sty.rs8
-rw-r--r--library/alloc/src/lib.rs10
-rw-r--r--library/core/src/ptr/unique.rs2
-rw-r--r--library/std/src/io/buffered/bufreader.rs27
-rw-r--r--library/std/src/io/buffered/bufwriter.rs138
-rw-r--r--library/std/src/io/buffered/linewriter.rs50
-rw-r--r--library/std/src/io/buffered/linewritershim.rs6
-rw-r--r--library/std/src/io/copy.rs2
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/lib.rs13
-rw-r--r--library/std/src/os/unix/net/ancillary.rs1
-rw-r--r--library/std/src/sys/unix/kernel_copy.rs4
-rw-r--r--library/std/src/sys/unix/thread.rs23
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile3
-rw-r--r--src/ci/github-actions/ci.yml16
-rwxr-xr-xsrc/ci/scripts/create-doc-artifacts.sh42
-rw-r--r--src/librustdoc/clean/mod.rs5
-rw-r--r--src/librustdoc/html/render/mod.rs3
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css4
-rw-r--r--src/librustdoc/html/static/js/search.js43
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs1
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed6
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs6
-rw-r--r--src/tools/clippy/tests/ui/from_over_into_unfixable.rs6
-rw-r--r--src/tools/clippy/tests/ui/from_over_into_unfixable.stderr33
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.rs22
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.stderr18
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs26
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr9
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/fail/terminate-terminator.rs2
-rw-r--r--tests/codegen/enum-debug-niche-2.rs4
-rw-r--r--tests/codegen/enum-u128.rs27
-rw-r--r--tests/mir-opt/inline/asm_unwind.rs3
-rw-r--r--tests/mir-opt/inline/cycle.rs1
-rw-r--r--tests/mir-opt/inline/inline_diverging.rs1
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff30
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff30
-rw-r--r--tests/mir-opt/inline/inline_generator.rs5
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff149
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff159
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.rs2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff112
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff112
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir111
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir111
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff112
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff112
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir111
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir111
-rw-r--r--tests/rustdoc-gui/search-reexport.goml6
-rw-r--r--tests/rustdoc-gui/search-result-color.goml18
-rw-r--r--tests/rustdoc-gui/search-result-display.goml4
-rw-r--r--tests/rustdoc-gui/search-result-keyword.goml7
-rw-r--r--tests/rustdoc/generic-associated-types/gats.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type2-tait.stderr4
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait.stderr4
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait2.stderr4
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs3
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr15
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr5
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs3
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr15
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.rs8
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.stderr6
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.rs6
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.stderr6
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.rs2
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.stderr6
-rw-r--r--tests/ui/lint/lint-ctypes-73251.rs4
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.rs4
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.stderr6
-rw-r--r--tests/ui/mir/mir_alignment_check.rs1
-rw-r--r--tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs21
-rw-r--r--tests/ui/parser/lit-err-in-macro.rs10
-rw-r--r--tests/ui/parser/lit-err-in-macro.stderr8
-rw-r--r--tests/ui/traits/issue-105231.rs9
-rw-r--r--tests/ui/traits/issue-105231.stderr29
-rw-r--r--tests/ui/traits/new-solver/closure-substs-ambiguity.rs7
-rw-r--r--tests/ui/traits/new-solver/opportunistic-region-resolve.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked3.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked3.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/bounds.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/defining-use-submodule.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/impl_for_weak_alias.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/obligation_ice.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-3.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr5
167 files changed, 1875 insertions, 1960 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f87aecb6876..398a70ee6a2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,6 +38,7 @@ jobs:
     env:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
+      HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
       CACHE_DOMAIN: ci-caches.rust-lang.org
@@ -143,6 +144,17 @@ jobs:
           AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
           TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
         if: success() && !env.SKIP_JOB
+      - name: create github artifacts
+        run: src/ci/scripts/create-doc-artifacts.sh
+        if: success() && !env.SKIP_JOB
+      - name: upload artifacts to github
+        uses: actions/upload-artifact@v3
+        with:
+          name: "${{ env.DOC_ARTIFACT_NAME }}"
+          path: obj/artifacts/doc
+          if-no-files-found: ignore
+          retention-days: 5
+        if: success() && !env.SKIP_JOB
       - name: upload artifacts to S3
         run: src/ci/scripts/upload-artifacts.sh
         env:
@@ -156,6 +168,7 @@ jobs:
     env:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
+      HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
@@ -557,6 +570,17 @@ jobs:
           AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
           TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
         if: success() && !env.SKIP_JOB
+      - name: create github artifacts
+        run: src/ci/scripts/create-doc-artifacts.sh
+        if: success() && !env.SKIP_JOB
+      - name: upload artifacts to github
+        uses: actions/upload-artifact@v3
+        with:
+          name: "${{ env.DOC_ARTIFACT_NAME }}"
+          path: obj/artifacts/doc
+          if-no-files-found: ignore
+          retention-days: 5
+        if: success() && !env.SKIP_JOB
       - name: upload artifacts to S3
         run: src/ci/scripts/upload-artifacts.sh
         env:
@@ -571,6 +595,7 @@ jobs:
       DIST_TRY_BUILD: 1
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
+      HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
@@ -672,6 +697,17 @@ jobs:
           AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
           TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
         if: success() && !env.SKIP_JOB
+      - name: create github artifacts
+        run: src/ci/scripts/create-doc-artifacts.sh
+        if: success() && !env.SKIP_JOB
+      - name: upload artifacts to github
+        uses: actions/upload-artifact@v3
+        with:
+          name: "${{ env.DOC_ARTIFACT_NAME }}"
+          path: obj/artifacts/doc
+          if-no-files-found: ignore
+          retention-days: 5
+        if: success() && !env.SKIP_JOB
       - name: upload artifacts to S3
         run: src/ci/scripts/upload-artifacts.sh
         env:
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index bad87db4732..b62f4676f70 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -108,6 +108,10 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.const_uint(self.type_u64(), i)
     }
 
+    fn const_u128(&self, i: u128) -> RValue<'gcc> {
+        self.const_uint_big(self.type_u128(), i)
+    }
+
     fn const_usize(&self, i: u64) -> RValue<'gcc> {
         let bit_size = self.data_layout().pointer_size.bits();
         if bit_size < 64 {
@@ -254,7 +258,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         // SIMD builtins require a constant value.
         self.bitcast_if_needed(value, typ)
     }
-    
+
     fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
         self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None)
     }
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index a3910fef954..a2db59bd6c4 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -168,6 +168,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         self.const_uint(self.type_i64(), i)
     }
 
+    fn const_u128(&self, i: u128) -> &'ll Value {
+        self.const_uint_big(self.type_i128(), i)
+    }
+
     fn const_usize(&self, i: u64) -> &'ll Value {
         let bit_size = self.data_layout().pointer_size.bits();
         if bit_size < 64 {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index fa67a1b3310..1a8618e0c55 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -429,7 +429,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
         return existing_di_node;
     }
 
-    debug!("type_di_node: {:?}", t);
+    debug!("type_di_node: {:?} kind: {:?}", t, t.kind());
 
     let DINodeCreationResult { di_node, already_stored_in_typemap } = match *t.kind() {
         ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 978141917c6..666b9762f5a 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -412,13 +412,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
             enum_type_and_layout.size.bits(),
             enum_type_and_layout.align.abi.bits() as u32,
             Size::ZERO.bits(),
-            discr_value.opt_single_val().map(|value| {
-                // NOTE(eddyb) do *NOT* remove this assert, until
-                // we pass the full 128-bit value to LLVM, otherwise
-                // truncation will be silent and remain undetected.
-                assert_eq!(value as u64 as u128, value);
-                cx.const_u64(value as u64)
-            }),
+            discr_value.opt_single_val().map(|value| cx.const_u128(value)),
             DIFlags::FlagZero,
             variant_member_info.variant_struct_type_di_node,
         )
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 8d346c8c0d0..557b120b2c8 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{ErrorGuaranteed, Handler};
-use rustc_fs_util::fix_windows_verbatim_for_gcc;
+use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::find_native_static_library;
 use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
@@ -2682,6 +2682,30 @@ fn add_upstream_native_libraries(
     }
 }
 
+// Rehome lib paths (which exclude the library file name) that point into the sysroot lib directory
+// to be relative to the sysroot directory, which may be a relative path specified by the user.
+//
+// If the sysroot is a relative path, and the sysroot libs are specified as an absolute path, the
+// linker command line can be non-deterministic due to the paths including the current working
+// directory. The linker command line needs to be deterministic since it appears inside the PDB
+// file generated by the MSVC linker. See https://github.com/rust-lang/rust/issues/112586.
+//
+// The returned path will always have `fix_windows_verbatim_for_gcc()` applied to it.
+fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf {
+    let sysroot_lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
+    let canonical_sysroot_lib_path =
+        { try_canonicalize(&sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) };
+
+    let canonical_lib_dir = try_canonicalize(lib_dir).unwrap_or_else(|_| lib_dir.to_path_buf());
+    if canonical_lib_dir == canonical_sysroot_lib_path {
+        // This path, returned by `target_filesearch().get_lib_path()`, has
+        // already had `fix_windows_verbatim_for_gcc()` applied if needed.
+        sysroot_lib_path
+    } else {
+        fix_windows_verbatim_for_gcc(&lib_dir)
+    }
+}
+
 // Adds the static "rlib" versions of all crates to the command line.
 // There's a bit of magic which happens here specifically related to LTO,
 // namely that we remove upstream object files.
@@ -2713,7 +2737,13 @@ fn add_static_crate<'a>(
     let cratepath = &src.rlib.as_ref().unwrap().0;
 
     let mut link_upstream = |path: &Path| {
-        cmd.link_rlib(&fix_windows_verbatim_for_gcc(path));
+        let rlib_path = if let Some(dir) = path.parent() {
+            let file_name = path.file_name().expect("rlib path has no file name path component");
+            rehome_sysroot_lib_dir(sess, &dir).join(file_name)
+        } else {
+            fix_windows_verbatim_for_gcc(path)
+        };
+        cmd.link_rlib(&rlib_path);
     };
 
     if !are_upstream_rust_objects_already_included(sess)
@@ -2782,7 +2812,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
     // what its name is
     let parent = cratepath.parent();
     if let Some(dir) = parent {
-        cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
+        cmd.include_path(&rehome_sysroot_lib_dir(sess, dir));
     }
     let stem = cratepath.file_stem().unwrap().to_str().unwrap();
     // Convert library file-stem into a cc -l argument.
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index dc2fc396480..d6e9bfce1a4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -15,6 +15,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     fn const_i32(&self, i: i32) -> Self::Value;
     fn const_u32(&self, i: u32) -> Self::Value;
     fn const_u64(&self, i: u64) -> Self::Value;
+    fn const_u128(&self, i: u128) -> Self::Value;
     fn const_usize(&self, i: u64) -> Self::Value;
     fn const_u8(&self, i: u8) -> Self::Value;
     fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 57d939747aa..106cf111474 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -781,8 +781,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             );
                             return;
                         }
-                        Ok(Some(ImplSource::Closure(data))) => {
-                            if !tcx.is_const_fn_raw(data.closure_def_id) {
+                        // Closure: Fn{Once|Mut}
+                        Ok(Some(ImplSource::Builtin(_)))
+                            if poly_trait_pred.self_ty().skip_binder().is_closure()
+                                && tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
+                        {
+                            let ty::Closure(closure_def_id, substs) =
+                                *poly_trait_pred.self_ty().no_bound_vars().unwrap().kind()
+                            else {
+                                unreachable!()
+                            };
+                            if !tcx.is_const_fn_raw(closure_def_id) {
                                 self.check_op(ops::FnCallNonConst {
                                     caller,
                                     callee,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 1da20579021..a2d23425f3b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -172,7 +172,7 @@ impl Qualif for NeedsNonConstDrop {
 
         if !matches!(
             impl_src,
-            ImplSource::ConstDestruct(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
+            ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
         ) {
             // If our const destruct candidate is not ConstDestruct or implied by the param env,
             // then it's bad
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index 11ad5b49df2..4f01e0a24a5 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -63,6 +63,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
             ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
 
+            ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
             ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
             ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
             ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index b2bdf9c7e6d..40bfa3715be 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -9,7 +9,7 @@ use rustc_session::parse::{feature_err, ParseSess};
 use rustc_span::symbol::{kw, sym, Ident};
 
 use rustc_span::edition::Edition;
-use rustc_span::{Span, SyntaxContext};
+use rustc_span::Span;
 
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
                                         `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
@@ -72,7 +72,7 @@ pub(super) fn parse(
                                             // `SyntaxContext::root()` from a foreign crate will
                                             // have the edition of that crate (which we manually
                                             // retrieve via the `edition` parameter).
-                                            if span.ctxt() == SyntaxContext::root() {
+                                            if span.ctxt().is_root() {
                                                 edition
                                             } else {
                                                 span.edition()
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 4b3bc816b95..4e23a28b371 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -260,6 +260,8 @@ language_item_table! {
     EhCatchTypeinfo,         sym::eh_catch_typeinfo,   eh_catch_typeinfo,          Target::Static,         GenericRequirement::None;
 
     OwnedBox,                sym::owned_box,           owned_box,                  Target::Struct,         GenericRequirement::Minimum(1);
+    // Experimental language item for Miri
+    PtrUnique,               sym::ptr_unique,          ptr_unique,                 Target::Struct,         GenericRequirement::Exact(1);
 
     PhantomData,             sym::phantom_data,        phantom_data,               Target::Struct,         GenericRequirement::Exact(1);
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
new file mode 100644
index 00000000000..05a3ab63d5c
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -0,0 +1,124 @@
+use rustc_ast::TraitObjectSyntax;
+use rustc_errors::{Diagnostic, StashKey};
+use rustc_hir as hir;
+use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
+use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
+
+use super::AstConv;
+
+impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
+    /// Make sure that we are in the condition to suggest the blanket implementation.
+    pub(super) fn maybe_lint_blanket_trait_impl(
+        &self,
+        self_ty: &hir::Ty<'_>,
+        diag: &mut Diagnostic,
+    ) {
+        let tcx = self.tcx();
+        let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
+        if let hir::Node::Item(hir::Item {
+            kind:
+                hir::ItemKind::Impl(hir::Impl {
+                    self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
+                }),
+            ..
+        }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
+        {
+            if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
+                return;
+            }
+            let of_trait_span = of_trait_ref.path.span;
+            // make sure that we are not calling unwrap to abort during the compilation
+            let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
+            let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
+            // check if the trait has generics, to make a correct suggestion
+            let param_name = generics.params.next_type_param_name(None);
+
+            let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
+                (span, format!(", {}: {}", param_name, impl_trait_name))
+            } else {
+                (generics.span, format!("<{}: {}>", param_name, impl_trait_name))
+            };
+            diag.multipart_suggestion(
+            format!("alternatively use a blanket \
+                     implementation to implement `{of_trait_name}` for \
+                     all types that also implement `{impl_trait_name}`"),
+                vec![
+                    (self_ty.span, param_name),
+                    add_generic_sugg,
+                ],
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
+    pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
+        let tcx = self.tcx();
+        if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
+            self_ty.kind
+        {
+            let needs_bracket = in_path
+                && !tcx
+                    .sess
+                    .source_map()
+                    .span_to_prev_source(self_ty.span)
+                    .ok()
+                    .is_some_and(|s| s.trim_end().ends_with('<'));
+
+            let is_global = poly_trait_ref.trait_ref.path.is_global();
+
+            let mut sugg = Vec::from_iter([(
+                self_ty.span.shrink_to_lo(),
+                format!(
+                    "{}dyn {}",
+                    if needs_bracket { "<" } else { "" },
+                    if is_global { "(" } else { "" },
+                ),
+            )]);
+
+            if is_global || needs_bracket {
+                sugg.push((
+                    self_ty.span.shrink_to_hi(),
+                    format!(
+                        "{}{}",
+                        if is_global { ")" } else { "" },
+                        if needs_bracket { ">" } else { "" },
+                    ),
+                ));
+            }
+
+            if self_ty.span.edition().rust_2021() {
+                let msg = "trait objects must include the `dyn` keyword";
+                let label = "add `dyn` keyword before this trait";
+                let mut diag =
+                    rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
+                if self_ty.span.can_be_used_for_suggestions() {
+                    diag.multipart_suggestion_verbose(
+                        label,
+                        sugg,
+                        Applicability::MachineApplicable,
+                    );
+                }
+                // check if the impl trait that we are considering is a impl of a local trait
+                self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
+                diag.stash(self_ty.span, StashKey::TraitMissingMethod);
+            } else {
+                let msg = "trait objects without an explicit `dyn` are deprecated";
+                tcx.struct_span_lint_hir(
+                    BARE_TRAIT_OBJECTS,
+                    self_ty.hir_id,
+                    self_ty.span,
+                    msg,
+                    |lint| {
+                        lint.multipart_suggestion_verbose(
+                            "use `dyn`",
+                            sugg,
+                            Applicability::MachineApplicable,
+                        );
+                        self.maybe_lint_blanket_trait_impl(&self_ty, lint);
+                        lint
+                    },
+                );
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 1037a49acdf..221c7ce4f6f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -4,6 +4,7 @@
 
 mod errors;
 pub mod generics;
+mod lint;
 
 use crate::astconv::errors::prohibit_assoc_ty_binding;
 use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
@@ -19,7 +20,7 @@ use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{
     struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
-    MultiSpan, StashKey,
+    MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -33,14 +34,12 @@ use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{DynKind, ToPredicate};
-use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
+use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_target::spec::abi;
-use rustc_trait_selection::traits::error_reporting::{
-    report_object_safety_error, suggestions::NextTypeParamName,
-};
+use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 use rustc_trait_selection::traits::wf::object_region_bounds;
 use rustc_trait_selection::traits::{
     self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt,
@@ -1458,7 +1457,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         item_segment: &hir::PathSegment<'_>,
     ) -> Ty<'tcx> {
         let substs = self.ast_path_substs_for_ty(span, did, item_segment);
-        self.tcx().at(span).type_of(did).subst(self.tcx(), substs)
+        let ty = self.tcx().at(span).type_of(did);
+
+        if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
+            && ty.skip_binder().has_opaque_types()
+        {
+            // Type aliases referring to types that contain opaque types (but aren't just directly
+            // referencing a single opaque type) get encoded as a type alias that normalization will
+            // then actually instantiate the where bounds of.
+            let alias_ty = self.tcx().mk_alias_ty(did, substs);
+            self.tcx().mk_alias(ty::Weak, alias_ty)
+        } else {
+            ty.subst(self.tcx(), substs)
+        }
     }
 
     fn conv_object_ty_poly_trait_ref(
@@ -3703,115 +3714,4 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
         Some(r)
     }
-
-    /// Make sure that we are in the condition to suggest the blanket implementation.
-    fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) {
-        let tcx = self.tcx();
-        let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
-        if let hir::Node::Item(hir::Item {
-            kind:
-                hir::ItemKind::Impl(hir::Impl {
-                    self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
-                }),
-            ..
-        }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
-        {
-            if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
-                return;
-            }
-            let of_trait_span = of_trait_ref.path.span;
-            // make sure that we are not calling unwrap to abort during the compilation
-            let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
-            let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
-            // check if the trait has generics, to make a correct suggestion
-            let param_name = generics.params.next_type_param_name(None);
-
-            let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
-                (span, format!(", {}: {}", param_name, impl_trait_name))
-            } else {
-                (generics.span, format!("<{}: {}>", param_name, impl_trait_name))
-            };
-            diag.multipart_suggestion(
-            format!("alternatively use a blanket \
-                     implementation to implement `{of_trait_name}` for \
-                     all types that also implement `{impl_trait_name}`"),
-                vec![
-                    (self_ty.span, param_name),
-                    add_generic_sugg,
-                ],
-                Applicability::MaybeIncorrect,
-            );
-        }
-    }
-
-    fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
-        let tcx = self.tcx();
-        if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
-            self_ty.kind
-        {
-            let needs_bracket = in_path
-                && !tcx
-                    .sess
-                    .source_map()
-                    .span_to_prev_source(self_ty.span)
-                    .ok()
-                    .is_some_and(|s| s.trim_end().ends_with('<'));
-
-            let is_global = poly_trait_ref.trait_ref.path.is_global();
-
-            let mut sugg = Vec::from_iter([(
-                self_ty.span.shrink_to_lo(),
-                format!(
-                    "{}dyn {}",
-                    if needs_bracket { "<" } else { "" },
-                    if is_global { "(" } else { "" },
-                ),
-            )]);
-
-            if is_global || needs_bracket {
-                sugg.push((
-                    self_ty.span.shrink_to_hi(),
-                    format!(
-                        "{}{}",
-                        if is_global { ")" } else { "" },
-                        if needs_bracket { ">" } else { "" },
-                    ),
-                ));
-            }
-
-            if self_ty.span.edition().rust_2021() {
-                let msg = "trait objects must include the `dyn` keyword";
-                let label = "add `dyn` keyword before this trait";
-                let mut diag =
-                    rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
-                if self_ty.span.can_be_used_for_suggestions() {
-                    diag.multipart_suggestion_verbose(
-                        label,
-                        sugg,
-                        Applicability::MachineApplicable,
-                    );
-                }
-                // check if the impl trait that we are considering is a impl of a local trait
-                self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
-                diag.stash(self_ty.span, StashKey::TraitMissingMethod);
-            } else {
-                let msg = "trait objects without an explicit `dyn` are deprecated";
-                tcx.struct_span_lint_hir(
-                    BARE_TRAIT_OBJECTS,
-                    self_ty.hir_id,
-                    self_ty.span,
-                    msg,
-                    |lint| {
-                        lint.multipart_suggestion_verbose(
-                            "use `dyn`",
-                            sugg,
-                            Applicability::MachineApplicable,
-                        );
-                        self.maybe_lint_blanket_trait_impl(&self_ty, lint);
-                        lint
-                    },
-                );
-            }
-        }
-    }
 }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4554d167080..f93f395caed 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -217,10 +217,10 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
             check_item_fn(tcx, def_id, item.ident, item.span, sig.decl);
         }
         hir::ItemKind::Static(ty, ..) => {
-            check_item_type(tcx, def_id, ty.span, false);
+            check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
         }
         hir::ItemKind::Const(ty, ..) => {
-            check_item_type(tcx, def_id, ty.span, false);
+            check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
         }
         hir::ItemKind::Struct(_, ast_generics) => {
             check_type_defn(tcx, item, false);
@@ -242,6 +242,12 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
         }
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => {}
+        hir::ItemKind::TyAlias(hir_ty, ..) => {
+            if tcx.type_of(item.owner_id.def_id).skip_binder().has_opaque_types() {
+                // Bounds are respected for `type X = impl Trait` and `type X = (impl Trait, Y);`
+                check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
+            }
+        }
         _ => {}
     }
 }
@@ -258,7 +264,9 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
         hir::ForeignItemKind::Fn(decl, ..) => {
             check_item_fn(tcx, def_id, item.ident, item.span, decl)
         }
-        hir::ForeignItemKind::Static(ty, ..) => check_item_type(tcx, def_id, ty.span, true),
+        hir::ForeignItemKind::Static(ty, ..) => {
+            check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
+        }
         hir::ForeignItemKind::Type => (),
     }
 }
@@ -1100,20 +1108,32 @@ fn check_item_fn(
     })
 }
 
-fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_foreign_ty: bool) {
+enum UnsizedHandling {
+    Forbid,
+    Allow,
+    AllowIfForeignTail,
+}
+
+fn check_item_type(
+    tcx: TyCtxt<'_>,
+    item_id: LocalDefId,
+    ty_span: Span,
+    unsized_handling: UnsizedHandling,
+) {
     debug!("check_item_type: {:?}", item_id);
 
     enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
         let ty = tcx.type_of(item_id).subst_identity();
         let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
 
-        let mut forbid_unsized = true;
-        if allow_foreign_ty {
-            let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env);
-            if let ty::Foreign(_) = tail.kind() {
-                forbid_unsized = false;
+        let forbid_unsized = match unsized_handling {
+            UnsizedHandling::Forbid => true,
+            UnsizedHandling::Allow => false,
+            UnsizedHandling::AllowIfForeignTail => {
+                let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env);
+                !matches!(tail.kind(), ty::Foreign(_))
             }
-        }
+        };
 
         wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
         if forbid_unsized {
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 23beacd2a8c..eb299a1ea79 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -200,35 +200,32 @@ fn do_orphan_check_impl<'tcx>(
                 NonlocalImpl::DisallowOther,
             ),
 
-            // trait Id { type This: ?Sized; }
-            // impl<T: ?Sized> Id for T {
-            //     type This = T;
-            // }
-            // impl<T: ?Sized> AutoTrait for <T as Id>::This {}
-            ty::Alias(AliasKind::Projection, _) => (
-                LocalImpl::Disallow { problematic_kind: "associated type" },
-                NonlocalImpl::DisallowOther,
-            ),
-
-            // ```
-            // struct S<T>(T);
-            // impl<T: ?Sized> S<T> {
-            //     type This = T;
-            // }
-            // impl<T: ?Sized> AutoTrait for S<T>::This {}
-            // ```
-            // FIXME(inherent_associated_types): The example code above currently leads to a cycle
-            ty::Alias(AliasKind::Inherent, _) => (
-                LocalImpl::Disallow { problematic_kind: "associated type" },
-                NonlocalImpl::DisallowOther,
-            ),
-
-            // type Opaque = impl Trait;
-            // impl AutoTrait for Opaque {}
-            ty::Alias(AliasKind::Opaque, _) => (
-                LocalImpl::Disallow { problematic_kind: "opaque type" },
-                NonlocalImpl::DisallowOther,
-            ),
+            ty::Alias(kind, _) => {
+                let problematic_kind = match kind {
+                    // trait Id { type This: ?Sized; }
+                    // impl<T: ?Sized> Id for T {
+                    //     type This = T;
+                    // }
+                    // impl<T: ?Sized> AutoTrait for <T as Id>::This {}
+                    AliasKind::Projection => "associated type",
+                    // type Foo = (impl Sized, bool)
+                    // impl AutoTrait for Foo {}
+                    AliasKind::Weak => "type alias",
+                    // type Opaque = impl Trait;
+                    // impl AutoTrait for Opaque {}
+                    AliasKind::Opaque => "opaque type",
+                    // ```
+                    // struct S<T>(T);
+                    // impl<T: ?Sized> S<T> {
+                    //     type This = T;
+                    // }
+                    // impl<T: ?Sized> AutoTrait for S<T>::This {}
+                    // ```
+                    // FIXME(inherent_associated_types): The example code above currently leads to a cycle
+                    AliasKind::Inherent => "associated type",
+                };
+                (LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
+            }
 
             ty::Bool
             | ty::Char
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index b92d561fb86..90e8e523ea3 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -122,6 +122,7 @@ pub(super) fn explicit_item_bounds(
             };
             opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
         }
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
         _ => bug!("item_bounds called on {:?}", def_id),
     };
     ty::EarlyBinder::bind(bounds)
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index e4c6e6e391a..a653a652231 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -128,7 +128,9 @@ fn diagnostic_hir_wf_check<'tcx>(
                 ref item => bug!("Unexpected TraitItem {:?}", item),
             },
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
+                hir::ItemKind::TyAlias(ty, _)
+                | hir::ItemKind::Static(ty, _, _)
+                | hir::ItemKind::Const(ty, _) => vec![ty],
                 hir::ItemKind::Impl(impl_) => match &impl_.of_trait {
                     Some(t) => t
                         .path
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 9659a0ec13d..dce426ca2db 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -98,7 +98,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
         );
 
-        let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin {
+        let tupled_upvars_ty = self.next_root_ty_var(TypeVariableOrigin {
             kind: TypeVariableOriginKind::ClosureSynthetic,
             span: self.tcx.def_span(expr_def_id),
         });
@@ -143,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Create a type variable (for now) to represent the closure kind.
             // It will be unified during the upvar inference phase (`upvar.rs`)
-            None => self.next_ty_var(TypeVariableOrigin {
+            None => self.next_root_ty_var(TypeVariableOrigin {
                 // FIXME(eddyb) distinguish closure kind inference variables from the rest.
                 kind: TypeVariableOriginKind::ClosureSynthetic,
                 span: expr_span,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 67f45f9aa3f..630878bbf0c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -189,6 +189,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn errors_reported_since_creation(&self) -> bool {
         self.tcx.sess.err_count() > self.err_count_on_creation
     }
+
+    pub fn next_root_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
+        self.tcx.mk_ty_var(self.next_ty_var_id_in_universe(origin, ty::UniverseIndex::ROOT))
+    }
 }
 
 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 3e4812e7ca9..fc1f90fdc13 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2375,6 +2375,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 ty::AliasKind::Projection | ty::AliasKind::Inherent => {
                     format!("the associated type `{}`", p)
                 }
+                ty::AliasKind::Weak => format!("the type alias `{}`", p),
                 ty::AliasKind::Opaque => format!("the opaque type `{}`", p),
             },
         };
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 7b05bff5151..f02f3668dc1 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1465,8 +1465,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
         let hir::ItemKind::TyAlias(ty, type_alias_generics) = &item.kind else {
             return
         };
-        if let hir::TyKind::OpaqueDef(..) = ty.kind {
-            // Bounds are respected for `type X = impl Trait`
+        if cx.tcx.type_of(item.owner_id.def_id).skip_binder().has_opaque_types() {
+            // Bounds are respected for `type X = impl Trait` and `type X = (impl Trait, Y);`
             return;
         }
         if cx.tcx.type_of(item.owner_id).skip_binder().has_inherent_projections() {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index ec9e7c7fdae..9a2d45ccd66 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1255,7 +1255,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
 
             ty::Param(..)
-            | ty::Alias(ty::Projection | ty::Inherent, ..)
+            | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
             | ty::Infer(..)
             | ty::Bound(..)
             | ty::Error(_)
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 29dae67bfca..1b19ed9ad14 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -82,15 +82,40 @@ impl CanonicalVarValues<'_> {
     }
 
     pub fn is_identity_modulo_regions(&self) -> bool {
-        self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() {
-            ty::GenericArgKind::Lifetime(_) => true,
-            ty::GenericArgKind::Type(ty) => {
-                matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv)
-            }
-            ty::GenericArgKind::Const(ct) => {
-                matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.as_usize() == bv)
+        let mut var = ty::BoundVar::from_u32(0);
+        for arg in self.var_values {
+            match arg.unpack() {
+                ty::GenericArgKind::Lifetime(r) => {
+                    if let ty::ReLateBound(ty::INNERMOST, br) = *r
+                        && var == br.var
+                    {
+                        var = var + 1;
+                    } else {
+                        // It's ok if this region var isn't unique
+                    }
+                },
+                ty::GenericArgKind::Type(ty) => {
+                    if let ty::Bound(ty::INNERMOST, bt) = *ty.kind()
+                        && var == bt.var
+                    {
+                        var = var + 1;
+                    } else {
+                        return false;
+                    }
+                }
+                ty::GenericArgKind::Const(ct) => {
+                    if let ty::ConstKind::Bound(ty::INNERMOST, bc) = ct.kind()
+                        && var == bc
+                    {
+                        var = var + 1;
+                    } else {
+                        return false;
+                    }
+                }
             }
-        })
+        }
+
+        true
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 2165403da26..6b036194381 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -3,7 +3,7 @@ use rustc_middle::hir;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::MirSpanview;
-use rustc_span::{BytePos, Pos, Span, SyntaxContext};
+use rustc_span::{BytePos, Pos, Span};
 
 use std::cmp;
 use std::io::{self, Write};
@@ -327,7 +327,7 @@ fn compute_block_span(data: &BasicBlockData<'_>, body_span: Span) -> Span {
     let mut span = data.terminator().source_info.span;
     for statement_span in data.statements.iter().map(|statement| statement.source_info.span) {
         // Only combine Spans from the root context, and within the function's body_span.
-        if statement_span.ctxt() == SyntaxContext::root() && body_span.contains(statement_span) {
+        if statement_span.ctxt().is_root() && body_span.contains(statement_span) {
             span = span.to(statement_span);
         }
     }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index a6c8d41e925..132b11b29eb 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1904,6 +1904,16 @@ rustc_queries! {
     }
 
     /// Do not call this query directly: invoke `normalize` instead.
+    query normalize_weak_ty(
+        goal: CanonicalProjectionGoal<'tcx>
+    ) -> Result<
+        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>,
+        NoSolution,
+    > {
+        desc { "normalizing `{}`", goal.value.value }
+    }
+
+    /// Do not call this query directly: invoke `normalize` instead.
     query normalize_inherent_projection_ty(
         goal: CanonicalProjectionGoal<'tcx>
     ) -> Result<
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index bf3872e81d4..492b7228488 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -448,6 +448,9 @@ pub enum ObligationCauseCode<'tcx> {
 
     /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
     ConstParam(Ty<'tcx>),
+
+    /// Obligations emitted during the normalization of a weak type alias.
+    TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId),
 }
 
 /// The 'location' at which we try to perform HIR-based wf checking.
@@ -643,12 +646,6 @@ pub enum ImplSource<'tcx, N> {
     /// ImplSource identifying a particular impl.
     UserDefined(ImplSourceUserDefinedData<'tcx, N>),
 
-    /// ImplSource for auto trait implementations.
-    /// This carries the information and nested obligations with regards
-    /// to an auto implementation for a trait `Trait`. The nested obligations
-    /// ensure the trait implementation holds for all the constituent types.
-    AutoImpl(ImplSourceAutoImplData<N>),
-
     /// Successful resolution to an obligation provided by the caller
     /// for some type parameter. The `Vec<N>` represents the
     /// obligations incurred from normalizing the where-clause (if
@@ -656,84 +653,46 @@ pub enum ImplSource<'tcx, N> {
     Param(Vec<N>, ty::BoundConstness),
 
     /// Virtual calls through an object.
-    Object(ImplSourceObjectData<'tcx, N>),
+    Object(ImplSourceObjectData<N>),
 
     /// Successful resolution for a builtin trait.
-    Builtin(ImplSourceBuiltinData<N>),
+    Builtin(Vec<N>),
 
     /// ImplSource for trait upcasting coercion
-    TraitUpcasting(ImplSourceTraitUpcastingData<'tcx, N>),
-
-    /// ImplSource automatically generated for a closure. The `DefId` is the ID
-    /// of the closure expression. This is an `ImplSource::UserDefined` in spirit, but the
-    /// impl is generated by the compiler and does not appear in the source.
-    Closure(ImplSourceClosureData<'tcx, N>),
-
-    /// Same as above, but for a function pointer type with the given signature.
-    FnPointer(ImplSourceFnPointerData<'tcx, N>),
-
-    /// ImplSource automatically generated for a generator.
-    Generator(ImplSourceGeneratorData<'tcx, N>),
-
-    /// ImplSource automatically generated for a generator backing an async future.
-    Future(ImplSourceFutureData<'tcx, N>),
+    TraitUpcasting(ImplSourceTraitUpcastingData<N>),
 
     /// ImplSource for a trait alias.
     TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
-
-    /// ImplSource for a `const Drop` implementation.
-    ConstDestruct(ImplSourceConstDestructData<N>),
 }
 
 impl<'tcx, N> ImplSource<'tcx, N> {
     pub fn nested_obligations(self) -> Vec<N> {
         match self {
             ImplSource::UserDefined(i) => i.nested,
-            ImplSource::Param(n, _) => n,
-            ImplSource::Builtin(i) => i.nested,
-            ImplSource::AutoImpl(d) => d.nested,
-            ImplSource::Closure(c) => c.nested,
-            ImplSource::Generator(c) => c.nested,
-            ImplSource::Future(c) => c.nested,
+            ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
             ImplSource::Object(d) => d.nested,
-            ImplSource::FnPointer(d) => d.nested,
             ImplSource::TraitAlias(d) => d.nested,
             ImplSource::TraitUpcasting(d) => d.nested,
-            ImplSource::ConstDestruct(i) => i.nested,
         }
     }
 
     pub fn borrow_nested_obligations(&self) -> &[N] {
         match self {
             ImplSource::UserDefined(i) => &i.nested,
-            ImplSource::Param(n, _) => n,
-            ImplSource::Builtin(i) => &i.nested,
-            ImplSource::AutoImpl(d) => &d.nested,
-            ImplSource::Closure(c) => &c.nested,
-            ImplSource::Generator(c) => &c.nested,
-            ImplSource::Future(c) => &c.nested,
+            ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
             ImplSource::Object(d) => &d.nested,
-            ImplSource::FnPointer(d) => &d.nested,
             ImplSource::TraitAlias(d) => &d.nested,
             ImplSource::TraitUpcasting(d) => &d.nested,
-            ImplSource::ConstDestruct(i) => &i.nested,
         }
     }
 
     pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
         match self {
             ImplSource::UserDefined(i) => &mut i.nested,
-            ImplSource::Param(n, _) => n,
-            ImplSource::Builtin(i) => &mut i.nested,
-            ImplSource::AutoImpl(d) => &mut d.nested,
-            ImplSource::Closure(c) => &mut c.nested,
-            ImplSource::Generator(c) => &mut c.nested,
-            ImplSource::Future(c) => &mut c.nested,
+            ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
             ImplSource::Object(d) => &mut d.nested,
-            ImplSource::FnPointer(d) => &mut d.nested,
             ImplSource::TraitAlias(d) => &mut d.nested,
             ImplSource::TraitUpcasting(d) => &mut d.nested,
-            ImplSource::ConstDestruct(i) => &mut i.nested,
         }
     }
 
@@ -748,37 +707,12 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 nested: i.nested.into_iter().map(f).collect(),
             }),
             ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
-            ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
-                nested: i.nested.into_iter().map(f).collect(),
-            }),
+            ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
             ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
-                upcast_trait_ref: o.upcast_trait_ref,
+                upcast_trait_def_id: o.upcast_trait_def_id,
                 vtable_base: o.vtable_base,
                 nested: o.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData {
-                trait_def_id: d.trait_def_id,
-                nested: d.nested.into_iter().map(f).collect(),
-            }),
-            ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData {
-                closure_def_id: c.closure_def_id,
-                substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect(),
-            }),
-            ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData {
-                generator_def_id: c.generator_def_id,
-                substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect(),
-            }),
-            ImplSource::Future(c) => ImplSource::Future(ImplSourceFutureData {
-                generator_def_id: c.generator_def_id,
-                substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect(),
-            }),
-            ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData {
-                fn_ty: p.fn_ty,
-                nested: p.nested.into_iter().map(f).collect(),
-            }),
             ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
                 alias_def_id: d.alias_def_id,
                 substs: d.substs,
@@ -786,16 +720,10 @@ impl<'tcx, N> ImplSource<'tcx, N> {
             }),
             ImplSource::TraitUpcasting(d) => {
                 ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
-                    upcast_trait_ref: d.upcast_trait_ref,
                     vtable_vptr_slot: d.vtable_vptr_slot,
                     nested: d.nested.into_iter().map(f).collect(),
                 })
             }
-            ImplSource::ConstDestruct(i) => {
-                ImplSource::ConstDestruct(ImplSourceConstDestructData {
-                    nested: i.nested.into_iter().map(f).collect(),
-                })
-            }
         }
     }
 }
@@ -820,47 +748,7 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
 
 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceGeneratorData<'tcx, N> {
-    pub generator_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    /// Nested obligations. This can be non-empty if the generator
-    /// signature contains associated types.
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceFutureData<'tcx, N> {
-    pub generator_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    /// Nested obligations. This can be non-empty if the generator
-    /// signature contains associated types.
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceClosureData<'tcx, N> {
-    pub closure_def_id: DefId,
-    pub substs: SubstsRef<'tcx>,
-    /// Nested obligations. This can be non-empty if the closure
-    /// signature contains associated types.
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceAutoImplData<N> {
-    pub trait_def_id: DefId,
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceTraitUpcastingData<'tcx, N> {
-    /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
-    pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
-
+pub struct ImplSourceTraitUpcastingData<N> {
     /// The vtable is formed by concatenating together the method lists of
     /// the base object trait and all supertraits, pointers to supertrait vtable will
     /// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
@@ -870,17 +758,11 @@ pub struct ImplSourceTraitUpcastingData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceBuiltinData<N> {
-    pub nested: Vec<N>,
-}
-
 #[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceObjectData<'tcx, N> {
+pub struct ImplSourceObjectData<N> {
     /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
-    pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
+    pub upcast_trait_def_id: DefId,
 
     /// The vtable is formed by concatenating together the method lists of
     /// the base object trait and all supertraits, pointers to supertrait vtable will
@@ -893,19 +775,6 @@ pub struct ImplSourceObjectData<'tcx, N> {
 
 #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceFnPointerData<'tcx, N> {
-    pub fn_ty: Ty<'tcx>,
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct ImplSourceConstDestructData<N> {
-    pub nested: Vec<N>,
-}
-
-#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
-#[derive(TypeFoldable, TypeVisitable)]
 pub struct ImplSourceTraitAliasData<'tcx, N> {
     pub alias_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 6acb7745d65..ac02d6ed62f 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -9,15 +9,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
         match *self {
             super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
 
-            super::ImplSource::AutoImpl(ref t) => write!(f, "{:?}", t),
-
-            super::ImplSource::Closure(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::Generator(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::Future(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d),
+            super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
 
             super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
 
@@ -25,13 +17,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
                 write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
             }
 
-            super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
-
             super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
 
             super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
-
-            super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d),
         }
     }
 }
@@ -46,78 +34,26 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx,
     }
 }
 
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceGeneratorData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
-            self.generator_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFutureData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceFutureData(generator_def_id={:?}, substs={:?}, nested={:?})",
-            self.generator_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceClosureData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
-            self.closure_def_id, self.substs, self.nested
-        )
-    }
-}
-
-impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceBuiltinData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ImplSourceBuiltinData(nested={:?})", self.nested)
-    }
-}
-
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "ImplSourceTraitUpcastingData(upcast={:?}, vtable_vptr_slot={:?}, nested={:?})",
-            self.upcast_trait_ref, self.vtable_vptr_slot, self.nested
-        )
-    }
-}
-
-impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceAutoImplData<N> {
+impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
-            "ImplSourceAutoImplData(trait_def_id={:?}, nested={:?})",
-            self.trait_def_id, self.nested
+            "ImplSourceTraitUpcastingData(vtable_vptr_slot={:?}, nested={:?})",
+            self.vtable_vptr_slot, self.nested
         )
     }
 }
 
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<'tcx, N> {
+impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
             f,
             "ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})",
-            self.upcast_trait_ref, self.vtable_base, self.nested
+            self.upcast_trait_def_id, self.vtable_base, self.nested
         )
     }
 }
 
-impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceFnPointerData<'tcx, N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ImplSourceFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
-    }
-}
-
 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(
@@ -127,9 +63,3 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx,
         )
     }
 }
-
-impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested)
-    }
-}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4ee543bbfb6..449129b8418 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2012,6 +2012,7 @@ impl<'tcx> TyCtxt<'tcx> {
             (ty::Opaque, DefKind::OpaqueTy)
                 | (ty::Projection | ty::Inherent, DefKind::AssocTy)
                 | (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
+                | (ty::Weak, DefKind::TyAlias)
         );
         self.mk_ty_from_kind(Alias(kind, alias_ty))
     }
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 66293f19eef..c794c3faded 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -300,6 +300,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Placeholder(..) => "higher-ranked type".into(),
             ty::Bound(..) => "bound type variable".into(),
             ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(),
+            ty::Alias(ty::Weak, _) => "type alias".into(),
             ty::Param(_) => "type parameter".into(),
             ty::Alias(ty::Opaque, ..) => "opaque type".into(),
         }
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index d64875a9f00..9cce9d64d5d 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -178,7 +178,7 @@ impl FlagComputation {
 
             &ty::Alias(kind, data) => {
                 self.add_flags(match kind {
-                    ty::Projection => TypeFlags::HAS_TY_PROJECTION,
+                    ty::Weak | ty::Projection => TypeFlags::HAS_TY_PROJECTION,
                     ty::Inherent => TypeFlags::HAS_TY_INHERENT,
                     ty::Opaque => TypeFlags::HAS_TY_OPAQUE,
                 });
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 72341e656e2..ff5d99794f1 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -586,6 +586,24 @@ pub enum Clause<'tcx> {
     ConstArgHasType(Const<'tcx>, Ty<'tcx>),
 }
 
+impl<'tcx> Binder<'tcx, Clause<'tcx>> {
+    pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
+        if let ty::Clause::Trait(trait_clause) = self.skip_binder() {
+            Some(self.rebind(trait_clause))
+        } else {
+            None
+        }
+    }
+
+    pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
+        if let ty::Clause::Projection(projection_clause) = self.skip_binder() {
+            Some(self.rebind(projection_clause))
+        } else {
+            None
+        }
+    }
+}
+
 #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub enum PredicateKind<'tcx> {
@@ -1203,6 +1221,17 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for TraitRef<'tcx> {
+    #[inline(always)]
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        Binder::dummy(Clause::Trait(TraitPredicate {
+            trait_ref: self,
+            constness: ty::BoundConstness::NotConst,
+            polarity: ty::ImplPolarity::Positive,
+        }))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
     #[inline(always)]
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
@@ -1211,6 +1240,14 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
+    #[inline(always)]
+    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
+        pred.to_predicate(tcx)
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
     #[inline(always)]
     fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
@@ -1240,6 +1277,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyTraitPredicate<'tcx> {
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        self.map_bound(|p| Clause::Trait(p))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
@@ -1258,6 +1301,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyProjectionPredicate<'tcx> {
+    fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
+        self.map_bound(|p| Clause::Projection(p))
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
@@ -1327,6 +1376,23 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::TypeWellFormedFromEnv(..) => None,
         }
     }
+
+    pub fn as_clause(self) -> Option<Binder<'tcx, Clause<'tcx>>> {
+        let predicate = self.kind();
+        match predicate.skip_binder() {
+            PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
+            PredicateKind::AliasRelate(..)
+            | PredicateKind::Subtype(..)
+            | PredicateKind::Coerce(..)
+            | PredicateKind::WellFormed(..)
+            | PredicateKind::ObjectSafe(..)
+            | PredicateKind::ClosureKind(..)
+            | PredicateKind::ConstEvaluatable(..)
+            | PredicateKind::ConstEquate(..)
+            | PredicateKind::Ambiguous
+            | PredicateKind::TypeWellFormedFromEnv(..) => None,
+        }
+    }
 }
 
 /// Represents the bounds declared on a particular set of type
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 6156fdf7eac..f36b8ad8df6 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -731,7 +731,7 @@ pub trait PrettyPrinter<'tcx>:
             ty::Foreign(def_id) => {
                 p!(print_def_path(def_id, &[]));
             }
-            ty::Alias(ty::Projection | ty::Inherent, ref data) => {
+            ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ref data) => {
                 if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
                     && self.tcx().is_impl_trait_in_trait(data.def_id)
                 {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 8bcae3d9ab7..74a3bddf2fa 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -391,13 +391,13 @@ impl<'tcx> Relate<'tcx> for Ty<'tcx> {
 /// Relates `a` and `b` structurally, calling the relation for all nested values.
 /// Any semantic equality, e.g. of projections, and inference variables have to be
 /// handled by the caller.
+#[instrument(level = "trace", skip(relation), ret)]
 pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
     relation: &mut R,
     a: Ty<'tcx>,
     b: Ty<'tcx>,
 ) -> RelateResult<'tcx, Ty<'tcx>> {
     let tcx = relation.tcx();
-    debug!("structurally_relate_tys: a={:?} b={:?}", a, b);
     match (a.kind(), b.kind()) {
         (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
             // The caller should handle these cases!
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d19a7bcde79..5f2f241bc0d 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1231,6 +1231,7 @@ impl<'tcx> AliasTy<'tcx> {
             DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
             DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
             DefKind::OpaqueTy => ty::Opaque,
+            DefKind::TyAlias => ty::Weak,
             kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
         }
     }
diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
index ef64f70fdf3..fd349c07040 100644
--- a/compiler/rustc_mir_transform/src/check_alignment.rs
+++ b/compiler/rustc_mir_transform/src/check_alignment.rs
@@ -15,6 +15,10 @@ pub struct CheckAlignment;
 
 impl<'tcx> MirPass<'tcx> for CheckAlignment {
     fn is_enabled(&self, sess: &Session) -> bool {
+        // FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
+        if sess.target.llvm_target == "i686-pc-windows-msvc" {
+            return false;
+        }
         sess.opts.debug_assertions
     }
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 5487b5987e0..b28fed7159f 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -479,11 +479,12 @@ impl<'tcx> Inliner<'tcx> {
         // Abort if type validation found anything fishy.
         checker.validation?;
 
+        // N.B. We still apply our cost threshold to #[inline(always)] functions.
+        // That attribute is often applied to very large functions that exceed LLVM's (very
+        // generous) inlining threshold. Such functions are very poor MIR inlining candidates.
+        // Always inlining #[inline(always)] functions in MIR, on net, slows down the compiler.
         let cost = checker.cost;
-        if let InlineAttr::Always = callee_attrs.inline {
-            debug!("INLINING {:?} because inline(always) [cost={}]", callsite, cost);
-            Ok(())
-        } else if cost <= threshold {
+        if cost <= threshold {
             debug!("INLINING {:?} [cost={} <= threshold={}]", callsite, cost, threshold);
             Ok(())
         } else {
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index ebcc3b03999..531644f0b84 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -155,14 +155,16 @@ where
     // functions and statics defined in the local crate.
     let PlacedRootMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
         let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
-        place_root_mono_items(cx, mono_items)
-    };
+        let mut placed = place_root_mono_items(cx, mono_items);
 
-    for cgu in &mut codegen_units {
-        cgu.create_size_estimate(tcx);
-    }
+        for cgu in &mut placed.codegen_units {
+            cgu.create_size_estimate(tcx);
+        }
 
-    debug_dump(tcx, "ROOTS", &codegen_units, unique_inlined_stats);
+        debug_dump(tcx, "ROOTS", &placed.codegen_units, placed.unique_inlined_stats);
+
+        placed
+    };
 
     // Merge until we have at most `max_cgu_count` codegen units.
     // `merge_codegen_units` is responsible for updating the CGU size
@@ -179,59 +181,34 @@ where
     // local functions the definition of which is marked with `#[inline]`.
     {
         let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
-        place_inlined_mono_items(cx, &mut codegen_units)
-    };
+        place_inlined_mono_items(cx, &mut codegen_units);
 
-    for cgu in &mut codegen_units {
-        cgu.create_size_estimate(tcx);
-    }
+        for cgu in &mut codegen_units {
+            cgu.create_size_estimate(tcx);
+        }
 
-    debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
+        debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
+    }
 
     // Next we try to make as many symbols "internal" as possible, so LLVM has
     // more freedom to optimize.
     if !tcx.sess.link_dead_code() {
         let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
         internalize_symbols(cx, &mut codegen_units, internalization_candidates);
+
+        debug_dump(tcx, "INTERNALIZE", &codegen_units, unique_inlined_stats);
     }
 
+    // Mark one CGU for dead code, if necessary.
     let instrument_dead_code =
         tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions();
-
     if instrument_dead_code {
-        assert!(
-            codegen_units.len() > 0,
-            "There must be at least one CGU that code coverage data can be generated in."
-        );
-
-        // Find the smallest CGU that has exported symbols and put the dead
-        // function stubs in that CGU. We look for exported symbols to increase
-        // the likelihood the linker won't throw away the dead functions.
-        // FIXME(#92165): In order to truly resolve this, we need to make sure
-        // the object file (CGU) containing the dead function stubs is included
-        // in the final binary. This will probably require forcing these
-        // function symbols to be included via `-u` or `/include` linker args.
-        let mut cgus: Vec<_> = codegen_units.iter_mut().collect();
-        cgus.sort_by_key(|cgu| cgu.size_estimate());
-
-        let dead_code_cgu =
-            if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
-                cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
-            }) {
-                cgu
-            } else {
-                // If there are no CGUs that have externally linked items,
-                // then we just pick the first CGU as a fallback.
-                &mut codegen_units[0]
-            };
-        dead_code_cgu.make_code_coverage_dead_code_cgu();
+        mark_code_coverage_dead_code_cgu(&mut codegen_units);
     }
 
     // Ensure CGUs are sorted by name, so that we get deterministic results.
     assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))));
 
-    debug_dump(tcx, "FINAL", &codegen_units, unique_inlined_stats);
-
     codegen_units
 }
 
@@ -363,9 +340,7 @@ fn merge_codegen_units<'tcx>(
 
         // Move the mono-items from `smallest` to `second_smallest`
         second_smallest.modify_size_estimate(smallest.size_estimate());
-        for (k, v) in smallest.items_mut().drain() {
-            second_smallest.items_mut().insert(k, v);
-        }
+        second_smallest.items_mut().extend(smallest.items_mut().drain());
 
         // Record that `second_smallest` now contains all the stuff that was
         // in `smallest` before.
@@ -545,6 +520,28 @@ fn internalize_symbols<'tcx>(
     }
 }
 
+fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>]) {
+    assert!(!codegen_units.is_empty());
+
+    // Find the smallest CGU that has exported symbols and put the dead
+    // function stubs in that CGU. We look for exported symbols to increase
+    // the likelihood the linker won't throw away the dead functions.
+    // FIXME(#92165): In order to truly resolve this, we need to make sure
+    // the object file (CGU) containing the dead function stubs is included
+    // in the final binary. This will probably require forcing these
+    // function symbols to be included via `-u` or `/include` linker args.
+    let dead_code_cgu = codegen_units
+        .iter_mut()
+        .filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
+        .min_by_key(|cgu| cgu.size_estimate());
+
+    // If there are no CGUs that have externally linked items, then we just
+    // pick the first CGU as a fallback.
+    let dead_code_cgu = if let Some(cgu) = dead_code_cgu { cgu } else { &mut codegen_units[0] };
+
+    dead_code_cgu.make_code_coverage_dead_code_cgu();
+}
+
 fn characteristic_def_id_of_mono_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     mono_item: MonoItem<'tcx>,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index d81b3899201..57202ac9c6e 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2029,17 +2029,14 @@ impl<'a> Parser<'a> {
         let recovered = self.recover_after_dot();
         let token = recovered.as_ref().unwrap_or(&self.token);
         match token::Lit::from_token(token) {
-            Some(token_lit) => {
-                match MetaItemLit::from_token_lit(token_lit, token.span) {
+            Some(lit) => {
+                match MetaItemLit::from_token_lit(lit, token.span) {
                     Ok(lit) => {
                         self.bump();
                         Some(lit)
                     }
                     Err(err) => {
-                        let span = token.span;
-                        let token::Literal(lit) = token.kind else {
-                            unreachable!();
-                        };
+                        let span = token.uninterpolated_span();
                         self.bump();
                         report_lit_error(&self.sess, err, lit, span);
                         // Pack possible quotes and prefixes from the original literal into
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index a51a1c9a8a4..5ef11acadce 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -242,6 +242,9 @@ where
                     }
                 }
             }
+            ty::Alias(ty::Weak, alias) => {
+                self.def_id_visitor.visit_def_id(alias.def_id, "type alias", &ty);
+            }
             ty::Alias(ty::Projection, proj) => {
                 if self.def_id_visitor.skip_assoc_tys() {
                     // Visitors searching for minimal visibility/reachability want to
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 0c7e36b3bef..9f2ff437842 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -507,7 +507,7 @@ impl HygieneData {
             self.normalize_to_macro_rules(call_site_ctxt)
         };
 
-        if call_site_ctxt == SyntaxContext::root() {
+        if call_site_ctxt.is_root() {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
@@ -671,12 +671,17 @@ impl SyntaxContext {
     }
 
     #[inline]
-    pub(crate) fn as_u32(self) -> u32 {
+    pub const fn is_root(self) -> bool {
+        self.0 == SyntaxContext::root().as_u32()
+    }
+
+    #[inline]
+    pub(crate) const fn as_u32(self) -> u32 {
         self.0
     }
 
     #[inline]
-    pub(crate) fn from_u32(raw: u32) -> SyntaxContext {
+    pub(crate) const fn from_u32(raw: u32) -> SyntaxContext {
         SyntaxContext(raw)
     }
 
@@ -1500,7 +1505,7 @@ impl<CTX: HashStableContext> HashStable<CTX> for SyntaxContext {
         const TAG_EXPANSION: u8 = 0;
         const TAG_NO_EXPANSION: u8 = 1;
 
-        if *self == SyntaxContext::root() {
+        if self.is_root() {
             TAG_NO_EXPANSION.hash_stable(ctx, hasher);
         } else {
             TAG_EXPANSION.hash_stable(ctx, hasher);
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index eae3f0fa041..e7a53c63e83 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -826,9 +826,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::root() {
+            if span_data.ctxt.is_root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::root() {
+            } else if end_data.ctxt.is_root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -837,7 +837,7 @@ impl Span {
         Span::new(
             cmp::min(span_data.lo, end_data.lo),
             cmp::max(span_data.hi, end_data.hi),
-            if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.ctxt.is_root() { end_data.ctxt } else { span_data.ctxt },
             if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
@@ -855,7 +855,7 @@ impl Span {
         Span::new(
             span.hi,
             end.lo,
-            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
+            if end.ctxt.is_root() { end.ctxt } else { span.ctxt },
             if span.parent == end.parent { span.parent } else { None },
         )
     }
@@ -879,9 +879,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::root() {
+            if span_data.ctxt.is_root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::root() {
+            } else if end_data.ctxt.is_root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -890,7 +890,7 @@ impl Span {
         Span::new(
             span_data.lo,
             end_data.lo,
-            if end_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
+            if end_data.ctxt.is_root() { end_data.ctxt } else { span_data.ctxt },
             if span_data.parent == end_data.parent { span_data.parent } else { None },
         )
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c5ce2575fff..19d986a3152 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1156,6 +1156,7 @@ symbols! {
         ptr_null_mut,
         ptr_offset_from,
         ptr_offset_from_unsigned,
+        ptr_unique,
         pub_macro_rules,
         pub_restricted,
         public,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 0a805e2422d..5dc00e31786 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -483,6 +483,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
             }
 
             ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
+            ty::Alias(ty::Weak, _) => bug!("symbol_names: unexpected weak projection"),
             ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"),
             ty::GeneratorWitnessMIR(..) => bug!("symbol_names: unexpected `GeneratorWitnessMIR`"),
         }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 1b749b9c854..543611daae8 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -105,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx>;
 
@@ -115,7 +115,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_implied_clause(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
@@ -131,7 +131,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_alias_bound_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
             ecx.validate_alias_bound_self_from_param_env(goal)
@@ -144,7 +144,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_object_bound_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
     ) -> QueryResult<'tcx> {
         Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
             let tcx = ecx.tcx();
@@ -467,11 +467,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
         for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
-            match G::consider_implied_clause(self, goal, assumption, []) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_implied_clause(self, goal, clause, []) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
@@ -508,20 +510,23 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Placeholder(..)
             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
             | ty::Alias(ty::Inherent, _)
+            | ty::Alias(ty::Weak, _)
             | ty::Error(_) => return,
             ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
             | ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
-            // Excluding IATs here as they don't have meaningful item bounds.
+            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
             ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
         };
 
         for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
         {
-            match G::consider_alias_bound_candidate(self, goal, assumption) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_alias_bound_candidate(self, goal, clause) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
@@ -675,18 +680,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // projection predicates that we reach by elaborating the principal trait ref,
             // since that'll cause ambiguity.
             //
-            // We can remove this when we have implemented intersections in responses.
+            // We can remove this when we have implemented lifetime intersections in responses.
             if assumption.to_opt_poly_projection_pred().is_some()
                 && !own_bounds.contains(&assumption)
             {
                 continue;
             }
 
-            match G::consider_object_bound_candidate(self, goal, assumption) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+            if let Some(clause) = assumption.as_clause() {
+                match G::consider_object_bound_candidate(self, goal, clause) {
+                    Ok(result) => {
+                        candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+                    }
+                    Err(NoSolution) => (),
                 }
-                Err(NoSolution) => (),
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 0f3f8f1ac2c..97b86a06c8c 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -33,7 +33,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
         ty::Dynamic(..)
         | ty::Param(..)
         | ty::Foreign(..)
-        | ty::Alias(ty::Projection | ty::Inherent, ..)
+        | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
         | ty::Placeholder(..)
         | ty::Bound(..)
         | ty::Infer(_) => {
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index 29bdb5ff67d..05248cb9d17 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -208,8 +208,25 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
         t
     }
 
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        let r = self.infcx.shallow_resolve(r);
+    fn fold_region(&mut self, mut r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+        match self.canonicalize_mode {
+            CanonicalizeMode::Input => {
+                // Don't resolve infer vars in input, since it affects
+                // caching and may cause trait selection bugs which rely
+                // on regions to be equal.
+            }
+            CanonicalizeMode::Response { .. } => {
+                if let ty::ReVar(vid) = *r {
+                    r = self
+                        .infcx
+                        .inner
+                        .borrow_mut()
+                        .unwrap_region_constraints()
+                        .opportunistic_resolve_var(self.infcx.tcx, vid);
+                }
+            }
+        }
+
         let kind = match *r {
             ty::ReLateBound(..) => return r,
 
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index a8a0e1ebfb4..8592fc164d0 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -263,7 +263,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
             let new_canonical_response =
                 EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
-            if !new_canonical_response.value.var_values.is_identity() {
+            // We only check for modulo regions as we convert all regions in
+            // the input to new existentials, even if they're expected to be
+            // `'static` or a placeholder region.
+            if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
                 bug!(
                     "unstable result: re-canonicalized goal={canonical_goal:#?} \
                     first_response={canonical_response:#?} \
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index f4c29c837b8..a30a14df80b 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -29,6 +29,7 @@ mod opaques;
 mod project_goals;
 mod search_graph;
 mod trait_goals;
+mod weak_types;
 
 pub use eval_ctxt::{EvalCtxt, InferCtxtEvalExt};
 pub use fulfill::FulfillmentCtxt;
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 242f9ba8747..e9600968f48 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -57,6 +57,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
             DefKind::AnonConst => self.normalize_anon_const(goal),
             DefKind::OpaqueTy => self.normalize_opaque_type(goal),
+            DefKind::TyAlias => self.normalize_weak_type(goal),
             kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
         }
     }
@@ -105,15 +106,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx> {
-        if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
-            && poly_projection_pred.projection_def_id() == goal.predicate.def_id()
+        if let Some(projection_pred) = assumption.as_projection_clause()
+            && projection_pred.projection_def_id() == goal.predicate.def_id()
         {
             ecx.probe(|ecx| {
                 let assumption_projection_pred =
-                    ecx.instantiate_binder_with_infer(poly_projection_pred);
+                    ecx.instantiate_binder_with_infer(projection_pred);
                 ecx.eq(
                     goal.param_env,
                     goal.predicate.projection_ty,
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f722f281314..279fc1229d4 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -81,17 +81,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-        assumption: ty::Predicate<'tcx>,
+        assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
     ) -> QueryResult<'tcx> {
-        if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
-            && poly_trait_pred.def_id() == goal.predicate.def_id()
-            && poly_trait_pred.polarity() == goal.predicate.polarity
+        if let Some(trait_clause) = assumption.as_trait_clause()
+            && trait_clause.def_id() == goal.predicate.def_id()
+            && trait_clause.polarity() == goal.predicate.polarity
         {
             // FIXME: Constness
             ecx.probe(|ecx| {
                 let assumption_trait_pred =
-                    ecx.instantiate_binder_with_infer(poly_trait_pred);
+                    ecx.instantiate_binder_with_infer(trait_clause);
                 ecx.eq(
                     goal.param_env,
                     goal.predicate.trait_ref,
@@ -618,7 +618,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             ty::Dynamic(..)
             | ty::Param(..)
             | ty::Foreign(..)
-            | ty::Alias(ty::Projection | ty::Inherent, ..)
+            | ty::Alias(ty::Projection | ty::Weak | ty::Inherent, ..)
             | ty::Placeholder(..) => Some(Err(NoSolution)),
 
             ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
diff --git a/compiler/rustc_trait_selection/src/solve/weak_types.rs b/compiler/rustc_trait_selection/src/solve/weak_types.rs
new file mode 100644
index 00000000000..b095b54c554
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/solve/weak_types.rs
@@ -0,0 +1,19 @@
+use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
+use rustc_middle::ty;
+
+use super::EvalCtxt;
+
+impl<'tcx> EvalCtxt<'_, 'tcx> {
+    pub(super) fn normalize_weak_type(
+        &mut self,
+        goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
+    ) -> QueryResult<'tcx> {
+        let tcx = self.tcx();
+        let weak_ty = goal.predicate.projection_ty;
+        let expected = goal.predicate.term.ty().expect("no such thing as a const alias");
+
+        let actual = tcx.type_of(weak_ty.def_id).subst(tcx, weak_ty.substs);
+        self.eq(goal.param_env, expected, actual)?;
+        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 190a78f6a8e..0065c7fc253 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -292,7 +292,12 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
             Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate)
         })
         .chain(obligations)
-        .find(|o| !selcx.predicate_may_hold_fatal(o));
+        .find(|o| {
+            selcx.evaluate_root_obligation(o).map_or(
+                false, // Overflow has occurred, and treat the obligation as possibly holding.
+                |result| !result.may_apply(),
+            )
+        });
 
     if let Some(failing_obligation) = opt_failing_obligation {
         debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
@@ -690,7 +695,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> {
             | ty::RawPtr(..)
             | ty::Never
             | ty::Tuple(..)
-            | ty::Alias(ty::Projection | ty::Inherent, ..) => self.found_non_local_ty(ty),
+            | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) => {
+                self.found_non_local_ty(ty)
+            }
 
             ty::Param(..) => self.found_param_ty(ty),
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 1bc4599377a..ffbe2888bf8 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1824,12 +1824,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 ty::Alias(ty::Projection, ..) => Some(12),
                 ty::Alias(ty::Inherent, ..) => Some(13),
                 ty::Alias(ty::Opaque, ..) => Some(14),
-                ty::Never => Some(15),
-                ty::Adt(..) => Some(16),
-                ty::Generator(..) => Some(17),
-                ty::Foreign(..) => Some(18),
-                ty::GeneratorWitness(..) => Some(19),
-                ty::GeneratorWitnessMIR(..) => Some(20),
+                ty::Alias(ty::Weak, ..) => Some(15),
+                ty::Never => Some(16),
+                ty::Adt(..) => Some(17),
+                ty::Generator(..) => Some(18),
+                ty::Foreign(..) => Some(19),
+                ty::GeneratorWitness(..) => Some(20),
+                ty::GeneratorWitnessMIR(..) => Some(21),
                 ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 5783383e93e..fcf813e3a39 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3198,6 +3198,29 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     )
                 });
             }
+            ObligationCauseCode::TypeAlias(ref nested, span, def_id) => {
+                // #74711: avoid a stack overflow
+                ensure_sufficient_stack(|| {
+                    self.note_obligation_cause_code(
+                        body_id,
+                        err,
+                        predicate,
+                        param_env,
+                        nested,
+                        obligated_types,
+                        seen_requirements,
+                    )
+                });
+                let mut multispan = MultiSpan::from(span);
+                multispan.push_span_label(span, "required by this bound");
+                err.span_note(
+                    multispan,
+                    format!(
+                        "required by a bound on the type alias `{}`",
+                        self.infcx.tcx.item_name(def_id)
+                    ),
+                );
+            }
             ObligationCauseCode::FunctionArgumentObligation {
                 arg_hir_id,
                 call_hir_id,
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index f8d056e321e..ff55eaf13ad 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -9,7 +9,7 @@ use rustc_span::def_id::LocalDefId;
 
 pub use rustc_middle::traits::query::OutlivesBound;
 
-type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
+pub type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
 pub trait InferCtxtExt<'a, 'tcx> {
     fn implied_outlives_bounds(
         &self,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 0a1e971f268..8399fbfc5be 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -3,6 +3,7 @@
 use super::specialization_graph;
 use super::translate_substs;
 use super::util;
+use super::ImplSourceUserDefinedData;
 use super::MismatchedProjectionTypes;
 use super::Obligation;
 use super::ObligationCause;
@@ -10,10 +11,6 @@ use super::PredicateObligation;
 use super::Selection;
 use super::SelectionContext;
 use super::SelectionError;
-use super::{
-    ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
-    ImplSourceUserDefinedData,
-};
 use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
 
 use crate::errors::InherentProjectionNormalizationOverflow;
@@ -30,7 +27,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::at::At;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::infer::DefineOpaqueTypes;
-use rustc_infer::traits::ImplSourceBuiltinData;
+use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
@@ -621,6 +618,30 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 );
                 normalized_ty
             }
+            ty::Weak => {
+                let infcx = self.selcx.infcx;
+                self.obligations.extend(
+                    infcx
+                        .tcx
+                        .predicates_of(data.def_id)
+                        .instantiate_own(infcx.tcx, data.substs)
+                        .map(|(mut predicate, span)| {
+                            if data.has_escaping_bound_vars() {
+                                (predicate, ..) = BoundVarReplacer::replace_bound_vars(
+                                    infcx,
+                                    &mut self.universes,
+                                    predicate,
+                                );
+                            }
+                            let mut cause = self.cause.clone();
+                            cause.map_code(|code| {
+                                ObligationCauseCode::TypeAlias(code, span, data.def_id)
+                            });
+                            Obligation::new(infcx.tcx, cause, self.param_env, predicate)
+                        }),
+                );
+                infcx.tcx.type_of(data.def_id).subst(infcx.tcx, data.substs).fold_with(self)
+            }
 
             ty::Inherent if !data.has_escaping_bound_vars() => {
                 // This branch is *mostly* just an optimization: when we don't
@@ -1545,7 +1566,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
     // Check whether the self-type is itself a projection.
     // If so, extract what we know from the trait and try to come up with a good answer.
     let bounds = match *obligation.predicate.self_ty().kind() {
-        // Excluding IATs here as they don't have meaningful item bounds.
+        // Excluding IATs and type aliases here as they don't have meaningful item bounds.
         ty::Alias(ty::Projection | ty::Opaque, ref data) => {
             tcx.item_bounds(data.def_id).subst(tcx, data.substs)
         }
@@ -1696,11 +1717,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
         };
 
         let eligible = match &impl_source {
-            super::ImplSource::Closure(_)
-            | super::ImplSource::Generator(_)
-            | super::ImplSource::Future(_)
-            | super::ImplSource::FnPointer(_)
-            | super::ImplSource::TraitAlias(_) => true,
+            super::ImplSource::TraitAlias(_) => true,
             super::ImplSource::UserDefined(impl_data) => {
                 // We have to be careful when projecting out of an
                 // impl because of specialization. If we are not in
@@ -1758,7 +1775,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                 let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
 
                 let lang_items = selcx.tcx().lang_items();
-                if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
+                if [lang_items.gen_trait(), lang_items.future_trait()].contains(&Some(poly_trait_ref.def_id()))
+                    || selcx.tcx().fn_trait_kind_from_def_id(poly_trait_ref.def_id()).is_some()
+                {
+                    true
+                } else if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
                     match self_ty.kind() {
                         ty::Bool
                         | ty::Char
@@ -1905,9 +1926,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                 // why we special case object types.
                 false
             }
-            super::ImplSource::AutoImpl(..)
-            | super::ImplSource::TraitUpcasting(_)
-            | super::ImplSource::ConstDestruct(_) => {
+            | super::ImplSource::TraitUpcasting(_) => {
                 // These traits have no associated types.
                 selcx.tcx().sess.delay_span_bug(
                     obligation.cause.span,
@@ -1971,17 +1990,27 @@ fn confirm_select_candidate<'cx, 'tcx>(
 ) -> Progress<'tcx> {
     match impl_source {
         super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
-        super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
-        super::ImplSource::Future(data) => confirm_future_candidate(selcx, obligation, data),
-        super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
-        super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
-        super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
+        super::ImplSource::Builtin(data) => {
+            let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx());
+            let lang_items = selcx.tcx().lang_items();
+            if lang_items.gen_trait() == Some(trait_def_id) {
+                confirm_generator_candidate(selcx, obligation, data)
+            } else if lang_items.future_trait() == Some(trait_def_id) {
+                confirm_future_candidate(selcx, obligation, data)
+            } else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
+                if obligation.predicate.self_ty().is_closure() {
+                    confirm_closure_candidate(selcx, obligation, data)
+                } else {
+                    confirm_fn_pointer_candidate(selcx, obligation, data)
+                }
+            } else {
+                confirm_builtin_candidate(selcx, obligation, data)
+            }
+        }
         super::ImplSource::Object(_)
-        | super::ImplSource::AutoImpl(..)
         | super::ImplSource::Param(..)
         | super::ImplSource::TraitUpcasting(_)
-        | super::ImplSource::TraitAlias(..)
-        | super::ImplSource::ConstDestruct(_) => {
+        | super::ImplSource::TraitAlias(..) => {
             // we don't create Select candidates with this kind of resolution
             span_bug!(
                 obligation.cause.span,
@@ -1995,9 +2024,14 @@ fn confirm_select_candidate<'cx, 'tcx>(
 fn confirm_generator_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    impl_source: ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>,
+    nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let gen_sig = impl_source.substs.as_generator().poly_sig();
+    let ty::Generator(_, substs, _) =
+        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
+    else {
+        unreachable!()
+    };
+    let gen_sig = substs.as_generator().poly_sig();
     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
         selcx,
         obligation.param_env,
@@ -2035,16 +2069,21 @@ fn confirm_generator_candidate<'cx, 'tcx>(
     });
 
     confirm_param_env_candidate(selcx, obligation, predicate, false)
-        .with_addl_obligations(impl_source.nested)
+        .with_addl_obligations(nested)
         .with_addl_obligations(obligations)
 }
 
 fn confirm_future_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    impl_source: ImplSourceFutureData<'tcx, PredicateObligation<'tcx>>,
+    nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let gen_sig = impl_source.substs.as_generator().poly_sig();
+    let ty::Generator(_, substs, _) =
+        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
+    else {
+        unreachable!()
+    };
+    let gen_sig = substs.as_generator().poly_sig();
     let Normalized { value: gen_sig, obligations } = normalize_with_depth(
         selcx,
         obligation.param_env,
@@ -2074,14 +2113,14 @@ fn confirm_future_candidate<'cx, 'tcx>(
     });
 
     confirm_param_env_candidate(selcx, obligation, predicate, false)
-        .with_addl_obligations(impl_source.nested)
+        .with_addl_obligations(nested)
         .with_addl_obligations(obligations)
 }
 
 fn confirm_builtin_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
+    data: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
     let self_ty = obligation.predicate.self_ty();
@@ -2129,15 +2168,15 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
 
     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
         .with_addl_obligations(obligations)
-        .with_addl_obligations(data.nested)
+        .with_addl_obligations(data)
 }
 
 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    fn_pointer_impl_source: ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>,
+    nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let fn_type = selcx.infcx.shallow_resolve(fn_pointer_impl_source.fn_ty);
+    let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
     let sig = fn_type.fn_sig(selcx.tcx());
     let Normalized { value: sig, obligations } = normalize_with_depth(
         selcx,
@@ -2148,16 +2187,21 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
     );
 
     confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
-        .with_addl_obligations(fn_pointer_impl_source.nested)
+        .with_addl_obligations(nested)
         .with_addl_obligations(obligations)
 }
 
 fn confirm_closure_candidate<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
-    impl_source: ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>,
+    nested: Vec<PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let closure_sig = impl_source.substs.as_closure().sig();
+    let ty::Closure(_, substs) =
+        selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
+    else {
+        unreachable!()
+    };
+    let closure_sig = substs.as_closure().sig();
     let Normalized { value: closure_sig, obligations } = normalize_with_depth(
         selcx,
         obligation.param_env,
@@ -2169,7 +2213,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
     debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
 
     confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
-        .with_addl_obligations(impl_source.nested)
+        .with_addl_obligations(nested)
         .with_addl_obligations(obligations)
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 8bf934cb78a..2d97a808225 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -257,7 +257,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
 
             ty::Opaque => ty.try_super_fold_with(self)?,
 
-            ty::Projection | ty::Inherent => {
+            ty::Projection | ty::Inherent | ty::Weak => {
                 // See note in `rustc_trait_selection::traits::project`
 
                 let infcx = self.infcx;
@@ -282,6 +282,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
                 debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                 let result = match kind {
                     ty::Projection => tcx.normalize_projection_ty(c_data),
+                    ty::Weak => tcx.normalize_weak_ty(c_data),
                     ty::Inherent => tcx.normalize_inherent_projection_ty(c_data),
                     _ => unreachable!(),
                 }?;
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 3c223db5a0b..f2dfa6921f4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -143,7 +143,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // Before we go into the whole placeholder thing, just
         // quickly check if the self-type is a projection at all.
         match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
-            // Excluding IATs here as they don't have meaningful item bounds.
+            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
             ty::Alias(ty::Projection | ty::Opaque, _) => {}
             ty::Infer(ty::TyVar(_)) => {
                 span_bug!(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 7853af959ad..3c356978d5c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -27,11 +27,9 @@ use crate::traits::vtable::{
 };
 use crate::traits::{
     BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
-    ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
-    ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
-    ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
-    ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
-    ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
+    ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData,
+    ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
+    OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
     TraitNotObjectSafe, TraitObligation, Unimplemented,
 };
 
@@ -72,7 +70,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             AutoImplCandidate => {
                 let data = self.confirm_auto_impl_candidate(obligation);
-                ImplSource::AutoImpl(data)
+                ImplSource::Builtin(data)
             }
 
             ProjectionCandidate(idx, constness) => {
@@ -87,22 +85,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             ClosureCandidate { .. } => {
                 let vtable_closure = self.confirm_closure_candidate(obligation)?;
-                ImplSource::Closure(vtable_closure)
+                ImplSource::Builtin(vtable_closure)
             }
 
             GeneratorCandidate => {
                 let vtable_generator = self.confirm_generator_candidate(obligation)?;
-                ImplSource::Generator(vtable_generator)
+                ImplSource::Builtin(vtable_generator)
             }
 
             FutureCandidate => {
                 let vtable_future = self.confirm_future_candidate(obligation)?;
-                ImplSource::Future(vtable_future)
+                ImplSource::Builtin(vtable_future)
             }
 
             FnPointerCandidate { is_const } => {
                 let data = self.confirm_fn_pointer_candidate(obligation, is_const)?;
-                ImplSource::FnPointer(data)
+                ImplSource::Builtin(data)
             }
 
             TraitAliasCandidate => {
@@ -114,7 +112,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // This indicates something like `Trait + Send: Send`. In this case, we know that
                 // this holds because that's what the object type is telling us, and there's really
                 // no additional obligations to prove and no types in particular to unify, etc.
-                ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst)
+                ImplSource::Builtin(Vec::new())
             }
 
             BuiltinUnsizeCandidate => {
@@ -129,7 +127,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             ConstDestructCandidate(def_id) => {
                 let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
-                ImplSource::ConstDestruct(data)
+                ImplSource::Builtin(data)
             }
         };
 
@@ -163,7 +161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let placeholder_self_ty = placeholder_trait_predicate.self_ty();
         let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
         let (def_id, substs) = match *placeholder_self_ty.kind() {
-            // Excluding IATs here as they don't have meaningful item bounds.
+            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
             ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
                 (def_id, substs)
             }
@@ -244,7 +242,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         obligation: &TraitObligation<'tcx>,
         has_nested: bool,
-    ) -> ImplSourceBuiltinData<PredicateObligation<'tcx>> {
+    ) -> Vec<PredicateObligation<'tcx>> {
         debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
 
         let lang_items = self.tcx().lang_items();
@@ -277,14 +275,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         debug!(?obligations);
 
-        ImplSourceBuiltinData { nested: obligations }
+        obligations
     }
 
     #[instrument(level = "debug", skip(self))]
     fn confirm_transmutability_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         use rustc_transmute::{Answer, Condition};
         #[instrument(level = "debug", skip(tcx, obligation, predicate))]
         fn flatten_answer_tree<'tcx>(
@@ -369,7 +367,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         };
 
         debug!(?fully_flattened);
-        Ok(ImplSourceBuiltinData { nested: fully_flattened })
+        Ok(fully_flattened)
     }
 
     /// This handles the case where an `auto trait Foo` impl is being used.
@@ -380,7 +378,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn confirm_auto_impl_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
+    ) -> Vec<PredicateObligation<'tcx>> {
         debug!(?obligation, "confirm_auto_impl_candidate");
 
         let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
@@ -394,7 +392,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &TraitObligation<'tcx>,
         trait_def_id: DefId,
         nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
-    ) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
+    ) -> Vec<PredicateObligation<'tcx>> {
         debug!(?nested, "vtable_auto_impl");
         ensure_sufficient_stack(|| {
             let cause = obligation.derived_cause(BuiltinDerivedObligation);
@@ -424,7 +422,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             debug!(?obligations, "vtable_auto_impl");
 
-            ImplSourceAutoImplData { trait_def_id, nested: obligations }
+            obligations
         })
     }
 
@@ -487,7 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         obligation: &TraitObligation<'tcx>,
         index: usize,
-    ) -> Result<ImplSourceObjectData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         let tcx = self.tcx();
         debug!(?obligation, ?index, "confirm_object_candidate");
 
@@ -654,15 +652,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
         );
 
-        Ok(ImplSourceObjectData { upcast_trait_ref, vtable_base, nested })
+        Ok(ImplSourceObjectData {
+            upcast_trait_def_id: upcast_trait_ref.def_id(),
+            vtable_base,
+            nested,
+        })
     }
 
     fn confirm_fn_pointer_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
         is_const: bool,
-    ) -> Result<ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
-    {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         debug!(?obligation, "confirm_fn_pointer_candidate");
 
         let tcx = self.tcx();
@@ -714,7 +715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]);
         nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
 
-        Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
+        Ok(nested)
     }
 
     fn confirm_trait_alias_candidate(
@@ -746,8 +747,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn confirm_generator_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> Result<ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
-    {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         // Okay to skip binder because the substs on generator types never
         // touch bound regions, they just capture the in-scope
         // type/region parameters.
@@ -780,13 +780,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
         debug!(?trait_ref, ?nested, "generator candidate obligations");
 
-        Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
+        Ok(nested)
     }
 
     fn confirm_future_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> Result<ImplSourceFutureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         // Okay to skip binder because the substs on generator types never
         // touch bound regions, they just capture the in-scope
         // type/region parameters.
@@ -810,14 +810,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
         debug!(?trait_ref, ?nested, "future candidate obligations");
 
-        Ok(ImplSourceFutureData { generator_def_id, substs, nested })
+        Ok(nested)
     }
 
     #[instrument(skip(self), level = "debug")]
     fn confirm_closure_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> Result<ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         let kind = self
             .tcx()
             .fn_trait_kind_from_def_id(obligation.predicate.def_id())
@@ -844,7 +844,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ));
         }
 
-        Ok(ImplSourceClosureData { closure_def_id, substs, nested })
+        Ok(nested)
     }
 
     /// In the case of closure types and fn pointers,
@@ -912,8 +912,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         obligation: &TraitObligation<'tcx>,
         idx: usize,
-    ) -> Result<ImplSourceTraitUpcastingData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
-    {
+    ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         let tcx = self.tcx();
 
         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
@@ -1010,13 +1009,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let vtable_vptr_slot =
             prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap();
 
-        Ok(ImplSourceTraitUpcastingData { upcast_trait_ref, vtable_vptr_slot, nested })
+        Ok(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
     }
 
     fn confirm_builtin_unsize_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
-    ) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         let tcx = self.tcx();
 
         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
@@ -1217,17 +1216,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => bug!("source: {source}, target: {target}"),
         };
 
-        Ok(ImplSourceBuiltinData { nested })
+        Ok(nested)
     }
 
     fn confirm_const_destruct_candidate(
         &mut self,
         obligation: &TraitObligation<'tcx>,
         impl_def_id: Option<DefId>,
-    ) -> Result<ImplSourceConstDestructData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+    ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
         if !obligation.is_const() {
-            return Ok(ImplSourceConstDestructData { nested: vec![] });
+            return Ok(vec![]);
         }
 
         let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
@@ -1381,6 +1380,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
         }
 
-        Ok(ImplSourceConstDestructData { nested })
+        Ok(nested)
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5acd7b573dd..e72d3ca97d7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -518,19 +518,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     // The result is "true" if the obligation *may* hold and "false" if
     // we can be sure it does not.
 
-    /// Evaluates whether the obligation `obligation` can be satisfied (by any means).
-    pub fn predicate_may_hold_fatal(&mut self, obligation: &PredicateObligation<'tcx>) -> bool {
-        debug!(?obligation, "predicate_may_hold_fatal");
-
-        // This fatal query is a stopgap that should only be used in standard mode,
-        // where we do not expect overflow to be propagated.
-        assert!(self.query_mode == TraitQueryMode::Standard);
-
-        self.evaluate_root_obligation(obligation)
-            .expect("Overflow should be caught earlier in standard query mode")
-            .may_apply()
-    }
-
     /// Evaluates whether the obligation `obligation` can be satisfied
     /// and returns an `EvaluationResult`. This is meant for the
     /// *initial* call.
@@ -2327,7 +2314,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Dynamic(..)
             | ty::Param(..)
             | ty::Foreign(..)
-            | ty::Alias(ty::Projection | ty::Inherent, ..)
+            | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
             | ty::Bound(..)
             | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                 bug!("asked to assemble constituent types of unexpected type: {:?}", t);
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 537405b7eb9..906c357e8ca 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -243,12 +243,12 @@ pub fn upcast_choices<'tcx>(
 /// `object.upcast_trait_ref`) within the vtable for `object`.
 pub fn get_vtable_index_of_object_method<'tcx, N>(
     tcx: TyCtxt<'tcx>,
-    object: &super::ImplSourceObjectData<'tcx, N>,
+    object: &super::ImplSourceObjectData<N>,
     method_def_id: DefId,
 ) -> Option<usize> {
     // Count number of methods preceding the one we are selecting and
     // add them to the total offset.
-    tcx.own_existential_vtable_entries(object.upcast_trait_ref.def_id())
+    tcx.own_existential_vtable_entries(object.upcast_trait_def_id)
         .iter()
         .copied()
         .position(|def_id| def_id == method_def_id)
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 086ab32b520..92d899b0f13 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -731,6 +731,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                     }
                 }
 
+                ty::Alias(ty::Weak, ty::AliasTy { def_id, substs, .. }) => {
+                    let obligations = self.nominal_obligations(def_id, substs);
+                    self.out.extend(obligations);
+                }
+
                 ty::Dynamic(data, r, _) => {
                     // WfObject
                     //
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index e6c6e0f13df..f9a7c8c386a 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -372,6 +372,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                     substitution: substs.lower_into(interner),
                 }))
             }
+            ty::Alias(ty::Weak, ty::AliasTy { .. }) => unimplemented!(),
             ty::Alias(ty::Inherent, _) => unimplemented!(),
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
                 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index b552ba41acd..83828f177bc 100644
--- a/compiler/rustc_traits/src/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
@@ -10,7 +10,12 @@ use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext};
 use std::sync::atomic::Ordering;
 
 pub(crate) fn provide(p: &mut Providers) {
-    *p = Providers { normalize_projection_ty, normalize_inherent_projection_ty, ..*p };
+    *p = Providers {
+        normalize_projection_ty,
+        normalize_weak_ty,
+        normalize_inherent_projection_ty,
+        ..*p
+    };
 }
 
 fn normalize_projection_ty<'tcx>(
@@ -43,6 +48,33 @@ fn normalize_projection_ty<'tcx>(
     )
 }
 
+fn normalize_weak_ty<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    goal: CanonicalProjectionGoal<'tcx>,
+) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> {
+    debug!("normalize_provider(goal={:#?})", goal);
+
+    tcx.sess.perf_stats.normalize_projection_ty.fetch_add(1, Ordering::Relaxed);
+    tcx.infer_ctxt().enter_canonical_trait_query(
+        &goal,
+        |ocx, ParamEnvAnd { param_env, value: goal }| {
+            let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.substs).map(
+                |(predicate, span)| {
+                    traits::Obligation::new(
+                        tcx,
+                        ObligationCause::dummy_with_span(span),
+                        param_env,
+                        predicate,
+                    )
+                },
+            );
+            ocx.register_obligations(obligations);
+            let normalized_ty = tcx.type_of(goal.def_id).subst(tcx, goal.substs);
+            Ok(NormalizationResult { normalized_ty })
+        },
+    )
+}
+
 fn normalize_inherent_projection_ty<'tcx>(
     tcx: TyCtxt<'tcx>,
     goal: CanonicalProjectionGoal<'tcx>,
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index dd911239ac4..45b1075b602 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -177,85 +177,6 @@ fn resolve_associated_item<'tcx>(
 
             Some(ty::Instance::new(leaf_def.item.def_id, substs))
         }
-        traits::ImplSource::Generator(generator_data) => {
-            if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
-                // For compiler developers who'd like to add new items to `Generator`,
-                // you either need to generate a shim body, or perhaps return
-                // `InstanceDef::Item` pointing to a trait default method body if
-                // it is given a default implementation by the trait.
-                span_bug!(
-                    tcx.def_span(generator_data.generator_def_id),
-                    "no definition for `{trait_ref}::{}` for built-in generator type",
-                    tcx.item_name(trait_item_id)
-                )
-            }
-            Some(Instance {
-                def: ty::InstanceDef::Item(generator_data.generator_def_id),
-                substs: generator_data.substs,
-            })
-        }
-        traits::ImplSource::Future(future_data) => {
-            if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
-                // `Future::poll` is generated by the compiler.
-                Some(Instance {
-                    def: ty::InstanceDef::Item(future_data.generator_def_id),
-                    substs: future_data.substs,
-                })
-            } else {
-                // All other methods are default methods of the `Future` trait.
-                // (this assumes that `ImplSource::Future` is only used for methods on `Future`)
-                debug_assert!(tcx.defaultness(trait_item_id).has_value());
-                Some(Instance::new(trait_item_id, rcvr_substs))
-            }
-        }
-        traits::ImplSource::Closure(closure_data) => {
-            if cfg!(debug_assertions)
-                && ![sym::call, sym::call_mut, sym::call_once]
-                    .contains(&tcx.item_name(trait_item_id))
-            {
-                // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
-                // you either need to generate a shim body, or perhaps return
-                // `InstanceDef::Item` pointing to a trait default method body if
-                // it is given a default implementation by the trait.
-                span_bug!(
-                    tcx.def_span(closure_data.closure_def_id),
-                    "no definition for `{trait_ref}::{}` for built-in closure type",
-                    tcx.item_name(trait_item_id)
-                )
-            }
-            let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
-            Instance::resolve_closure(
-                tcx,
-                closure_data.closure_def_id,
-                closure_data.substs,
-                trait_closure_kind,
-            )
-        }
-        traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
-            ty::FnDef(..) | ty::FnPtr(..) => {
-                if cfg!(debug_assertions)
-                    && ![sym::call, sym::call_mut, sym::call_once]
-                        .contains(&tcx.item_name(trait_item_id))
-                {
-                    // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
-                    // you either need to generate a shim body, or perhaps return
-                    // `InstanceDef::Item` pointing to a trait default method body if
-                    // it is given a default implementation by the trait.
-                    bug!(
-                        "no definition for `{trait_ref}::{}` for built-in fn type",
-                        tcx.item_name(trait_item_id)
-                    )
-                }
-                Some(Instance {
-                    def: ty::InstanceDef::FnPtrShim(trait_item_id, data.fn_ty),
-                    substs: rcvr_substs,
-                })
-            }
-            _ => bug!(
-                "no built-in definition for `{trait_ref}::{}` for non-fn type",
-                tcx.item_name(trait_item_id)
-            ),
-        },
         traits::ImplSource::Object(ref data) => {
             traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {
                 Instance {
@@ -308,15 +229,73 @@ fn resolve_associated_item<'tcx>(
                         span: tcx.def_span(trait_item_id),
                     })
                 }
+            } else if Some(trait_ref.def_id) == lang_items.future_trait() {
+                let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
+                    bug!()
+                };
+                if Some(trait_item_id) == tcx.lang_items().future_poll_fn() {
+                    // `Future::poll` is generated by the compiler.
+                    Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs: substs })
+                } else {
+                    // All other methods are default methods of the `Future` trait.
+                    // (this assumes that `ImplSource::Builtin` is only used for methods on `Future`)
+                    debug_assert!(tcx.defaultness(trait_item_id).has_value());
+                    Some(Instance::new(trait_item_id, rcvr_substs))
+                }
+            } else if Some(trait_ref.def_id) == lang_items.gen_trait() {
+                let ty::Generator(generator_def_id, substs, _) = *rcvr_substs.type_at(0).kind() else {
+                    bug!()
+                };
+                if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::resume {
+                    // For compiler developers who'd like to add new items to `Generator`,
+                    // you either need to generate a shim body, or perhaps return
+                    // `InstanceDef::Item` pointing to a trait default method body if
+                    // it is given a default implementation by the trait.
+                    span_bug!(
+                        tcx.def_span(generator_def_id),
+                        "no definition for `{trait_ref}::{}` for built-in generator type",
+                        tcx.item_name(trait_item_id)
+                    )
+                }
+                Some(Instance { def: ty::InstanceDef::Item(generator_def_id), substs })
+            } else if tcx.fn_trait_kind_from_def_id(trait_ref.def_id).is_some() {
+                // FIXME: This doesn't check for malformed libcore that defines, e.g.,
+                // `trait Fn { fn call_once(&self) { .. } }`. This is mostly for extension
+                // methods.
+                if cfg!(debug_assertions)
+                    && ![sym::call, sym::call_mut, sym::call_once]
+                        .contains(&tcx.item_name(trait_item_id))
+                {
+                    // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
+                    // you either need to generate a shim body, or perhaps return
+                    // `InstanceDef::Item` pointing to a trait default method body if
+                    // it is given a default implementation by the trait.
+                    bug!(
+                        "no definition for `{trait_ref}::{}` for built-in callable type",
+                        tcx.item_name(trait_item_id)
+                    )
+                }
+                match *rcvr_substs.type_at(0).kind() {
+                    ty::Closure(closure_def_id, substs) => {
+                        let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap();
+                        Instance::resolve_closure(tcx, closure_def_id, substs, trait_closure_kind)
+                    }
+                    ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
+                        def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_substs.type_at(0)),
+                        substs: rcvr_substs,
+                    }),
+                    _ => bug!(
+                        "no built-in definition for `{trait_ref}::{}` for non-fn type",
+                        tcx.item_name(trait_item_id)
+                    ),
+                }
             } else {
                 None
             }
         }
-        traits::ImplSource::AutoImpl(..)
-        | traits::ImplSource::Param(..)
+        traits::ImplSource::Param(..)
         | traits::ImplSource::TraitAlias(..)
-        | traits::ImplSource::TraitUpcasting(_)
-        | traits::ImplSource::ConstDestruct(_) => None,
+        | traits::ImplSource::TraitUpcasting(_) => None,
     })
 }
 
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index fa18f921ee4..f621673f1d6 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -36,9 +36,17 @@ pub enum DynKind {
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum AliasKind {
+    /// A projection `<Type as Trait>::AssocType`.
+    /// Can get normalized away if monomorphic enough.
     Projection,
     Inherent,
+    /// An opaque type (usually from `impl Trait` in type aliases or function return types)
+    /// Can only be normalized away in RevealAll mode
     Opaque,
+    /// A type alias that actually checks its trait bounds.
+    /// Currently only used if the type alias references opaque types.
+    /// Can always be normalized away.
+    Weak,
 }
 
 /// Defines the kinds of types used by the type system.
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 59fa91c1066..967ad3a0e69 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -56,6 +56,11 @@
 //! [`Rc`]: rc
 //! [`RefCell`]: core::cell
 
+// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
+//
 #![allow(unused_attributes)]
 #![stable(feature = "alloc", since = "1.36.0")]
 #![doc(
@@ -75,11 +80,6 @@
 ))]
 #![no_std]
 #![needs_allocator]
-// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be
-// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// rustc itself never sets the feature, so this line has no affect there.
-#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
-//
 // Lints:
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(fuzzy_provenance_casts)]
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index a853f15edb7..ff7e91d3ec3 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -32,6 +32,8 @@ use crate::ptr::NonNull;
 )]
 #[doc(hidden)]
 #[repr(transparent)]
+// Lang item used experimentally by Miri to define the semantics of `Unique`.
+#[cfg_attr(not(bootstrap), lang = "ptr_unique")]
 pub struct Unique<T: ?Sized> {
     pointer: NonNull<T>,
     // NOTE: this marker has no consequences for variance, but is necessary
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 4f339a18a48..3edf9d747ce 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -47,9 +47,9 @@ use buffer::Buffer;
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct BufReader<R> {
-    inner: R,
+pub struct BufReader<R: ?Sized> {
     buf: Buffer,
+    inner: R,
 }
 
 impl<R: Read> BufReader<R> {
@@ -95,7 +95,7 @@ impl<R: Read> BufReader<R> {
     }
 }
 
-impl<R> BufReader<R> {
+impl<R: ?Sized> BufReader<R> {
     /// Gets a reference to the underlying reader.
     ///
     /// It is inadvisable to directly read from the underlying reader.
@@ -213,7 +213,10 @@ impl<R> BufReader<R> {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_inner(self) -> R {
+    pub fn into_inner(self) -> R
+    where
+        R: Sized,
+    {
         self.inner
     }
 
@@ -226,13 +229,13 @@ impl<R> BufReader<R> {
 
 // This is only used by a test which asserts that the initialization-tracking is correct.
 #[cfg(test)]
-impl<R> BufReader<R> {
+impl<R: ?Sized> BufReader<R> {
     pub fn initialized(&self) -> usize {
         self.buf.initialized()
     }
 }
 
-impl<R: Seek> BufReader<R> {
+impl<R: ?Sized + Seek> BufReader<R> {
     /// Seeks relative to the current position. If the new position lies within the buffer,
     /// the buffer will not be flushed, allowing for more efficient seeks.
     /// This method does not return the location of the underlying reader, so the caller
@@ -257,7 +260,7 @@ impl<R: Seek> BufReader<R> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Read> Read for BufReader<R> {
+impl<R: ?Sized + Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         // If we don't have any buffered data and we're doing a massive read
         // (larger than our internal buffer), bypass our internal buffer
@@ -371,7 +374,7 @@ impl<R: Read> Read for BufReader<R> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Read> BufRead for BufReader<R> {
+impl<R: ?Sized + Read> BufRead for BufReader<R> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         self.buf.fill_buf(&mut self.inner)
     }
@@ -384,11 +387,11 @@ impl<R: Read> BufRead for BufReader<R> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<R> fmt::Debug for BufReader<R>
 where
-    R: fmt::Debug,
+    R: ?Sized + fmt::Debug,
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufReader")
-            .field("reader", &self.inner)
+            .field("reader", &&self.inner)
             .field(
                 "buffer",
                 &format_args!("{}/{}", self.buf.filled() - self.buf.pos(), self.capacity()),
@@ -398,7 +401,7 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<R: Seek> Seek for BufReader<R> {
+impl<R: ?Sized + Seek> Seek for BufReader<R> {
     /// Seek to an offset, in bytes, in the underlying reader.
     ///
     /// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
@@ -491,7 +494,7 @@ impl<R: Seek> Seek for BufReader<R> {
     }
 }
 
-impl<T> SizeHint for BufReader<T> {
+impl<T: ?Sized> SizeHint for BufReader<T> {
     #[inline]
     fn lower_bound(&self) -> usize {
         SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index 14c455d4fa3..0e2450655e5 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -67,8 +67,7 @@ use crate::ptr;
 /// [`TcpStream`]: crate::net::TcpStream
 /// [`flush`]: BufWriter::flush
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct BufWriter<W: Write> {
-    inner: W,
+pub struct BufWriter<W: ?Sized + Write> {
     // The buffer. Avoid using this like a normal `Vec` in common code paths.
     // That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
     // methods that require bounds checking or the like. This makes an enormous
@@ -78,6 +77,7 @@ pub struct BufWriter<W: Write> {
     // write the buffered data a second time in BufWriter's destructor. This
     // flag tells the Drop impl if it should skip the flush.
     panicked: bool,
+    inner: W,
 }
 
 impl<W: Write> BufWriter<W> {
@@ -115,6 +115,69 @@ impl<W: Write> BufWriter<W> {
         BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
     }
 
+    /// Unwraps this `BufWriter<W>`, returning the underlying writer.
+    ///
+    /// The buffer is written out before returning the writer.
+    ///
+    /// # Errors
+    ///
+    /// An [`Err`] will be returned if an error occurs while flushing the buffer.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io::BufWriter;
+    /// use std::net::TcpStream;
+    ///
+    /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
+    ///
+    /// // unwrap the TcpStream and flush the buffer
+    /// let stream = buffer.into_inner().unwrap();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
+        match self.flush_buf() {
+            Err(e) => Err(IntoInnerError::new(self, e)),
+            Ok(()) => Ok(self.into_parts().0),
+        }
+    }
+
+    /// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
+    /// unwritten data.
+    ///
+    /// If the underlying writer panicked, it is not known what portion of the data was written.
+    /// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
+    /// contents can still be recovered).
+    ///
+    /// `into_parts` makes no attempt to flush data and cannot fail.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{BufWriter, Write};
+    ///
+    /// let mut buffer = [0u8; 10];
+    /// let mut stream = BufWriter::new(buffer.as_mut());
+    /// write!(stream, "too much data").unwrap();
+    /// stream.flush().expect_err("it doesn't fit");
+    /// let (recovered_writer, buffered_data) = stream.into_parts();
+    /// assert_eq!(recovered_writer.len(), 0);
+    /// assert_eq!(&buffered_data.unwrap(), b"ata");
+    /// ```
+    #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
+    pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
+        let buf = mem::take(&mut self.buf);
+        let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
+
+        // SAFETY: forget(self) prevents double dropping inner
+        let inner = unsafe { ptr::read(&self.inner) };
+        mem::forget(self);
+
+        (inner, buf)
+    }
+}
+
+impl<W: ?Sized + Write> BufWriter<W> {
     /// Send data in our local buffer into the inner writer, looping as
     /// necessary until either it's all been sent or an error occurs.
     ///
@@ -284,67 +347,6 @@ impl<W: Write> BufWriter<W> {
         self.buf.capacity()
     }
 
-    /// Unwraps this `BufWriter<W>`, returning the underlying writer.
-    ///
-    /// The buffer is written out before returning the writer.
-    ///
-    /// # Errors
-    ///
-    /// An [`Err`] will be returned if an error occurs while flushing the buffer.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::io::BufWriter;
-    /// use std::net::TcpStream;
-    ///
-    /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
-    ///
-    /// // unwrap the TcpStream and flush the buffer
-    /// let stream = buffer.into_inner().unwrap();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
-        match self.flush_buf() {
-            Err(e) => Err(IntoInnerError::new(self, e)),
-            Ok(()) => Ok(self.into_parts().0),
-        }
-    }
-
-    /// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
-    /// unwritten data.
-    ///
-    /// If the underlying writer panicked, it is not known what portion of the data was written.
-    /// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
-    /// contents can still be recovered).
-    ///
-    /// `into_parts` makes no attempt to flush data and cannot fail.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::io::{BufWriter, Write};
-    ///
-    /// let mut buffer = [0u8; 10];
-    /// let mut stream = BufWriter::new(buffer.as_mut());
-    /// write!(stream, "too much data").unwrap();
-    /// stream.flush().expect_err("it doesn't fit");
-    /// let (recovered_writer, buffered_data) = stream.into_parts();
-    /// assert_eq!(recovered_writer.len(), 0);
-    /// assert_eq!(&buffered_data.unwrap(), b"ata");
-    /// ```
-    #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
-    pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
-        let buf = mem::take(&mut self.buf);
-        let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
-
-        // SAFETY: forget(self) prevents double dropping inner
-        let inner = unsafe { ptr::read(&self.inner) };
-        mem::forget(self);
-
-        (inner, buf)
-    }
-
     // Ensure this function does not get inlined into `write`, so that it
     // remains inlineable and its common path remains as short as possible.
     // If this function ends up being called frequently relative to `write`,
@@ -511,7 +513,7 @@ impl fmt::Debug for WriterPanicked {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Write for BufWriter<W> {
+impl<W: ?Sized + Write> Write for BufWriter<W> {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         // Use < instead of <= to avoid a needless trip through the buffer in some cases.
@@ -640,20 +642,20 @@ impl<W: Write> Write for BufWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> fmt::Debug for BufWriter<W>
+impl<W: ?Sized + Write> fmt::Debug for BufWriter<W>
 where
     W: fmt::Debug,
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufWriter")
-            .field("writer", &self.inner)
+            .field("writer", &&self.inner)
             .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
             .finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write + Seek> Seek for BufWriter<W> {
+impl<W: ?Sized + Write + Seek> Seek for BufWriter<W> {
     /// Seek to the offset, in bytes, in the underlying writer.
     ///
     /// Seeking always writes out the internal buffer before seeking.
@@ -664,7 +666,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Drop for BufWriter<W> {
+impl<W: ?Sized + Write> Drop for BufWriter<W> {
     fn drop(&mut self) {
         if !self.panicked {
             // dtors should not panic, so we ignore a failed flush
diff --git a/library/std/src/io/buffered/linewriter.rs b/library/std/src/io/buffered/linewriter.rs
index a26a4ab330e..3d4ae704193 100644
--- a/library/std/src/io/buffered/linewriter.rs
+++ b/library/std/src/io/buffered/linewriter.rs
@@ -64,7 +64,7 @@ use crate::io::{self, buffered::LineWriterShim, BufWriter, IntoInnerError, IoSli
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct LineWriter<W: Write> {
+pub struct LineWriter<W: ?Sized + Write> {
     inner: BufWriter<W>,
 }
 
@@ -109,27 +109,6 @@ impl<W: Write> LineWriter<W> {
         LineWriter { inner: BufWriter::with_capacity(capacity, inner) }
     }
 
-    /// Gets a reference to the underlying writer.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::io::LineWriter;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let file = File::create("poem.txt")?;
-    ///     let file = LineWriter::new(file);
-    ///
-    ///     let reference = file.get_ref();
-    ///     Ok(())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_ref(&self) -> &W {
-        self.inner.get_ref()
-    }
-
     /// Gets a mutable reference to the underlying writer.
     ///
     /// Caution must be taken when calling methods on the mutable reference
@@ -184,8 +163,31 @@ impl<W: Write> LineWriter<W> {
     }
 }
 
+impl<W: ?Sized + Write> LineWriter<W> {
+    /// Gets a reference to the underlying writer.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io::LineWriter;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let file = File::create("poem.txt")?;
+    ///     let file = LineWriter::new(file);
+    ///
+    ///     let reference = file.get_ref();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &W {
+        self.inner.get_ref()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> Write for LineWriter<W> {
+impl<W: ?Sized + Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         LineWriterShim::new(&mut self.inner).write(buf)
     }
@@ -216,7 +218,7 @@ impl<W: Write> Write for LineWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W: Write> fmt::Debug for LineWriter<W>
+impl<W: ?Sized + Write> fmt::Debug for LineWriter<W>
 where
     W: fmt::Debug,
 {
diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs
index 0175d2693e8..f2a55da05b2 100644
--- a/library/std/src/io/buffered/linewritershim.rs
+++ b/library/std/src/io/buffered/linewritershim.rs
@@ -11,11 +11,11 @@ use crate::sys_common::memchr;
 /// `BufWriters` to be temporarily given line-buffering logic; this is what
 /// enables Stdout to be alternately in line-buffered or block-buffered mode.
 #[derive(Debug)]
-pub struct LineWriterShim<'a, W: Write> {
+pub struct LineWriterShim<'a, W: ?Sized + Write> {
     buffer: &'a mut BufWriter<W>,
 }
 
-impl<'a, W: Write> LineWriterShim<'a, W> {
+impl<'a, W: ?Sized + Write> LineWriterShim<'a, W> {
     pub fn new(buffer: &'a mut BufWriter<W>) -> Self {
         Self { buffer }
     }
@@ -49,7 +49,7 @@ impl<'a, W: Write> LineWriterShim<'a, W> {
     }
 }
 
-impl<'a, W: Write> Write for LineWriterShim<'a, W> {
+impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> {
     /// Write some data into this BufReader with line buffering. This means
     /// that, if any newlines are present in the data, the data up to the last
     /// newline is sent directly to the underlying writer, and data after it
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index 1d9d93f5b64..420fc400705 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -86,7 +86,7 @@ impl<W: Write + ?Sized> BufferedCopySpec for W {
     }
 }
 
-impl<I: Write> BufferedCopySpec for BufWriter<I> {
+impl<I: ?Sized + Write> BufferedCopySpec for BufWriter<I> {
     fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
         if writer.capacity() < DEFAULT_BUF_SIZE {
             return stack_buffer_copy(reader, writer);
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 8a007d095d5..173233d7150 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2754,7 +2754,7 @@ trait SizeHint {
     }
 }
 
-impl<T> SizeHint for T {
+impl<T: ?Sized> SizeHint for T {
     #[inline]
     default fn lower_bound(&self) -> usize {
         0
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index d53f1a2b2ff..da08c018d0e 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -188,6 +188,13 @@
 //! [array]: prim@array
 //! [slice]: prim@slice
 
+// To run std tests without x.py without ending up with two copies of std, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
+// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
+#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
+//
 #![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
 #![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
 #![doc(
@@ -202,12 +209,6 @@
     no_global_oom_handling,
     not(no_global_oom_handling)
 ))]
-// To run std tests without x.py without ending up with two copies of std, Miri needs to be
-// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// rustc itself never sets the feature, so this line has no affect there.
-#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
-// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
-#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
 // Don't link to std. We are std.
 #![no_std]
 // Tell the compiler to link to either panic_abort or panic_unwind
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 7565fbc0d09..814f1c7c283 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -17,6 +17,7 @@ mod libc {
     pub use libc::c_int;
     pub struct ucred;
     pub struct cmsghdr;
+    pub struct sockcred2;
     pub type pid_t = i32;
     pub type gid_t = u32;
     pub type uid_t = u32;
diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs
index 16c8e0c0ebf..7d49bbdcbe0 100644
--- a/library/std/src/sys/unix/kernel_copy.rs
+++ b/library/std/src/sys/unix/kernel_copy.rs
@@ -466,7 +466,7 @@ impl<T: CopyRead> CopyRead for Take<T> {
     }
 }
 
-impl<T: CopyRead> CopyRead for BufReader<T> {
+impl<T: ?Sized + CopyRead> CopyRead for BufReader<T> {
     fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64> {
         let buf = self.buffer();
         let buf = &buf[0..min(buf.len(), outer_limit.try_into().unwrap_or(usize::MAX))];
@@ -495,7 +495,7 @@ impl<T: CopyRead> CopyRead for BufReader<T> {
     }
 }
 
-impl<T: CopyWrite> CopyWrite for BufWriter<T> {
+impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
     fn properties(&self) -> CopyParams {
         self.get_ref().properties()
     }
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 878af5088d9..010015667f7 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -344,6 +344,29 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
                 }
             }
 
+            #[cfg(target_os = "netbsd")]
+            {
+                unsafe {
+                    let set = libc::_cpuset_create();
+                    if !set.is_null() {
+                        let mut count: usize = 0;
+                        if libc::pthread_getaffinity_np(libc::pthread_self(), libc::_cpuset_size(set), set) == 0 {
+                            for i in 0..u64::MAX {
+                                match libc::_cpuset_isset(i, set) {
+                                    -1 => break,
+                                    0 => continue,
+                                    _ => count = count + 1,
+                                }
+                            }
+                        }
+                        libc::_cpuset_destroy(set);
+                        if let Some(count) = NonZeroUsize::new(count) {
+                            return Ok(count);
+                        }
+                    }
+                }
+            }
+
             let mut cpus: libc::c_uint = 0;
             let mut cpus_size = crate::mem::size_of_val(&cpus);
 
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 515890aef8d..85a9a5d3375 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -45,6 +45,9 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
            python3 ../x.py test --stage 0 core alloc std test proc_macro && \
            # Build both public and internal documentation.
+           RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 library && \
+           mkdir -p /checkout/obj/staging/doc && \
+           cp -r build/x86_64-unknown-linux-gnu/doc /checkout/obj/staging && \
            RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 compiler && \
            RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 library/test && \
            /scripts/validate-toolstate.sh && \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 19ead2f1b11..efffc382242 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -34,6 +34,8 @@ x--expand-yaml-anchors--remove:
   - &shared-ci-variables
     CI_JOB_NAME: ${{ matrix.name }}
     CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
+    # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
+    HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
 
   - &public-variables
     SCCACHE_BUCKET: rust-lang-ci-sccache2
@@ -229,6 +231,20 @@ x--expand-yaml-anchors--remove:
           TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
         <<: *step
 
+      - name: create github artifacts
+        run: src/ci/scripts/create-doc-artifacts.sh
+        <<: *step
+
+      - name: upload artifacts to github
+        uses: actions/upload-artifact@v3
+        with:
+          # name is set in previous step
+          name: ${{ env.DOC_ARTIFACT_NAME }}
+          path: obj/artifacts/doc
+          if-no-files-found: ignore
+          retention-days: 5
+        <<: *step
+
       - name: upload artifacts to S3
         run: src/ci/scripts/upload-artifacts.sh
         env:
diff --git a/src/ci/scripts/create-doc-artifacts.sh b/src/ci/scripts/create-doc-artifacts.sh
new file mode 100755
index 00000000000..2516b0d8505
--- /dev/null
+++ b/src/ci/scripts/create-doc-artifacts.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Compress doc artifacts and name them based on the commit, or the date if
+# commit is not available.
+
+set -euox pipefail
+
+# Try to get short commit hash, fallback to date
+if [ -n "$HEAD_SHA" ]; then
+    short_rev=$(echo "${HEAD_SHA}" | cut -c1-8)
+else
+    short_rev=$(git rev-parse --short HEAD || date -u +'%Y-%m-%dT%H%M%SZ')
+fi
+
+# Try to get branch, fallback to none
+branch=$(git branch --show-current || echo)
+
+if [ -n "$branch" ]; then
+    branch="${branch}-"
+fi
+
+if [ "${GITHUB_EVENT_NAME:=none}" = "pull_request" ]; then
+    pr_num=$(echo "$GITHUB_REF_NAME" | cut -d'/' -f1)
+    name="doc-${pr_num}-${short_rev}"
+else
+    name="doc-${branch}${short_rev}"
+fi
+
+
+if [ -d "obj/staging/doc" ]; then
+    mkdir -p obj/artifacts/doc
+
+    # Level 12 seems to give a good tradeoff of time vs. space savings
+    ZSTD_CLEVEL=12 ZSTD_NBTHREADS=4 \
+    tar --zstd -cf "obj/artifacts/doc/${name}.tar.zst" -C obj/staging/doc .
+
+    ls -lh obj/artifacts/doc
+fi
+
+# Set this environment variable for future use if running in CI
+if [ -n "$GITHUB_ENV" ]; then
+    echo "DOC_ARTIFACT_NAME=${name}" >> "$GITHUB_ENV"
+fi
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 0c7950bfd3d..9f698a3b6bf 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2052,6 +2052,11 @@ pub(crate) fn clean_middle_ty<'tcx>(
             }))
         }
 
+        ty::Alias(ty::Weak, data) => {
+            let ty = cx.tcx.type_of(data.def_id).subst(cx.tcx, data.substs);
+            clean_middle_ty(bound_ty.rebind(ty), cx, None, None)
+        }
+
         ty::Param(ref p) => {
             if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
                 ImplTrait(bounds)
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 5bd9389a400..322ab7a4af3 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -800,10 +800,11 @@ fn assoc_type(
     if !bounds.is_empty() {
         write!(w, ": {}", print_generic_bounds(bounds, cx))
     }
-    write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
+    // Render the default before the where-clause which aligns with the new recommended style. See #89122.
     if let Some(default) = default {
         write!(w, " = {}", default.print(cx))
     }
+    write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
 }
 
 fn assoc_method(
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 054cfe7597e..b487cfa5c25 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -213,7 +213,7 @@ a.anchor,
 h1 a,
 .search-results a,
 .stab,
-.result-name .primitive > i, .result-name .keyword > i {
+.result-name i {
 	color: var(--main-color);
 }
 
@@ -887,7 +887,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 .search-results .result-name span.alias {
 	color: var(--search-results-alias-color);
 }
-.search-results .result-name span.grey {
+.search-results .result-name .grey {
 	color: var(--search-results-grey-color);
 }
 
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 25259971eff..e724bf1601a 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -35,6 +35,35 @@ const itemTypes = [
     "traitalias",
 ];
 
+const longItemTypes = [
+    "module",
+    "extern crate",
+    "re-export",
+    "struct",
+    "enum",
+    "function",
+    "type alias",
+    "static",
+    "trait",
+    "",
+    "trait method",
+    "method",
+    "struct field",
+    "enum variant",
+    "macro",
+    "primitive type",
+    "associated type",
+    "constant",
+    "associated constant",
+    "union",
+    "foreign type",
+    "keyword",
+    "existential type",
+    "attribute macro",
+    "derive macro",
+    "trait alias",
+];
+
 // used for special search precedence
 const TY_PRIMITIVE = itemTypes.indexOf("primitive");
 const TY_KEYWORD = itemTypes.indexOf("keyword");
@@ -1966,16 +1995,11 @@ function initSearch(rawSearchIndex) {
             array.forEach(item => {
                 const name = item.name;
                 const type = itemTypes[item.ty];
+                const longType = longItemTypes[item.ty];
+                const typeName = longType.length !== 0 ? `${longType}` : "?";
 
                 length += 1;
 
-                let extra = "";
-                if (type === "primitive") {
-                    extra = " <i>(primitive type)</i>";
-                } else if (type === "keyword") {
-                    extra = " <i>(keyword)</i>";
-                }
-
                 const link = document.createElement("a");
                 link.className = "result-" + type;
                 link.href = item.href;
@@ -1993,13 +2017,14 @@ function initSearch(rawSearchIndex) {
 
                     alias.insertAdjacentHTML(
                         "beforeend",
-                        "<span class=\"grey\"><i>&nbsp;- see&nbsp;</i></span>");
+                        "<i class=\"grey\">&nbsp;- see&nbsp;</i>");
 
                     resultName.appendChild(alias);
                 }
+
                 resultName.insertAdjacentHTML(
                     "beforeend",
-                    item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>");
+                    `${typeName} ${item.displayPath}<span class="${type}">${name}</span>`);
                 link.appendChild(resultName);
 
                 const description = document.createElement("div");
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index a1d2147cb49..dbaf6aaa853 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1424,6 +1424,7 @@ fn ty_auto_deref_stability<'tcx>(
                 continue;
             },
             ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty),
+            ty::Alias(ty::Weak, _) => unreachable!("should have been normalized away above"),
             ty::Alias(ty::Inherent, _) => unreachable!("inherent projection should have been normalized away above"),
             ty::Alias(ty::Projection, _) if ty.has_non_region_param() => {
                 TyPosition::new_deref_stable_for_result(precedence, ty)
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index d18f9387565..204019130ed 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -82,10 +82,4 @@ fn msrv_1_41() {
     }
 }
 
-type Opaque = impl Sized;
-struct IntoOpaque;
-impl Into<Opaque> for IntoOpaque {
-    fn into(self) -> Opaque {}
-}
-
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index de8ff0b06bd..46e02847e30 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -82,10 +82,4 @@ fn msrv_1_41() {
     }
 }
 
-type Opaque = impl Sized;
-struct IntoOpaque;
-impl Into<Opaque> for IntoOpaque {
-    fn into(self) -> Opaque {}
-}
-
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
index 3b280b7488a..bd62c655216 100644
--- a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
+++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
@@ -32,4 +32,10 @@ impl Into<u8> for ContainsVal {
     }
 }
 
+type Opaque = impl Sized;
+struct IntoOpaque;
+impl Into<Opaque> for IntoOpaque {
+    fn into(self) -> Opaque {}
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
index 251f1d84e74..bb966af4b0f 100644
--- a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
@@ -1,29 +1,12 @@
-error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into_unfixable.rs:11:1
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/from_over_into_unfixable.rs:35:15
    |
-LL | impl Into<InMacro> for String {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type Opaque = impl Sized;
+   |               ^^^^^^^^^^
    |
-   = help: replace the `Into` implementation with `From<std::string::String>`
-   = note: `-D clippy::from-over-into` implied by `-D warnings`
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
-error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into_unfixable.rs:19:1
-   |
-LL | impl Into<WeirdUpperSelf> for &'static [u8] {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: replace the `Into` implementation with `From<&'static [u8]>`
-
-error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into_unfixable.rs:28:1
-   |
-LL | impl Into<u8> for ContainsVal {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see
-           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence
-   = help: replace the `Into` implementation with `From<ContainsVal>`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self.rs b/src/tools/clippy/tests/ui/new_ret_no_self.rs
index a2a30c8b931..4eff62b85ff 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.rs
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.rs
@@ -401,25 +401,3 @@ mod issue7344 {
         }
     }
 }
-
-mod issue10041 {
-    struct Bomb;
-
-    impl Bomb {
-        // Hidden <Rhs = Self> default generic parameter.
-        pub fn new() -> impl PartialOrd {
-            0i32
-        }
-    }
-
-    // TAIT with self-referencing bounds
-    type X = impl std::ops::Add<Output = X>;
-
-    struct Bomb2;
-
-    impl Bomb2 {
-        pub fn new() -> X {
-            0i32
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self.stderr b/src/tools/clippy/tests/ui/new_ret_no_self.stderr
index 2eaebfb5cac..2b053b462b1 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.stderr
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.stderr
@@ -92,21 +92,5 @@ LL | |             unimplemented!()
 LL | |         }
    | |_________^
 
-error: methods called `new` usually return `Self`
-  --> $DIR/new_ret_no_self.rs:410:9
-   |
-LL | /         pub fn new() -> impl PartialOrd {
-LL | |             0i32
-LL | |         }
-   | |_________^
-
-error: methods called `new` usually return `Self`
-  --> $DIR/new_ret_no_self.rs:421:9
-   |
-LL | /         pub fn new() -> X {
-LL | |             0i32
-LL | |         }
-   | |_________^
-
-error: aborting due to 14 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs
new file mode 100644
index 00000000000..7bc6fec10ba
--- /dev/null
+++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+#![warn(clippy::new_ret_no_self)]
+
+mod issue10041 {
+    struct Bomb;
+
+    impl Bomb {
+        // Hidden <Rhs = Self> default generic parameter.
+        pub fn new() -> impl PartialOrd {
+            0i32
+        }
+    }
+
+    // TAIT with self-referencing bounds
+    type X = impl std::ops::Add<Output = X>;
+
+    struct Bomb2;
+
+    impl Bomb2 {
+        pub fn new() -> X {
+            0i32
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr
new file mode 100644
index 00000000000..babb634fdcd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `<i32 as std::ops::Add>::Output == issue10041::X`
+  --> $DIR/new_ret_no_self_overflow.rs:20:25
+   |
+LL |         pub fn new() -> X {
+   |                         ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 4b6de3601ca..aa382960891 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-c84d5e7078435a0ddd8770c3530fe7fdbf026ec4
+7513407ac8e673f536d34743fe393bd8b7c45441
diff --git a/src/tools/miri/tests/fail/terminate-terminator.rs b/src/tools/miri/tests/fail/terminate-terminator.rs
index b9199cff079..bd6cd69215a 100644
--- a/src/tools/miri/tests/fail/terminate-terminator.rs
+++ b/src/tools/miri/tests/fail/terminate-terminator.rs
@@ -1,4 +1,4 @@
-//@compile-flags: -Zmir-opt-level=3
+//@compile-flags: -Zmir-opt-level=3 -Zinline-mir-hint-threshold=1000
 // Enable MIR inlining to ensure that `TerminatorKind::Terminate` is generated
 // instead of just `UnwindAction::Terminate`.
 
diff --git a/tests/codegen/enum-debug-niche-2.rs b/tests/codegen/enum-debug-niche-2.rs
index 9c72ad9d248..4b607d50574 100644
--- a/tests/codegen/enum-debug-niche-2.rs
+++ b/tests/codegen/enum-debug-niche-2.rs
@@ -7,8 +7,8 @@
 // compile-flags: -g -C no-prepopulate-passes
 
 // CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}}
-// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i64 4294967295{{[,)].*}}
-// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}}
+// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i128 4294967295{{[,)].*}}
+// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i128 0{{[,)].*}}
 
 #![feature(never_type)]
 
diff --git a/tests/codegen/enum-u128.rs b/tests/codegen/enum-u128.rs
new file mode 100644
index 00000000000..f50d360ac9f
--- /dev/null
+++ b/tests/codegen/enum-u128.rs
@@ -0,0 +1,27 @@
+// This tests that debug info for "c-like" 128bit enums is properly emitted.
+// This is ignored for the fallback mode on MSVC due to problems with PDB.
+
+//
+// ignore-msvc
+
+// compile-flags: -g -C no-prepopulate-passes
+
+// CHECK-LABEL: @main
+// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "Foo",{{.*}}flags: DIFlagEnumClass,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Lo",{{.*}}value: 0,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Hi",{{.*}}value: 18446744073709551616,{{.*}}
+// CHECK: {{.*}}DIEnumerator{{.*}}name: "Bar",{{.*}}value: 18446745000000000123,{{.*}}
+
+#![allow(incomplete_features)]
+#![feature(repr128)]
+
+#[repr(u128)]
+pub enum Foo {
+    Lo,
+    Hi = 1 << 64,
+    Bar = 18_446_745_000_000_000_123,
+}
+
+pub fn main() {
+    let foo = Foo::Bar;
+}
diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs
index a977ebf1bb7..573ae1ba68d 100644
--- a/tests/mir-opt/inline/asm_unwind.rs
+++ b/tests/mir-opt/inline/asm_unwind.rs
@@ -2,6 +2,7 @@
 //
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 // needs-asm-support
+// compile-flags: -Zinline-mir-hint-threshold=1000
 #![feature(asm_unwind)]
 
 struct D;
@@ -10,7 +11,7 @@ impl Drop for D {
     fn drop(&mut self) {}
 }
 
-#[inline(always)]
+#[inline]
 fn foo() {
     let _d = D;
     unsafe { std::arch::asm!("", options(may_unwind)) };
diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs
index af2ca895cc6..1b74d818451 100644
--- a/tests/mir-opt/inline/cycle.rs
+++ b/tests/mir-opt/inline/cycle.rs
@@ -1,4 +1,5 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// compile-flags: -Zinline-mir-hint-threshold=1000
 
 // EMIT_MIR cycle.f.Inline.diff
 #[inline(always)]
diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs
index febf1a8a6bf..e01c4c1dd02 100644
--- a/tests/mir-opt/inline/inline_diverging.rs
+++ b/tests/mir-opt/inline/inline_diverging.rs
@@ -1,6 +1,7 @@
 // Tests inlining of diverging calls.
 //
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// compile-flags: -Zinline-mir-hint-threshold=1000
 #![crate_type = "lib"]
 
 // EMIT_MIR inline_diverging.f.Inline.diff
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
index fa48c56d185..e05c605a4e4 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
@@ -4,30 +4,30 @@
   fn main() -> () {
       let mut _0: ();
       let _1: std::ops::GeneratorState<i32, bool>;
-      let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>;
-      let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
-      let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8];
+      let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>;
+      let mut _3: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
+      let mut _4: [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +     let mut _5: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
 +     }
-+     scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) {
++     scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new) {
 +         debug pointer => _3;
 +         scope 4 {
-+             scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) {
++             scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new_unchecked) {
 +                 debug pointer => _3;
 +             }
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
 +         debug a => _5;
-+         let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
++         let mut _6: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +         let mut _7: u32;
 +         let mut _8: i32;
-+         let mut _9: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
-+         let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
++         let mut _9: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
++         let mut _10: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +     }
   
       bb0: {
@@ -39,18 +39,18 @@
 -     }
 - 
 -     bb1: {
-+         _4 = [generator@$DIR/inline_generator.rs:15:5: 15:8 (#0)];
++         _4 = [generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)];
           _3 = &mut _4;
--         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind unreachable];
+-         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new(move _3) -> [return: bb2, unwind unreachable];
 -     }
 - 
 -     bb2: {
-+         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _3 };
++         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]> { pointer: move _3 };
           StorageDead(_3);
--         _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
+-         _1 = <[generator@$DIR/inline_generator.rs:16:5: 16:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
 +         StorageLive(_5);
 +         _5 = const false;
-+         _6 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _6 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         _7 = discriminant((*_6));
 +         switchInt(move _7) -> [0: bb2, 1: bb6, 3: bb7, otherwise: bb8];
       }
@@ -82,7 +82,7 @@
 + 
 +     bb5: {
 +         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         discriminant((*_9)) = 3;
 +         goto -> bb1;
 +     }
@@ -95,7 +95,7 @@
 +         StorageLive(_8);
 +         StorageDead(_8);
 +         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         discriminant((*_10)) = 1;
 +         goto -> bb1;
 +     }
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index 63f70ccc3b5..588f04048d6 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -4,30 +4,30 @@
   fn main() -> () {
       let mut _0: ();
       let _1: std::ops::GeneratorState<i32, bool>;
-      let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>;
-      let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
-      let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8];
+      let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>;
+      let mut _3: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
+      let mut _4: [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +     let mut _5: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
 +     }
-+     scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) {
++     scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new) {
 +         debug pointer => _3;
 +         scope 4 {
-+             scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) {
++             scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new_unchecked) {
 +                 debug pointer => _3;
 +             }
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
 +         debug a => _5;
-+         let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
++         let mut _6: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +         let mut _7: u32;
 +         let mut _8: i32;
-+         let mut _9: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
-+         let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8];
++         let mut _9: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
++         let mut _10: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8];
 +     }
   
       bb0: {
@@ -39,18 +39,18 @@
 -     }
 - 
 -     bb1: {
-+         _4 = [generator@$DIR/inline_generator.rs:15:5: 15:8 (#0)];
++         _4 = [generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)];
           _3 = &mut _4;
--         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4];
+-         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]>::new(move _3) -> [return: bb2, unwind: bb4];
 -     }
 - 
 -     bb2: {
-+         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _3 };
++         _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:16:5: 16:8]> { pointer: move _3 };
           StorageDead(_3);
--         _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4];
+-         _1 = <[generator@$DIR/inline_generator.rs:16:5: 16:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4];
 +         StorageLive(_5);
 +         _5 = const false;
-+         _6 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _6 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         _7 = discriminant((*_6));
 +         switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
       }
@@ -87,7 +87,7 @@
 + 
 +     bb6: {
 +         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         discriminant((*_9)) = 3;
 +         goto -> bb1;
 +     }
@@ -100,7 +100,7 @@
 +         StorageLive(_8);
 +         StorageDead(_8);
 +         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]);
++         _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:16:5: 16:8]);
 +         discriminant((*_10)) = 1;
 +         goto -> bb1;
 +     }
diff --git a/tests/mir-opt/inline/inline_generator.rs b/tests/mir-opt/inline/inline_generator.rs
index 61f1da897bd..2d71458c174 100644
--- a/tests/mir-opt/inline/inline_generator.rs
+++ b/tests/mir-opt/inline/inline_generator.rs
@@ -1,4 +1,5 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// compile-flags: -Zinline-mir-hint-threshold=1000
 #![feature(generators, generator_trait)]
 
 use std::ops::Generator;
@@ -9,8 +10,8 @@ fn main() {
     let _r = Pin::new(&mut g()).resume(false);
 }
 
-#[inline(always)]
+#[inline]
 pub fn g() -> impl Generator<bool> {
-    #[inline(always)]
+    #[inline]
     |a| { yield if a { 7 } else { 13 } }
 }
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
index b186a701f65..f3a6923415a 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
@@ -18,6 +18,99 @@
 +         let mut _6: *mut u8;
 +         let mut _7: *const std::vec::Vec<u32>;
 +         scope 4 {
++             scope 5 (inlined alloc::alloc::exchange_malloc) {
++                 debug size => _4;
++                 debug align => _5;
++                 let _8: std::alloc::Layout;
++                 let mut _9: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
++                 let mut _10: isize;
++                 let mut _12: !;
++                 scope 6 {
++                     debug layout => _8;
++                     let _11: std::ptr::NonNull<[u8]>;
++                     let mut _13: &std::alloc::Global;
++                     scope 8 {
++                         debug ptr => _11;
++                         scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) {
++                             debug self => _11;
++                             let mut _15: std::ptr::NonNull<u8>;
++                             scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) {
++                                 debug self => _11;
++                                 let mut _16: *mut u8;
++                                 let mut _17: *mut [u8];
++                                 scope 20 {
++                                     scope 21 (inlined NonNull::<[u8]>::as_ptr) {
++                                         debug self => _11;
++                                         let mut _18: *const [u8];
++                                     }
++                                     scope 22 (inlined ptr::mut_ptr::<impl *mut [u8]>::as_mut_ptr) {
++                                         debug self => _17;
++                                     }
++                                     scope 23 (inlined NonNull::<u8>::new_unchecked) {
++                                         debug ptr => _16;
++                                         let mut _19: *const u8;
++                                         scope 24 {
++                                             scope 25 (inlined NonNull::<T>::new_unchecked::runtime::<u8>) {
++                                                 debug ptr => _16;
++                                                 scope 26 (inlined ptr::mut_ptr::<impl *mut u8>::is_null) {
++                                                     debug self => _16;
++                                                     let mut _20: *mut u8;
++                                                     scope 27 {
++                                                         scope 28 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
++                                                             debug ptr => _20;
++                                                             scope 29 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
++                                                                 debug self => _20;
++                                                                 scope 30 {
++                                                                     scope 31 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
++                                                                         debug self => _20;
++                                                                     }
++                                                                 }
++                                                             }
++                                                         }
++                                                     }
++                                                 }
++                                             }
++                                         }
++                                     }
++                                 }
++                             }
++                             scope 32 (inlined NonNull::<u8>::as_ptr) {
++                                 debug self => _15;
++                                 let mut _21: *const u8;
++                             }
++                         }
++                     }
++                     scope 17 (inlined <std::alloc::Global as Allocator>::allocate) {
++                         debug self => const _;
++                         debug layout => _8;
++                     }
++                 }
++                 scope 7 {
++                     scope 9 (inlined Layout::from_size_align_unchecked) {
++                         debug size => _4;
++                         debug align => _5;
++                         let mut _14: std::ptr::Alignment;
++                         scope 10 {
++                             scope 11 (inlined std::ptr::Alignment::new_unchecked) {
++                                 debug align => _5;
++                                 scope 12 {
++                                     scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) {
++                                         debug align => _5;
++                                         scope 15 (inlined core::num::<impl usize>::is_power_of_two) {
++                                             debug self => _5;
++                                             scope 16 (inlined core::num::<impl usize>::count_ones) {
++                                                 debug self => _5;
++                                             }
++                                         }
++                                     }
++                                 }
++                                 scope 13 {
++                                 }
++                             }
++                         }
++                     }
++                 }
++             }
 +         }
 +     }
   
@@ -31,7 +124,17 @@
 +         StorageDead(_3);
 +         _4 = SizeOf(std::vec::Vec<u32>);
 +         _5 = AlignOf(std::vec::Vec<u32>);
-+         _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb2, unwind unreachable];
++         StorageLive(_8);
++         StorageLive(_11);
++         StorageLive(_12);
++         StorageLive(_13);
++         StorageLive(_14);
++         _14 = _5 as std::ptr::Alignment (Transmute);
++         _8 = Layout { size: _4, align: move _14 };
++         StorageDead(_14);
++         StorageLive(_9);
++         _13 = const _;
++         _9 = std::alloc::Global::alloc_impl(_13, _8, const false) -> [return: bb5, unwind unreachable];
       }
   
       bb1: {
@@ -41,18 +144,56 @@
       }
   
       bb2: {
++         _12 = handle_alloc_error(_8) -> unwind unreachable;
++     }
++ 
++     bb3: {
++         unreachable;
++     }
++ 
++     bb4: {
++         _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>);
++         StorageLive(_15);
++         StorageLive(_16);
++         StorageLive(_17);
++         StorageLive(_18);
++         _18 = (_11.0: *const [u8]);
++         _17 = move _18 as *mut [u8] (PtrToPtr);
++         StorageDead(_18);
++         _16 = _17 as *mut u8 (PtrToPtr);
++         StorageDead(_17);
++         StorageLive(_19);
++         StorageLive(_20);
++         _19 = _16 as *const u8 (Pointer(MutToConstPointer));
++         _15 = NonNull::<u8> { pointer: _19 };
++         StorageDead(_20);
++         StorageDead(_19);
++         StorageDead(_16);
++         StorageLive(_21);
++         _21 = (_15.0: *const u8);
++         _6 = move _21 as *mut u8 (PtrToPtr);
++         StorageDead(_21);
++         StorageDead(_15);
++         StorageDead(_9);
++         StorageDead(_13);
++         StorageDead(_12);
++         StorageDead(_11);
++         StorageDead(_8);
 +         _1 = ShallowInitBox(move _6, std::vec::Vec<u32>);
 +         _7 = (((_1.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>);
 +         (*_7) = move _2;
           StorageDead(_2);
           _0 = const ();
 -         drop(_1) -> [return: bb3, unwind unreachable];
--     }
-- 
++         drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
 -     bb3: {
 -         StorageDead(_1);
 -         return;
-+         drop(_1) -> [return: bb1, unwind unreachable];
++     bb5: {
++         _10 = discriminant(_9);
++         switchInt(move _10) -> [0: bb4, 1: bb2, otherwise: bb3];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
index a789f9933b4..4615a3f9826 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
@@ -18,6 +18,99 @@
 +         let mut _6: *mut u8;
 +         let mut _7: *const std::vec::Vec<u32>;
 +         scope 4 {
++             scope 5 (inlined alloc::alloc::exchange_malloc) {
++                 debug size => _4;
++                 debug align => _5;
++                 let _8: std::alloc::Layout;
++                 let mut _9: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
++                 let mut _10: isize;
++                 let mut _12: !;
++                 scope 6 {
++                     debug layout => _8;
++                     let _11: std::ptr::NonNull<[u8]>;
++                     let mut _13: &std::alloc::Global;
++                     scope 8 {
++                         debug ptr => _11;
++                         scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) {
++                             debug self => _11;
++                             let mut _15: std::ptr::NonNull<u8>;
++                             scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) {
++                                 debug self => _11;
++                                 let mut _16: *mut u8;
++                                 let mut _17: *mut [u8];
++                                 scope 20 {
++                                     scope 21 (inlined NonNull::<[u8]>::as_ptr) {
++                                         debug self => _11;
++                                         let mut _18: *const [u8];
++                                     }
++                                     scope 22 (inlined ptr::mut_ptr::<impl *mut [u8]>::as_mut_ptr) {
++                                         debug self => _17;
++                                     }
++                                     scope 23 (inlined NonNull::<u8>::new_unchecked) {
++                                         debug ptr => _16;
++                                         let mut _19: *const u8;
++                                         scope 24 {
++                                             scope 25 (inlined NonNull::<T>::new_unchecked::runtime::<u8>) {
++                                                 debug ptr => _16;
++                                                 scope 26 (inlined ptr::mut_ptr::<impl *mut u8>::is_null) {
++                                                     debug self => _16;
++                                                     let mut _20: *mut u8;
++                                                     scope 27 {
++                                                         scope 28 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
++                                                             debug ptr => _20;
++                                                             scope 29 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
++                                                                 debug self => _20;
++                                                                 scope 30 {
++                                                                     scope 31 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
++                                                                         debug self => _20;
++                                                                     }
++                                                                 }
++                                                             }
++                                                         }
++                                                     }
++                                                 }
++                                             }
++                                         }
++                                     }
++                                 }
++                             }
++                             scope 32 (inlined NonNull::<u8>::as_ptr) {
++                                 debug self => _15;
++                                 let mut _21: *const u8;
++                             }
++                         }
++                     }
++                     scope 17 (inlined <std::alloc::Global as Allocator>::allocate) {
++                         debug self => const _;
++                         debug layout => _8;
++                     }
++                 }
++                 scope 7 {
++                     scope 9 (inlined Layout::from_size_align_unchecked) {
++                         debug size => _4;
++                         debug align => _5;
++                         let mut _14: std::ptr::Alignment;
++                         scope 10 {
++                             scope 11 (inlined std::ptr::Alignment::new_unchecked) {
++                                 debug align => _5;
++                                 scope 12 {
++                                     scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) {
++                                         debug align => _5;
++                                         scope 15 (inlined core::num::<impl usize>::is_power_of_two) {
++                                             debug self => _5;
++                                             scope 16 (inlined core::num::<impl usize>::count_ones) {
++                                                 debug self => _5;
++                                             }
++                                         }
++                                     }
++                                 }
++                                 scope 13 {
++                                 }
++                             }
++                         }
++                     }
++                 }
++             }
 +         }
 +     }
   
@@ -31,7 +124,17 @@
 +         StorageDead(_3);
 +         _4 = SizeOf(std::vec::Vec<u32>);
 +         _5 = AlignOf(std::vec::Vec<u32>);
-+         _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb3, unwind: bb4];
++         StorageLive(_8);
++         StorageLive(_11);
++         StorageLive(_12);
++         StorageLive(_13);
++         StorageLive(_14);
++         _14 = _5 as std::ptr::Alignment (Transmute);
++         _8 = Layout { size: _4, align: move _14 };
++         StorageDead(_14);
++         StorageLive(_9);
++         _13 = const _;
++         _9 = std::alloc::Global::alloc_impl(_13, _8, const false) -> [return: bb7, unwind: bb3];
       }
   
       bb1: {
@@ -48,20 +151,62 @@
 +         resume;
       }
   
-      bb3: {
+-     bb3: {
 -         StorageDead(_1);
 -         return;
++     bb3 (cleanup): {
++         drop(_2) -> [return: bb2, unwind terminate];
+      }
+  
+-     bb4 (cleanup): {
+-         resume;
++     bb4: {
++         _12 = handle_alloc_error(_8) -> bb3;
++     }
++ 
++     bb5: {
++         unreachable;
++     }
++ 
++     bb6: {
++         _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>);
++         StorageLive(_15);
++         StorageLive(_16);
++         StorageLive(_17);
++         StorageLive(_18);
++         _18 = (_11.0: *const [u8]);
++         _17 = move _18 as *mut [u8] (PtrToPtr);
++         StorageDead(_18);
++         _16 = _17 as *mut u8 (PtrToPtr);
++         StorageDead(_17);
++         StorageLive(_19);
++         StorageLive(_20);
++         _19 = _16 as *const u8 (Pointer(MutToConstPointer));
++         _15 = NonNull::<u8> { pointer: _19 };
++         StorageDead(_20);
++         StorageDead(_19);
++         StorageDead(_16);
++         StorageLive(_21);
++         _21 = (_15.0: *const u8);
++         _6 = move _21 as *mut u8 (PtrToPtr);
++         StorageDead(_21);
++         StorageDead(_15);
++         StorageDead(_9);
++         StorageDead(_13);
++         StorageDead(_12);
++         StorageDead(_11);
++         StorageDead(_8);
 +         _1 = ShallowInitBox(move _6, std::vec::Vec<u32>);
 +         _7 = (((_1.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>);
 +         (*_7) = move _2;
 +         StorageDead(_2);
 +         _0 = const ();
 +         drop(_1) -> [return: bb1, unwind: bb2];
-      }
-  
-      bb4 (cleanup): {
--         resume;
-+         drop(_2) -> [return: bb2, unwind terminate];
++     }
++ 
++     bb7: {
++         _10 = discriminant(_9);
++         switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs
index bc578ec90e8..56f174e515b 100644
--- a/tests/mir-opt/inline/inline_into_box_place.rs
+++ b/tests/mir-opt/inline/inline_into_box_place.rs
@@ -1,7 +1,7 @@
 // ignore-endian-big
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 // ignore-debug MIR alignment checks in std alter the diff, breaking the test
-// compile-flags: -Z mir-opt-level=4
+// compile-flags: -Zmir-opt-level=4 -Zinline-mir-hint-threshold=200
 
 // EMIT_MIR inline_into_box_place.main.Inline.diff
 fn main() {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
index 890d9b109fb..093925b8e4f 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
@@ -7,129 +7,19 @@
       let mut _0: u16;
       let mut _3: u16;
       let mut _4: u32;
-+     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-+         debug self => _3;
-+         debug rhs => _4;
-+         let mut _5: u16;
-+         scope 2 {
-+             scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) {
-+                 debug x => _4;
-+                 let mut _6: std::option::Option<u16>;
-+                 let mut _7: std::result::Result<u16, std::num::TryFromIntError>;
-+                 scope 4 {
-+                     scope 5 (inlined <u32 as TryInto<u16>>::try_into) {
-+                         debug self => _4;
-+                         scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) {
-+                             debug u => _4;
-+                             let mut _8: bool;
-+                             let mut _9: u32;
-+                             let mut _10: u16;
-+                         }
-+                     }
-+                     scope 7 (inlined Result::<u16, TryFromIntError>::ok) {
-+                         debug self => _7;
-+                         let mut _11: isize;
-+                         let _12: u16;
-+                         scope 8 {
-+                             debug x => _12;
-+                         }
-+                     }
-+                     scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) {
-+                         debug self => _6;
-+                         let mut _13: &std::option::Option<u16>;
-+                         let mut _14: isize;
-+                         scope 10 {
-+                             debug val => _5;
-+                         }
-+                         scope 11 {
-+                             scope 13 (inlined unreachable_unchecked) {
-+                                 scope 14 {
-+                                     scope 15 (inlined unreachable_unchecked::runtime) {
-+                                     }
-+                                 }
-+                             }
-+                         }
-+                         scope 12 (inlined Option::<u16>::is_some) {
-+                             debug self => _13;
-+                         }
-+                     }
-+                 }
-+             }
-+         }
-+     }
   
       bb0: {
           StorageLive(_3);
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable];
-+         StorageLive(_5);
-+         StorageLive(_6);
-+         StorageLive(_7);
-+         StorageLive(_8);
-+         StorageLive(_9);
-+         _9 = const 65535_u32;
-+         _8 = Gt(_4, move _9);
-+         StorageDead(_9);
-+         switchInt(move _8) -> [0: bb3, otherwise: bb2];
+          _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
-+         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
-+     }
-+ 
-+     bb2: {
-+         _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(()));
-+         goto -> bb4;
-+     }
-+ 
-+     bb3: {
-+         StorageLive(_10);
-+         _10 = _4 as u16 (IntToInt);
-+         _7 = Result::<u16, TryFromIntError>::Ok(move _10);
-+         StorageDead(_10);
-+         goto -> bb4;
-+     }
-+ 
-+     bb4: {
-+         StorageDead(_8);
-+         StorageLive(_12);
-+         _11 = discriminant(_7);
-+         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6];
-+     }
-+ 
-+     bb5: {
-+         _6 = Option::<u16>::None;
-+         goto -> bb8;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
-+     }
-+ 
-+     bb7: {
-+         _12 = move ((_7 as Ok).0: u16);
-+         _6 = Option::<u16>::Some(move _12);
-+         goto -> bb8;
-+     }
-+ 
-+     bb8: {
-+         StorageDead(_12);
-+         StorageDead(_7);
-+         StorageLive(_13);
-+         _14 = discriminant(_6);
-+         switchInt(move _14) -> [1: bb9, otherwise: bb6];
-+     }
-+ 
-+     bb9: {
-+         _5 = move ((_6 as Some).0: u16);
-+         StorageDead(_13);
-+         StorageDead(_6);
-+         _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
index 118e601b136..50934e0439a 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
@@ -7,129 +7,19 @@
       let mut _0: u16;
       let mut _3: u16;
       let mut _4: u32;
-+     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-+         debug self => _3;
-+         debug rhs => _4;
-+         let mut _5: u16;
-+         scope 2 {
-+             scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) {
-+                 debug x => _4;
-+                 let mut _6: std::option::Option<u16>;
-+                 let mut _7: std::result::Result<u16, std::num::TryFromIntError>;
-+                 scope 4 {
-+                     scope 5 (inlined <u32 as TryInto<u16>>::try_into) {
-+                         debug self => _4;
-+                         scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) {
-+                             debug u => _4;
-+                             let mut _8: bool;
-+                             let mut _9: u32;
-+                             let mut _10: u16;
-+                         }
-+                     }
-+                     scope 7 (inlined Result::<u16, TryFromIntError>::ok) {
-+                         debug self => _7;
-+                         let mut _11: isize;
-+                         let _12: u16;
-+                         scope 8 {
-+                             debug x => _12;
-+                         }
-+                     }
-+                     scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) {
-+                         debug self => _6;
-+                         let mut _13: &std::option::Option<u16>;
-+                         let mut _14: isize;
-+                         scope 10 {
-+                             debug val => _5;
-+                         }
-+                         scope 11 {
-+                             scope 13 (inlined unreachable_unchecked) {
-+                                 scope 14 {
-+                                     scope 15 (inlined unreachable_unchecked::runtime) {
-+                                     }
-+                                 }
-+                             }
-+                         }
-+                         scope 12 (inlined Option::<u16>::is_some) {
-+                             debug self => _13;
-+                         }
-+                     }
-+                 }
-+             }
-+         }
-+     }
   
       bb0: {
           StorageLive(_3);
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> bb1;
-+         StorageLive(_5);
-+         StorageLive(_6);
-+         StorageLive(_7);
-+         StorageLive(_8);
-+         StorageLive(_9);
-+         _9 = const 65535_u32;
-+         _8 = Gt(_4, move _9);
-+         StorageDead(_9);
-+         switchInt(move _8) -> [0: bb3, otherwise: bb2];
+          _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> bb1;
       }
   
       bb1: {
-+         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
-+     }
-+ 
-+     bb2: {
-+         _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(()));
-+         goto -> bb4;
-+     }
-+ 
-+     bb3: {
-+         StorageLive(_10);
-+         _10 = _4 as u16 (IntToInt);
-+         _7 = Result::<u16, TryFromIntError>::Ok(move _10);
-+         StorageDead(_10);
-+         goto -> bb4;
-+     }
-+ 
-+     bb4: {
-+         StorageDead(_8);
-+         StorageLive(_12);
-+         _11 = discriminant(_7);
-+         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6];
-+     }
-+ 
-+     bb5: {
-+         _6 = Option::<u16>::None;
-+         goto -> bb8;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
-+     }
-+ 
-+     bb7: {
-+         _12 = move ((_7 as Ok).0: u16);
-+         _6 = Option::<u16>::Some(move _12);
-+         goto -> bb8;
-+     }
-+ 
-+     bb8: {
-+         StorageDead(_12);
-+         StorageDead(_7);
-+         StorageLive(_13);
-+         _14 = discriminant(_6);
-+         switchInt(move _14) -> [1: bb9, otherwise: bb6];
-+     }
-+ 
-+     bb9: {
-+         _5 = move ((_6 as Some).0: u16);
-+         StorageDead(_13);
-+         StorageDead(_6);
-+         _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
index 0d692251051..46f3511b14c 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
@@ -4,121 +4,12 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     debug a => _1;
     debug b => _2;
     let mut _0: u16;
-    scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-        debug self => _1;
-        debug rhs => _2;
-        let mut _11: u16;
-        scope 2 {
-            scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) {
-                debug x => _2;
-                let mut _6: std::result::Result<u16, std::num::TryFromIntError>;
-                let mut _9: std::option::Option<u16>;
-                scope 4 {
-                    scope 5 (inlined <u32 as TryInto<u16>>::try_into) {
-                        debug self => _2;
-                        scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) {
-                            debug u => _2;
-                            let mut _3: u32;
-                            let mut _4: bool;
-                            let mut _5: u16;
-                        }
-                    }
-                    scope 7 (inlined Result::<u16, TryFromIntError>::ok) {
-                        debug self => _6;
-                        let mut _7: isize;
-                        let _8: u16;
-                        scope 8 {
-                            debug x => _8;
-                        }
-                    }
-                    scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) {
-                        debug self => _9;
-                        let mut _10: isize;
-                        let mut _12: &std::option::Option<u16>;
-                        scope 10 {
-                            debug val => _11;
-                        }
-                        scope 11 {
-                            scope 13 (inlined unreachable_unchecked) {
-                                scope 14 {
-                                    scope 15 (inlined unreachable_unchecked::runtime) {
-                                    }
-                                }
-                            }
-                        }
-                        scope 12 (inlined Option::<u16>::is_some) {
-                            debug self => _12;
-                        }
-                    }
-                }
-            }
-        }
-    }
 
     bb0: {
-        StorageLive(_11);
-        StorageLive(_9);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_3);
-        _3 = const 65535_u32;
-        _4 = Gt(_2, move _3);
-        StorageDead(_3);
-        switchInt(move _4) -> [0: bb1, otherwise: bb2];
+        _0 = core::num::<impl u16>::unchecked_shl(_1, _2) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        StorageLive(_5);
-        _5 = _2 as u16 (IntToInt);
-        _6 = Result::<u16, TryFromIntError>::Ok(move _5);
-        StorageDead(_5);
-        goto -> bb3;
-    }
-
-    bb2: {
-        _6 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(()));
-        goto -> bb3;
-    }
-
-    bb3: {
-        StorageDead(_4);
-        StorageLive(_8);
-        _7 = discriminant(_6);
-        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9];
-    }
-
-    bb4: {
-        _8 = move ((_6 as Ok).0: u16);
-        _9 = Option::<u16>::Some(move _8);
-        goto -> bb6;
-    }
-
-    bb5: {
-        _9 = Option::<u16>::None;
-        goto -> bb6;
-    }
-
-    bb6: {
-        StorageDead(_8);
-        StorageDead(_6);
-        StorageLive(_12);
-        _10 = discriminant(_9);
-        switchInt(move _10) -> [1: bb7, otherwise: bb9];
-    }
-
-    bb7: {
-        _11 = move ((_9 as Some).0: u16);
-        StorageDead(_12);
-        StorageDead(_9);
-        _0 = unchecked_shl::<u16>(_1, move _11) -> [return: bb8, unwind unreachable];
-    }
-
-    bb8: {
-        StorageDead(_11);
         return;
     }
-
-    bb9: {
-        unreachable;
-    }
 }
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
index 0d692251051..35fee449c35 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
@@ -4,121 +4,12 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     debug a => _1;
     debug b => _2;
     let mut _0: u16;
-    scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
-        debug self => _1;
-        debug rhs => _2;
-        let mut _11: u16;
-        scope 2 {
-            scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) {
-                debug x => _2;
-                let mut _6: std::result::Result<u16, std::num::TryFromIntError>;
-                let mut _9: std::option::Option<u16>;
-                scope 4 {
-                    scope 5 (inlined <u32 as TryInto<u16>>::try_into) {
-                        debug self => _2;
-                        scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) {
-                            debug u => _2;
-                            let mut _3: u32;
-                            let mut _4: bool;
-                            let mut _5: u16;
-                        }
-                    }
-                    scope 7 (inlined Result::<u16, TryFromIntError>::ok) {
-                        debug self => _6;
-                        let mut _7: isize;
-                        let _8: u16;
-                        scope 8 {
-                            debug x => _8;
-                        }
-                    }
-                    scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) {
-                        debug self => _9;
-                        let mut _10: isize;
-                        let mut _12: &std::option::Option<u16>;
-                        scope 10 {
-                            debug val => _11;
-                        }
-                        scope 11 {
-                            scope 13 (inlined unreachable_unchecked) {
-                                scope 14 {
-                                    scope 15 (inlined unreachable_unchecked::runtime) {
-                                    }
-                                }
-                            }
-                        }
-                        scope 12 (inlined Option::<u16>::is_some) {
-                            debug self => _12;
-                        }
-                    }
-                }
-            }
-        }
-    }
 
     bb0: {
-        StorageLive(_11);
-        StorageLive(_9);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_3);
-        _3 = const 65535_u32;
-        _4 = Gt(_2, move _3);
-        StorageDead(_3);
-        switchInt(move _4) -> [0: bb1, otherwise: bb2];
+        _0 = core::num::<impl u16>::unchecked_shl(_1, _2) -> bb1;
     }
 
     bb1: {
-        StorageLive(_5);
-        _5 = _2 as u16 (IntToInt);
-        _6 = Result::<u16, TryFromIntError>::Ok(move _5);
-        StorageDead(_5);
-        goto -> bb3;
-    }
-
-    bb2: {
-        _6 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(()));
-        goto -> bb3;
-    }
-
-    bb3: {
-        StorageDead(_4);
-        StorageLive(_8);
-        _7 = discriminant(_6);
-        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9];
-    }
-
-    bb4: {
-        _8 = move ((_6 as Ok).0: u16);
-        _9 = Option::<u16>::Some(move _8);
-        goto -> bb6;
-    }
-
-    bb5: {
-        _9 = Option::<u16>::None;
-        goto -> bb6;
-    }
-
-    bb6: {
-        StorageDead(_8);
-        StorageDead(_6);
-        StorageLive(_12);
-        _10 = discriminant(_9);
-        switchInt(move _10) -> [1: bb7, otherwise: bb9];
-    }
-
-    bb7: {
-        _11 = move ((_9 as Some).0: u16);
-        StorageDead(_12);
-        StorageDead(_9);
-        _0 = unchecked_shl::<u16>(_1, move _11) -> [return: bb8, unwind unreachable];
-    }
-
-    bb8: {
-        StorageDead(_11);
         return;
     }
-
-    bb9: {
-        unreachable;
-    }
 }
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff
index 61155f5078f..1659a51b090 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-abort.diff
@@ -7,129 +7,19 @@
       let mut _0: i16;
       let mut _3: i16;
       let mut _4: u32;
-+     scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
-+         debug self => _3;
-+         debug rhs => _4;
-+         let mut _5: i16;
-+         scope 2 {
-+             scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) {
-+                 debug x => _4;
-+                 let mut _6: std::option::Option<i16>;
-+                 let mut _7: std::result::Result<i16, std::num::TryFromIntError>;
-+                 scope 4 {
-+                     scope 5 (inlined <u32 as TryInto<i16>>::try_into) {
-+                         debug self => _4;
-+                         scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) {
-+                             debug u => _4;
-+                             let mut _8: bool;
-+                             let mut _9: u32;
-+                             let mut _10: i16;
-+                         }
-+                     }
-+                     scope 7 (inlined Result::<i16, TryFromIntError>::ok) {
-+                         debug self => _7;
-+                         let mut _11: isize;
-+                         let _12: i16;
-+                         scope 8 {
-+                             debug x => _12;
-+                         }
-+                     }
-+                     scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) {
-+                         debug self => _6;
-+                         let mut _13: &std::option::Option<i16>;
-+                         let mut _14: isize;
-+                         scope 10 {
-+                             debug val => _5;
-+                         }
-+                         scope 11 {
-+                             scope 13 (inlined unreachable_unchecked) {
-+                                 scope 14 {
-+                                     scope 15 (inlined unreachable_unchecked::runtime) {
-+                                     }
-+                                 }
-+                             }
-+                         }
-+                         scope 12 (inlined Option::<i16>::is_some) {
-+                             debug self => _13;
-+                         }
-+                     }
-+                 }
-+             }
-+         }
-+     }
   
       bb0: {
           StorageLive(_3);
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable];
-+         StorageLive(_5);
-+         StorageLive(_6);
-+         StorageLive(_7);
-+         StorageLive(_8);
-+         StorageLive(_9);
-+         _9 = const 32767_u32;
-+         _8 = Gt(_4, move _9);
-+         StorageDead(_9);
-+         switchInt(move _8) -> [0: bb3, otherwise: bb2];
+          _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
-+         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
-+     }
-+ 
-+     bb2: {
-+         _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(()));
-+         goto -> bb4;
-+     }
-+ 
-+     bb3: {
-+         StorageLive(_10);
-+         _10 = _4 as i16 (IntToInt);
-+         _7 = Result::<i16, TryFromIntError>::Ok(move _10);
-+         StorageDead(_10);
-+         goto -> bb4;
-+     }
-+ 
-+     bb4: {
-+         StorageDead(_8);
-+         StorageLive(_12);
-+         _11 = discriminant(_7);
-+         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6];
-+     }
-+ 
-+     bb5: {
-+         _6 = Option::<i16>::None;
-+         goto -> bb8;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
-+     }
-+ 
-+     bb7: {
-+         _12 = move ((_7 as Ok).0: i16);
-+         _6 = Option::<i16>::Some(move _12);
-+         goto -> bb8;
-+     }
-+ 
-+     bb8: {
-+         StorageDead(_12);
-+         StorageDead(_7);
-+         StorageLive(_13);
-+         _14 = discriminant(_6);
-+         switchInt(move _14) -> [1: bb9, otherwise: bb6];
-+     }
-+ 
-+     bb9: {
-+         _5 = move ((_6 as Some).0: i16);
-+         StorageDead(_13);
-+         StorageDead(_6);
-+         _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
index 181a423164b..cb5ec37feb3 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.panic-unwind.diff
@@ -7,129 +7,19 @@
       let mut _0: i16;
       let mut _3: i16;
       let mut _4: u32;
-+     scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
-+         debug self => _3;
-+         debug rhs => _4;
-+         let mut _5: i16;
-+         scope 2 {
-+             scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) {
-+                 debug x => _4;
-+                 let mut _6: std::option::Option<i16>;
-+                 let mut _7: std::result::Result<i16, std::num::TryFromIntError>;
-+                 scope 4 {
-+                     scope 5 (inlined <u32 as TryInto<i16>>::try_into) {
-+                         debug self => _4;
-+                         scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) {
-+                             debug u => _4;
-+                             let mut _8: bool;
-+                             let mut _9: u32;
-+                             let mut _10: i16;
-+                         }
-+                     }
-+                     scope 7 (inlined Result::<i16, TryFromIntError>::ok) {
-+                         debug self => _7;
-+                         let mut _11: isize;
-+                         let _12: i16;
-+                         scope 8 {
-+                             debug x => _12;
-+                         }
-+                     }
-+                     scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) {
-+                         debug self => _6;
-+                         let mut _13: &std::option::Option<i16>;
-+                         let mut _14: isize;
-+                         scope 10 {
-+                             debug val => _5;
-+                         }
-+                         scope 11 {
-+                             scope 13 (inlined unreachable_unchecked) {
-+                                 scope 14 {
-+                                     scope 15 (inlined unreachable_unchecked::runtime) {
-+                                     }
-+                                 }
-+                             }
-+                         }
-+                         scope 12 (inlined Option::<i16>::is_some) {
-+                             debug self => _13;
-+                         }
-+                     }
-+                 }
-+             }
-+         }
-+     }
   
       bb0: {
           StorageLive(_3);
           _3 = _1;
           StorageLive(_4);
           _4 = _2;
--         _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> bb1;
-+         StorageLive(_5);
-+         StorageLive(_6);
-+         StorageLive(_7);
-+         StorageLive(_8);
-+         StorageLive(_9);
-+         _9 = const 32767_u32;
-+         _8 = Gt(_4, move _9);
-+         StorageDead(_9);
-+         switchInt(move _8) -> [0: bb3, otherwise: bb2];
+          _0 = core::num::<impl i16>::unchecked_shr(move _3, move _4) -> bb1;
       }
   
       bb1: {
-+         StorageDead(_5);
           StorageDead(_4);
           StorageDead(_3);
           return;
-+     }
-+ 
-+     bb2: {
-+         _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(()));
-+         goto -> bb4;
-+     }
-+ 
-+     bb3: {
-+         StorageLive(_10);
-+         _10 = _4 as i16 (IntToInt);
-+         _7 = Result::<i16, TryFromIntError>::Ok(move _10);
-+         StorageDead(_10);
-+         goto -> bb4;
-+     }
-+ 
-+     bb4: {
-+         StorageDead(_8);
-+         StorageLive(_12);
-+         _11 = discriminant(_7);
-+         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6];
-+     }
-+ 
-+     bb5: {
-+         _6 = Option::<i16>::None;
-+         goto -> bb8;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
-+     }
-+ 
-+     bb7: {
-+         _12 = move ((_7 as Ok).0: i16);
-+         _6 = Option::<i16>::Some(move _12);
-+         goto -> bb8;
-+     }
-+ 
-+     bb8: {
-+         StorageDead(_12);
-+         StorageDead(_7);
-+         StorageLive(_13);
-+         _14 = discriminant(_6);
-+         switchInt(move _14) -> [1: bb9, otherwise: bb6];
-+     }
-+ 
-+     bb9: {
-+         _5 = move ((_6 as Some).0: i16);
-+         StorageDead(_13);
-+         StorageDead(_6);
-+         _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir
index 66936df380b..9f2f40002a3 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-abort.mir
@@ -4,121 +4,12 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
     debug a => _1;
     debug b => _2;
     let mut _0: i16;
-    scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
-        debug self => _1;
-        debug rhs => _2;
-        let mut _11: i16;
-        scope 2 {
-            scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) {
-                debug x => _2;
-                let mut _6: std::result::Result<i16, std::num::TryFromIntError>;
-                let mut _9: std::option::Option<i16>;
-                scope 4 {
-                    scope 5 (inlined <u32 as TryInto<i16>>::try_into) {
-                        debug self => _2;
-                        scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) {
-                            debug u => _2;
-                            let mut _3: u32;
-                            let mut _4: bool;
-                            let mut _5: i16;
-                        }
-                    }
-                    scope 7 (inlined Result::<i16, TryFromIntError>::ok) {
-                        debug self => _6;
-                        let mut _7: isize;
-                        let _8: i16;
-                        scope 8 {
-                            debug x => _8;
-                        }
-                    }
-                    scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) {
-                        debug self => _9;
-                        let mut _10: isize;
-                        let mut _12: &std::option::Option<i16>;
-                        scope 10 {
-                            debug val => _11;
-                        }
-                        scope 11 {
-                            scope 13 (inlined unreachable_unchecked) {
-                                scope 14 {
-                                    scope 15 (inlined unreachable_unchecked::runtime) {
-                                    }
-                                }
-                            }
-                        }
-                        scope 12 (inlined Option::<i16>::is_some) {
-                            debug self => _12;
-                        }
-                    }
-                }
-            }
-        }
-    }
 
     bb0: {
-        StorageLive(_11);
-        StorageLive(_9);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_3);
-        _3 = const 32767_u32;
-        _4 = Gt(_2, move _3);
-        StorageDead(_3);
-        switchInt(move _4) -> [0: bb1, otherwise: bb2];
+        _0 = core::num::<impl i16>::unchecked_shr(_1, _2) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        StorageLive(_5);
-        _5 = _2 as i16 (IntToInt);
-        _6 = Result::<i16, TryFromIntError>::Ok(move _5);
-        StorageDead(_5);
-        goto -> bb3;
-    }
-
-    bb2: {
-        _6 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(()));
-        goto -> bb3;
-    }
-
-    bb3: {
-        StorageDead(_4);
-        StorageLive(_8);
-        _7 = discriminant(_6);
-        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9];
-    }
-
-    bb4: {
-        _8 = move ((_6 as Ok).0: i16);
-        _9 = Option::<i16>::Some(move _8);
-        goto -> bb6;
-    }
-
-    bb5: {
-        _9 = Option::<i16>::None;
-        goto -> bb6;
-    }
-
-    bb6: {
-        StorageDead(_8);
-        StorageDead(_6);
-        StorageLive(_12);
-        _10 = discriminant(_9);
-        switchInt(move _10) -> [1: bb7, otherwise: bb9];
-    }
-
-    bb7: {
-        _11 = move ((_9 as Some).0: i16);
-        StorageDead(_12);
-        StorageDead(_9);
-        _0 = unchecked_shr::<i16>(_1, move _11) -> [return: bb8, unwind unreachable];
-    }
-
-    bb8: {
-        StorageDead(_11);
         return;
     }
-
-    bb9: {
-        unreachable;
-    }
 }
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir
index 66936df380b..aaf3bb62e8a 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.panic-unwind.mir
@@ -4,121 +4,12 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
     debug a => _1;
     debug b => _2;
     let mut _0: i16;
-    scope 1 (inlined core::num::<impl i16>::unchecked_shr) {
-        debug self => _1;
-        debug rhs => _2;
-        let mut _11: i16;
-        scope 2 {
-            scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) {
-                debug x => _2;
-                let mut _6: std::result::Result<i16, std::num::TryFromIntError>;
-                let mut _9: std::option::Option<i16>;
-                scope 4 {
-                    scope 5 (inlined <u32 as TryInto<i16>>::try_into) {
-                        debug self => _2;
-                        scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) {
-                            debug u => _2;
-                            let mut _3: u32;
-                            let mut _4: bool;
-                            let mut _5: i16;
-                        }
-                    }
-                    scope 7 (inlined Result::<i16, TryFromIntError>::ok) {
-                        debug self => _6;
-                        let mut _7: isize;
-                        let _8: i16;
-                        scope 8 {
-                            debug x => _8;
-                        }
-                    }
-                    scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) {
-                        debug self => _9;
-                        let mut _10: isize;
-                        let mut _12: &std::option::Option<i16>;
-                        scope 10 {
-                            debug val => _11;
-                        }
-                        scope 11 {
-                            scope 13 (inlined unreachable_unchecked) {
-                                scope 14 {
-                                    scope 15 (inlined unreachable_unchecked::runtime) {
-                                    }
-                                }
-                            }
-                        }
-                        scope 12 (inlined Option::<i16>::is_some) {
-                            debug self => _12;
-                        }
-                    }
-                }
-            }
-        }
-    }
 
     bb0: {
-        StorageLive(_11);
-        StorageLive(_9);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_3);
-        _3 = const 32767_u32;
-        _4 = Gt(_2, move _3);
-        StorageDead(_3);
-        switchInt(move _4) -> [0: bb1, otherwise: bb2];
+        _0 = core::num::<impl i16>::unchecked_shr(_1, _2) -> bb1;
     }
 
     bb1: {
-        StorageLive(_5);
-        _5 = _2 as i16 (IntToInt);
-        _6 = Result::<i16, TryFromIntError>::Ok(move _5);
-        StorageDead(_5);
-        goto -> bb3;
-    }
-
-    bb2: {
-        _6 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(()));
-        goto -> bb3;
-    }
-
-    bb3: {
-        StorageDead(_4);
-        StorageLive(_8);
-        _7 = discriminant(_6);
-        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9];
-    }
-
-    bb4: {
-        _8 = move ((_6 as Ok).0: i16);
-        _9 = Option::<i16>::Some(move _8);
-        goto -> bb6;
-    }
-
-    bb5: {
-        _9 = Option::<i16>::None;
-        goto -> bb6;
-    }
-
-    bb6: {
-        StorageDead(_8);
-        StorageDead(_6);
-        StorageLive(_12);
-        _10 = discriminant(_9);
-        switchInt(move _10) -> [1: bb7, otherwise: bb9];
-    }
-
-    bb7: {
-        _11 = move ((_9 as Some).0: i16);
-        StorageDead(_12);
-        StorageDead(_9);
-        _0 = unchecked_shr::<i16>(_1, move _11) -> [return: bb8, unwind unreachable];
-    }
-
-    bb8: {
-        StorageDead(_11);
         return;
     }
-
-    bb9: {
-        unreachable;
-    }
 }
diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml
index c5c386ce750..6ea6d53e287 100644
--- a/tests/rustdoc-gui/search-reexport.goml
+++ b/tests/rustdoc-gui/search-reexport.goml
@@ -14,7 +14,7 @@ assert-attribute: (
     "//a[@class='result-import']",
     {"href": "../test_docs/index.html#reexport.TheStdReexport"},
 )
-assert-text: ("//a[@class='result-import']", "test_docs::TheStdReexport")
+assert-text: ("a.result-import .result-name", "re-export test_docs::TheStdReexport")
 click: "//a[@class='result-import']"
 // We check that it has the background modified thanks to the focus.
 wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"})
@@ -25,8 +25,8 @@ press-key: 'Enter'
 write: (".search-input", "AliasForTheStdReexport")
 wait-for: "//a[@class='result-import']"
 assert-text: (
-    "//a[@class='result-import']",
-    "AliasForTheStdReexport - see test_docs::TheStdReexport",
+    "a.result-import .result-name",
+    "AliasForTheStdReexport - see re-export test_docs::TheStdReexport",
 )
 // Same thing again, we click on it to ensure the background is once again set as expected.
 click: "//a[@class='result-import']"
diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml
index 90f7160b724..c75e4141434 100644
--- a/tests/rustdoc-gui/search-result-color.goml
+++ b/tests/rustdoc-gui/search-result-color.goml
@@ -65,12 +65,6 @@ assert-css: (
     {"border-bottom-color": "#aaa3"}
 )
 
-// Checking the color of "keyword" text.
-assert-css: (
-    "//*[@class='result-name']//*[text()='(keyword)']",
-    {"color": "#788797"},
-)
-
 store-value: (entry_color, "#0096cf") // color of the search entry
 store-value: (hover_entry_color, "#fff") // color of the hovered/focused search entry
 store-value: (background_color, "transparent") // background color
@@ -182,12 +176,6 @@ assert-css: (
     {"border-bottom-color": "#aaa3"}
 )
 
-// Checking the color for "keyword" text.
-assert-css: (
-    "//*[@class='result-name']//*[text()='(keyword)']",
-    {"color": "#ddd"},
-)
-
 store-value: (entry_color, "#ddd") // color of the search entry
 store-value: (hover_entry_color, "#ddd") // color of the hovered/focused search entry
 store-value: (background_color, "transparent") // background color
@@ -284,12 +272,6 @@ assert-css: (
     {"border-bottom-color": "#aaa3"}
 )
 
-// Checking the color for "keyword" text.
-assert-css: (
-    "//*[@class='result-name']//*[text()='(keyword)']",
-    {"color": "#000"},
-)
-
 store-value: (entry_color, "#000") // color of the search entry
 store-value: (hover_entry_color, "#000") // color of the hovered/focused search entry
 store-value: (background_color, "transparent") // background color
diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml
index bf096f62c48..afb3a44be30 100644
--- a/tests/rustdoc-gui/search-result-display.goml
+++ b/tests/rustdoc-gui/search-result-display.goml
@@ -7,11 +7,11 @@ press-key: 'Enter'
 wait-for: "#crate-search"
 // The width is returned by "getComputedStyle" which returns the exact number instead of the
 // CSS rule which is "50%"...
-assert-css: (".search-results div.desc", {"width": "310px"})
+assert-size: (".search-results div.desc", {"width": 310})
 set-window-size: (600, 100)
 // As counter-intuitive as it may seem, in this width, the width is "100%", which is why
 // when computed it's larger.
-assert-css: (".search-results div.desc", {"width": "566px"})
+assert-size: (".search-results div.desc", {"width": 566})
 
 // The result set is all on one line.
 assert-css: (".search-results .result-name > span", {"display": "inline"})
diff --git a/tests/rustdoc-gui/search-result-keyword.goml b/tests/rustdoc-gui/search-result-keyword.goml
index 5d56e9d9cd4..1b2be6d4e3e 100644
--- a/tests/rustdoc-gui/search-result-keyword.goml
+++ b/tests/rustdoc-gui/search-result-keyword.goml
@@ -5,9 +5,4 @@ write: (".search-input", "CookieMonster")
 press-key: 'Enter'
 // Waiting for the search results to appear...
 wait-for: "#search-tabs"
-// Note: The two next assert commands could be merged as one but readability would be
-// less good.
-//
-// Checking that the CSS is displaying " (keyword)" in italic.
-assert-text: (".result-name span.keyword > i", "(keyword)")
-assert-text: (".result-name span.keyword", "CookieMonster (keyword)")
+assert-text: (".result-keyword .result-name", "keyword CookieMonster")
diff --git a/tests/rustdoc/generic-associated-types/gats.rs b/tests/rustdoc/generic-associated-types/gats.rs
index 7ab82bb5829..605176e5fea 100644
--- a/tests/rustdoc/generic-associated-types/gats.rs
+++ b/tests/rustdoc/generic-associated-types/gats.rs
@@ -23,9 +23,9 @@ impl LendingIterator for () {
 pub struct Infinite<T>(T);
 
 // @has foo/trait.LendingIterator.html
-// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T"
+// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> = &'a T where Self: 'a"
 impl<T> LendingIterator for Infinite<T> {
-    type Item<'a> where Self: 'a = &'a T;
+    type Item<'a> = &'a T where Self: 'a;
 
     fn next<'a>(&'a self) -> Self::Item<'a> {
         &self.0
diff --git a/tests/ui/impl-trait/nested-return-type2-tait.stderr b/tests/ui/impl-trait/nested-return-type2-tait.stderr
index a8eb69cfcb7..4383e8ab3a0 100644
--- a/tests/ui/impl-trait/nested-return-type2-tait.stderr
+++ b/tests/ui/impl-trait/nested-return-type2-tait.stderr
@@ -8,10 +8,6 @@ LL | fn foo() -> impl Trait<Assoc = Sendable> {
    |                        ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
-help: add this bound
-   |
-LL | type Sendable = impl Send + Duh;
-   |                           +++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/impl-trait/nested-return-type3-tait.stderr b/tests/ui/impl-trait/nested-return-type3-tait.stderr
index 5f58c8dca4a..d32944a0d72 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait.stderr
+++ b/tests/ui/impl-trait/nested-return-type3-tait.stderr
@@ -8,10 +8,6 @@ LL | fn foo() -> impl Trait<Assoc = Sendable> {
    |                        ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
-help: add this bound
-   |
-LL | type Sendable = impl Send + Duh;
-   |                           +++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/impl-trait/nested-return-type3-tait2.stderr b/tests/ui/impl-trait/nested-return-type3-tait2.stderr
index c07f6ead750..a2eddd11665 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait2.stderr
+++ b/tests/ui/impl-trait/nested-return-type3-tait2.stderr
@@ -8,10 +8,6 @@ LL | type Traitable = impl Trait<Assoc = Sendable>;
    |                             ^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
-help: add this bound
-   |
-LL | type Sendable = impl Send + Duh;
-   |                           +++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
index af9dfe25bb4..01c933473ea 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
@@ -1,5 +1,7 @@
 #![feature(type_alias_impl_trait)]
 
+// check-pass
+
 type Foo = impl PartialEq<(Foo, i32)>;
 
 struct Bar;
@@ -11,7 +13,6 @@ impl PartialEq<(Foo, i32)> for Bar {
 }
 
 fn foo() -> Foo {
-    //~^ ERROR can't compare `Bar` with `(Bar, i32)`
     Bar
 }
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
deleted file mode 100644
index 7b63a3d0b9f..00000000000
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0277]: can't compare `Bar` with `(Bar, i32)`
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:13:13
-   |
-LL | fn foo() -> Foo {
-   |             ^^^ no implementation for `Bar == (Bar, i32)`
-LL |
-LL |     Bar
-   |     --- return type was inferred to be `Bar` here
-   |
-   = help: the trait `PartialEq<(Bar, i32)>` is not implemented for `Bar`
-   = help: the trait `PartialEq<(Foo, i32)>` is implemented for `Bar`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index fe62a8f3288..bbd60d4398b 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -20,6 +20,11 @@ LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
    |
    = note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
               found signature `fn(&a::Bar, &(a::Foo, i32)) -> _`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:9
+   |
+LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unconstrained opaque type
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
index ad0a003e879..aab10be2de2 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
@@ -1,5 +1,3 @@
-// check-pass
-
 #![feature(type_alias_impl_trait)]
 
 type Foo = impl PartialEq<(Foo, i32)>;
@@ -13,6 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar {
 }
 
 fn foo() -> Foo {
+    //~^ ERROR can't compare `Bar` with `(Foo, i32)`
     Bar
 }
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr
new file mode 100644
index 00000000000..b98b859a99b
--- /dev/null
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr
@@ -0,0 +1,15 @@
+error[E0277]: can't compare `Bar` with `(Foo, i32)`
+  --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
+   |
+LL | fn foo() -> Foo {
+   |             ^^^ no implementation for `Bar == (Foo, i32)`
+LL |
+LL |     Bar
+   |     --- return type was inferred to be `Bar` here
+   |
+   = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar`
+   = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/lint/lint-ctypes-73249-2.rs b/tests/ui/lint/lint-ctypes-73249-2.rs
index 691047c8a40..f30377d6c16 100644
--- a/tests/ui/lint/lint-ctypes-73249-2.rs
+++ b/tests/ui/lint/lint-ctypes-73249-2.rs
@@ -1,7 +1,7 @@
 #![feature(type_alias_impl_trait)]
 #![deny(improper_ctypes)]
 
-pub trait Baz {}
+trait Baz {}
 
 impl Baz for () {}
 
@@ -9,7 +9,7 @@ type Qux = impl Baz;
 
 fn assign() -> Qux {}
 
-pub trait Foo {
+trait Foo {
     type Assoc: 'static;
 }
 
@@ -18,12 +18,12 @@ impl Foo for () {
 }
 
 #[repr(transparent)]
-pub struct A<T: Foo> {
+struct A<T: Foo> {
     x: &'static <T as Foo>::Assoc,
 }
 
 extern "C" {
-    pub fn lint_me() -> A<()>; //~ ERROR: uses type `Qux`
+    fn lint_me() -> A<()>; //~ ERROR: uses type `Qux`
 }
 
 fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73249-2.stderr b/tests/ui/lint/lint-ctypes-73249-2.stderr
index 8073c33dd46..49fa54114b2 100644
--- a/tests/ui/lint/lint-ctypes-73249-2.stderr
+++ b/tests/ui/lint/lint-ctypes-73249-2.stderr
@@ -1,8 +1,8 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73249-2.rs:26:25
+  --> $DIR/lint-ctypes-73249-2.rs:26:21
    |
-LL |     pub fn lint_me() -> A<()>;
-   |                         ^^^^^ not FFI-safe
+LL |     fn lint_me() -> A<()>;
+   |                     ^^^^^ not FFI-safe
    |
    = note: opaque types have no C equivalent
 note: the lint level is defined here
diff --git a/tests/ui/lint/lint-ctypes-73251-1.rs b/tests/ui/lint/lint-ctypes-73251-1.rs
index 145ba784f7c..fc11f23a104 100644
--- a/tests/ui/lint/lint-ctypes-73251-1.rs
+++ b/tests/ui/lint/lint-ctypes-73251-1.rs
@@ -1,13 +1,13 @@
 #![feature(type_alias_impl_trait)]
 #![deny(improper_ctypes)]
 
-pub trait Baz {}
+trait Baz {}
 
 impl Baz for u32 {}
 
 type Qux = impl Baz;
 
-pub trait Foo {
+trait Foo {
     type Assoc;
 }
 
@@ -20,7 +20,7 @@ fn assign() -> Qux {
 }
 
 extern "C" {
-    pub fn lint_me() -> <u32 as Foo>::Assoc; //~ ERROR: uses type `Qux`
+    fn lint_me() -> <u32 as Foo>::Assoc; //~ ERROR: uses type `Qux`
 }
 
 fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73251-1.stderr b/tests/ui/lint/lint-ctypes-73251-1.stderr
index 9f43576ad73..b4eb921b97e 100644
--- a/tests/ui/lint/lint-ctypes-73251-1.stderr
+++ b/tests/ui/lint/lint-ctypes-73251-1.stderr
@@ -1,8 +1,8 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73251-1.rs:23:25
+  --> $DIR/lint-ctypes-73251-1.rs:23:21
    |
-LL |     pub fn lint_me() -> <u32 as Foo>::Assoc;
-   |                         ^^^^^^^^^^^^^^^^^^^ not FFI-safe
+LL |     fn lint_me() -> <u32 as Foo>::Assoc;
+   |                     ^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = note: opaque types have no C equivalent
 note: the lint level is defined here
diff --git a/tests/ui/lint/lint-ctypes-73251-2.rs b/tests/ui/lint/lint-ctypes-73251-2.rs
index df71a945796..fbe0a58f3b5 100644
--- a/tests/ui/lint/lint-ctypes-73251-2.rs
+++ b/tests/ui/lint/lint-ctypes-73251-2.rs
@@ -33,7 +33,7 @@ fn use_of_b() -> AliasB {
 }
 
 extern "C" {
-    pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `AliasA`
+    fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `AliasA`
 }
 
 fn main() {}
diff --git a/tests/ui/lint/lint-ctypes-73251-2.stderr b/tests/ui/lint/lint-ctypes-73251-2.stderr
index 0b3de379c19..e44cd45bd30 100644
--- a/tests/ui/lint/lint-ctypes-73251-2.stderr
+++ b/tests/ui/lint/lint-ctypes-73251-2.stderr
@@ -1,8 +1,8 @@
 error: `extern` block uses type `AliasA`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73251-2.rs:36:25
+  --> $DIR/lint-ctypes-73251-2.rs:36:21
    |
-LL |     pub fn lint_me() -> <AliasB as TraitB>::Assoc;
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+LL |     fn lint_me() -> <AliasB as TraitB>::Assoc;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = note: opaque types have no C equivalent
 note: the lint level is defined here
diff --git a/tests/ui/lint/lint-ctypes-73251.rs b/tests/ui/lint/lint-ctypes-73251.rs
index ebc2ca77b67..a00d1a75aec 100644
--- a/tests/ui/lint/lint-ctypes-73251.rs
+++ b/tests/ui/lint/lint-ctypes-73251.rs
@@ -3,7 +3,7 @@
 #![feature(type_alias_impl_trait)]
 #![deny(improper_ctypes)]
 
-pub trait Foo {
+trait Foo {
     type Assoc;
 }
 
@@ -16,7 +16,7 @@ type Bar = impl Foo<Assoc = u32>;
 fn assign() -> Bar {}
 
 extern "C" {
-    pub fn lint_me() -> <Bar as Foo>::Assoc;
+    fn lint_me() -> <Bar as Foo>::Assoc;
 }
 
 fn main() {}
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.rs b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
index b7cc38e99fc..5faeac9ed4c 100644
--- a/tests/ui/lint/opaque-ty-ffi-unsafe.rs
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
@@ -3,12 +3,12 @@
 
 type A = impl Fn();
 
-pub fn ret_closure() -> A {
+pub(crate) fn ret_closure() -> A {
     || {}
 }
 
 extern "C" {
-    pub fn a(_: A);
+    pub(crate) fn a(_: A);
     //~^ ERROR `extern` block uses type `A`, which is not FFI-safe [improper_ctypes]
 }
 
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
index 33aa95854e3..ba9e18bcce5 100644
--- a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -1,8 +1,8 @@
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/opaque-ty-ffi-unsafe.rs:11:17
+  --> $DIR/opaque-ty-ffi-unsafe.rs:11:24
    |
-LL |     pub fn a(_: A);
-   |                 ^ not FFI-safe
+LL |     pub(crate) fn a(_: A);
+   |                        ^ not FFI-safe
    |
    = note: opaque types have no C equivalent
 note: the lint level is defined here
diff --git a/tests/ui/mir/mir_alignment_check.rs b/tests/ui/mir/mir_alignment_check.rs
index 68a5384b30d..d1bf3d46a7c 100644
--- a/tests/ui/mir/mir_alignment_check.rs
+++ b/tests/ui/mir/mir_alignment_check.rs
@@ -1,5 +1,6 @@
 // run-fail
 // ignore-wasm32-bare: No panic messages
+// ignore-i686-pc-windows-msvc: #112480
 // compile-flags: -C debug-assertions
 // error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is
 
diff --git a/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs b/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs
new file mode 100644
index 00000000000..56388c1047e
--- /dev/null
+++ b/tests/ui/mir/mir_alignment_check_i686-pc-windows-msvc.rs
@@ -0,0 +1,21 @@
+// run-pass
+// only-i686-pc-windows-msvc
+// compile-flags: -Copt-level=0 -Cdebug-assertions=yes
+
+// MSVC isn't sure if on 32-bit Windows its u64 type is 8-byte-aligned or 4-byte-aligned.
+// So this test ensures that on i686-pc-windows-msvc, we do not insert a runtime check
+// that will fail on dereferencing of a pointer to u64 which is not 8-byte-aligned but is
+// 4-byte-aligned.
+
+#![feature(strict_provenance)]
+
+fn main() {
+    let mut x = [0u64; 2];
+    let ptr: *mut u8 = x.as_mut_ptr().cast::<u8>();
+    unsafe {
+        let misaligned = ptr.add(4).cast::<u64>();
+        assert!(misaligned.addr() % 8 != 0);
+        assert!(misaligned.addr() % 4 == 0);
+        *misaligned = 42;
+    }
+}
diff --git a/tests/ui/parser/lit-err-in-macro.rs b/tests/ui/parser/lit-err-in-macro.rs
new file mode 100644
index 00000000000..cff8ee6b40c
--- /dev/null
+++ b/tests/ui/parser/lit-err-in-macro.rs
@@ -0,0 +1,10 @@
+macro_rules! f {
+    ($abi:literal) => {
+        extern $abi fn f() {}
+    }
+}
+
+f!("Foo"__);
+//~^ ERROR suffixes on string literals are invalid
+
+fn main() {}
diff --git a/tests/ui/parser/lit-err-in-macro.stderr b/tests/ui/parser/lit-err-in-macro.stderr
new file mode 100644
index 00000000000..a61fb5c85d4
--- /dev/null
+++ b/tests/ui/parser/lit-err-in-macro.stderr
@@ -0,0 +1,8 @@
+error: suffixes on string literals are invalid
+  --> $DIR/lit-err-in-macro.rs:7:4
+   |
+LL | f!("Foo"__);
+   |    ^^^^^^^ invalid suffix `__`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
new file mode 100644
index 00000000000..74c7afd6b9e
--- /dev/null
+++ b/tests/ui/traits/issue-105231.rs
@@ -0,0 +1,9 @@
+//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
+struct A<T>(B<T>);
+//~^ ERROR recursive types `A` and `B` have infinite size
+struct B<T>(A<A<T>>);
+trait Foo {}
+impl<T> Foo for T where T: Send {}
+impl Foo for B<u8> {}
+
+fn main() {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
new file mode 100644
index 00000000000..fe20c47c57a
--- /dev/null
+++ b/tests/ui/traits/issue-105231.stderr
@@ -0,0 +1,29 @@
+error[E0072]: recursive types `A` and `B` have infinite size
+  --> $DIR/issue-105231.rs:2:1
+   |
+LL | struct A<T>(B<T>);
+   | ^^^^^^^^^^^ ---- recursive without indirection
+LL |
+LL | struct B<T>(A<A<T>>);
+   | ^^^^^^^^^^^ ------- recursive without indirection
+   |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+   |
+LL ~ struct A<T>(Box<B<T>>);
+LL |
+LL ~ struct B<T>(Box<A<A<T>>>);
+   |
+
+error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
+note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+  --> $DIR/issue-105231.rs:4:8
+   |
+LL | struct B<T>(A<A<T>>);
+   |        ^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0072, E0275.
+For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/traits/new-solver/closure-substs-ambiguity.rs b/tests/ui/traits/new-solver/closure-substs-ambiguity.rs
new file mode 100644
index 00000000000..48432f4020f
--- /dev/null
+++ b/tests/ui/traits/new-solver/closure-substs-ambiguity.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+fn main() {
+    let mut x: Vec<_> = vec![];
+    x.extend(Some(1i32).into_iter().map(|x| x));
+}
diff --git a/tests/ui/traits/new-solver/opportunistic-region-resolve.rs b/tests/ui/traits/new-solver/opportunistic-region-resolve.rs
new file mode 100644
index 00000000000..2610789cd48
--- /dev/null
+++ b/tests/ui/traits/new-solver/opportunistic-region-resolve.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+#![feature(rustc_attrs)]
+
+#[rustc_coinductive]
+trait Trait {}
+
+#[rustc_coinductive]
+trait Indirect {}
+impl<T: Trait + ?Sized> Indirect for T {}
+
+impl<'a> Trait for &'a () where &'a (): Indirect {}
+
+fn impls_trait<T: Trait>() {}
+
+fn main() {
+    impls_trait::<&'static ()>();
+}
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
index a1584581e6c..d9f7c7809b9 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
@@ -4,9 +4,9 @@
 #![allow(dead_code)]
 
 mod m {
-    type Foo = impl std::fmt::Debug;
+    pub(crate) type Foo = impl std::fmt::Debug;
 
-    pub fn foo() -> Foo {
+    pub(crate) fn foo() -> Foo {
         22_u32
     }
 }
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs
new file mode 100644
index 00000000000..5a9e87c0919
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::{Debug, Display};
+
+struct Struct<V: Display>(Option<V>);
+
+// Make sure that, in contrast to type aliases without opaque types,
+// we actually do a wf check for the aliased type.
+type Foo<T: Debug> = (impl Debug, Struct<T>);
+//~^ ERROR: `T` doesn't implement `std::fmt::Display`
+
+fn foo<U: Debug + Display>() -> Foo<U> {
+    (Vec::<U>::new(), Struct(None))
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked3.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked3.stderr
new file mode 100644
index 00000000000..a845cba7716
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked3.stderr
@@ -0,0 +1,20 @@
+error[E0277]: `T` doesn't implement `std::fmt::Display`
+  --> $DIR/bounds-are-checked3.rs:9:35
+   |
+LL | type Foo<T: Debug> = (impl Debug, Struct<T>);
+   |                                   ^^^^^^^^^ `T` cannot be formatted with the default formatter
+   |
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Struct`
+  --> $DIR/bounds-are-checked3.rs:5:18
+   |
+LL | struct Struct<V: Display>(Option<V>);
+   |                  ^^^^^^^ required by this bound in `Struct`
+help: consider further restricting this bound
+   |
+LL | type Foo<T: Debug + std::fmt::Display> = (impl Debug, Struct<T>);
+   |                   +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/bounds.rs b/tests/ui/type-alias-impl-trait/bounds.rs
new file mode 100644
index 00000000000..dc05b70c5cc
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bounds.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+// check-pass
+
+use std::fmt::Debug;
+
+// No need to report the `type_alias_bounds` lint, as
+// the moment an opaque type is mentioned, we actually do check
+// type alias bounds.
+type Foo<T: Debug> = (impl Debug, usize);
+
+fn foo<U: Debug>() -> Foo<U> {
+    (Vec::<U>::new(), 1234)
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr
index 00b0dbbb583..c923eb08ab3 100644
--- a/tests/ui/type-alias-impl-trait/coherence.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.stderr
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
    | |                                       |
-   | |                                       type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate
+   | |                                       `AliasOfForeignType<T>` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
diff --git a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
index 8b51f55715e..4d84b2cbbe9 100644
--- a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
+++ b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
@@ -11,12 +11,12 @@ type Foo = impl std::fmt::Display;
 type Bar = impl std::fmt::Display;
 
 mod foo {
-    pub fn foo() -> super::Foo {
+    pub(crate) fn foo() -> super::Foo {
         "foo"
     }
 
-    pub mod bar {
-        pub fn bar() -> crate::Bar {
+    pub(crate) mod bar {
+        pub(crate) fn bar() -> crate::Bar {
             1
         }
     }
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
index c73288329b0..bc9280127ac 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -4,11 +4,11 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
 LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
    |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
    |
-note: required by a bound in `Underconstrained`
+note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained.rs:6:26
    |
 LL | type Underconstrained<T: Trait> = impl Send;
-   |                          ^^^^^ required by this bound in `Underconstrained`
+   |                          ^^^^^ required by this bound
 help: consider restricting type parameter `T`
    |
 LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index d77d978aa44..fdc9ec090db 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -4,11 +4,11 @@ error[E0277]: `U` doesn't implement `Debug`
 LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
    |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-note: required by a bound in `Underconstrained`
+note: required by a bound on the type alias `Underconstrained`
   --> $DIR/generic_underconstrained2.rs:5:26
    |
 LL | type Underconstrained<T: std::fmt::Debug> = impl Send;
-   |                          ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained`
+   |                          ^^^^^^^^^^^^^^^ required by this bound
 help: consider restricting type parameter `U`
    |
 LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
@@ -20,11 +20,11 @@ error[E0277]: `V` doesn't implement `Debug`
 LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
    |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-note: required by a bound in `Underconstrained2`
+note: required by a bound on the type alias `Underconstrained2`
   --> $DIR/generic_underconstrained2.rs:13:27
    |
 LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
-   |                           ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained2`
+   |                           ^^^^^^^^^^^^^^^ required by this bound
 help: consider restricting type parameter `V`
    |
 LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
diff --git a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs
new file mode 100644
index 00000000000..00d1a1a226d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+#![feature(auto_traits)]
+
+type Alias = (impl Sized, u8);
+
+auto trait Trait {}
+impl Trait for Alias {}
+//~^ ERROR traits with a default impl, like `Trait`, cannot be implemented for type alias `Alias`
+
+fn _def() -> Alias {
+    (42, 42)
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.stderr b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.stderr
new file mode 100644
index 00000000000..c312ee7dece
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.stderr
@@ -0,0 +1,11 @@
+error[E0321]: traits with a default impl, like `Trait`, cannot be implemented for type alias `Alias`
+  --> $DIR/impl_for_weak_alias.rs:7:1
+   |
+LL | impl Trait for Alias {}
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: a trait object implements `Trait` if and only if `Trait` is one of the trait object's trait bounds
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0321`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
index 4a11bb5020e..b89c3e4590f 100644
--- a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
@@ -1,9 +1,10 @@
 #![feature(type_alias_impl_trait)]
 
+// check-pass
+
 type Foo = impl Fn() -> Foo;
 
 fn foo() -> Foo {
-//~^ ERROR: overflow evaluating the requirement
     foo
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
deleted file mode 100644
index 0a34e8486a5..00000000000
--- a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0275]: overflow evaluating the requirement `Foo: Sized`
-  --> $DIR/issue-53398-cyclic-types.rs:5:13
-   |
-LL | fn foo() -> Foo {
-   |             ^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
-   = note: required because it appears within the type `fn() -> Foo {foo}`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/obligation_ice.rs b/tests/ui/type-alias-impl-trait/obligation_ice.rs
new file mode 100644
index 00000000000..5aef04ff19c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/obligation_ice.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+
+use std::iter::{once, Chain};
+
+trait Trait<'a, 'b: 'a> {}
+
+impl<'a, 'b: 'a, T> Trait<'a, 'b> for std::iter::Cloned<T> {}
+
+type I<'a, 'b: 'a, A: Trait<'a, 'b>> = Chain<A, impl Iterator<Item = &'static str>>;
+fn test2<'a, 'b, A: Trait<'a, 'b> + Iterator<Item = &'static str>>(x: A) -> I<'a, 'b, A> {
+    x.chain(once("5"))
+}
+
+fn main() {
+    assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::<Vec<_>>());
+}
diff --git a/tests/ui/type-alias-impl-trait/privacy.rs b/tests/ui/type-alias-impl-trait/privacy.rs
new file mode 100644
index 00000000000..aa092f6f8ec
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/privacy.rs
@@ -0,0 +1,8 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = (impl Sized, u8);
+pub fn foo() -> Foo {
+    //~^ ERROR private type alias `Foo` in public interface
+    (42, 42)
+}
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/privacy.stderr b/tests/ui/type-alias-impl-trait/privacy.stderr
new file mode 100644
index 00000000000..e8c6039cdc8
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/privacy.stderr
@@ -0,0 +1,11 @@
+error[E0446]: private type alias `Foo` in public interface
+  --> $DIR/privacy.rs:4:1
+   |
+LL | type Foo = (impl Sized, u8);
+   | -------- `Foo` declared as private
+LL | pub fn foo() -> Foo {
+   | ^^^^^^^^^^^^^^^^^^^ can't leak private type alias
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs
index d40715717d4..18f09b54867 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-3.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs
@@ -1,9 +1,9 @@
-// run-pass
 #![feature(type_alias_impl_trait)]
 
 type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
 
 fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+    //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>`
     i
 }
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr
new file mode 100644
index 00000000000..4155a114b4f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr
@@ -0,0 +1,15 @@
+error[E0277]: can't compare `&i32` with `Bar<'a, 'b>`
+  --> $DIR/self-referential-3.rs:5:31
+   |
+LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>`
+LL |
+LL |     i
+   |     - return type was inferred to be `&i32` here
+   |
+   = help: the trait `PartialEq<Bar<'a, 'b>>` is not implemented for `&i32`
+   = help: the trait `PartialEq` is implemented for `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs
index 3ff5406a382..34b7c24df9f 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential.rs
@@ -10,7 +10,7 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
 type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
 
 fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-    //~^ ERROR can't compare `&i32` with `(i32, &i32)`
+    //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
     (42, i)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr
index aff489d70e3..9a17d495b62 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential.stderr
@@ -10,16 +10,16 @@ LL |     i
    = help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
-error[E0277]: can't compare `&i32` with `(i32, &i32)`
+error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
   --> $DIR/self-referential.rs:12:31
    |
 LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, &i32)`
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0})`
 LL |
 LL |     (42, i)
    |     ------- return type was inferred to be `(i32, &i32)` here
    |
-   = help: the trait `PartialEq<(i32, &i32)>` is not implemented for `&i32`
+   = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0})>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
 error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
index 07c891f0638..4e7388517a5 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
@@ -4,20 +4,20 @@
 
 // Regression test for issue #61863
 
-pub trait MyTrait {}
+trait MyTrait {}
 
 #[derive(Debug)]
-pub struct MyStruct {
+struct MyStruct {
     v: u64,
 }
 
 impl MyTrait for MyStruct {}
 
-pub fn bla() -> TE {
+fn bla() -> TE {
     return MyStruct { v: 1 };
 }
 
-pub fn bla2() -> TE {
+fn bla2() -> TE {
     bla()
 }
 
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index e9032433494..24f5cc8c733 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -25,6 +25,11 @@ LL |         fn dont_define_this(_private: Private) {}
    |                                       ^^^^^^^
    = note: expected signature `fn(Private)`
               found signature `fn(MyPrivate)`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/unnameable_type.rs:20:5
+   |
+LL |     fn dont_define_this(_private: MyPrivate) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors