about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.github/workflows/dependencies.yml4
-rw-r--r--Cargo.lock159
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs20
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/coverageinfo.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs41
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs39
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs3
-rw-r--r--compiler/rustc_errors/src/emitter.rs3
-rw-r--r--compiler/rustc_errors/src/lib.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs22
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs2
-rw-r--r--compiler/rustc_interface/src/interface.rs2
-rw-r--r--compiler/rustc_metadata/src/creader.rs27
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs1
-rw-r--r--compiler/rustc_middle/src/hooks/mod.rs6
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs9
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs6
-rw-r--r--compiler/rustc_middle/src/query/mod.rs16
-rw-r--r--compiler/rustc_mir_build/src/build/cfg.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs11
-rw-r--r--compiler/rustc_mir_build/src/lib.rs4
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs9
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs7
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs34
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs20
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs98
-rw-r--r--compiler/rustc_session/src/parse.rs7
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml1
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs218
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs26
-rw-r--r--compiler/rustc_target/src/asm/arm.rs6
-rw-r--r--compiler/rustc_target/src/asm/avr.rs6
-rw-r--r--compiler/rustc_target/src/asm/bpf.rs6
-rw-r--r--compiler/rustc_target/src/asm/csky.rs6
-rw-r--r--compiler/rustc_target/src/asm/hexagon.rs6
-rw-r--r--compiler/rustc_target/src/asm/loongarch.rs6
-rw-r--r--compiler/rustc_target/src/asm/m68k.rs6
-rw-r--r--compiler/rustc_target/src/asm/mips.rs6
-rw-r--r--compiler/rustc_target/src/asm/mod.rs20
-rw-r--r--compiler/rustc_target/src/asm/msp430.rs6
-rw-r--r--compiler/rustc_target/src/asm/nvptx.rs6
-rw-r--r--compiler/rustc_target/src/asm/powerpc.rs6
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs6
-rw-r--r--compiler/rustc_target/src/asm/s390x.rs6
-rw-r--r--compiler/rustc_target/src/asm/spirv.rs6
-rw-r--r--compiler/rustc_target/src/asm/wasm.rs6
-rw-r--r--compiler/rustc_target/src/asm/x86.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs37
-rw-r--r--compiler/stable_mir/src/mir/alloc.rs4
-rw-r--r--compiler/stable_mir/src/target.rs2
-rw-r--r--library/core/src/fmt/mod.rs14
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/intrinsics/simd.rs2
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/panicking.rs14
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs83
-rw-r--r--library/std/src/sys/pal/uefi/os.rs8
-rw-r--r--library/std/src/sys/pal/unix/net.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs8
-rw-r--r--library/unwind/src/lib.rs1
-rw-r--r--library/unwind/src/wasm.rs5
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs65
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh18
-rw-r--r--src/ci/github-actions/ci.yml2
-rw-r--r--src/librustdoc/doctest.rs9
-rw-r--r--src/tools/compiletest/src/lib.rs2
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/fd/event.rs4
-rw-r--r--src/tools/rustfmt/src/parse/session.rs3
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs16
-rw-r--r--tests/ui/asm/aarch64/type-check-3.stderr40
-rw-r--r--tests/ui/asm/bad-template.aarch64.stderr4
-rw-r--r--tests/ui/asm/bad-template.x86_64.stderr4
-rw-r--r--tests/ui/asm/x86_64/type-check-3.stderr16
-rw-r--r--tests/ui/associated-type-bounds/auxiliary/implied-predicates.rs7
-rw-r--r--tests/ui/associated-type-bounds/implied-predicates.rs9
-rw-r--r--tests/ui/associated-type-bounds/resolution-failure-building-vtable-representation-ice-90691.rs42
-rw-r--r--tests/ui/binding/issue-53114-safety-checks.stderr64
-rw-r--r--tests/ui/const-generics/const-argument-if-length.full.stderr5
-rw-r--r--tests/ui/const-generics/defaults/generic-expr-default.stderr10
-rw-r--r--tests/ui/const-generics/ensure_is_evaluatable.stderr5
-rw-r--r--tests/ui/const-generics/fn_with_two_const_inputs.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.fixed21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_binop_arg_tys.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_cast_arg_ty.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr20
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/different-fn.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/failed-to-normalize-ice-issue-88421.rs36
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-83765.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-85848.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr5
-rw-r--r--tests/ui/const-generics/issues/issue-67739.full.stderr5
-rw-r--r--tests/ui/const-generics/issues/issue-71202.stderr78
-rw-r--r--tests/ui/const-generics/issues/issue-84659.fixed13
-rw-r--r--tests/ui/const-generics/issues/issue-84659.rs3
-rw-r--r--tests/ui/const-generics/issues/issue-84659.stderr7
-rw-r--r--tests/ui/const-generics/issues/issue-90455.fixed13
-rw-r--r--tests/ui/const-generics/issues/issue-90455.rs3
-rw-r--r--tests/ui/const-generics/issues/issue-90455.stderr7
-rw-r--r--tests/ui/consts/const-needs_drop-monomorphic.stderr5
-rw-r--r--tests/ui/consts/ice-bad-input-type-for-cast-83056.rs7
-rw-r--r--tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr20
-rw-r--r--tests/ui/coroutine/clone-rpit.next.stderr5
-rw-r--r--tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs16
-rw-r--r--tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr22
-rw-r--r--tests/ui/extern/extern-C-str-arg-ice-80125.rs15
-rw-r--r--tests/ui/extern/extern-C-str-arg-ice-80125.stderr35
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.fixed25
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.rs12
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.stderr13
-rw-r--r--tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr5
-rw-r--r--tests/ui/panics/panic-in-message-fmt.run.stderr1
-rw-r--r--tests/ui/polymorphization/ice-poly-with-mir-opts-90192.rs20
-rw-r--r--tests/ui/privacy/decl-macro-infinite-global-import-cycle-ice-64784.rs16
-rw-r--r--tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs6
-rw-r--r--tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs2
-rw-r--r--tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs12
-rw-r--r--tests/ui/resolve/multiple_definitions_attribute_merging.stderr4
-rw-r--r--tests/ui/resolve/proc_macro_generated_packed.stderr4
-rw-r--r--tests/ui/sanitizer/cfi-complex-receiver.rs42
-rw-r--r--tests/ui/sanitizer/cfi-drop-no-principal.rs21
-rw-r--r--tests/ui/sanitizer/cfi-self-ref.rs33
-rw-r--r--tests/ui/sanitizer/cfi-virtual-auto.rs22
-rw-r--r--tests/ui/simd/array-trait.stderr6
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr25
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr25
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.rs18
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.stderr25
-rw-r--r--tests/ui/specialization/issue-51892.stderr5
-rw-r--r--tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr5
-rw-r--r--tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs28
-rw-r--r--tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.rs21
-rw-r--r--tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.stderr23
-rw-r--r--tests/ui/variance/variance-associated-consts.stderr5
-rw-r--r--triagebot.toml4
168 files changed, 1781 insertions, 745 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 767ea29d636..f1c87b0a76e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -166,7 +166,7 @@ jobs:
         run: src/ci/scripts/create-doc-artifacts.sh
         if: success() && !env.SKIP_JOB
       - name: upload artifacts to github
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: "${{ env.DOC_ARTIFACT_NAME }}"
           path: obj/artifacts/doc
@@ -576,7 +576,7 @@ jobs:
         run: src/ci/scripts/create-doc-artifacts.sh
         if: success() && !env.SKIP_JOB
       - name: upload artifacts to github
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: "${{ env.DOC_ARTIFACT_NAME }}"
           path: obj/artifacts/doc
@@ -715,7 +715,7 @@ jobs:
         run: src/ci/scripts/create-doc-artifacts.sh
         if: success() && !env.SKIP_JOB
       - name: upload artifacts to github
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: "${{ env.DOC_ARTIFACT_NAME }}"
           path: obj/artifacts/doc
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index d7a31c8e80f..1dc5b0e9d08 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -70,13 +70,13 @@ jobs:
           cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
           git status --porcelain | grep -q Cargo.lock || gh run cancel ${{ github.run_id }}
       - name: upload Cargo.lock artifact for use in PR
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: Cargo-lock
           path: Cargo.lock
           retention-days: 1
       - name: upload cargo-update log artifact for use in PR
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           name: cargo-updates
           path: cargo_update.log
diff --git a/Cargo.lock b/Cargo.lock
index b8fe1ebaf80..9163538765d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -49,9 +49,9 @@ dependencies = [
 
 [[package]]
 name = "aho-corasick"
-version = "1.1.2"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
 dependencies = [
  "memchr",
 ]
@@ -246,7 +246,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -272,9 +272,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
 name = "backtrace"
-version = "0.3.69"
+version = "0.3.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
 dependencies = [
  "addr2line",
  "cc",
@@ -317,9 +317,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.4.2"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
 
 [[package]]
 name = "block-buffer"
@@ -400,9 +400,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.5.0"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
 
 [[package]]
 name = "camino"
@@ -428,9 +428,9 @@ dependencies = [
 
 [[package]]
 name = "cargo-platform"
-version = "0.1.7"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f"
+checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
 dependencies = [
  "serde",
 ]
@@ -563,7 +563,7 @@ dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -590,7 +590,7 @@ dependencies = [
  "regex",
  "rustc_tools_util",
  "serde",
- "syn 2.0.53",
+ "syn 2.0.55",
  "tempfile",
  "termize",
  "tester",
@@ -949,7 +949,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim 0.10.0",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -960,7 +960,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -975,7 +975,7 @@ version = "0.1.79"
 dependencies = [
  "itertools 0.12.1",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1016,7 +1016,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1026,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1049,7 +1049,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1138,7 +1138,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1293,9 +1293,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "fastrand"
-version = "2.0.1"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
 
 [[package]]
 name = "field-offset"
@@ -1484,7 +1484,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1922,7 +1922,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -1972,9 +1972,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
 
 [[package]]
 name = "indexmap"
-version = "2.2.5"
+version = "2.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -2205,7 +2205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
 dependencies = [
  "cfg-if",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.4",
 ]
 
 [[package]]
@@ -2220,16 +2220,16 @@ version = "0.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "libc",
  "redox_syscall",
 ]
 
 [[package]]
 name = "libz-sys"
-version = "1.1.15"
+version = "1.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6"
+checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9"
 dependencies = [
  "cc",
  "libc",
@@ -2546,7 +2546,7 @@ version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "cfg-if",
  "cfg_aliases",
  "libc",
@@ -2683,7 +2683,7 @@ version = "0.10.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "cfg-if",
  "foreign-types",
  "libc",
@@ -2700,7 +2700,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -2893,7 +2893,7 @@ dependencies = [
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -3055,7 +3055,7 @@ version = "0.9.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "memchr",
  "unicase",
 ]
@@ -3066,7 +3066,7 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "memchr",
  "pulldown-cmark-escape",
  "unicase",
@@ -3170,9 +3170,9 @@ dependencies = [
 
 [[package]]
 name = "rayon"
-version = "1.9.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
 dependencies = [
  "either",
  "rayon-core",
@@ -3285,9 +3285,9 @@ dependencies = [
 
 [[package]]
 name = "reqwest"
-version = "0.11.26"
+version = "0.11.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2"
+checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
 dependencies = [
  "base64",
  "bytes",
@@ -3448,7 +3448,7 @@ dependencies = [
 name = "rustc_abi"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "rand",
  "rand_xoshiro",
  "rustc_data_structures",
@@ -3479,7 +3479,7 @@ dependencies = [
 name = "rustc_ast"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "memchr",
  "rustc_ast_ir",
  "rustc_data_structures",
@@ -3642,7 +3642,7 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "itertools 0.12.1",
  "libc",
  "measureme",
@@ -3677,7 +3677,7 @@ name = "rustc_codegen_ssa"
 version = "0.0.0"
 dependencies = [
  "ar_archive_writer",
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "cc",
  "itertools 0.12.1",
  "jobserver",
@@ -3746,7 +3746,7 @@ name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
  "arrayvec",
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "either",
  "elsa",
  "ena",
@@ -3929,7 +3929,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "unic-langid",
 ]
 
@@ -4064,7 +4064,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "synstructure",
 ]
 
@@ -4210,7 +4210,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "synstructure",
 ]
 
@@ -4218,7 +4218,7 @@ dependencies = [
 name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "libloading",
  "odht",
  "rustc_ast",
@@ -4248,7 +4248,7 @@ dependencies = [
 name = "rustc_middle"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "derivative",
  "either",
  "field-offset",
@@ -4385,7 +4385,7 @@ dependencies = [
 name = "rustc_parse"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
@@ -4525,7 +4525,7 @@ dependencies = [
 name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "pulldown-cmark 0.9.6",
  "rustc_arena",
  "rustc_ast",
@@ -4564,7 +4564,7 @@ dependencies = [
 name = "rustc_session"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "getopts",
  "libc",
  "rustc_ast",
@@ -4624,7 +4624,7 @@ dependencies = [
 name = "rustc_symbol_mangling"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "punycode",
  "rustc-demangle",
  "rustc_data_structures",
@@ -4634,6 +4634,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
+ "rustc_trait_selection",
  "tracing",
  "twox-hash",
 ]
@@ -4642,7 +4643,7 @@ dependencies = [
 name = "rustc_target"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "object 0.32.2",
  "rustc_abi",
  "rustc_data_structures",
@@ -4666,7 +4667,7 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
 name = "rustc_trait_selection"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "itertools 0.12.1",
  "rustc_ast",
  "rustc_ast_ir",
@@ -4745,7 +4746,7 @@ dependencies = [
 name = "rustc_type_ir"
 version = "0.0.0"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "derivative",
  "rustc_ast_ir",
  "rustc_data_structures",
@@ -4838,7 +4839,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -4873,11 +4874,11 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.31"
+version = "0.38.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
+checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
 dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.5.0",
  "errno",
  "libc",
  "linux-raw-sys",
@@ -5021,7 +5022,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -5117,9 +5118,9 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.13.1"
+version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
 [[package]]
 name = "snap"
@@ -5328,9 +5329,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.53"
+version = "2.0.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
+checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5351,7 +5352,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -5530,7 +5531,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -5753,7 +5754,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -5970,7 +5971,7 @@ checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "unic-langid-impl",
 ]
 
@@ -6126,9 +6127,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
 [[package]]
 name = "uuid"
-version = "1.7.0"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
+checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
 dependencies = [
  "getrandom",
 ]
@@ -6202,7 +6203,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "wasm-bindgen-shared",
 ]
 
@@ -6236,7 +6237,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -6327,7 +6328,7 @@ dependencies = [
  "rayon",
  "serde",
  "serde_json",
- "syn 2.0.53",
+ "syn 2.0.55",
  "windows-metadata",
 ]
 
@@ -6581,7 +6582,7 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "synstructure",
 ]
 
@@ -6602,7 +6603,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
@@ -6622,7 +6623,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
  "synstructure",
 ]
 
@@ -6645,7 +6646,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.53",
+ "syn 2.0.55",
 ]
 
 [[package]]
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 11561539f6d..0106e285604 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -4,7 +4,6 @@ use crate::session_diagnostics::{
     CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
     CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
 };
-use itertools::Itertools;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, Namespace};
@@ -226,16 +225,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         }
                     } else {
                         if autoderef_index.is_none() {
-                            autoderef_index =
-                                match place.projection.into_iter().rev().find_position(|elem| {
-                                    !matches!(
-                                        elem,
-                                        ProjectionElem::Deref | ProjectionElem::Downcast(..)
-                                    )
-                                }) {
-                                    Some((index, _)) => Some(place.projection.len() - index),
-                                    None => Some(0),
-                                };
+                            autoderef_index = match place.projection.iter().rposition(|elem| {
+                                !matches!(
+                                    elem,
+                                    ProjectionElem::Deref | ProjectionElem::Downcast(..)
+                                )
+                            }) {
+                                Some(index) => Some(index + 1),
+                                None => Some(0),
+                            };
                         }
                         if index >= autoderef_index.unwrap() {
                             buf.insert(0, '*');
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 9b679019e96..06b14a1f118 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -541,7 +541,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
             let builtin_unreachable: RValue<'gcc> = unsafe {
                 std::mem::transmute(builtin_unreachable)
             };
-            self.call(self.type_void(), None, None, builtin_unreachable, &[], None);
+            self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
         }
 
         // Write results to outputs.
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index f5cda81f6ab..43cc46cfe68 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
     TyAndLayout,
 };
-use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance};
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 use rustc_target::abi::{
@@ -592,12 +592,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         then: Block<'gcc>,
         catch: Block<'gcc>,
         _funclet: Option<&Funclet>,
+        instance: Option<Instance<'tcx>>,
     ) -> RValue<'gcc> {
         let try_block = self.current_func().new_block("try");
 
         let current_block = self.block.clone();
         self.block = try_block;
-        let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here?
+        let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here?
         self.block = current_block;
 
         let return_value =
@@ -1667,6 +1668,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         func: RValue<'gcc>,
         args: &[RValue<'gcc>],
         funclet: Option<&Funclet>,
+        _instance: Option<Instance<'tcx>>,
     ) -> RValue<'gcc> {
         // FIXME(antoyo): remove when having a proper API.
         let gcc_func = unsafe { std::mem::transmute(func) };
diff --git a/compiler/rustc_codegen_gcc/src/coverageinfo.rs b/compiler/rustc_codegen_gcc/src/coverageinfo.rs
index 849e9886ef3..4e44f78f23c 100644
--- a/compiler/rustc_codegen_gcc/src/coverageinfo.rs
+++ b/compiler/rustc_codegen_gcc/src/coverageinfo.rs
@@ -1,11 +1,11 @@
 use rustc_codegen_ssa::traits::CoverageInfoBuilderMethods;
-use rustc_middle::mir::Coverage;
+use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::ty::Instance;
 
 use crate::builder::Builder;
 
 impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
+    fn add_coverage(&mut self, _instance: Instance<'tcx>, _kind: &CoverageKind) {
         // TODO(antoyo)
     }
 }
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index a6c8b72e851..cebd45c09aa 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -133,6 +133,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     func,
                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                     None,
+                    None,
                 )
             }
             sym::likely => self.expect(args[0].immediate(), true),
@@ -401,7 +402,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn abort(&mut self) {
         let func = self.context.get_builtin_function("abort");
         let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
-        self.call(self.type_void(), None, None, func, &[], None);
+        self.call(self.type_void(), None, None, func, &[], None, None);
     }
 
     fn assume(&mut self, value: Self::Value) {
@@ -1103,7 +1104,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
     dest: RValue<'gcc>,
 ) {
     if bx.sess().panic_strategy() == PanicStrategy::Abort {
-        bx.call(bx.type_void(), None, None, try_func, &[data], None);
+        bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
         // Return 0 unconditionally from the intrinsic call;
         // we can never unwind.
         let ret_align = bx.tcx.data_layout.i32_align.abi;
@@ -1177,21 +1178,21 @@ fn codegen_gnu_try<'gcc>(
         let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
         let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
         let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
-        bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
+        bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
         bx.ret(bx.const_i32(1));
 
         // NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
         // generate a try/catch.
         // FIXME(antoyo): add a check in the libgccjit API to prevent this.
         bx.switch_to_block(current_block);
-        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
+        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
     });
 
     let func = unsafe { std::mem::transmute(func) };
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 74539d4d495..500904ce188 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -466,11 +466,11 @@ pub(crate) fn inline_asm_call<'ll>(
 
             let call = if !labels.is_empty() {
                 assert!(catch_funclet.is_none());
-                bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None)
+                bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
             } else if let Some((catch, funclet)) = catch_funclet {
-                bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet)
+                bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
             } else {
-                bx.call(fty, None, None, v, inputs, None)
+                bx.call(fty, None, None, v, inputs, None, None)
             };
 
             // Store mark in a metadata node so we can map LLVM errors
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 63e59ea13fc..a5a5ae73d77 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -19,9 +19,12 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
 };
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_span::Span;
-use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions};
+use rustc_symbol_mangling::typeid::{
+    kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
+    TypeIdOptions,
+};
 use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
 use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
 use smallvec::SmallVec;
@@ -221,6 +224,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         then: &'ll BasicBlock,
         catch: &'ll BasicBlock,
         funclet: Option<&Funclet<'ll>>,
+        instance: Option<Instance<'tcx>>,
     ) -> &'ll Value {
         debug!("invoke {:?} with args ({:?})", llfn, args);
 
@@ -233,10 +237,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         }
 
         // Emit CFI pointer type membership test
-        self.cfi_type_test(fn_attrs, fn_abi, llfn);
+        self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
 
         // Emit KCFI operand bundle
-        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
+        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
         let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
         if let Some(kcfi_bundle) = kcfi_bundle {
             bundles.push(kcfi_bundle);
@@ -1231,6 +1235,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         llfn: &'ll Value,
         args: &[&'ll Value],
         funclet: Option<&Funclet<'ll>>,
+        instance: Option<Instance<'tcx>>,
     ) -> &'ll Value {
         debug!("call {:?} with args ({:?})", llfn, args);
 
@@ -1243,10 +1248,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         }
 
         // Emit CFI pointer type membership test
-        self.cfi_type_test(fn_attrs, fn_abi, llfn);
+        self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
 
         // Emit KCFI operand bundle
-        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
+        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
         let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
         if let Some(kcfi_bundle) = kcfi_bundle {
             bundles.push(kcfi_bundle);
@@ -1468,7 +1473,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
 
     pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
         let (ty, f) = self.cx.get_intrinsic(intrinsic);
-        self.call(ty, None, None, f, args, None)
+        self.call(ty, None, None, f, args, None, None)
     }
 
     fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
@@ -1526,7 +1531,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             format!("llvm.{instr}.sat.i{int_width}.f{float_width}")
         };
         let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
-        self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None)
+        self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None)
     }
 
     pub(crate) fn landing_pad(
@@ -1554,6 +1559,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         default_dest: &'ll BasicBlock,
         indirect_dest: &[&'ll BasicBlock],
         funclet: Option<&Funclet<'ll>>,
+        instance: Option<Instance<'tcx>>,
     ) -> &'ll Value {
         debug!("invoke {:?} with args ({:?})", llfn, args);
 
@@ -1566,10 +1572,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         }
 
         // Emit CFI pointer type membership test
-        self.cfi_type_test(fn_attrs, fn_abi, llfn);
+        self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
 
         // Emit KCFI operand bundle
-        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
+        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
         let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
         if let Some(kcfi_bundle) = kcfi_bundle {
             bundles.push(kcfi_bundle);
@@ -1601,6 +1607,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         &mut self,
         fn_attrs: Option<&CodegenFnAttrs>,
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
+        instance: Option<Instance<'tcx>>,
         llfn: &'ll Value,
     ) {
         let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
@@ -1622,7 +1629,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
             }
 
-            let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
+            let typeid = if let Some(instance) = instance {
+                typeid_for_instance(self.tcx, &instance, options)
+            } else {
+                typeid_for_fnabi(self.tcx, fn_abi, options)
+            };
             let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
 
             // Test whether the function pointer is associated with the type identifier.
@@ -1644,6 +1655,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         &mut self,
         fn_attrs: Option<&CodegenFnAttrs>,
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
+        instance: Option<Instance<'tcx>>,
         llfn: &'ll Value,
     ) -> Option<llvm::OperandBundleDef<'ll>> {
         let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
@@ -1665,7 +1677,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
             }
 
-            let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
+            let kcfi_typeid = if let Some(instance) = instance {
+                kcfi_typeid_for_instance(self.tcx, &instance, options)
+            } else {
+                kcfi_typeid_for_fnabi(self.tcx, fn_abi, options)
+            };
+
             Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
         } else {
             None
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 54f4bc06340..85277db6d53 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -14,7 +14,6 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_llvm::RustString;
 use rustc_middle::bug;
 use rustc_middle::mir::coverage::CoverageKind;
-use rustc_middle::mir::Coverage;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::Instance;
 
@@ -75,7 +74,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
 
 impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
     #[instrument(level = "debug", skip(self))]
-    fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage) {
+    fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) {
         // Our caller should have already taken care of inlining subtleties,
         // so we can assume that counter/expression IDs in this coverage
         // statement are meaningful for the given instance.
@@ -98,7 +97,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             .entry(instance)
             .or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info));
 
-        let Coverage { kind } = coverage;
         match *kind {
             CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => unreachable!(
                 "marker statement {kind:?} should have been removed by CleanupPostBorrowck"
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 2409b2e78d7..ab135e3ed64 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -181,6 +181,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     simple_fn,
                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                     None,
+                    Some(instance),
                 )
             }
             sym::likely => {
@@ -539,7 +540,7 @@ fn catch_unwind_intrinsic<'ll>(
 ) {
     if bx.sess().panic_strategy() == PanicStrategy::Abort {
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
-        bx.call(try_func_ty, None, None, try_func, &[data], None);
+        bx.call(try_func_ty, None, None, try_func, &[data], None, None);
         // Return 0 unconditionally from the intrinsic call;
         // we can never unwind.
         let ret_align = bx.tcx().data_layout.i32_align.abi;
@@ -640,7 +641,7 @@ fn codegen_msvc_try<'ll>(
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
         let slot = bx.alloca(bx.type_ptr(), ptr_align);
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
-        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
+        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
 
         bx.switch_to_block(normal);
         bx.ret(bx.const_i32(0));
@@ -684,7 +685,7 @@ fn codegen_msvc_try<'ll>(
         let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
         let ptr = bx.load(bx.type_ptr(), slot, ptr_align);
         let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
-        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
+        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
         bx.catch_ret(&funclet, caught);
 
         // The flag value of 64 indicates a "catch-all".
@@ -692,7 +693,7 @@ fn codegen_msvc_try<'ll>(
         let flags = bx.const_i32(64);
         let null = bx.const_null(bx.type_ptr());
         let funclet = bx.catch_pad(cs, &[null, flags, null]);
-        bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet));
+        bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet), None);
         bx.catch_ret(&funclet, caught);
 
         bx.switch_to_block(caught);
@@ -701,7 +702,7 @@ fn codegen_msvc_try<'ll>(
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -750,7 +751,7 @@ fn codegen_wasm_try<'ll>(
         //   }
         //
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
-        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
+        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
 
         bx.switch_to_block(normal);
         bx.ret(bx.const_i32(0));
@@ -766,7 +767,7 @@ fn codegen_wasm_try<'ll>(
         let _sel = bx.call_intrinsic("llvm.wasm.get.ehselector", &[funclet.cleanuppad()]);
 
         let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
-        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
+        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
         bx.catch_ret(&funclet, caught);
 
         bx.switch_to_block(caught);
@@ -775,7 +776,7 @@ fn codegen_wasm_try<'ll>(
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -818,7 +819,7 @@ fn codegen_gnu_try<'ll>(
         let data = llvm::get_param(bx.llfn(), 1);
         let catch_func = llvm::get_param(bx.llfn(), 2);
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
-        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
+        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
 
         bx.switch_to_block(then);
         bx.ret(bx.const_i32(0));
@@ -836,13 +837,13 @@ fn codegen_gnu_try<'ll>(
         bx.add_clause(vals, tydesc);
         let ptr = bx.extract_value(vals, 0);
         let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
-        bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
+        bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
         bx.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -882,7 +883,7 @@ fn codegen_emcc_try<'ll>(
         let data = llvm::get_param(bx.llfn(), 1);
         let catch_func = llvm::get_param(bx.llfn(), 2);
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
-        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
+        bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
 
         bx.switch_to_block(then);
         bx.ret(bx.const_i32(0));
@@ -920,13 +921,13 @@ fn codegen_emcc_try<'ll>(
         bx.store(is_rust_panic, catch_data_1, i8_align);
 
         let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
-        bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None);
+        bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None, None);
         bx.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -1439,6 +1440,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             f,
             &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
             None,
+            None,
         );
         Ok(c)
     }
@@ -1607,6 +1609,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             f,
             &[args[1].immediate(), alignment, mask, args[0].immediate()],
             None,
+            None,
         );
         return Ok(v);
     }
@@ -1706,6 +1709,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             f,
             &[args[1].immediate(), alignment, mask, args[2].immediate()],
             None,
+            None,
         );
         return Ok(v);
     }
@@ -1799,6 +1803,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             f,
             &[args[2].immediate(), args[1].immediate(), alignment, mask],
             None,
+            None,
         );
         return Ok(v);
     }
@@ -1904,6 +1909,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             f,
             &[args[0].immediate(), args[1].immediate(), alignment, mask],
             None,
+            None,
         );
         return Ok(v);
     }
@@ -2352,11 +2358,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
                 f,
                 &[args[0].immediate(), bx.const_int(bx.type_i1(), 0)],
                 None,
+                None,
             ))
         } else {
             let fn_ty = bx.type_func(&[vec_ty], vec_ty);
             let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-            Ok(bx.call(fn_ty, None, None, f, &[args[0].immediate()], None))
+            Ok(bx.call(fn_ty, None, None, f, &[args[0].immediate()], None, None))
         };
     }
 
@@ -2409,7 +2416,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
         let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty);
         let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-        let v = bx.call(fn_ty, None, None, f, &[lhs, rhs], None);
+        let v = bx.call(fn_ty, None, None, f, &[lhs, rhs], None, None);
         return Ok(v);
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 13809ef72ec..f7f2bfca838 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -462,27 +462,34 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         let ptr_ty = cx.type_ptr();
         let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
 
-        let (start_fn, start_ty, args) = if let EntryFnType::Main { sigpipe } = entry_type {
+        let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
+        {
             let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
-            let start_fn = cx.get_fn_addr(ty::Instance::expect_resolve(
+            let start_instance = ty::Instance::expect_resolve(
                 cx.tcx(),
                 ty::ParamEnv::reveal_all(),
                 start_def_id,
                 cx.tcx().mk_args(&[main_ret_ty.into()]),
-            ));
+            );
+            let start_fn = cx.get_fn_addr(start_instance);
 
             let i8_ty = cx.type_i8();
             let arg_sigpipe = bx.const_u8(sigpipe);
 
             let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, ptr_ty, i8_ty], isize_ty);
-            (start_fn, start_ty, vec![rust_main, arg_argc, arg_argv, arg_sigpipe])
+            (
+                start_fn,
+                start_ty,
+                vec![rust_main, arg_argc, arg_argv, arg_sigpipe],
+                Some(start_instance),
+            )
         } else {
             debug!("using user-defined start fn");
             let start_ty = cx.type_func(&[isize_ty, ptr_ty], isize_ty);
-            (rust_main, start_ty, vec![arg_argc, arg_argv])
+            (rust_main, start_ty, vec![arg_argc, arg_argv], None)
         };
 
-        let result = bx.call(start_ty, None, None, start_fn, &args, None);
+        let result = bx.call(start_ty, None, None, start_fn, &args, None, instance);
         if cx.sess().target.os.contains("uefi") {
             bx.ret(result);
         } else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index dcc27a4f0e5..8c668597a43 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -232,6 +232,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
                 ret_llbb,
                 unwind_block,
                 self.funclet(fx),
+                instance,
             );
             if fx.mir[self.bb].is_cleanup {
                 bx.apply_attrs_to_cleanup_callsite(invokeret);
@@ -247,7 +248,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             }
             MergingSucc::False
         } else {
-            let llret = bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx));
+            let llret =
+                bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance);
             if fx.mir[self.bb].is_cleanup {
                 bx.apply_attrs_to_cleanup_callsite(llret);
             }
@@ -502,7 +504,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let ty = location.ty(self.mir, bx.tcx()).ty;
         let ty = self.monomorphize(ty);
         let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
-        let instance = drop_fn.clone();
 
         if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
             // we don't actually need to drop anything.
@@ -518,7 +519,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             args1 = [place.llval];
             &args1[..]
         };
-        let (drop_fn, fn_abi) =
+        let (drop_fn, fn_abi, drop_instance) =
             match ty.kind() {
                 // FIXME(eddyb) perhaps move some of this logic into
                 // `Instance::resolve_drop_in_place`?
@@ -550,6 +551,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
                             .get_fn(bx, vtable, ty, fn_abi),
                         fn_abi,
+                        virtual_drop,
                     )
                 }
                 ty::Dynamic(_, _, ty::DynStar) => {
@@ -592,9 +594,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
                             .get_fn(bx, meta.immediate(), ty, fn_abi),
                         fn_abi,
+                        virtual_drop,
                     )
                 }
-                _ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
+                _ => (
+                    bx.get_fn_addr(drop_fn),
+                    bx.fn_abi_of_instance(drop_fn, ty::List::empty()),
+                    drop_fn,
+                ),
             };
         helper.do_call(
             self,
@@ -605,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             Some((ReturnDest::Nothing, target)),
             unwind,
             &[],
-            Some(instance),
+            Some(drop_instance),
             mergeable_succ,
         )
     }
@@ -1699,7 +1706,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         } else {
             let fn_ty = bx.fn_decl_backend_type(fn_abi);
 
-            let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref());
+            let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref(), None);
             bx.apply_attrs_to_cleanup_callsite(llret);
         }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
index ee70465966d..72187277228 100644
--- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
@@ -1,12 +1,12 @@
 use crate::traits::*;
 
-use rustc_middle::mir::Coverage;
+use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::SourceScope;
 
 use super::FunctionCx;
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
-    pub fn codegen_coverage(&self, bx: &mut Bx, coverage: &Coverage, scope: SourceScope) {
+    pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
         // Determine the instance that coverage data was originally generated for.
         let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
             self.monomorphize(inlined)
@@ -15,6 +15,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         };
 
         // Handle the coverage info in a backend-specific way.
-        bx.add_coverage(instance, coverage);
+        bx.add_coverage(instance, kind);
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 0e8c4abf212..0af84ff067a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     } else {
                         None
                     };
-                    bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None)
+                    bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None, Some(instance))
                 } else {
                     bx.get_static(def_id)
                 };
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index ac7dfbb261d..2188eeae426 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -64,8 +64,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     cg_indirect_place.storage_dead(bx);
                 }
             }
-            mir::StatementKind::Coverage(box ref coverage) => {
-                self.codegen_coverage(bx, coverage, statement.source_info.scope);
+            mir::StatementKind::Coverage(ref kind) => {
+                self.codegen_coverage(bx, kind, statement.source_info.scope);
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
                 if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index e2e95cede60..c250cc26823 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -70,7 +70,15 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             // (But we are in good company, this code is duplicated plenty of times.)
             let fn_ty = bx.fn_decl_backend_type(fn_abi);
 
-            bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None);
+            bx.call(
+                fn_ty,
+                /* fn_attrs */ None,
+                Some(fn_abi),
+                llfn,
+                &[msg.0, msg.1],
+                None,
+                None,
+            );
 
             // This function does not return so we can now return whatever we want.
             let size = bx.const_usize(layout.size.bytes());
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 7bc9dee3a89..6c8dcc5b690 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -17,7 +17,7 @@ use crate::MemFlags;
 
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{Instance, Ty};
 use rustc_session::config::OptLevel;
 use rustc_span::Span;
 use rustc_target::abi::call::FnAbi;
@@ -82,6 +82,7 @@ pub trait BuilderMethods<'a, 'tcx>:
         then: Self::BasicBlock,
         catch: Self::BasicBlock,
         funclet: Option<&Self::Funclet>,
+        instance: Option<Instance<'tcx>>,
     ) -> Self::Value;
     fn unreachable(&mut self);
 
@@ -389,6 +390,7 @@ pub trait BuilderMethods<'a, 'tcx>:
         llfn: Self::Value,
         args: &[Self::Value],
         funclet: Option<&Self::Funclet>,
+        instance: Option<Instance<'tcx>>,
     ) -> Self::Value;
     fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
index 7e8de0ddc5b..d1d813bd389 100644
--- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
@@ -1,5 +1,5 @@
 use super::BackendTypes;
-use rustc_middle::mir::Coverage;
+use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::ty::Instance;
 
 pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
@@ -7,5 +7,5 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
     ///
     /// This can potentially be a no-op in backends that don't support
     /// coverage instrumentation.
-    fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage);
+    fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind);
 }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 1664475f52a..08e3e42a82e 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -346,8 +346,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
                     self.fail(location, format!("explicit `{kind:?}` is forbidden"));
                 }
             }
-            StatementKind::Coverage(coverage) => {
-                let kind = &coverage.kind;
+            StatementKind::Coverage(kind) => {
                 if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup)
                     && let CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. } = kind
                 {
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index fceccb7e9b6..bd8e78bda26 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -541,6 +541,7 @@ pub struct SilentEmitter {
     pub fallback_bundle: LazyFallbackBundle,
     pub fatal_dcx: DiagCtxt,
     pub fatal_note: Option<String>,
+    pub emit_fatal_diagnostic: bool,
 }
 
 impl Translate for SilentEmitter {
@@ -561,7 +562,7 @@ impl Emitter for SilentEmitter {
     }
 
     fn emit_diagnostic(&mut self, mut diag: DiagInner) {
-        if diag.level == Level::Fatal {
+        if self.emit_fatal_diagnostic && diag.level == Level::Fatal {
             if let Some(fatal_note) = &self.fatal_note {
                 diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
             }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 238bc63ec58..7b40954e735 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -612,12 +612,18 @@ impl DiagCtxt {
         Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
     }
 
-    pub fn make_silent(&mut self, fallback_bundle: LazyFallbackBundle, fatal_note: Option<String>) {
+    pub fn make_silent(
+        &mut self,
+        fallback_bundle: LazyFallbackBundle,
+        fatal_note: Option<String>,
+        emit_fatal_diagnostic: bool,
+    ) {
         self.wrap_emitter(|old_dcx| {
             Box::new(emitter::SilentEmitter {
                 fallback_bundle,
                 fatal_dcx: DiagCtxt { inner: Lock::new(old_dcx) },
                 fatal_note,
+                emit_fatal_diagnostic,
             })
         });
     }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 6cb15708a42..df4db3ec3fb 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -6,7 +6,9 @@ use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::Symbol;
 use rustc_target::abi::FieldIdx;
-use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
+use rustc_target::asm::{
+    InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
+};
 
 pub struct InlineAsmCtxt<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -251,8 +253,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         }
 
         // Check whether a modifier is suggested for using this type.
-        if let Some((suggested_modifier, suggested_result)) =
-            reg_class.suggest_modifier(asm_arch, asm_ty)
+        if let Some(ModifierInfo {
+            modifier: suggested_modifier,
+            result: suggested_result,
+            size: suggested_size,
+        }) = reg_class.suggest_modifier(asm_arch, asm_ty)
         {
             // Search for any use of this operand without a modifier and emit
             // the suggestion for them.
@@ -266,8 +271,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                 }
             }
             if !spans.is_empty() {
-                let (default_modifier, default_result) =
-                    reg_class.default_modifier(asm_arch).unwrap();
+                let ModifierInfo {
+                    modifier: default_modifier,
+                    result: default_result,
+                    size: default_size,
+                } = reg_class.default_modifier(asm_arch).unwrap();
                 self.tcx.node_span_lint(
                     lint::builtin::ASM_SUB_REGISTER,
                     expr.hir_id,
@@ -276,10 +284,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     |lint| {
                         lint.span_label(expr.span, "for this argument");
                         lint.help(format!(
-                            "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`",
+                            "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
                         ));
                         lint.help(format!(
-                            "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
+                            "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}` (for {default_size}-bit values)",
                         ));
                     },
                 );
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 5156a8d3479..e901ca36dad 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -65,7 +65,7 @@ const BASE_HIR: &[&str] = &[
 const BASE_IMPL: &[&str] =
     &[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_header];
 
-/// DepNodes for mir_built/Optimized, which is relevant in "executable"
+/// DepNodes for exported mir bodies, which is relevant in "executable"
 /// code, i.e., functions+methods
 const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir];
 
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 8ba14d37982..656c7ffae19 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -48,6 +48,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
             let psess = ParseSess::with_silent_emitter(
                 vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
                 format!("this error occurred on the command line: `--cfg={s}`"),
+                true,
             );
             let filename = FileName::cfg_spec_source_code(&s);
 
@@ -111,6 +112,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
         let psess = ParseSess::with_silent_emitter(
             vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
             format!("this error occurred on the command line: `--check-cfg={s}`"),
+            true,
         );
         let filename = FileName::cfg_spec_source_code(&s);
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index b544bc8a782..784fd4b3a3b 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -389,6 +389,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         None
     }
 
+    // The `dependency` type is determined by the command line arguments(`--extern`) and
+    // `private_dep`. However, sometimes the directly dependent crate is not specified by
+    // `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the
+    // scenario where the command parameter is set to `public-dependency`
+    fn is_private_dep(&self, name: &str, private_dep: Option<bool>) -> bool {
+        self.sess.opts.externs.get(name).map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
+            && private_dep.unwrap_or(true)
+    }
+
     fn register_crate(
         &mut self,
         host_lib: Option<Library>,
@@ -404,14 +413,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         let Library { source, metadata } = lib;
         let crate_root = metadata.get_root();
         let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
-
-        let private_dep = self
-            .sess
-            .opts
-            .externs
-            .get(name.as_str())
-            .map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
-            && private_dep.unwrap_or(true);
+        let private_dep = self.is_private_dep(name.as_str(), private_dep);
 
         // Claim this crate number and cache it
         let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
@@ -601,14 +603,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
 
         match result {
             (LoadResult::Previous(cnum), None) => {
+                // When `private_dep` is none, it indicates the directly dependent crate. If it is
+                // not specified by `--extern` on command line parameters, it may be
+                // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
+                // `public-dependency` here.
+                let private_dep = self.is_private_dep(name.as_str(), private_dep);
                 let data = self.cstore.get_crate_data_mut(cnum);
                 if data.is_proc_macro_crate() {
                     dep_kind = CrateDepKind::MacrosOnly;
                 }
                 data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind));
-                if let Some(private_dep) = private_dep {
-                    data.update_and_private_dep(private_dep);
-                }
+                data.update_and_private_dep(private_dep);
                 Ok(cnum)
             }
             (LoadResult::Loaded(library), host_library) => {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 1aabd296641..b69a295f010 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -211,6 +211,7 @@ provide! { tcx, def_id, other, cdata,
     generics_of => { table }
     inferred_outlives_of => { table_defaulted_array }
     super_predicates_of => { table }
+    implied_predicates_of => { table }
     type_of => { table }
     type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
     variances_of => { table }
@@ -276,18 +277,6 @@ provide! { tcx, def_id, other, cdata,
             .map(|lazy| lazy.decode((cdata, tcx)))
             .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
     }
-    implied_predicates_of => {
-        cdata
-            .root
-            .tables
-            .implied_predicates_of
-            .get(cdata, def_id.index)
-            .map(|lazy| lazy.decode((cdata, tcx)))
-            .unwrap_or_else(|| {
-                debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
-                tcx.super_predicates_of(def_id)
-            })
-    }
 
     associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 42724f7dd2b..61060038b50 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1435,6 +1435,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if let DefKind::Trait = def_kind {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
                 record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
+                record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
 
                 let module_children = self.tcx.module_children_local(local_id);
                 record_array!(self.tables.module_children_non_reexports[def_id] <-
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
index b984df3646e..aa2cddad093 100644
--- a/compiler/rustc_middle/src/hooks/mod.rs
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -77,4 +77,10 @@ declare_hooks! {
     ///
     /// (Eligible functions might nevertheless be skipped for other reasons.)
     hook is_eligible_for_coverage(key: LocalDefId) -> bool;
+
+    /// Create the MIR for a given `DefId` - this includes
+    /// unreachable code.
+    /// You do not want to call this yourself, instead use the cached version
+    /// via `mir_built`
+    hook build_mir(key: LocalDefId) -> mir::Body<'tcx>;
 }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index fbee4a9366f..f0499cf344f 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -13,7 +13,7 @@ use rustc_middle::mir::interpret::{
     Provenance,
 };
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{self, *};
+use rustc_middle::mir::*;
 use rustc_target::abi::Size;
 
 const INDENT: &str = "    ";
@@ -711,7 +711,7 @@ impl Debug for Statement<'_> {
             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({place:?}, {variance:?}, {c_ty:?})")
             }
-            Coverage(box mir::Coverage { ref kind }) => write!(fmt, "Coverage::{kind:?}"),
+            Coverage(ref kind) => write!(fmt, "Coverage::{kind:?}"),
             Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
             ConstEvalCounter => write!(fmt, "ConstEvalCounter"),
             Nop => write!(fmt, "nop"),
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 36b7a48b2a2..12bf8efd73a 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -373,7 +373,7 @@ pub enum StatementKind<'tcx> {
     ///
     /// Interpreters and codegen backends that don't support coverage instrumentation
     /// can usually treat this as a no-op.
-    Coverage(Box<Coverage>),
+    Coverage(CoverageKind),
 
     /// Denotes a call to an intrinsic that does not require an unwind path and always returns.
     /// This avoids adding a new block and a terminator for simple intrinsics.
@@ -519,12 +519,6 @@ pub enum FakeReadCause {
 
 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct Coverage {
-    pub kind: CoverageKind,
-}
-
-#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
-#[derive(TypeFoldable, TypeVisitable)]
 pub struct CopyNonOverlapping<'tcx> {
     pub src: Operand<'tcx>,
     pub dst: Operand<'tcx>,
@@ -1458,5 +1452,6 @@ mod size_asserts {
     static_assert_size!(Place<'_>, 16);
     static_assert_size!(PlaceElem<'_>, 24);
     static_assert_size!(Rvalue<'_>, 40);
+    static_assert_size!(StatementKind<'_>, 16);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index be960669ff4..3835bd371d9 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -156,10 +156,10 @@ macro_rules! make_mir_visitor {
 
             fn visit_coverage(
                 &mut self,
-                coverage: & $($mutability)? Coverage,
+                kind: & $($mutability)? coverage::CoverageKind,
                 location: Location,
             ) {
-                self.super_coverage(coverage, location);
+                self.super_coverage(kind, location);
             }
 
             fn visit_retag(
@@ -803,7 +803,7 @@ macro_rules! make_mir_visitor {
             }
 
             fn super_coverage(&mut self,
-                              _coverage: & $($mutability)? Coverage,
+                              _kind: & $($mutability)? coverage::CoverageKind,
                               _location: Location) {
             }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3984b3b61c2..38cfd11a016 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -505,21 +505,15 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    /// Fetch the MIR for a given `DefId` right after it's built - this includes
-    /// unreachable code.
+    /// Build the MIR for a given `DefId` and prepare it for const qualification.
+    ///
+    /// See the [rustc dev guide] for more info.
+    ///
+    /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html
     query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
         desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) }
     }
 
-    /// Fetch the MIR for a given `DefId` up till the point where it is
-    /// ready for const qualification.
-    ///
-    /// See the README for the `mir` module for details.
-    query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
-        desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) }
-        no_hash
-    }
-
     /// Try to build an abstract representation of the given constant.
     query thir_abstract_const(
         key: DefId
diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs
index 2bd0e289731..18e45291e9a 100644
--- a/compiler/rustc_mir_build/src/build/cfg.rs
+++ b/compiler/rustc_mir_build/src/build/cfg.rs
@@ -107,9 +107,7 @@ impl<'tcx> CFG<'tcx> {
     /// This results in more accurate coverage reports for certain kinds of
     /// syntax (e.g. `continue` or `if !`) that would otherwise not appear in MIR.
     pub(crate) fn push_coverage_span_marker(&mut self, block: BasicBlock, source_info: SourceInfo) {
-        let kind = StatementKind::Coverage(Box::new(Coverage {
-            kind: coverage::CoverageKind::SpanMarker,
-        }));
+        let kind = StatementKind::Coverage(coverage::CoverageKind::SpanMarker);
         let stmt = Statement { source_info, kind };
         self.push(block, stmt);
     }
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs
index 0b8ec234dda..ab0043906b1 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs
@@ -127,9 +127,7 @@ impl Builder<'_, '_> {
 
             let marker_statement = mir::Statement {
                 source_info,
-                kind: mir::StatementKind::Coverage(Box::new(mir::Coverage {
-                    kind: CoverageKind::BlockMarker { id },
-                })),
+                kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
             };
             self.cfg.push(block, marker_statement);
 
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 109ffedec55..0475bb8908b 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -6,7 +6,7 @@
 //! present, and if so we branch off into this module, which implements the attribute by
 //! implementing a custom lowering from THIR to MIR.
 //!
-//! The result of this lowering is returned "normally" from the `mir_built` query, with the only
+//! The result of this lowering is returned "normally" from the `build_mir` hook, with the only
 //! notable difference being that the `injected` field in the body is set. Various components of the
 //! MIR pipeline, like borrowck and the pass manager will then consult this field (via
 //! `body.should_skip()`) to skip the parts of the MIR pipeline that precede the MIR phase the user
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index acadfe7b35e..a43aadab478 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -18,6 +18,7 @@ use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::*;
+use rustc_middle::query::TyCtxtAt;
 use rustc_middle::thir::{
     self, BindingMode, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
 };
@@ -30,13 +31,6 @@ use rustc_target::spec::abi::Abi;
 
 use super::lints;
 
-pub(crate) fn mir_built(
-    tcx: TyCtxt<'_>,
-    def: LocalDefId,
-) -> &rustc_data_structures::steal::Steal<Body<'_>> {
-    tcx.alloc_steal_mir(mir_build(tcx, def))
-}
-
 pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
@@ -54,7 +48,8 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 }
 
 /// Construct the MIR for a given `DefId`.
-fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
+pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx> {
+    let tcx = tcx.tcx;
     tcx.ensure_with_value().thir_abstract_const(def);
     if let Err(e) = tcx.check_match(def) {
         return construct_error(tcx, def, e);
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 7b22aea9158..82fb7d1ae4a 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -22,14 +22,14 @@ mod errors;
 pub mod lints;
 mod thir;
 
-use rustc_middle::query::Providers;
+use rustc_middle::util::Providers;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 pub fn provide(providers: &mut Providers) {
     providers.check_match = thir::pattern::check_match;
     providers.lit_to_const = thir::constant::lit_to_const;
-    providers.mir_built = build::mir_built;
+    providers.hooks.build_mir = build::mir_build;
     providers.closure_saved_names_of_captured_variables =
         build::closure_saved_names_of_captured_variables;
     providers.check_unsafety = check_unsafety::check_unsafety;
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index aaf2035fc21..da82f8de781 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -18,7 +18,7 @@
 
 use crate::MirPass;
 use rustc_middle::mir::coverage::CoverageKind;
-use rustc_middle::mir::{Body, BorrowKind, Coverage, Rvalue, StatementKind, TerminatorKind};
+use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::TyCtxt;
 
 pub struct CleanupPostBorrowck;
@@ -30,12 +30,11 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
                 match statement.kind {
                     StatementKind::AscribeUserType(..)
                     | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Fake, _)))
-                    | StatementKind::Coverage(box Coverage {
+                    | StatementKind::Coverage(
                         // These kinds of coverage statements are markers inserted during
                         // MIR building, and are not needed after InstrumentCoverage.
-                        kind: CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
-                        ..
-                    })
+                        CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
+                    )
                     | StatementKind::FakeRead(..) => statement.make_nop(),
                     _ => (),
                 }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 83189c6a50a..ae3b1a3d1af 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -15,7 +15,7 @@ use crate::MirPass;
 
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::{
-    self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator,
+    self, BasicBlock, BasicBlockData, SourceInfo, Statement, StatementKind, Terminator,
     TerminatorKind,
 };
 use rustc_middle::ty::TyCtxt;
@@ -230,10 +230,7 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
     debug!("  injecting statement {counter_kind:?} for {bb:?}");
     let data = &mut mir_body[bb];
     let source_info = data.terminator().source_info;
-    let statement = Statement {
-        source_info,
-        kind: StatementKind::Coverage(Box::new(Coverage { kind: counter_kind })),
-    };
+    let statement = Statement { source_info, kind: StatementKind::Coverage(counter_kind) };
     data.statements.insert(0, statement);
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 1de7b6f66a7..b5dd9dcc7b4 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -1,7 +1,7 @@
 use rustc_data_structures::captures::Captures;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::coverage::{CounterId, CoverageKind};
-use rustc_middle::mir::{Body, Coverage, CoverageIdsInfo, Statement, StatementKind};
+use rustc_middle::mir::{Body, CoverageIdsInfo, Statement, StatementKind};
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::util::Providers;
@@ -54,7 +54,7 @@ fn coverage_ids_info<'tcx>(
     let mir_body = tcx.instance_mir(instance_def);
 
     let max_counter_id = all_coverage_in_mir_body(mir_body)
-        .filter_map(|coverage| match coverage.kind {
+        .filter_map(|kind| match *kind {
             CoverageKind::CounterIncrement { id } => Some(id),
             _ => None,
         })
@@ -66,12 +66,10 @@ fn coverage_ids_info<'tcx>(
 
 fn all_coverage_in_mir_body<'a, 'tcx>(
     body: &'a Body<'tcx>,
-) -> impl Iterator<Item = &'a Coverage> + Captures<'tcx> {
+) -> impl Iterator<Item = &'a CoverageKind> + Captures<'tcx> {
     body.basic_blocks.iter().flat_map(|bb_data| &bb_data.statements).filter_map(|statement| {
         match statement.kind {
-            StatementKind::Coverage(box ref coverage) if !is_inlined(body, statement) => {
-                Some(coverage)
-            }
+            StatementKind::Coverage(ref kind) if !is_inlined(body, statement) => Some(kind),
             _ => None,
         }
     })
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 3f6a4156044..adb0c9f1929 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -187,9 +187,7 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
         // for their parent `BasicBlock`.
         StatementKind::StorageLive(_)
         | StatementKind::StorageDead(_)
-        // Ignore `ConstEvalCounter`s
         | StatementKind::ConstEvalCounter
-        // Ignore `Nop`s
         | StatementKind::Nop => None,
 
         // FIXME(#78546): MIR InstrumentCoverage - Can the source_info.span for `FakeRead`
@@ -211,30 +209,28 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
         StatementKind::FakeRead(box (FakeReadCause::ForGuardBinding, _)) => None,
 
         // Retain spans from most other statements.
-        StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
+        StatementKind::FakeRead(_)
         | StatementKind::Intrinsic(..)
-        | StatementKind::Coverage(box mir::Coverage {
+        | StatementKind::Coverage(
             // The purpose of `SpanMarker` is to be matched and accepted here.
-            kind: CoverageKind::SpanMarker
-        })
+            CoverageKind::SpanMarker,
+        )
         | StatementKind::Assign(_)
         | StatementKind::SetDiscriminant { .. }
         | StatementKind::Deinit(..)
         | StatementKind::Retag(_, _)
         | StatementKind::PlaceMention(..)
-        | StatementKind::AscribeUserType(_, _) => {
-            Some(statement.source_info.span)
-        }
+        | StatementKind::AscribeUserType(_, _) => Some(statement.source_info.span),
 
-        StatementKind::Coverage(box mir::Coverage {
-            // Block markers are used for branch coverage, so ignore them here.
-            kind: CoverageKind::BlockMarker {..}
-        }) => None,
+        // Block markers are used for branch coverage, so ignore them here.
+        StatementKind::Coverage(CoverageKind::BlockMarker { .. }) => None,
 
-        StatementKind::Coverage(box mir::Coverage {
-            // These coverage statements should not exist prior to coverage instrumentation.
-            kind: CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. }
-        }) => bug!("Unexpected coverage statement found during coverage instrumentation: {statement:?}"),
+        // These coverage statements should not exist prior to coverage instrumentation.
+        StatementKind::Coverage(
+            CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. },
+        ) => bug!(
+            "Unexpected coverage statement found during coverage instrumentation: {statement:?}"
+        ),
     }
 }
 
@@ -382,9 +378,7 @@ pub(super) fn extract_branch_mappings(
     // Fill out the mapping from block marker IDs to their enclosing blocks.
     for (bb, data) in mir_body.basic_blocks.iter_enumerated() {
         for statement in &data.statements {
-            if let StatementKind::Coverage(coverage) = &statement.kind
-                && let CoverageKind::BlockMarker { id } = coverage.kind
-            {
+            if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind {
                 block_markers[id] = Some(bb);
             }
         }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 24bc263e5a7..15988c0ea6b 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -127,7 +127,7 @@ pub fn provide(providers: &mut Providers) {
     cross_crate_inline::provide(providers);
     providers.queries = query::Providers {
         mir_keys,
-        mir_const,
+        mir_built,
         mir_const_qualif,
         mir_promoted,
         mir_drops_elaborated_and_const_checked,
@@ -259,9 +259,9 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
 
     // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
     // cannot yet be stolen), because `mir_promoted()`, which steals
-    // from `mir_const()`, forces this query to execute before
+    // from `mir_built()`, forces this query to execute before
     // performing the steal.
-    let body = &tcx.mir_const(def).borrow();
+    let body = &tcx.mir_built(def).borrow();
 
     if body.return_ty().references_error() {
         // It's possible to reach here without an error being emitted (#121103).
@@ -279,19 +279,13 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
     validator.qualifs_in_return_place()
 }
 
-/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
-/// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
-/// We used to have this for pre-miri MIR based const eval.
-fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
+fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
     // MIR unsafety check uses the raw mir, so make sure it is run.
     if !tcx.sess.opts.unstable_opts.thir_unsafeck {
         tcx.ensure_with_value().mir_unsafety_check_result(def);
     }
 
-    // has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
-    tcx.ensure_with_value().has_ffi_unwind_calls(def);
-
-    let mut body = tcx.mir_built(def).steal();
+    let mut body = tcx.build_mir(def);
 
     pass_manager::dump_mir_for_phase_change(tcx, &body);
 
@@ -339,7 +333,9 @@ fn mir_promoted(
         | DefKind::AnonConst => tcx.mir_const_qualif(def),
         _ => ConstQualifs::default(),
     };
-    let mut body = tcx.mir_const(def).steal();
+    // has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
+    tcx.ensure_with_value().has_ffi_unwind_calls(def);
+    let mut body = tcx.mir_built(def).steal();
     if let Some(error_reported) = const_qualifs.tainted_by_errors {
         body.tainted_by_errors = Some(error_reported);
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index fe17eba0d7b..7e317c3df14 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -16,7 +16,6 @@ use core::mem;
 use core::ops::ControlFlow;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
-use rustc_ast::tokenstream::Spacing;
 use rustc_ast::util::case::Case;
 use rustc_ast::util::classify;
 use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
@@ -999,13 +998,57 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
+        // At this point we've consumed something like `expr.` and `self.token` holds the token
+        // after the dot.
         match self.token.uninterpolate().kind {
             token::Ident(..) => self.parse_dot_suffix(base, lo),
             token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
-                Ok(self.parse_expr_tuple_field_access(lo, base, symbol, suffix, None))
+                let ident_span = self.token.span;
+                self.bump();
+                Ok(self.mk_expr_tuple_field_access(lo, ident_span, base, symbol, suffix))
             }
             token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
-                Ok(self.parse_expr_tuple_field_access_float(lo, base, symbol, suffix))
+                Ok(match self.break_up_float(symbol, self.token.span) {
+                    // 1e2
+                    DestructuredFloat::Single(sym, _sp) => {
+                        // `foo.1e2`: a single complete dot access, fully consumed. We end up with
+                        // the `1e2` token in `self.prev_token` and the following token in
+                        // `self.token`.
+                        let ident_span = self.token.span;
+                        self.bump();
+                        self.mk_expr_tuple_field_access(lo, ident_span, base, sym, suffix)
+                    }
+                    // 1.
+                    DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
+                        // `foo.1.`: a single complete dot access and the start of another.
+                        // We end up with the `sym` (`1`) token in `self.prev_token` and a dot in
+                        // `self.token`.
+                        assert!(suffix.is_none());
+                        self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
+                        self.bump_with((Token::new(token::Dot, dot_span), self.token_spacing));
+                        self.mk_expr_tuple_field_access(lo, ident_span, base, sym, None)
+                    }
+                    // 1.2 | 1.2e3
+                    DestructuredFloat::MiddleDot(
+                        sym1,
+                        ident1_span,
+                        _dot_span,
+                        sym2,
+                        ident2_span,
+                    ) => {
+                        // `foo.1.2` (or `foo.1.2e3`): two complete dot accesses. We end up with
+                        // the `sym2` (`2` or `2e3`) token in `self.prev_token` and the following
+                        // token in `self.token`.
+                        let next_token2 =
+                            Token::new(token::Ident(sym2, IdentIsRaw::No), ident2_span);
+                        self.bump_with((next_token2, self.token_spacing));
+                        self.bump();
+                        let base1 =
+                            self.mk_expr_tuple_field_access(lo, ident1_span, base, sym1, None);
+                        self.mk_expr_tuple_field_access(lo, ident2_span, base1, sym2, suffix)
+                    }
+                    DestructuredFloat::Error => base,
+                })
             }
             _ => {
                 self.error_unexpected_after_dot();
@@ -1119,41 +1162,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn parse_expr_tuple_field_access_float(
-        &mut self,
-        lo: Span,
-        base: P<Expr>,
-        float: Symbol,
-        suffix: Option<Symbol>,
-    ) -> P<Expr> {
-        match self.break_up_float(float, self.token.span) {
-            // 1e2
-            DestructuredFloat::Single(sym, _sp) => {
-                self.parse_expr_tuple_field_access(lo, base, sym, suffix, None)
-            }
-            // 1.
-            DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
-                assert!(suffix.is_none());
-                self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
-                let next_token = (Token::new(token::Dot, dot_span), self.token_spacing);
-                self.parse_expr_tuple_field_access(lo, base, sym, None, Some(next_token))
-            }
-            // 1.2 | 1.2e3
-            DestructuredFloat::MiddleDot(symbol1, ident1_span, dot_span, symbol2, ident2_span) => {
-                self.token = Token::new(token::Ident(symbol1, IdentIsRaw::No), ident1_span);
-                // This needs to be `Spacing::Alone` to prevent regressions.
-                // See issue #76399 and PR #76285 for more details
-                let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone);
-                let base1 =
-                    self.parse_expr_tuple_field_access(lo, base, symbol1, None, Some(next_token1));
-                let next_token2 = Token::new(token::Ident(symbol2, IdentIsRaw::No), ident2_span);
-                self.bump_with((next_token2, self.token_spacing)); // `.`
-                self.parse_expr_tuple_field_access(lo, base1, symbol2, suffix, None)
-            }
-            DestructuredFloat::Error => base,
-        }
-    }
-
     /// Parse the field access used in offset_of, matched by `$(e:expr)+`.
     /// Currently returns a list of idents. However, it should be possible in
     /// future to also do array indices, which might be arbitrary expressions.
@@ -1255,24 +1263,18 @@ impl<'a> Parser<'a> {
         Ok(fields.into_iter().collect())
     }
 
-    fn parse_expr_tuple_field_access(
+    fn mk_expr_tuple_field_access(
         &mut self,
         lo: Span,
+        ident_span: Span,
         base: P<Expr>,
         field: Symbol,
         suffix: Option<Symbol>,
-        next_token: Option<(Token, Spacing)>,
     ) -> P<Expr> {
-        match next_token {
-            Some(next_token) => self.bump_with(next_token),
-            None => self.bump(),
-        }
-        let span = self.prev_token.span;
-        let field = ExprKind::Field(base, Ident::new(field, span));
         if let Some(suffix) = suffix {
-            self.expect_no_tuple_index_suffix(span, suffix);
+            self.expect_no_tuple_index_suffix(ident_span, suffix);
         }
-        self.mk_expr(lo.to(span), field)
+        self.mk_expr(lo.to(ident_span), ExprKind::Field(base, Ident::new(field, ident_span)))
     }
 
     /// Parse a function call expression, `expr(...)`.
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 5434bbe0b98..f6053f43fbd 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -269,7 +269,11 @@ impl ParseSess {
         }
     }
 
-    pub fn with_silent_emitter(locale_resources: Vec<&'static str>, fatal_note: String) -> Self {
+    pub fn with_silent_emitter(
+        locale_resources: Vec<&'static str>,
+        fatal_note: String,
+        emit_fatal_diagnostic: bool,
+    ) -> Self {
         let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let emitter = Box::new(HumanEmitter::new(
@@ -281,6 +285,7 @@ impl ParseSess {
             fallback_bundle,
             fatal_dcx,
             fatal_note: Some(fatal_note),
+            emit_fatal_diagnostic,
         }))
         .disable_warnings();
         ParseSess::with_dcx(dcx, sm)
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
index 0ce522c9cab..1c8f1d03670 100644
--- a/compiler/rustc_symbol_mangling/Cargo.toml
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -15,6 +15,7 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
+rustc_trait_selection = { path = "../rustc_trait_selection" }
 tracing = "0.1"
 twox-hash = "1.6.3"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 02bb1fde75c..0588af9bda7 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -90,6 +90,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![feature(let_chains)]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs
index e8763e49e62..3bf564a4a16 100644
--- a/compiler/rustc_symbol_mangling/src/typeid.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid.rs
@@ -36,7 +36,7 @@ pub fn typeid_for_instance<'tcx>(
     instance: &Instance<'tcx>,
     options: TypeIdOptions,
 ) -> String {
-    typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options)
+    typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options)
 }
 
 /// Returns a KCFI type metadata identifier for the specified FnAbi.
@@ -61,6 +61,6 @@ pub fn kcfi_typeid_for_instance<'tcx>(
     // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
     // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
     let mut hash: XxHash64 = Default::default();
-    hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes());
+    hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options).as_bytes());
     hash.finish() as u32
 }
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 07a382d161d..3101015281b 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_middle::ty::layout::IntegerExt;
+use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{
     self, Const, ExistentialPredicate, FloatTy, FnSig, Instance, IntTy, List, Region, RegionKind,
     TermKind, Ty, TyCtxt, UintTy,
@@ -21,7 +22,9 @@ use rustc_span::sym;
 use rustc_target::abi::call::{Conv, FnAbi, PassMode};
 use rustc_target::abi::Integer;
 use rustc_target::spec::abi::Abi;
+use rustc_trait_selection::traits;
 use std::fmt::Write as _;
+use std::iter;
 
 use crate::typeid::TypeIdOptions;
 
@@ -178,14 +181,14 @@ fn encode_fnsig<'tcx>(
     // Encode the return type
     let transform_ty_options = TransformTyOptions::from_bits(options.bits())
         .unwrap_or_else(|| bug!("encode_fnsig: invalid option(s) `{:?}`", options.bits()));
-    let ty = transform_ty(tcx, fn_sig.output(), transform_ty_options);
+    let ty = transform_ty(tcx, fn_sig.output(), &mut Vec::new(), transform_ty_options);
     s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
 
     // Encode the parameter types
     let tys = fn_sig.inputs();
     if !tys.is_empty() {
         for ty in tys {
-            let ty = transform_ty(tcx, *ty, transform_ty_options);
+            let ty = transform_ty(tcx, *ty, &mut Vec::new(), transform_ty_options);
             s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
         }
 
@@ -747,9 +750,8 @@ fn transform_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: &List<ty::PolyExistentialPredicate<'tcx>>,
 ) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
-    let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates
-        .iter()
-        .filter_map(|predicate| match predicate.skip_binder() {
+    tcx.mk_poly_existential_predicates_from_iter(predicates.iter().filter_map(|predicate| {
+        match predicate.skip_binder() {
             ty::ExistentialPredicate::Trait(trait_ref) => {
                 let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
                 Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait(
@@ -758,20 +760,20 @@ fn transform_predicates<'tcx>(
             }
             ty::ExistentialPredicate::Projection(..) => None,
             ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
-        })
-        .collect();
-    tcx.mk_poly_existential_predicates(&predicates)
+        }
+    }))
 }
 
 /// Transforms args for being encoded and used in the substitution dictionary.
 fn transform_args<'tcx>(
     tcx: TyCtxt<'tcx>,
     args: GenericArgsRef<'tcx>,
+    parents: &mut Vec<Ty<'tcx>>,
     options: TransformTyOptions,
 ) -> GenericArgsRef<'tcx> {
     let args = args.iter().map(|arg| match arg.unpack() {
         GenericArgKind::Type(ty) if ty.is_c_void(tcx) => Ty::new_unit(tcx).into(),
-        GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
+        GenericArgKind::Type(ty) => transform_ty(tcx, ty, parents, options).into(),
         _ => arg,
     });
     tcx.mk_args_from_iter(args)
@@ -781,9 +783,12 @@ fn transform_args<'tcx>(
 // c_void types into unit types unconditionally, generalizes pointers if
 // TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
 // TransformTyOptions::NORMALIZE_INTEGERS option is set.
-fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptions) -> Ty<'tcx> {
-    let mut ty = ty;
-
+fn transform_ty<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mut ty: Ty<'tcx>,
+    parents: &mut Vec<Ty<'tcx>>,
+    options: TransformTyOptions,
+) -> Ty<'tcx> {
     match ty.kind() {
         ty::Float(..) | ty::Str | ty::Never | ty::Foreign(..) | ty::CoroutineWitness(..) => {}
 
@@ -843,17 +848,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
         _ if ty.is_unit() => {}
 
         ty::Tuple(tys) => {
-            ty = Ty::new_tup_from_iter(tcx, tys.iter().map(|ty| transform_ty(tcx, ty, options)));
+            ty = Ty::new_tup_from_iter(
+                tcx,
+                tys.iter().map(|ty| transform_ty(tcx, ty, parents, options)),
+            );
         }
 
         ty::Array(ty0, len) => {
             let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
 
-            ty = Ty::new_array(tcx, transform_ty(tcx, *ty0, options), len);
+            ty = Ty::new_array(tcx, transform_ty(tcx, *ty0, parents, options), len);
         }
 
         ty::Slice(ty0) => {
-            ty = Ty::new_slice(tcx, transform_ty(tcx, *ty0, options));
+            ty = Ty::new_slice(tcx, transform_ty(tcx, *ty0, parents, options));
         }
 
         ty::Adt(adt_def, args) => {
@@ -862,7 +870,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
             } else if options.contains(TransformTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c()
             {
                 ty = Ty::new_adt(tcx, *adt_def, ty::List::empty());
-            } else if adt_def.repr().transparent() && adt_def.is_struct() {
+            } else if adt_def.repr().transparent() && adt_def.is_struct() && !parents.contains(&ty)
+            {
                 // Don't transform repr(transparent) types with an user-defined CFI encoding to
                 // preserve the user-defined CFI encoding.
                 if let Some(_) = tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
@@ -881,38 +890,48 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
                     // Generalize any repr(transparent) user-defined type that is either a pointer
                     // or reference, and either references itself or any other type that contains or
                     // references itself, to avoid a reference cycle.
+
+                    // If the self reference is not through a pointer, for example, due
+                    // to using `PhantomData`, need to skip normalizing it if we hit it again.
+                    parents.push(ty);
                     if ty0.is_any_ptr() && ty0.contains(ty) {
                         ty = transform_ty(
                             tcx,
                             ty0,
+                            parents,
                             options | TransformTyOptions::GENERALIZE_POINTERS,
                         );
                     } else {
-                        ty = transform_ty(tcx, ty0, options);
+                        ty = transform_ty(tcx, ty0, parents, options);
                     }
+                    parents.pop();
                 } else {
                     // Transform repr(transparent) types without non-ZST field into ()
                     ty = Ty::new_unit(tcx);
                 }
             } else {
-                ty = Ty::new_adt(tcx, *adt_def, transform_args(tcx, args, options));
+                ty = Ty::new_adt(tcx, *adt_def, transform_args(tcx, args, parents, options));
             }
         }
 
         ty::FnDef(def_id, args) => {
-            ty = Ty::new_fn_def(tcx, *def_id, transform_args(tcx, args, options));
+            ty = Ty::new_fn_def(tcx, *def_id, transform_args(tcx, args, parents, options));
         }
 
         ty::Closure(def_id, args) => {
-            ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, options));
+            ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, parents, options));
         }
 
         ty::CoroutineClosure(def_id, args) => {
-            ty = Ty::new_coroutine_closure(tcx, *def_id, transform_args(tcx, args, options));
+            ty = Ty::new_coroutine_closure(
+                tcx,
+                *def_id,
+                transform_args(tcx, args, parents, options),
+            );
         }
 
         ty::Coroutine(def_id, args) => {
-            ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, options));
+            ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, parents, options));
         }
 
         ty::Ref(region, ty0, ..) => {
@@ -924,9 +943,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
                 }
             } else {
                 if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ref(tcx, *region, transform_ty(tcx, *ty0, options));
+                    ty = Ty::new_mut_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
                 } else {
-                    ty = Ty::new_imm_ref(tcx, *region, transform_ty(tcx, *ty0, options));
+                    ty = Ty::new_imm_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
                 }
             }
         }
@@ -940,9 +959,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
                 }
             } else {
                 if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ptr(tcx, transform_ty(tcx, *ptr_ty, options));
+                    ty = Ty::new_mut_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
                 } else {
-                    ty = Ty::new_imm_ptr(tcx, transform_ty(tcx, *ptr_ty, options));
+                    ty = Ty::new_imm_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
                 }
             }
         }
@@ -955,9 +974,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
                     .skip_binder()
                     .inputs()
                     .iter()
-                    .map(|ty| transform_ty(tcx, *ty, options))
+                    .map(|ty| transform_ty(tcx, *ty, parents, options))
                     .collect();
-                let output = transform_ty(tcx, fn_sig.skip_binder().output(), options);
+                let output = transform_ty(tcx, fn_sig.skip_binder().output(), parents, options);
                 ty = Ty::new_fn_ptr(
                     tcx,
                     ty::Binder::bind_with_vars(
@@ -987,6 +1006,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
             ty = transform_ty(
                 tcx,
                 tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty),
+                parents,
                 options,
             );
         }
@@ -1037,7 +1057,7 @@ pub fn typeid_for_fnabi<'tcx>(
     // Encode the return type
     let transform_ty_options = TransformTyOptions::from_bits(options.bits())
         .unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
-    let ty = transform_ty(tcx, fn_abi.ret.layout.ty, transform_ty_options);
+    let ty = transform_ty(tcx, fn_abi.ret.layout.ty, &mut Vec::new(), transform_ty_options);
     typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
 
     // Encode the parameter types
@@ -1049,7 +1069,7 @@ pub fn typeid_for_fnabi<'tcx>(
         let mut pushed_arg = false;
         for arg in fn_abi.args.iter().filter(|arg| arg.mode != PassMode::Ignore) {
             pushed_arg = true;
-            let ty = transform_ty(tcx, arg.layout.ty, transform_ty_options);
+            let ty = transform_ty(tcx, arg.layout.ty, &mut Vec::new(), transform_ty_options);
             typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
         }
         if !pushed_arg {
@@ -1062,7 +1082,8 @@ pub fn typeid_for_fnabi<'tcx>(
             if fn_abi.args[n].mode == PassMode::Ignore {
                 continue;
             }
-            let ty = transform_ty(tcx, fn_abi.args[n].layout.ty, transform_ty_options);
+            let ty =
+                transform_ty(tcx, fn_abi.args[n].layout.ty, &mut Vec::new(), transform_ty_options);
             typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
         }
 
@@ -1088,53 +1109,108 @@ pub fn typeid_for_fnabi<'tcx>(
 /// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary.
 pub fn typeid_for_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: &Instance<'tcx>,
+    mut instance: Instance<'tcx>,
     options: TypeIdOptions,
 ) -> String {
+    if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
+        instance.args = strip_receiver_auto(tcx, instance.args)
+    }
+
+    if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
+        && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
+    {
+        let impl_method = tcx.associated_item(instance.def_id());
+        let method_id = impl_method
+            .trait_item_def_id
+            .expect("Part of a trait implementation, but not linked to the def_id?");
+        let trait_method = tcx.associated_item(method_id);
+        if traits::is_vtable_safe_method(tcx, trait_ref.skip_binder().def_id, trait_method) {
+            // Trait methods will have a Self polymorphic parameter, where the concreteized
+            // implementatation will not. We need to walk back to the more general trait method
+            let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
+                instance.args,
+                ty::ParamEnv::reveal_all(),
+                trait_ref,
+            );
+            let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+
+            // At the call site, any call to this concrete function through a vtable will be
+            // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
+            // original method id, and we've recovered the trait arguments, we can make the callee
+            // instance we're computing the alias set for match the caller instance.
+            //
+            // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
+            // If we ever *do* start encoding the vtable index, we will need to generate an alias set
+            // based on which vtables we are putting this method into, as there will be more than one
+            // index value when supertraits are involved.
+            instance.def = ty::InstanceDef::Virtual(method_id, 0);
+            let abstract_trait_args =
+                tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
+            instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
+        }
+    }
+
     let fn_abi = tcx
-        .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, ty::List::empty())))
+        .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty())))
         .unwrap_or_else(|instance| {
             bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance)
         });
 
-    // If this instance is a method and self is a reference, get the impl it belongs to
-    let impl_def_id = tcx.impl_of_method(instance.def_id());
-    if impl_def_id.is_some() && !fn_abi.args.is_empty() && fn_abi.args[0].layout.ty.is_ref() {
-        // If this impl is not an inherent impl, get the trait it implements
-        if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id.unwrap()) {
-            // Transform the concrete self into a reference to a trait object
-            let existential_predicate = trait_ref.map_bound(|trait_ref| {
-                ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
-                    tcx, trait_ref,
-                ))
-            });
-            let existential_predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(
-                existential_predicate.skip_binder(),
-            )]);
-            // Is the concrete self mutable?
-            let self_ty = if fn_abi.args[0].layout.ty.is_mutable_ptr() {
-                Ty::new_mut_ref(
-                    tcx,
-                    tcx.lifetimes.re_erased,
-                    Ty::new_dynamic(tcx, existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
-                )
-            } else {
-                Ty::new_imm_ref(
-                    tcx,
-                    tcx.lifetimes.re_erased,
-                    Ty::new_dynamic(tcx, existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
-                )
-            };
-
-            // Replace the concrete self in an fn_abi clone by the reference to a trait object
-            let mut fn_abi = fn_abi.clone();
-            // HACK(rcvalle): It is okay to not replace or update the entire ArgAbi here because the
-            //   other fields are never used.
-            fn_abi.args[0].layout.ty = self_ty;
+    typeid_for_fnabi(tcx, fn_abi, options)
+}
 
-            return typeid_for_fnabi(tcx, &fn_abi, options);
-        }
-    }
+fn strip_receiver_auto<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    args: ty::GenericArgsRef<'tcx>,
+) -> ty::GenericArgsRef<'tcx> {
+    let ty = args.type_at(0);
+    let ty::Dynamic(preds, lifetime, kind) = ty.kind() else {
+        bug!("Tried to strip auto traits from non-dynamic type {ty}");
+    };
+    let new_rcvr = if preds.principal().is_some() {
+        let filtered_preds =
+            tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| {
+                !matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..))
+            }));
+        Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind)
+    } else {
+        // If there's no principal type, re-encode it as a unit, since we don't know anything
+        // about it. This technically discards the knowledge that it was a type that was made
+        // into a trait object at some point, but that's not a lot.
+        tcx.types.unit
+    };
+    tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1))
+}
 
-    typeid_for_fnabi(tcx, fn_abi, options)
+fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> {
+    assert!(!poly_trait_ref.has_non_region_param());
+    let principal_pred = poly_trait_ref.map_bound(|trait_ref| {
+        ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
+    });
+    let mut assoc_preds: Vec<_> = traits::supertraits(tcx, poly_trait_ref)
+        .flat_map(|super_poly_trait_ref| {
+            tcx.associated_items(super_poly_trait_ref.def_id())
+                .in_definition_order()
+                .filter(|item| item.kind == ty::AssocKind::Type)
+                .map(move |assoc_ty| {
+                    super_poly_trait_ref.map_bound(|super_trait_ref| {
+                        let alias_ty = ty::AliasTy::new(tcx, assoc_ty.def_id, super_trait_ref.args);
+                        let resolved = tcx.normalize_erasing_regions(
+                            ty::ParamEnv::reveal_all(),
+                            alias_ty.to_ty(tcx),
+                        );
+                        ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
+                            def_id: assoc_ty.def_id,
+                            args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args,
+                            term: resolved.into(),
+                        })
+                    })
+                })
+        })
+        .collect();
+    assoc_preds.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
+    let preds = tcx.mk_poly_existential_predicates_from_iter(
+        iter::once(principal_pred).chain(assoc_preds.into_iter()),
+    );
+    Ty::new_dynamic(tcx, preds, tcx.lifetimes.re_erased, ty::Dyn)
 }
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index 97132311a5c..70528c1222c 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_macros::HashStable_Generic;
@@ -27,32 +27,28 @@ impl AArch64InlineAsmRegClass {
         None
     }
 
-    pub fn suggest_modifier(
-        self,
-        _arch: InlineAsmArch,
-        ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    pub fn suggest_modifier(self, _arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
         match self {
             Self::reg => match ty.size().bits() {
                 64 => None,
-                _ => Some(('w', "w0")),
+                _ => Some(('w', "w0", 32).into()),
             },
             Self::vreg | Self::vreg_low16 => match ty.size().bits() {
-                8 => Some(('b', "b0")),
-                16 => Some(('h', "h0")),
-                32 => Some(('s', "s0")),
-                64 => Some(('d', "d0")),
-                128 => Some(('q', "q0")),
+                8 => Some(('b', "b0", 8).into()),
+                16 => Some(('h', "h0", 16).into()),
+                32 => Some(('s', "s0", 32).into()),
+                64 => Some(('d', "d0", 64).into()),
+                128 => Some(('q', "q0", 128).into()),
                 _ => None,
             },
             Self::preg => None,
         }
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         match self {
-            Self::reg => Some(('x', "x0")),
-            Self::vreg | Self::vreg_low16 => Some(('v', "v0")),
+            Self::reg => Some(('x', "x0", 64).into()),
+            Self::vreg | Self::vreg_low16 => Some(('v', "v0", 128).into()),
             Self::preg => None,
         }
     }
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index 514e30ae020..f56dbac708b 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_macros::HashStable_Generic;
@@ -35,11 +35,11 @@ impl ArmInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs
index 9a96a61f5b2..eab38a4a4f4 100644
--- a/compiler/rustc_target/src/asm/avr.rs
+++ b/compiler/rustc_target/src/asm/avr.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -29,11 +29,11 @@ impl AvrInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs
index 3b03766a089..9bc94274675 100644
--- a/compiler/rustc_target/src/asm/bpf.rs
+++ b/compiler/rustc_target/src/asm/bpf.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -23,11 +23,11 @@ impl BpfInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs
index db3d8106040..64607ee4b81 100644
--- a/compiler/rustc_target/src/asm/csky.rs
+++ b/compiler/rustc_target/src/asm/csky.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -23,11 +23,11 @@ impl CSKYInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs
index d20270ac9e9..19da7b80848 100644
--- a/compiler/rustc_target/src/asm/hexagon.rs
+++ b/compiler/rustc_target/src/asm/hexagon.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -22,11 +22,11 @@ impl HexagonInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs
index 9d1a4f3eeea..15d0f54ce3b 100644
--- a/compiler/rustc_target/src/asm/loongarch.rs
+++ b/compiler/rustc_target/src/asm/loongarch.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -23,11 +23,11 @@ impl LoongArchInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/m68k.rs b/compiler/rustc_target/src/asm/m68k.rs
index 8c857550cf2..ac94dcc03dc 100644
--- a/compiler/rustc_target/src/asm/m68k.rs
+++ b/compiler/rustc_target/src/asm/m68k.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -24,11 +24,11 @@ impl M68kInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs
index 4e7c2eb1bf8..0ac1a43ae18 100644
--- a/compiler/rustc_target/src/asm/mips.rs
+++ b/compiler/rustc_target/src/asm/mips.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -23,11 +23,11 @@ impl MipsInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index a11884bea26..2e04dca98c5 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -6,6 +6,18 @@ use rustc_span::Symbol;
 use std::fmt;
 use std::str::FromStr;
 
+pub struct ModifierInfo {
+    pub modifier: char,
+    pub result: &'static str,
+    pub size: u64,
+}
+
+impl From<(char, &'static str, u64)> for ModifierInfo {
+    fn from((modifier, result, size): (char, &'static str, u64)) -> Self {
+        Self { modifier, result, size }
+    }
+}
+
 macro_rules! def_reg_class {
     ($arch:ident $arch_regclass:ident {
         $(
@@ -512,11 +524,7 @@ impl InlineAsmRegClass {
     /// Such suggestions are useful if a type smaller than the full register
     /// size is used and a modifier can be used to point to the subregister of
     /// the correct size.
-    pub fn suggest_modifier(
-        self,
-        arch: InlineAsmArch,
-        ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
         match self {
             Self::X86(r) => r.suggest_modifier(arch, ty),
             Self::Arm(r) => r.suggest_modifier(arch, ty),
@@ -545,7 +553,7 @@ impl InlineAsmRegClass {
     /// This is only needed when the register class can suggest a modifier, so
     /// that the user can be shown how to get the default behavior without a
     /// warning.
-    pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
         match self {
             Self::X86(r) => r.default_modifier(arch),
             Self::Arm(r) => r.default_modifier(arch),
diff --git a/compiler/rustc_target/src/asm/msp430.rs b/compiler/rustc_target/src/asm/msp430.rs
index a27d6390a72..439f3ba0b57 100644
--- a/compiler/rustc_target/src/asm/msp430.rs
+++ b/compiler/rustc_target/src/asm/msp430.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -22,11 +22,11 @@ impl Msp430InlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs
index 8e1e91e7c5f..57aa50fceb8 100644
--- a/compiler/rustc_target/src/asm/nvptx.rs
+++ b/compiler/rustc_target/src/asm/nvptx.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
@@ -23,11 +23,11 @@ impl NvptxInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs
index d3ccb30350a..4e8cbe34de9 100644
--- a/compiler/rustc_target/src/asm/powerpc.rs
+++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -26,11 +26,11 @@ impl PowerPCInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
index dea6d50fe2b..2505d36f5b8 100644
--- a/compiler/rustc_target/src/asm/riscv.rs
+++ b/compiler/rustc_target/src/asm/riscv.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_macros::HashStable_Generic;
@@ -26,11 +26,11 @@ impl RiscVInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index b8afeb824d8..6bc668454b1 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
@@ -24,11 +24,11 @@ impl S390xInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/spirv.rs b/compiler/rustc_target/src/asm/spirv.rs
index 31073da10b2..d13a6131f9a 100644
--- a/compiler/rustc_target/src/asm/spirv.rs
+++ b/compiler/rustc_target/src/asm/spirv.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
@@ -21,11 +21,11 @@ impl SpirVInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/wasm.rs b/compiler/rustc_target/src/asm/wasm.rs
index f095b7c6e11..eb0b23ef43d 100644
--- a/compiler/rustc_target/src/asm/wasm.rs
+++ b/compiler/rustc_target/src/asm/wasm.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
@@ -21,11 +21,11 @@ impl WasmInlineAsmRegClass {
         self,
         _arch: InlineAsmArch,
         _ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    ) -> Option<ModifierInfo> {
         None
     }
 
-    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
         None
     }
 
diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs
index 3902dac7ff6..3b5da8806cc 100644
--- a/compiler/rustc_target/src/asm/x86.rs
+++ b/compiler/rustc_target/src/asm/x86.rs
@@ -1,4 +1,4 @@
-use super::{InlineAsmArch, InlineAsmType};
+use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_macros::HashStable_Generic;
@@ -53,32 +53,28 @@ impl X86InlineAsmRegClass {
         }
     }
 
-    pub fn suggest_modifier(
-        self,
-        arch: InlineAsmArch,
-        ty: InlineAsmType,
-    ) -> Option<(char, &'static str)> {
+    pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
         match self {
             Self::reg => match ty.size().bits() {
-                16 => Some(('x', "ax")),
-                32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")),
+                16 => Some(('x', "ax", 16).into()),
+                32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax", 32).into()),
                 _ => None,
             },
             Self::reg_abcd => match ty.size().bits() {
-                16 => Some(('x', "ax")),
-                32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")),
+                16 => Some(('x', "ax", 16).into()),
+                32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax", 32).into()),
                 _ => None,
             },
             Self::reg_byte => None,
             Self::xmm_reg => None,
             Self::ymm_reg => match ty.size().bits() {
                 256 => None,
-                _ => Some(('x', "xmm0")),
+                _ => Some(('x', "xmm0", 128).into()),
             },
             Self::zmm_reg => match ty.size().bits() {
                 512 => None,
-                256 => Some(('y', "ymm0")),
-                _ => Some(('x', "xmm0")),
+                256 => Some(('y', "ymm0", 256).into()),
+                _ => Some(('x', "xmm0", 128).into()),
             },
             Self::kreg | Self::kreg0 => None,
             Self::mmx_reg | Self::x87_reg => None,
@@ -86,19 +82,19 @@ impl X86InlineAsmRegClass {
         }
     }
 
-    pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> {
+    pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
         match self {
             Self::reg | Self::reg_abcd => {
                 if arch == InlineAsmArch::X86_64 {
-                    Some(('r', "rax"))
+                    Some(('r', "rax", 64).into())
                 } else {
-                    Some(('e', "eax"))
+                    Some(('e', "eax", 32).into())
                 }
             }
             Self::reg_byte => None,
-            Self::xmm_reg => Some(('x', "xmm0")),
-            Self::ymm_reg => Some(('y', "ymm0")),
-            Self::zmm_reg => Some(('z', "zmm0")),
+            Self::xmm_reg => Some(('x', "xmm0", 128).into()),
+            Self::ymm_reg => Some(('y', "ymm0", 256).into()),
+            Self::zmm_reg => Some(('z', "zmm0", 512).into()),
             Self::kreg | Self::kreg0 => None,
             Self::mmx_reg | Self::x87_reg => None,
             Self::tmm_reg => None,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 9444cf8248e..3cc46b5c638 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -3536,12 +3536,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     let mut err =
                         self.dcx().struct_span_err(span, "unconstrained generic constant");
                     let const_span = self.tcx.def_span(uv.def);
+
+                    let const_ty = self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args);
+                    let cast = if const_ty != self.tcx.types.usize { " as usize" } else { "" };
+                    let msg = "try adding a `where` bound";
                     match self.tcx.sess.source_map().span_to_snippet(const_span) {
-                            Ok(snippet) => err.help(format!(
-                                "try adding a `where` bound using this expression: `where [(); {snippet}]:`"
-                            )),
-                            _ => err.help("consider adding a `where` bound using this expression"),
-                        };
+                        Ok(snippet) => {
+                            let code = format!("[(); {snippet}{cast}]:");
+                            let def_id = if let ObligationCauseCode::CompareImplItemObligation {
+                                trait_item_def_id,
+                                ..
+                            } = obligation.cause.code()
+                            {
+                                trait_item_def_id.as_local()
+                            } else {
+                                Some(obligation.cause.body_id)
+                            };
+                            if let Some(def_id) = def_id
+                                && let Some(generics) = self.tcx.hir().get_generics(def_id)
+                            {
+                                err.span_suggestion_verbose(
+                                    generics.tail_span_for_predicate_suggestion(),
+                                    msg,
+                                    format!("{} {code}", generics.add_where_or_trailing_comma()),
+                                    Applicability::MaybeIncorrect,
+                                );
+                            } else {
+                                err.help(format!("{msg}: where {code}"));
+                            };
+                        }
+                        _ => {
+                            err.help(msg);
+                        }
+                    };
                     Ok(err)
                 }
                 ty::ConstKind::Expr(_) => {
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs
index 66457933438..408e0bafa58 100644
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ b/compiler/stable_mir/src/mir/alloc.rs
@@ -55,7 +55,7 @@ impl IndexedVal for AllocId {
 /// Utility function used to read an allocation data into a unassigned integer.
 pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
     let mut buf = [0u8; std::mem::size_of::<u128>()];
-    match MachineInfo::target_endianess() {
+    match MachineInfo::target_endianness() {
         Endian::Little => {
             bytes.read_exact(&mut buf[..bytes.len()])?;
             Ok(u128::from_le_bytes(buf))
@@ -70,7 +70,7 @@ pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
 /// Utility function used to read an allocation data into an assigned integer.
 pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
     let mut buf = [0u8; std::mem::size_of::<i128>()];
-    match MachineInfo::target_endianess() {
+    match MachineInfo::target_endianness() {
         Endian::Little => {
             bytes.read_exact(&mut buf[..bytes.len()])?;
             Ok(i128::from_le_bytes(buf))
diff --git a/compiler/stable_mir/src/target.rs b/compiler/stable_mir/src/target.rs
index 3a9011a2ffe..e00a418c540 100644
--- a/compiler/stable_mir/src/target.rs
+++ b/compiler/stable_mir/src/target.rs
@@ -14,7 +14,7 @@ impl MachineInfo {
         with(|cx| cx.target_info())
     }
 
-    pub fn target_endianess() -> Endian {
+    pub fn target_endianness() -> Endian {
         with(|cx| cx.target_info().endian)
     }
 
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 4016167d05c..e880d5758ec 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -201,7 +201,7 @@ pub trait Write {
         impl<W: Write + ?Sized> SpecWriteFmt for &mut W {
             #[inline]
             default fn spec_write_fmt(mut self, args: Arguments<'_>) -> Result {
-                if let Some(s) = args.as_const_str() {
+                if let Some(s) = args.as_statically_known_str() {
                     self.write_str(s)
                 } else {
                     write(&mut self, args)
@@ -212,7 +212,7 @@ pub trait Write {
         impl<W: Write> SpecWriteFmt for &mut W {
             #[inline]
             fn spec_write_fmt(self, args: Arguments<'_>) -> Result {
-                if let Some(s) = args.as_const_str() {
+                if let Some(s) = args.as_statically_known_str() {
                     self.write_str(s)
                 } else {
                     write(self, args)
@@ -442,7 +442,7 @@ impl<'a> Arguments<'a> {
     /// Same as [`Arguments::as_str`], but will only return `Some(s)` if it can be determined at compile time.
     #[must_use]
     #[inline]
-    fn as_const_str(&self) -> Option<&'static str> {
+    fn as_statically_known_str(&self) -> Option<&'static str> {
         let s = self.as_str();
         if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }
     }
@@ -1617,7 +1617,11 @@ impl<'a> Formatter<'a> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result {
-        if let Some(s) = fmt.as_const_str() { self.buf.write_str(s) } else { write(self.buf, fmt) }
+        if let Some(s) = fmt.as_statically_known_str() {
+            self.buf.write_str(s)
+        } else {
+            write(self.buf, fmt)
+        }
     }
 
     /// Flags for formatting
@@ -2308,7 +2312,7 @@ impl Write for Formatter<'_> {
 
     #[inline]
     fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
-        if let Some(s) = args.as_const_str() {
+        if let Some(s) = args.as_statically_known_str() {
             self.buf.write_str(s)
         } else {
             write(self.buf, args)
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index dec31548fc8..bb1debfc77d 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1356,7 +1356,7 @@ extern "rust-intrinsic" {
     /// let v_clone = v_orig.clone();
     ///
     /// // This is the suggested, safe way.
-    /// // It does copy the entire vector, though, into a new array.
+    /// // It may copy the entire vector into a new one though, but also may not.
     /// let v_collected = v_clone.into_iter()
     ///                          .map(Some)
     ///                          .collect::<Vec<Option<&i32>>>();
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index b69f4f853b9..427a95f4665 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -470,7 +470,7 @@ extern "rust-intrinsic" {
     /// No matter whether the output is an array or an unsigned integer, it is treated as a single
     /// contiguous list of bits. The bitmask is always packed on the least-significant side of the
     /// output, and padded with 0s in the most-significant bits. The order of the bits depends on
-    /// endianess:
+    /// endianness:
     ///
     /// * On little endian, the least significant bit corresponds to the first vector element.
     /// * On big endian, the least significant bit corresponds to the last vector element.
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c457c39e0c1..dc5a8704498 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -328,6 +328,7 @@
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(float_next_up_down)]
+#![feature(fmt_internals)]
 #![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index e6e1d32fa54..31dbe86b66c 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -391,6 +391,7 @@ pub mod panic_count {
     pub fn increase(run_panic_hook: bool) -> Option<MustAbort> {
         let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed);
         if global_count & ALWAYS_ABORT_FLAG != 0 {
+            // Do *not* access thread-local state, we might be after a `fork`.
             return Some(MustAbort::AlwaysAbort);
         }
 
@@ -744,11 +745,14 @@ fn rust_panic_with_hook(
     if let Some(must_abort) = must_abort {
         match must_abort {
             panic_count::MustAbort::PanicInHook => {
-                // Don't try to print the message in this case
-                // - perhaps that is causing the recursive panics.
+                // Don't try to format the message in this case, perhaps that is causing the
+                // recursive panics. However if the message is just a string, no user-defined
+                // code is involved in printing it, so that is risk-free.
+                let msg_str = message.and_then(|m| m.as_str()).map(|m| [m]);
+                let message = msg_str.as_ref().map(|m| fmt::Arguments::new_const(m));
                 let panicinfo = PanicInfo::internal_constructor(
-                    None,     // no message
-                    location, // but we want to show the location!
+                    message.as_ref(),
+                    location,
                     can_unwind,
                     force_no_backtrace,
                 );
@@ -756,7 +760,7 @@ fn rust_panic_with_hook(
             }
             panic_count::MustAbort::AlwaysAbort => {
                 // Unfortunately, this does not print a backtrace, because creating
-                // a `Backtrace` will allocate, which we must to avoid here.
+                // a `Backtrace` will allocate, which we must avoid here.
                 let panicinfo = PanicInfo::internal_constructor(
                     message,
                     location,
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index ba53ed88f37..23aa4da14a7 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -10,14 +10,16 @@
 //! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles)
 
 use r_efi::efi::{self, Guid};
+use r_efi::protocols::{device_path, device_path_to_text};
 
+use crate::ffi::OsString;
+use crate::io::{self, const_io_error};
 use crate::mem::{size_of, MaybeUninit};
-use crate::os::uefi;
+use crate::os::uefi::{self, env::boot_services, ffi::OsStringExt};
 use crate::ptr::NonNull;
-use crate::{
-    io::{self, const_io_error},
-    os::uefi::env::boot_services,
-};
+use crate::slice;
+use crate::sync::atomic::{AtomicPtr, Ordering};
+use crate::sys_common::wstr::WStrUnits;
 
 const BOOT_SERVICES_UNAVAILABLE: io::Error =
     const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
@@ -142,9 +144,74 @@ pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result
 
 /// Get the Protocol for current system handle.
 /// Note: Some protocols need to be manually freed. It is the callers responsibility to do so.
-pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> Option<NonNull<T>> {
-    let system_handle = uefi::env::try_image_handle()?;
-    open_protocol(system_handle, protocol_guid).ok()
+pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> io::Result<NonNull<T>> {
+    let system_handle = uefi::env::try_image_handle().ok_or(io::const_io_error!(
+        io::ErrorKind::NotFound,
+        "Protocol not found in Image handle"
+    ))?;
+    open_protocol(system_handle, protocol_guid)
+}
+
+pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::Result<OsString> {
+    fn path_to_text(
+        protocol: NonNull<device_path_to_text::Protocol>,
+        path: NonNull<device_path::Protocol>,
+    ) -> io::Result<OsString> {
+        let path_ptr: *mut r_efi::efi::Char16 = unsafe {
+            ((*protocol.as_ptr()).convert_device_path_to_text)(
+                path.as_ptr(),
+                // DisplayOnly
+                r_efi::efi::Boolean::FALSE,
+                // AllowShortcuts
+                r_efi::efi::Boolean::FALSE,
+            )
+        };
+
+        // SAFETY: `convert_device_path_to_text` returns a pointer to a null-terminated UTF-16
+        // string, and that string cannot be deallocated prior to dropping the `WStrUnits`, so
+        // it's safe for `WStrUnits` to use.
+        let path_len = unsafe {
+            WStrUnits::new(path_ptr)
+                .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?
+                .count()
+        };
+
+        let path = OsString::from_wide(unsafe { slice::from_raw_parts(path_ptr.cast(), path_len) });
+
+        if let Some(boot_services) = crate::os::uefi::env::boot_services() {
+            let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+            unsafe {
+                ((*boot_services.as_ptr()).free_pool)(path_ptr.cast());
+            }
+        }
+
+        Ok(path)
+    }
+
+    static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
+        AtomicPtr::new(crate::ptr::null_mut());
+
+    if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
+        if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
+            handle,
+            device_path_to_text::PROTOCOL_GUID,
+        ) {
+            return path_to_text(protocol, path);
+        }
+    }
+
+    let device_path_to_text_handles = locate_handles(device_path_to_text::PROTOCOL_GUID)?;
+    for handle in device_path_to_text_handles {
+        if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
+            handle,
+            device_path_to_text::PROTOCOL_GUID,
+        ) {
+            LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
+            return path_to_text(protocol, path);
+        }
+    }
+
+    Err(io::const_io_error!(io::ErrorKind::NotFound, "No device path to text protocol found"))
 }
 
 /// Get RuntimeServices
diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs
index e6693db68e6..58838c5876e 100644
--- a/library/std/src/sys/pal/uefi/os.rs
+++ b/library/std/src/sys/pal/uefi/os.rs
@@ -1,4 +1,4 @@
-use super::{unsupported, RawOsError};
+use super::{helpers, unsupported, RawOsError};
 use crate::error::Error as StdError;
 use crate::ffi::{OsStr, OsString};
 use crate::fmt;
@@ -7,6 +7,7 @@ use crate::marker::PhantomData;
 use crate::os::uefi;
 use crate::path::{self, PathBuf};
 use crate::ptr::NonNull;
+use r_efi::efi::protocols::{device_path, loaded_image_device_path};
 use r_efi::efi::Status;
 
 pub fn errno() -> RawOsError {
@@ -164,7 +165,10 @@ impl fmt::Display for JoinPathsError {
 impl StdError for JoinPathsError {}
 
 pub fn current_exe() -> io::Result<PathBuf> {
-    unsupported()
+    let protocol = helpers::image_handle_protocol::<device_path::Protocol>(
+        loaded_image_device_path::PROTOCOL_GUID,
+    )?;
+    helpers::device_path_to_text(protocol).map(PathBuf::from)
 }
 
 pub struct Env(!);
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index 1f140f7844f..9a0a1b18aee 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -459,7 +459,7 @@ impl Socket {
             const AF_NAME_MAX: usize = 16;
             let mut buf = [0; AF_NAME_MAX];
             for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) {
-                *dst = *src as i8;
+                *dst = *src as libc::c_char;
             }
             let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() };
             arg.af_name = buf;
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 6520ca9fc48..a3e1b6782e8 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -355,8 +355,6 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
             target_os = "tvos",
             target_os = "linux",
             target_os = "macos",
-            target_os = "solaris",
-            target_os = "illumos",
             target_os = "aix",
         ))] {
             #[allow(unused_assignments)]
@@ -483,6 +481,12 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
                         .ok_or(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"))
                 }
             }
+        } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
+            let mut cpus = 0u32;
+            if unsafe { libc::pset_info(libc::PS_MYID, core::ptr::null_mut(), &mut cpus, core::ptr::null_mut()) } != 0 {
+                return Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
+            }
+            Ok(unsafe { NonZero::new_unchecked(cpus as usize) })
         } else if #[cfg(target_os = "haiku")] {
             // system_info cpu_count field gets the static data set at boot time with `smp_set_num_cpus`
             // `get_system_info` calls then `smp_get_num_cpus`
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 25bb5938b4c..51d31a00afe 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(staged_api)]
 #![feature(c_unwind)]
 #![feature(strict_provenance)]
+#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))]
 #![cfg_attr(not(target_env = "msvc"), feature(libc))]
 #![cfg_attr(
     all(target_family = "wasm", not(target_os = "emscripten")),
diff --git a/library/unwind/src/wasm.rs b/library/unwind/src/wasm.rs
index b06671bcb83..f4ffac1ba16 100644
--- a/library/unwind/src/wasm.rs
+++ b/library/unwind/src/wasm.rs
@@ -59,7 +59,10 @@ pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwi
             wasm_throw(0, exception.cast())
         } else {
             let _ = exception;
-            core::arch::wasm32::unreachable()
+            #[cfg(target_arch = "wasm32")]
+            core::arch::wasm32::unreachable();
+            #[cfg(target_arch = "wasm64")]
+            core::arch::wasm64::unreachable();
         }
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 6d3163b90b1..f22a9ca604e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1289,9 +1289,9 @@ macro_rules! test_definitions {
 /// Adapted from [`test_definitions`].
 macro_rules! coverage_test_alias {
     ($name:ident {
-        alias_and_mode: $alias_and_mode:expr,
-        default: $default:expr,
-        only_hosts: $only_hosts:expr $(,)?
+        alias_and_mode: $alias_and_mode:expr, // &'static str
+        default: $default:expr, // bool
+        only_hosts: $only_hosts:expr $(,)? // bool
     }) => {
         #[derive(Debug, Clone, PartialEq, Eq, Hash)]
         pub struct $name {
@@ -1309,6 +1309,8 @@ macro_rules! coverage_test_alias {
             const ONLY_HOSTS: bool = $only_hosts;
 
             fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+                // Register the mode name as a command-line alias.
+                // This allows `x test coverage-map` and `x test coverage-run`.
                 run.alias($alias_and_mode)
             }
 
@@ -1319,8 +1321,7 @@ macro_rules! coverage_test_alias {
             }
 
             fn run(self, builder: &Builder<'_>) {
-                Coverage { compiler: self.compiler, target: self.target }
-                    .run_unified_suite(builder, Self::MODE)
+                Coverage::run_coverage_tests(builder, self.compiler, self.target, Self::MODE);
             }
         }
     };
@@ -1449,11 +1450,20 @@ host_test!(RunMakeFullDeps {
 
 default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" });
 
-/// Custom test step that is responsible for running the coverage tests
-/// in multiple different modes.
+/// Coverage tests are a bit more complicated than other test suites, because
+/// we want to run the same set of test files in multiple different modes,
+/// in a way that's convenient and flexible when invoked manually.
+///
+/// This combined step runs the specified tests (or all of `tests/coverage`)
+/// in both "coverage-map" and "coverage-run" modes.
+///
+/// Used by:
+/// - `x test coverage`
+/// - `x test tests/coverage`
+/// - `x test tests/coverage/trivial.rs` (etc)
 ///
-/// Each individual mode also has its own alias that will run the tests in
-/// just that mode.
+/// (Each individual mode also has its own step that will run the tests in
+/// just that mode.)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Coverage {
     pub compiler: Compiler,
@@ -1464,24 +1474,41 @@ impl Coverage {
     const PATH: &'static str = "tests/coverage";
     const SUITE: &'static str = "coverage";
 
-    fn run_unified_suite(&self, builder: &Builder<'_>, mode: &'static str) {
+    /// Runs the coverage test suite (or a user-specified subset) in one mode.
+    ///
+    /// This same function is used by the multi-mode step ([`Coverage`]) and by
+    /// the single-mode steps ([`CoverageMap`] and [`CoverageRun`]), to help
+    /// ensure that they all behave consistently with each other, regardless of
+    /// how the coverage tests have been invoked.
+    fn run_coverage_tests(
+        builder: &Builder<'_>,
+        compiler: Compiler,
+        target: TargetSelection,
+        mode: &'static str,
+    ) {
+        // Like many other test steps, we delegate to a `Compiletest` step to
+        // actually run the tests. (See `test_definitions!`.)
         builder.ensure(Compiletest {
-            compiler: self.compiler,
-            target: self.target,
+            compiler,
+            target,
             mode,
             suite: Self::SUITE,
             path: Self::PATH,
             compare_mode: None,
-        })
+        });
     }
 }
 
 impl Step for Coverage {
     type Output = ();
+    // We rely on the individual CoverageMap/CoverageRun steps to run themselves.
     const DEFAULT: bool = false;
+    // When manually invoked, try to run as much as possible.
+    // Compiletest will automatically skip the "coverage-run" tests if necessary.
     const ONLY_HOSTS: bool = false;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        // Take responsibility for command-line paths within `tests/coverage`.
         run.suite_path(Self::PATH)
     }
 
@@ -1492,20 +1519,26 @@ impl Step for Coverage {
     }
 
     fn run(self, builder: &Builder<'_>) {
-        self.run_unified_suite(builder, CoverageMap::MODE);
-        self.run_unified_suite(builder, CoverageRun::MODE);
+        // Run the specified coverage tests (possibly all of them) in both modes.
+        Self::run_coverage_tests(builder, self.compiler, self.target, CoverageMap::MODE);
+        Self::run_coverage_tests(builder, self.compiler, self.target, CoverageRun::MODE);
     }
 }
 
-// Aliases for running the coverage tests in only one mode.
+// Runs `tests/coverage` in "coverage-map" mode only.
+// Used by `x test` and `x test coverage-map`.
 coverage_test_alias!(CoverageMap {
     alias_and_mode: "coverage-map",
     default: true,
     only_hosts: false,
 });
+// Runs `tests/coverage` in "coverage-run" mode only.
+// Used by `x test` and `x test coverage-run`.
 coverage_test_alias!(CoverageRun {
     alias_and_mode: "coverage-run",
     default: true,
+    // Compiletest knows how to automatically skip these tests when cross-compiling,
+    // but skipping the whole step here makes it clearer that they haven't run at all.
     only_hosts: true,
 });
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh
index b22d60f2b1d..5bc6f5cc216 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh
@@ -1,5 +1,10 @@
 #!/usr/bin/env bash
 
+GIT_REPO="https://github.com/rust-lang/gcc"
+
+# This commit hash needs to be updated to use a more recent gcc fork version.
+GIT_COMMIT="78dc50f0e50e6cd1433149520bd512a4e0eaa1bc"
+
 set -ex
 
 cd $1
@@ -7,13 +12,11 @@ cd $1
 source shared.sh
 
 # Setting up folders for GCC
-git clone https://github.com/antoyo/gcc gcc-src
-cd gcc-src
-# This commit hash needs to be updated to use a more recent gcc fork version.
-git checkout 78dc50f0e50e6cd1433149520bd512a4e0eaa1bc
+curl -L "$GIT_REPO/archive/$GIT_COMMIT.tar.gz" |
+    tar -xz --transform "s/gcc-$GIT_COMMIT/gcc-src/"
 
-mkdir ../gcc-build ../gcc-install
-cd ../gcc-build
+mkdir gcc-build gcc-install
+pushd gcc-build
 
 # Building GCC.
 hide_output \
@@ -28,6 +31,7 @@ hide_output \
 hide_output make -j$(nproc)
 hide_output make install
 
-rm -rf ../gcc-src
+popd
+rm -rf gcc-src gcc-build
 ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so
 ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so.0
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 972ef359337..80e23574404 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -261,7 +261,7 @@ x--expand-yaml-anchors--remove:
         <<: *step
 
       - name: upload artifacts to github
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           # name is set in previous step
           name: ${{ env.DOC_ARTIFACT_NAME }}
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 211921715b0..22a3cf4d44d 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -67,9 +67,6 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
         }
     }
 
-    if let Some(sysroot) = &options.maybe_sysroot {
-        content.push(format!("--sysroot={}", sysroot.display()));
-    }
     for lib_str in &options.lib_strs {
         content.push(format!("-L{lib_str}"));
     }
@@ -411,6 +408,10 @@ fn run_test(
 
     compiler.arg(&format!("@{}", rustdoc_options.arg_file.display()));
 
+    if let Some(sysroot) = &rustdoc_options.maybe_sysroot {
+        compiler.arg(format!("--sysroot={}", sysroot.display()));
+    }
+
     compiler.arg("--edition").arg(&edition.to_string());
     compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", path);
     compiler.env("UNSTABLE_RUSTDOC_TEST_LINE", format!("{}", line as isize - line_offset as isize));
@@ -950,6 +951,7 @@ pub(crate) struct IndividualTestOptions {
     runtool_args: Vec<String>,
     target: TargetTriple,
     test_id: String,
+    maybe_sysroot: Option<PathBuf>,
 }
 
 impl IndividualTestOptions {
@@ -982,6 +984,7 @@ impl IndividualTestOptions {
             runtool_args: options.runtool_args.clone(),
             target: options.target.clone(),
             test_id,
+            maybe_sysroot: options.maybe_sysroot.clone(),
         }
     }
 }
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index ef02e7fcb4a..b791b38379f 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -609,6 +609,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
         stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py"));
     }
 
+    stamp.add_dir(&rust_src_dir.join("src/tools/run-make-support"));
+
     // Compiletest itself.
     stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/"));
 
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index af98b38af8c..6973c0e9c35 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -457,7 +457,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let bitmask_len = u32::try_from(bitmask_len).unwrap();
 
                 // To read the mask, we transmute it to an integer.
-                // That does the right thing wrt endianess.
+                // That does the right thing wrt endianness.
                 let mask_ty = this.machine.layouts.uint(mask.layout.size).unwrap();
                 let mask = mask.transmute(mask_ty, this)?;
                 let mask: u64 = this.read_scalar(&mask)?.to_bits(mask_ty.size)?.try_into().unwrap();
@@ -509,7 +509,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     }
                 }
                 // We have to change the type of the place to be able to write `res` into it. This
-                // transmutes the integer to an array, which does the right thing wrt endianess.
+                // transmutes the integer to an array, which does the right thing wrt endianness.
                 let dest =
                     dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?;
                 this.write_int(res, &dest)?;
diff --git a/src/tools/miri/src/shims/unix/linux/fd/event.rs b/src/tools/miri/src/shims/unix/linux/fd/event.rs
index 1f17ffb88c8..49408fda3ae 100644
--- a/src/tools/miri/src/shims/unix/linux/fd/event.rs
+++ b/src/tools/miri/src/shims/unix/linux/fd/event.rs
@@ -38,7 +38,7 @@ impl FileDescriptor for Event {
     }
 
     /// A write call adds the 8-byte integer value supplied in
-    /// its buffer (in native endianess) to the counter.  The maximum value that may be
+    /// its buffer (in native endianness) to the counter.  The maximum value that may be
     /// stored in the counter is the largest unsigned 64-bit value
     /// minus 1 (i.e., 0xfffffffffffffffe).  If the addition would
     /// cause the counter's value to exceed the maximum, then the
@@ -57,7 +57,7 @@ impl FileDescriptor for Event {
     ) -> InterpResult<'tcx, io::Result<usize>> {
         let v1 = self.val.get();
         let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size
-        // Convert from target endianess to host endianess.
+        // Convert from target endianness to host endianness.
         let num = match tcx.sess.target.endian {
             Endian::Little => u64::from_le_bytes(bytes),
             Endian::Big => u64::from_be_bytes(bytes),
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index cb46e65999d..1a39d212386 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -121,6 +121,7 @@ fn default_dcx(
             fallback_bundle,
             fatal_dcx: DiagCtxt::new(emitter),
             fatal_note: None,
+            emit_fatal_diagnostic: false,
         })
     } else {
         emitter
@@ -209,7 +210,7 @@ impl ParseSess {
             rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
             false,
         );
-        self.raw_psess.dcx.make_silent(fallback_bundle, None);
+        self.raw_psess.dcx.make_silent(fallback_bundle, None, false);
     }
 
     pub(crate) fn span_to_filename(&self, span: Span) -> FileName {
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
index 6f47f5e3355..1332338b26a 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
@@ -34,6 +34,12 @@ pub struct Bar(i32);
 #[repr(transparent)]
 pub struct Type3<T>(T);
 
+// repr(transparent) wrapper which engages in self-reference
+#[repr(transparent)]
+pub struct Type4(Type4Helper<Type4>);
+#[repr(transparent)]
+pub struct Type4Helper<T>(*mut T);
+
 pub fn foo1(_: Type1) { }
 // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 pub fn foo2(_: Type1, _: Type1) { }
@@ -52,6 +58,13 @@ pub fn foo8(_: Type3<Bar>, _: Type3<Bar>) { }
 // CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 pub fn foo9(_: Type3<Bar>, _: Type3<Bar>, _: Type3<Bar>) { }
 // CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo10(_: Type4) { }
+// CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo11(_: Type4, _: Type4) { }
+// CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+pub fn foo12(_: Type4, _: Type4, _: Type4) { }
+// CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+
 
 // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooE"}
 // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooS_E"}
@@ -62,3 +75,6 @@ pub fn foo9(_: Type3<Bar>, _: Type3<Bar>, _: Type3<Bar>) { }
 // CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarE"}
 // CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarS_E"}
 // CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarS_S_E"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4E"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4S0_E"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4S0_S0_E"}
diff --git a/tests/ui/asm/aarch64/type-check-3.stderr b/tests/ui/asm/aarch64/type-check-3.stderr
index f710df2dcde..9e37bb4c203 100644
--- a/tests/ui/asm/aarch64/type-check-3.stderr
+++ b/tests/ui/asm/aarch64/type-check-3.stderr
@@ -4,8 +4,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0u8);
    |               ^^           --- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
    = note: `#[warn(asm_sub_register)]` on by default
 
 warning: formatting may not be suitable for sub-register argument
@@ -14,8 +14,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0u16);
    |               ^^           ---- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:52:15
@@ -23,8 +23,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0i32);
    |               ^^           ---- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:54:15
@@ -32,8 +32,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0f32);
    |               ^^           ---- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:57:15
@@ -41,8 +41,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(vreg) 0i16);
    |               ^^            ---- for this argument
    |
-   = help: use `{0:h}` to have the register formatted as `h0`
-   = help: or use `{0:v}` to keep the default formatting of `v0`
+   = help: use `{0:h}` to have the register formatted as `h0` (for 16-bit values)
+   = help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:59:15
@@ -50,8 +50,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(vreg) 0f32);
    |               ^^            ---- for this argument
    |
-   = help: use `{0:s}` to have the register formatted as `s0`
-   = help: or use `{0:v}` to keep the default formatting of `v0`
+   = help: use `{0:s}` to have the register formatted as `s0` (for 32-bit values)
+   = help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:61:15
@@ -59,8 +59,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(vreg) 0f64);
    |               ^^            ---- for this argument
    |
-   = help: use `{0:d}` to have the register formatted as `d0`
-   = help: or use `{0:v}` to keep the default formatting of `v0`
+   = help: use `{0:d}` to have the register formatted as `d0` (for 64-bit values)
+   = help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:63:15
@@ -68,8 +68,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(vreg_low16) 0f64);
    |               ^^                  ---- for this argument
    |
-   = help: use `{0:d}` to have the register formatted as `d0`
-   = help: or use `{0:v}` to keep the default formatting of `v0`
+   = help: use `{0:d}` to have the register formatted as `d0` (for 64-bit values)
+   = help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:66:15
@@ -77,8 +77,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{0} {0}", in(reg) 0i16);
    |               ^^^ ^^^           ---- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:68:15
@@ -86,8 +86,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{0} {0:x}", in(reg) 0i16);
    |               ^^^                 ---- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
 
 error: type `i128` cannot be used with this register class
   --> $DIR/type-check-3.rs:73:28
diff --git a/tests/ui/asm/bad-template.aarch64.stderr b/tests/ui/asm/bad-template.aarch64.stderr
index b18946d7c6d..5023cf317d7 100644
--- a/tests/ui/asm/bad-template.aarch64.stderr
+++ b/tests/ui/asm/bad-template.aarch64.stderr
@@ -194,8 +194,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = help: use `{0:w}` to have the register formatted as `w0`
-   = help: or use `{0:x}` to keep the default formatting of `x0`
+   = help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
+   = help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
    = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/tests/ui/asm/bad-template.x86_64.stderr b/tests/ui/asm/bad-template.x86_64.stderr
index 2f584c30a32..1b9775636f5 100644
--- a/tests/ui/asm/bad-template.x86_64.stderr
+++ b/tests/ui/asm/bad-template.x86_64.stderr
@@ -194,8 +194,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = help: use `{0:e}` to have the register formatted as `eax`
-   = help: or use `{0:r}` to keep the default formatting of `rax`
+   = help: use `{0:e}` to have the register formatted as `eax` (for 32-bit values)
+   = help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
    = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
diff --git a/tests/ui/asm/x86_64/type-check-3.stderr b/tests/ui/asm/x86_64/type-check-3.stderr
index 1baf50ff6e0..34bfcd71cac 100644
--- a/tests/ui/asm/x86_64/type-check-3.stderr
+++ b/tests/ui/asm/x86_64/type-check-3.stderr
@@ -44,8 +44,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{0} {0}", in(reg) 0i16);
    |               ^^^ ^^^           ---- for this argument
    |
-   = help: use `{0:x}` to have the register formatted as `ax`
-   = help: or use `{0:r}` to keep the default formatting of `rax`
+   = help: use `{0:x}` to have the register formatted as `ax` (for 16-bit values)
+   = help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
    = note: `#[warn(asm_sub_register)]` on by default
 
 warning: formatting may not be suitable for sub-register argument
@@ -54,8 +54,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{0} {0:x}", in(reg) 0i16);
    |               ^^^                 ---- for this argument
    |
-   = help: use `{0:x}` to have the register formatted as `ax`
-   = help: or use `{0:r}` to keep the default formatting of `rax`
+   = help: use `{0:x}` to have the register formatted as `ax` (for 16-bit values)
+   = help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:38:15
@@ -63,8 +63,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0i32);
    |               ^^           ---- for this argument
    |
-   = help: use `{0:e}` to have the register formatted as `eax`
-   = help: or use `{0:r}` to keep the default formatting of `rax`
+   = help: use `{0:e}` to have the register formatted as `eax` (for 32-bit values)
+   = help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:41:15
@@ -72,8 +72,8 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(ymm_reg) 0i64);
    |               ^^               ---- for this argument
    |
-   = help: use `{0:x}` to have the register formatted as `xmm0`
-   = help: or use `{0:y}` to keep the default formatting of `ymm0`
+   = help: use `{0:x}` to have the register formatted as `xmm0` (for 128-bit values)
+   = help: or use `{0:y}` to keep the default formatting of `ymm0` (for 256-bit values)
 
 error: type `i8` cannot be used with this register class
   --> $DIR/type-check-3.rs:52:28
diff --git a/tests/ui/associated-type-bounds/auxiliary/implied-predicates.rs b/tests/ui/associated-type-bounds/auxiliary/implied-predicates.rs
new file mode 100644
index 00000000000..fe74c64fbe2
--- /dev/null
+++ b/tests/ui/associated-type-bounds/auxiliary/implied-predicates.rs
@@ -0,0 +1,7 @@
+pub trait Bar: Super<SuperAssoc: Bound> {}
+
+pub trait Super {
+    type SuperAssoc;
+}
+
+pub trait Bound {}
diff --git a/tests/ui/associated-type-bounds/implied-predicates.rs b/tests/ui/associated-type-bounds/implied-predicates.rs
new file mode 100644
index 00000000000..e97d7a396c4
--- /dev/null
+++ b/tests/ui/associated-type-bounds/implied-predicates.rs
@@ -0,0 +1,9 @@
+//@ aux-build:implied-predicates.rs
+//@ check-pass
+
+extern crate implied_predicates;
+use implied_predicates::Bar;
+
+fn bar<B: Bar>() {}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/resolution-failure-building-vtable-representation-ice-90691.rs b/tests/ui/associated-type-bounds/resolution-failure-building-vtable-representation-ice-90691.rs
new file mode 100644
index 00000000000..d3c13974127
--- /dev/null
+++ b/tests/ui/associated-type-bounds/resolution-failure-building-vtable-representation-ice-90691.rs
@@ -0,0 +1,42 @@
+// ICE #90691 Encountered error `Unimplemented` selecting  ...
+//@ build-pass
+// issue: rust-lang/rust#90691
+
+trait TError: std::fmt::Debug {}
+impl TError for () {}
+
+trait SuperTrait {
+    type Error;
+}
+
+trait Trait: SuperTrait<Error: TError> {}
+
+impl<T> Trait for T
+where
+    T: SuperTrait,
+    <T as SuperTrait>::Error: TError,
+{
+}
+
+struct SomeTrait<S>(S);
+struct BoxedTrait(Box<dyn Trait<Error = ()>>);
+
+impl<S: 'static> From<SomeTrait<S>> for BoxedTrait {
+    fn from(other: SomeTrait<S>) -> Self {
+        Self(Box::new(other))
+    }
+}
+
+impl<S> SuperTrait for SomeTrait<S> {
+    type Error = ();
+}
+
+impl From<()> for BoxedTrait {
+    fn from(c: ()) -> Self {
+        Self::from(SomeTrait(c))
+    }
+}
+
+fn main() {
+    let _: BoxedTrait = ().into();
+}
diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr
index b7d805d9171..9d909e915c2 100644
--- a/tests/ui/binding/issue-53114-safety-checks.stderr
+++ b/tests/ui/binding/issue-53114-safety-checks.stderr
@@ -1,3 +1,23 @@
+error[E0793]: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:23:13
+   |
+LL |     let _ = &p.b;
+   |             ^^^^
+   |
+   = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
+   = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error[E0793]: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:28:17
+   |
+LL |     let (_,) = (&p.b,);
+   |                 ^^^^
+   |
+   = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
+   = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
 error[E0133]: access to union field is unsafe and requires unsafe function or block
   --> $DIR/issue-53114-safety-checks.rs:24:13
    |
@@ -31,20 +51,20 @@ LL |     let (_,) = (&u2.a,);
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:23:13
+  --> $DIR/issue-53114-safety-checks.rs:37:16
    |
-LL |     let _ = &p.b;
-   |             ^^^^
+LL |     let _: _ = &p.b;
+   |                ^^^^
    |
    = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
    = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:28:17
+  --> $DIR/issue-53114-safety-checks.rs:42:20
    |
-LL |     let (_,) = (&p.b,);
-   |                 ^^^^
+LL |     let (_,): _ = (&p.b,);
+   |                    ^^^^
    |
    = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
    = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
@@ -83,20 +103,20 @@ LL |     let (_,): _ = (&u2.a,);
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:37:16
+  --> $DIR/issue-53114-safety-checks.rs:51:11
    |
-LL |     let _: _ = &p.b;
-   |                ^^^^
+LL |     match &p.b  { _ => { } }
+   |           ^^^^
    |
    = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
    = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:42:20
+  --> $DIR/issue-53114-safety-checks.rs:56:12
    |
-LL |     let (_,): _ = (&p.b,);
-   |                    ^^^^
+LL |     match (&p.b,)  { (_,) => { } }
+   |            ^^^^
    |
    = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
    = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
@@ -134,26 +154,6 @@ LL |     match (&u2.a,) { (_,) => { } }
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:51:11
-   |
-LL |     match &p.b  { _ => { } }
-   |           ^^^^
-   |
-   = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
-   = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
-
-error[E0793]: reference to packed field is unaligned
-  --> $DIR/issue-53114-safety-checks.rs:56:12
-   |
-LL |     match (&p.b,)  { (_,) => { } }
-   |            ^^^^
-   |
-   = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
-   = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
-
 error: aborting due to 18 previous errors
 
 Some errors have detailed explanations: E0133, E0793.
diff --git a/tests/ui/const-generics/const-argument-if-length.full.stderr b/tests/ui/const-generics/const-argument-if-length.full.stderr
index db3d88392bd..4de98c11d2b 100644
--- a/tests/ui/const-generics/const-argument-if-length.full.stderr
+++ b/tests/ui/const-generics/const-argument-if-length.full.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     pad: [u8; is_zst::<T>()],
    |          ^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:`
+help: try adding a `where` bound
+   |
+LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: {
+   |                                   ++++++++++++++++++++++++++
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/const-argument-if-length.rs:16:12
diff --git a/tests/ui/const-generics/defaults/generic-expr-default.stderr b/tests/ui/const-generics/defaults/generic-expr-default.stderr
index ada1498d1c8..909edada4cb 100644
--- a/tests/ui/const-generics/defaults/generic-expr-default.stderr
+++ b/tests/ui/const-generics/defaults/generic-expr-default.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL | pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> {
    |                                                      ^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
+help: try adding a `where` bound
+   |
+LL | pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> where [(); { N + 1 }]: {
+   |                                                              ++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/generic-expr-default.rs:14:58
@@ -12,7 +15,10 @@ error: unconstrained generic constant
 LL | fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N>
    |                                                          ^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
+help: try adding a `where` bound
+   |
+LL | fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N> where [(); { N + 1 }]:
+   |                                                                      ++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/ensure_is_evaluatable.stderr b/tests/ui/const-generics/ensure_is_evaluatable.stderr
index b9bd9160b13..62f8bc34f2e 100644
--- a/tests/ui/const-generics/ensure_is_evaluatable.stderr
+++ b/tests/ui/const-generics/ensure_is_evaluatable.stderr
@@ -4,7 +4,6 @@ error: unconstrained generic constant
 LL |     bar()
    |     ^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
 note: required by a bound in `bar`
   --> $DIR/ensure_is_evaluatable.rs:15:10
    |
@@ -13,6 +12,10 @@ LL | fn bar<const N: usize>() -> [(); N]
 LL | where
 LL |     [(); N + 1]:,
    |          ^^^^^ required by this bound in `bar`
+help: try adding a `where` bound
+   |
+LL |     [(); M + 1]:, [(); N + 1]:
+   |                 ~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/fn_with_two_const_inputs.stderr b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
index ec31e02f144..c0a913a21fd 100644
--- a/tests/ui/const-generics/fn_with_two_const_inputs.stderr
+++ b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
@@ -4,7 +4,6 @@ error: unconstrained generic constant
 LL |     bar()
    |     ^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
 note: required by a bound in `bar`
   --> $DIR/fn_with_two_const_inputs.rs:18:10
    |
@@ -13,6 +12,10 @@ LL | fn bar<const N: usize>() -> [(); N]
 LL | where
 LL |     [(); N + 1]:,
    |          ^^^^^ required by this bound in `bar`
+help: try adding a `where` bound
+   |
+LL |     [(); both(N + 1, M + 1)]:, [(); N + 1]:
+   |                              ~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.fixed b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.fixed
new file mode 100644
index 00000000000..929282f40e6
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.fixed
@@ -0,0 +1,21 @@
+//@ run-rustfix
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features, dead_code)]
+
+struct Evaluatable<const N: u128> {}
+
+struct Foo<const N: u8>([u8; N as usize])
+//~^ ERROR unconstrained generic constant
+where
+    Evaluatable<{N as u128}>:, [(); N as usize]:;
+//~^ HELP try adding a `where` bound
+
+struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
+//~^ ERROR unconstrained generic constant
+//~| HELP try adding a `where` bound
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
+//~^ ERROR unconstrained generic constant
+//~| HELP try adding a `where` bound
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
index 3b5b87b2b3d..3a6c4d35451 100644
--- a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.rs
@@ -1,20 +1,21 @@
+//@ run-rustfix
 #![feature(generic_const_exprs)]
-#![allow(incomplete_features)]
+#![allow(incomplete_features, dead_code)]
 
 struct Evaluatable<const N: u128> {}
 
 struct Foo<const N: u8>([u8; N as usize])
-//~^ Error: unconstrained generic constant
-//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+//~^ ERROR unconstrained generic constant
 where
     Evaluatable<{N as u128}>:;
+//~^ HELP try adding a `where` bound
 
 struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
-//~^ Error: unconstrained generic constant
-//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+//~^ ERROR unconstrained generic constant
+//~| HELP try adding a `where` bound
 
 struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
-//~^ Error: unconstrained generic constant
-//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+//~^ ERROR unconstrained generic constant
+//~| HELP try adding a `where` bound
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
index 5ca04d25e55..ce8eca8d25e 100644
--- a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-2.stderr
@@ -1,26 +1,35 @@
 error: unconstrained generic constant
-  --> $DIR/abstract-const-as-cast-2.rs:6:25
+  --> $DIR/abstract-const-as-cast-2.rs:7:25
    |
 LL | struct Foo<const N: u8>([u8; N as usize])
    |                         ^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+help: try adding a `where` bound
+   |
+LL |     Evaluatable<{N as u128}>:, [(); N as usize]:;
+   |                              +++++++++++++++++++
 
 error: unconstrained generic constant
-  --> $DIR/abstract-const-as-cast-2.rs:12:26
+  --> $DIR/abstract-const-as-cast-2.rs:13:26
    |
 LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+help: try adding a `where` bound
+   |
+LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
+   |                                                                                               +++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
-  --> $DIR/abstract-const-as-cast-2.rs:16:25
+  --> $DIR/abstract-const-as-cast-2.rs:17:25
    |
 LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
    |                         ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+help: try adding a `where` bound
+   |
+LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
+   |                                                                              +++++++++++++++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index bd6fd67b89d..3622ef16a96 100644
--- a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -4,7 +4,6 @@ error: unconstrained generic constant
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
 note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
@@ -15,6 +14,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
    |
 LL |     fn assert_impl<T: Trait>() {}
    |                       ^^^^^ required by this bound in `assert_impl`
+help: try adding a `where` bound
+   |
+LL |     EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:17:5
@@ -36,7 +39,6 @@ error: unconstrained generic constant
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
 note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
@@ -47,6 +49,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
    |
 LL |     fn assert_impl<T: Trait>() {}
    |                       ^^^^^ required by this bound in `assert_impl`
+help: try adding a `where` bound
+   |
+LL |     EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:20:5
@@ -96,7 +102,6 @@ error: unconstrained generic constant
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
 note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
@@ -107,6 +112,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
    |
 LL |     fn assert_impl<T: Trait>() {}
    |                       ^^^^^ required by this bound in `assert_impl`
+help: try adding a `where` bound
+   |
+LL |     EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
+   |                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:35:5
@@ -128,7 +137,6 @@ error: unconstrained generic constant
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
 note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
@@ -139,6 +147,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
    |
 LL |     fn assert_impl<T: Trait>() {}
    |                       ^^^^^ required by this bound in `assert_impl`
+help: try adding a `where` bound
+   |
+LL |     EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
+   |                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:38:5
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
index 4b76ae6cfd5..5fc36ebc929 100644
--- a/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     bar::<{ N as usize as usize }>();
    |           ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<const N: u8>(a: [(); N as usize]) where [(); { N as usize as usize }]: {
+   |                                          ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
index c478718b4cc..471b850d8d5 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    |                                      ^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); 0 + N]:`
+help: try adding a `where` bound
+   |
+LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]) where [(); 0 + N]:;
+   |                                                    ++++++++++++++++++
 
 error: overly complex generic constant
   --> $DIR/array-size-in-generic-struct-param.rs:23:15
diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
index a8657bf5263..f3a38fcc005 100644
--- a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     bar::<{ T::ASSOC }>();
    |           ^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { T::ASSOC }]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<T: Trait, U: Trait>() where [(); U::ASSOC]:, [(); { T::ASSOC }]: {
+   |                                                   ~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr
index 9a8aa222dc1..0c29d94ed5b 100644
--- a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.stderr
@@ -24,7 +24,10 @@ error: unconstrained generic constant
 LL |     foo::<_, L>([(); L + 1 + L]);
    |                      ^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
+help: try adding a `where` bound
+   |
+LL |     [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
+   |                           ~~~~~~~~~~~~~~~~~~
 
 error: unconstrained generic constant
   --> $DIR/issue_114151.rs:17:17
@@ -34,11 +37,6 @@ LL |     foo::<_, L>([(); L + 1 + L]);
    |     |
    |     required by a bound introduced by this call
    |
-   = help: try adding a `where` bound using this expression: `where [(); {
-                   {
-                       N
-                   }
-               }]:`
 note: required by a bound in `foo`
   --> $DIR/issue_114151.rs:5:13
    |
@@ -51,6 +49,14 @@ LL | |             N
 LL | |         }
 LL | |     }],
    | |_____^ required by this bound in `foo`
+help: try adding a `where` bound
+   |
+LL ~     [(); (L - 1) + 1 + L]:, [(); {
+LL +         {
+LL +             N
+LL +         }
+LL +     }]:
+   |
 
 error: unconstrained generic constant `L + 1 + L`
   --> $DIR/issue_114151.rs:17:5
diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_binop_arg_tys.stderr b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_binop_arg_tys.stderr
index ba824e84a5a..6a62c0b4778 100644
--- a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_binop_arg_tys.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_binop_arg_tys.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |     Bar::<{ make_generic(N, 1_u8 == 0_u8) }>
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { make_generic(N, 1_u8 == 0_u8) }]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<const N: usize>() -> Bar<{ make_generic(N, true == false) }> where [(); { make_generic(N, 1_u8 == 0_u8) } as usize]: {
+   |                                                                     +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_cast_arg_ty.stderr b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_cast_arg_ty.stderr
index d3ba870a2d7..fba8b9e7784 100644
--- a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_cast_arg_ty.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_cast_arg_ty.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |     [(); (1_u8 as usize) + N]
    |          ^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); (1_u8 as usize) + N]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<const N: usize>() -> [(); (true as usize) + N] where [(); (1_u8 as usize) + N]: {
+   |                                                       ++++++++++++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
index da5194696e6..99eab935a09 100644
--- a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |     foo::<_, L>([(); L + 1 + L]);
    |                      ^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
+help: try adding a `where` bound
+   |
+LL |     [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
+   |                           ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
index 921314f0c50..a05aaf2af64 100644
--- a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
@@ -4,7 +4,6 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |                                            ^
    |
-   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
   --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
    |
@@ -13,6 +12,10 @@ LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
 LL | where
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+help: try adding a `where` bound
+   |
+LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
+   |              +++++++++++++++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:44
@@ -20,12 +23,15 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |                                            ^
    |
-   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
   --> $DIR/auxiliary/const_evaluatable_lib.rs:3:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+help: try adding a `where` bound
+   |
+LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
+   |              +++++++++++++++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:13
@@ -33,7 +39,6 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
   --> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
    |
@@ -42,6 +47,10 @@ LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
 LL | where
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+help: try adding a `where` bound
+   |
+LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
+   |              +++++++++++++++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/cross_crate_predicate.rs:7:13
@@ -49,12 +58,15 @@ error: unconstrained generic constant
 LL |     let _ = const_evaluatable_lib::test1::<T>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
   --> $DIR/auxiliary/const_evaluatable_lib.rs:3:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
+help: try adding a `where` bound
+   |
+LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
+   |              +++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
index 74111ef1d38..632ece0ddcb 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
@@ -20,7 +20,10 @@ error: unconstrained generic constant
 LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
+   |             ++++++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/dependence_lint.rs:10:9
@@ -28,7 +31,10 @@ error: unconstrained generic constant
 LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
+help: try adding a `where` bound
+   |
+LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
+   |             ++++++++++++++++++++++++++++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/different-fn.stderr b/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
index 83a2f3740b1..52917df0da1 100644
--- a/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/different-fn.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |     [0; size_of::<Foo<T>>()]
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
+help: try adding a `where` bound
+   |
+LL | fn test<T>() -> [u8; size_of::<T>()] where [(); size_of::<Foo<T>>()]: {
+   |                                      ++++++++++++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/failed-to-normalize-ice-issue-88421.rs b/tests/ui/const-generics/generic_const_exprs/failed-to-normalize-ice-issue-88421.rs
new file mode 100644
index 00000000000..3d41eeeff45
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/failed-to-normalize-ice-issue-88421.rs
@@ -0,0 +1,36 @@
+//@ check-pass
+// issue: rust-lang/rust#88421
+#![feature(adt_const_params)]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+use std::ops::Index;
+
+pub struct CellPossibilities;
+
+pub enum CellState<const SQUARE_SIZE: usize> {
+    Empty(Option<CellPossibilities>),
+}
+
+pub struct Sudoku<const SQUARE_SIZE: usize>;
+
+impl<const SQUARE_SIZE: usize> Sudoku<SQUARE_SIZE>where
+    [CellState<SQUARE_SIZE>; SQUARE_SIZE * SQUARE_SIZE]: Sized,
+{
+    pub fn random() {
+        let CellState::Empty(_) = Self[()];
+    }
+}
+
+impl<const SQUARE_SIZE: usize> Index<()> for Sudoku<SQUARE_SIZE>
+where
+    [CellState<SQUARE_SIZE>; SQUARE_SIZE * SQUARE_SIZE]: Sized,
+{
+    type Output = CellState<SQUARE_SIZE>;
+
+    fn index(&self, _: ()) -> &Self::Output {
+        todo!()
+    }
+}
+
+pub fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
index 87e26ce85dc..f27d52a1437 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |         ArrayHolder([0; Self::SIZE])
    |                         ^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); Self::SIZE]:`
+help: try adding a `where` bound
+   |
+LL |     pub const fn new() -> Self where [(); Self::SIZE]: {
+   |                                +++++++++++++++++++++++
 
 error[E0282]: type annotations needed for `ArrayHolder<X>`
   --> $DIR/issue-62504.rs:26:9
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr b/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr
index b693023f125..ca6681b635a 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-83765.stderr
@@ -13,12 +13,15 @@ error: unconstrained generic constant
 LL |         self.reference.size()
    |                        ^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
 note: required by a bound in `TensorSize::size`
   --> $DIR/issue-83765.rs:9:31
    |
 LL |     fn size(&self) -> [usize; Self::DIM];
    |                               ^^^^^^^^^ required by this bound in `TensorSize::size`
+help: try adding a `where` bound
+   |
+LL |     fn size(&self) -> [usize; DIM] where [(); Self::DIM]: {
+   |                                    ++++++++++++++++++++++
 
 error[E0308]: mismatched types
   --> $DIR/issue-83765.rs:32:9
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
index 3acccba026f..4abe39eb598 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -35,7 +35,6 @@ LL |     writes_to_specific_path(&cap);
    |     |
    |     required by a bound introduced by this call
    |
-   = help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
 note: required for `&C` to implement `Contains<(), true>`
   --> $DIR/issue-85848.rs:21:12
    |
@@ -53,6 +52,10 @@ note: required by a bound in `writes_to_specific_path`
    |
 LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
    |                               ^^^^^^^^^^^^^ required by this bound in `writes_to_specific_path`
+help: try adding a `where` bound
+   |
+LL | fn writes_to_path<C>(cap: &C) where [(); { contains::<T, U>() } as usize]: {
+   |                               ++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0308]: mismatched types
   --> $DIR/issue-85848.rs:24:5
diff --git a/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
index 395088bf2f2..c83e859ac79 100644
--- a/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/needs_where_clause.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |   b: [f32; complex_maths::<T>(N)],
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); complex_maths::<T>(N)]:`
+help: try adding a `where` bound
+   |
+LL | struct Example<T, const N: usize> where [(); complex_maths::<T>(N)]: {
+   |                                   ++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
index 4a87649f43d..a2680eac039 100644
--- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |   b: [f32; complex_maths(N)],
    |      ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
+help: try adding a `where` bound
+   |
+LL | pub struct Example<const N: usize> where [(); complex_maths(N)]: {
+   |                                    +++++++++++++++++++++++++++++
 
 error: unconstrained generic constant
   --> $DIR/no_where_clause.rs:18:15
@@ -12,7 +15,10 @@ error: unconstrained generic constant
 LL |       b: [0.; complex_maths(N)],
    |               ^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
+help: try adding a `where` bound
+   |
+LL |   pub fn new() -> Self where [(); complex_maths(N)]: {
+   |                        +++++++++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index 0bf99bb8b26..335130c958f 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -40,7 +40,10 @@ error: unconstrained generic constant
 LL |     bar2::<{ std::ops::Add::add(N, N) }>();
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:`
+help: try adding a `where` bound
+   |
+LL | fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: {
+   |                                                     +++++++++++++++++++++++++++++++++++++++++
 
 error[E0015]: cannot call non-const operator in constants
   --> $DIR/unify-op-with-fn-call.rs:20:39
diff --git a/tests/ui/const-generics/issues/issue-67739.full.stderr b/tests/ui/const-generics/issues/issue-67739.full.stderr
index bdf05023d5f..99368a66148 100644
--- a/tests/ui/const-generics/issues/issue-67739.full.stderr
+++ b/tests/ui/const-generics/issues/issue-67739.full.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |         [0u8; mem::size_of::<Self::Associated>()];
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); mem::size_of::<Self::Associated>()]:`
+help: try adding a `where` bound
+   |
+LL |     fn associated_size(&self) -> usize where [(); mem::size_of::<Self::Associated>()]: {
+   |                                        +++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-71202.stderr b/tests/ui/const-generics/issues/issue-71202.stderr
index 437b808c893..a2d38221852 100644
--- a/tests/ui/const-generics/issues/issue-71202.stderr
+++ b/tests/ui/const-generics/issues/issue-71202.stderr
@@ -10,24 +10,27 @@ LL | |         <IsCopy<T>>::VALUE
 LL | |     } as usize] = [];
    | |_____________________^
    |
-   = help: try adding a `where` bound using this expression: `where [(); 1 - {
-                   trait NotCopy {
-                       const VALUE: bool = false;
-                   }
-           
-                   impl<__Type: ?Sized> NotCopy for __Type {}
-           
-                   struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
-           
-                   impl<__Type> IsCopy<__Type>
-                   where
-                       __Type: Sized + Copy,
-                   {
-                       const VALUE: bool = true;
-                   }
-           
-                   <IsCopy<T>>::VALUE
-               } as usize]:`
+help: try adding a `where` bound
+   |
+LL ~     } as usize] where [(); 1 - {
+LL +         trait NotCopy {
+LL +             const VALUE: bool = false;
+LL +         }
+LL + 
+LL +         impl<__Type: ?Sized> NotCopy for __Type {}
+LL + 
+LL +         struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
+LL + 
+LL +         impl<__Type> IsCopy<__Type>
+LL +         where
+LL +             __Type: Sized + Copy,
+LL +         {
+LL +             const VALUE: bool = true;
+LL +         }
+LL + 
+LL +         <IsCopy<T>>::VALUE
+LL ~     } as usize]: = [];
+   |
 
 error: unconstrained generic constant
   --> $DIR/issue-71202.rs:28:19
@@ -35,24 +38,27 @@ error: unconstrained generic constant
 LL |     } as usize] = [];
    |                   ^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); 1 - {
-                   trait NotCopy {
-                       const VALUE: bool = false;
-                   }
-           
-                   impl<__Type: ?Sized> NotCopy for __Type {}
-           
-                   struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
-           
-                   impl<__Type> IsCopy<__Type>
-                   where
-                       __Type: Sized + Copy,
-                   {
-                       const VALUE: bool = true;
-                   }
-           
-                   <IsCopy<T>>::VALUE
-               } as usize]:`
+help: try adding a `where` bound
+   |
+LL ~     } as usize] where [(); 1 - {
+LL +         trait NotCopy {
+LL +             const VALUE: bool = false;
+LL +         }
+LL + 
+LL +         impl<__Type: ?Sized> NotCopy for __Type {}
+LL + 
+LL +         struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
+LL + 
+LL +         impl<__Type> IsCopy<__Type>
+LL +         where
+LL +             __Type: Sized + Copy,
+LL +         {
+LL +             const VALUE: bool = true;
+LL +         }
+LL + 
+LL +         <IsCopy<T>>::VALUE
+LL ~     } as usize]: = [];
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-84659.fixed b/tests/ui/const-generics/issues/issue-84659.fixed
new file mode 100644
index 00000000000..85f1adc5c19
--- /dev/null
+++ b/tests/ui/const-generics/issues/issue-84659.fixed
@@ -0,0 +1,13 @@
+//@ run-rustfix
+#![allow(incomplete_features, dead_code, unused_braces)]
+#![feature(generic_const_exprs)]
+
+trait Bar<const N: usize> {}
+
+trait Foo<'a> {
+    const N: usize;
+    type Baz: Bar<{ Self::N }> where [(); { Self::N }]:;
+    //~^ ERROR: unconstrained generic constant
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-84659.rs b/tests/ui/const-generics/issues/issue-84659.rs
index 440ca740af2..b2ea6320f73 100644
--- a/tests/ui/const-generics/issues/issue-84659.rs
+++ b/tests/ui/const-generics/issues/issue-84659.rs
@@ -1,4 +1,5 @@
-#![allow(incomplete_features)]
+//@ run-rustfix
+#![allow(incomplete_features, dead_code, unused_braces)]
 #![feature(generic_const_exprs)]
 
 trait Bar<const N: usize> {}
diff --git a/tests/ui/const-generics/issues/issue-84659.stderr b/tests/ui/const-generics/issues/issue-84659.stderr
index 796c5515e04..82e80603c7f 100644
--- a/tests/ui/const-generics/issues/issue-84659.stderr
+++ b/tests/ui/const-generics/issues/issue-84659.stderr
@@ -1,10 +1,13 @@
 error: unconstrained generic constant
-  --> $DIR/issue-84659.rs:8:15
+  --> $DIR/issue-84659.rs:9:15
    |
 LL |     type Baz: Bar<{ Self::N }>;
    |               ^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { Self::N }]:`
+help: try adding a `where` bound
+   |
+LL |     type Baz: Bar<{ Self::N }> where [(); { Self::N }]:;
+   |                                ++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-90455.fixed b/tests/ui/const-generics/issues/issue-90455.fixed
new file mode 100644
index 00000000000..2502d47eb46
--- /dev/null
+++ b/tests/ui/const-generics/issues/issue-90455.fixed
@@ -0,0 +1,13 @@
+//@ run-rustfix
+#![feature(generic_const_exprs, adt_const_params)]
+#![allow(incomplete_features, dead_code)]
+
+struct FieldElement<const N: &'static str> where [(); num_limbs(N)]: {
+    n: [u64; num_limbs(N)],
+    //~^ ERROR unconstrained generic constant
+}
+const fn num_limbs(_: &str) -> usize {
+    0
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-90455.rs b/tests/ui/const-generics/issues/issue-90455.rs
index a580410cf37..794c7d76cb1 100644
--- a/tests/ui/const-generics/issues/issue-90455.rs
+++ b/tests/ui/const-generics/issues/issue-90455.rs
@@ -1,5 +1,6 @@
+//@ run-rustfix
 #![feature(generic_const_exprs, adt_const_params)]
-#![allow(incomplete_features)]
+#![allow(incomplete_features, dead_code)]
 
 struct FieldElement<const N: &'static str> {
     n: [u64; num_limbs(N)],
diff --git a/tests/ui/const-generics/issues/issue-90455.stderr b/tests/ui/const-generics/issues/issue-90455.stderr
index 1db90609572..1fcc08db579 100644
--- a/tests/ui/const-generics/issues/issue-90455.stderr
+++ b/tests/ui/const-generics/issues/issue-90455.stderr
@@ -1,10 +1,13 @@
 error: unconstrained generic constant
-  --> $DIR/issue-90455.rs:5:8
+  --> $DIR/issue-90455.rs:6:8
    |
 LL |     n: [u64; num_limbs(N)],
    |        ^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); num_limbs(N)]:`
+help: try adding a `where` bound
+   |
+LL | struct FieldElement<const N: &'static str> where [(); num_limbs(N)]: {
+   |                                            +++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-needs_drop-monomorphic.stderr b/tests/ui/consts/const-needs_drop-monomorphic.stderr
index 0874a70ce39..446d34810c5 100644
--- a/tests/ui/consts/const-needs_drop-monomorphic.stderr
+++ b/tests/ui/consts/const-needs_drop-monomorphic.stderr
@@ -13,7 +13,10 @@ error: unconstrained generic constant
 LL |     Bool::<{ std::mem::needs_drop::<T>() }>::assert();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); { std::mem::needs_drop::<T>() }]:`
+help: try adding a `where` bound
+   |
+LL | fn f<T>() where [(); { std::mem::needs_drop::<T>() } as usize]: {
+   |           +++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs b/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs
new file mode 100644
index 00000000000..1a22dc2b549
--- /dev/null
+++ b/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs
@@ -0,0 +1,7 @@
+// #83056 ICE "bad input type for cast"
+// issue: rust-lang/rust#83056
+
+struct S([bool; f as usize]);
+fn f() -> T {}
+//~^ ERROR cannot find type `T` in this scope
+pub fn main() {}
diff --git a/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr
new file mode 100644
index 00000000000..115f1688520
--- /dev/null
+++ b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr
@@ -0,0 +1,20 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/ice-bad-input-type-for-cast-83056.rs:5:11
+   |
+LL | struct S([bool; f as usize]);
+   | ----------------------------- similarly named struct `S` defined here
+LL | fn f() -> T {}
+   |           ^
+   |
+help: a struct with a similar name exists
+   |
+LL | fn f() -> S {}
+   |           ~
+help: you might be missing a type parameter
+   |
+LL | fn f<T>() -> T {}
+   |     +++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr
index 02d3390496a..41aa2d63af0 100644
--- a/tests/ui/coroutine/clone-rpit.next.stderr
+++ b/tests/ui/coroutine/clone-rpit.next.stderr
@@ -14,11 +14,6 @@ note: ...which requires promoting constants in MIR for `foo::{closure#0}`...
    |
 LL |     move |_: ()| {
    |     ^^^^^^^^^^^^
-note: ...which requires preparing `foo::{closure#0}` for borrow checking...
-  --> $DIR/clone-rpit.rs:14:5
-   |
-LL |     move |_: ()| {
-   |     ^^^^^^^^^^^^
 note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls...
   --> $DIR/clone-rpit.rs:14:5
    |
diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs
new file mode 100644
index 00000000000..bba7190d43d
--- /dev/null
+++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs
@@ -0,0 +1,16 @@
+// test for ICE when casting extern "C" fn when it has a non-FFI-safe argument
+// issue: rust-lang/rust#52334
+//@ check-pass
+//@ normalize-stderr-test "\[i8\]" -> "[i8 or u8 (arch dependant)]"
+//@ normalize-stderr-test "\[u8\]" -> "[i8 or u8 (arch dependant)]"
+
+type Foo = extern "C" fn(::std::ffi::CStr);
+//~^ WARN `extern` fn uses type
+extern "C" {
+    fn meh(blah: Foo);
+    //~^ WARN `extern` block uses type
+}
+
+fn main() {
+    meh as usize;
+}
diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
new file mode 100644
index 00000000000..83492988479
--- /dev/null
+++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
@@ -0,0 +1,22 @@
+warning: `extern` fn uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
+  --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12
+   |
+LL | type Foo = extern "C" fn(::std::ffi::CStr);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
+   = note: `#[warn(improper_ctypes_definitions)]` on by default
+
+warning: `extern` block uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
+  --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18
+   |
+LL |     fn meh(blah: Foo);
+   |                  ^^^ not FFI-safe
+   |
+   = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
+   = note: `#[warn(improper_ctypes)]` on by default
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/extern/extern-C-str-arg-ice-80125.rs b/tests/ui/extern/extern-C-str-arg-ice-80125.rs
new file mode 100644
index 00000000000..0908d6199ef
--- /dev/null
+++ b/tests/ui/extern/extern-C-str-arg-ice-80125.rs
@@ -0,0 +1,15 @@
+// issue: rust-lang/rust#80125
+//@ check-pass
+type ExternCallback = extern "C" fn(*const u8, u32, str);
+//~^ WARN `extern` fn uses type `str`, which is not FFI-safe
+
+pub struct Struct(ExternCallback);
+
+#[no_mangle]
+pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
+//~^ WARN `extern` fn uses type `str`, which is not FFI-safe
+//~^^ WARN `extern` fn uses type `Struct`, which is not FFI-safe
+    Struct(bind)
+}
+
+fn main() {}
diff --git a/tests/ui/extern/extern-C-str-arg-ice-80125.stderr b/tests/ui/extern/extern-C-str-arg-ice-80125.stderr
new file mode 100644
index 00000000000..ebd6cec6ecd
--- /dev/null
+++ b/tests/ui/extern/extern-C-str-arg-ice-80125.stderr
@@ -0,0 +1,35 @@
+warning: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/extern-C-str-arg-ice-80125.rs:3:23
+   |
+LL | type ExternCallback = extern "C" fn(*const u8, u32, str);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+   = note: `#[warn(improper_ctypes_definitions)]` on by default
+
+warning: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/extern-C-str-arg-ice-80125.rs:9:44
+   |
+LL | pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
+   |                                            ^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+
+warning: `extern` fn uses type `Struct`, which is not FFI-safe
+  --> $DIR/extern-C-str-arg-ice-80125.rs:9:63
+   |
+LL | pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
+   |                                                               ^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: the type is defined here
+  --> $DIR/extern-C-str-arg-ice-80125.rs:6:1
+   |
+LL | pub struct Struct(ExternCallback);
+   | ^^^^^^^^^^^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.fixed b/tests/ui/generic-const-items/evaluatable-bounds.fixed
new file mode 100644
index 00000000000..de1baffbcdb
--- /dev/null
+++ b/tests/ui/generic-const-items/evaluatable-bounds.fixed
@@ -0,0 +1,25 @@
+// This is a regression test for issue #104400.
+
+//@ run-rustfix
+
+// Test that we can constrain generic const items that appear inside associated consts by
+// adding a (makeshift) "evaluatable"-bound to the item, after applying the suggestion.
+
+#![feature(generic_const_items, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+    const LEN: usize;
+
+    const ARRAY: [i32; Self::LEN] where [(); Self::LEN]:; //~ ERROR unconstrained generic constant
+
+}
+
+impl Trait for () {
+    const LEN: usize = 2;
+    const ARRAY: [i32; Self::LEN] = [360, 720];
+}
+
+fn main() {
+    let [_, _] = <() as Trait>::ARRAY;
+}
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.rs b/tests/ui/generic-const-items/evaluatable-bounds.rs
index 1a858f41999..b47801360f9 100644
--- a/tests/ui/generic-const-items/evaluatable-bounds.rs
+++ b/tests/ui/generic-const-items/evaluatable-bounds.rs
@@ -1,10 +1,9 @@
 // This is a regression test for issue #104400.
 
-//@ revisions: unconstrained constrained
-//@[constrained] check-pass
+//@ run-rustfix
 
 // Test that we can constrain generic const items that appear inside associated consts by
-// adding a (makeshift) "evaluatable"-bound to the item.
+// adding a (makeshift) "evaluatable"-bound to the item, after applying the suggestion.
 
 #![feature(generic_const_items, generic_const_exprs)]
 #![allow(incomplete_features)]
@@ -12,13 +11,8 @@
 trait Trait {
     const LEN: usize;
 
-    #[cfg(unconstrained)]
-    const ARRAY: [i32; Self::LEN]; //[unconstrained]~ ERROR unconstrained generic constant
+    const ARRAY: [i32; Self::LEN]; //~ ERROR unconstrained generic constant
 
-    #[cfg(constrained)]
-    const ARRAY: [i32; Self::LEN]
-    where
-        [(); Self::LEN]:;
 }
 
 impl Trait for () {
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.stderr b/tests/ui/generic-const-items/evaluatable-bounds.stderr
new file mode 100644
index 00000000000..ca26d633658
--- /dev/null
+++ b/tests/ui/generic-const-items/evaluatable-bounds.stderr
@@ -0,0 +1,13 @@
+error: unconstrained generic constant
+  --> $DIR/evaluatable-bounds.rs:14:5
+   |
+LL |     const ARRAY: [i32; Self::LEN];
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try adding a `where` bound
+   |
+LL |     const ARRAY: [i32; Self::LEN] where [(); Self::LEN]:;
+   |                                   ++++++++++++++++++++++
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr b/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr
index 1475d988ea4..b6f9bdce1cb 100644
--- a/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr
+++ b/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     const ARRAY: [i32; Self::LEN];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); Self::LEN]:`
+help: try adding a `where` bound
+   |
+LL |     const ARRAY: [i32; Self::LEN] where [(); Self::LEN]:;
+   |                                   ++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/panics/panic-in-message-fmt.run.stderr b/tests/ui/panics/panic-in-message-fmt.run.stderr
index c3a5733c8ae..46829c33a54 100644
--- a/tests/ui/panics/panic-in-message-fmt.run.stderr
+++ b/tests/ui/panics/panic-in-message-fmt.run.stderr
@@ -1,2 +1,3 @@
 panicked at $DIR/panic-in-message-fmt.rs:18:9:
+not yet implemented
 thread panicked while processing panic. aborting.
diff --git a/tests/ui/polymorphization/ice-poly-with-mir-opts-90192.rs b/tests/ui/polymorphization/ice-poly-with-mir-opts-90192.rs
new file mode 100644
index 00000000000..4557c7e517c
--- /dev/null
+++ b/tests/ui/polymorphization/ice-poly-with-mir-opts-90192.rs
@@ -0,0 +1,20 @@
+// issue: rust-lang/rust#90192
+// ICE assertion failed: matches!(ty.kind(), ty :: Param(_))
+//@ compile-flags:-Zpolymorphize=on -Zmir-opt-level=3
+//@ build-pass
+
+fn test<T>() {
+    std::mem::size_of::<T>();
+}
+
+pub fn foo<T>(_: T) -> &'static fn() {
+    &(test::<T> as fn())
+}
+
+fn outer<T>() {
+    foo(|| ());
+}
+
+fn main() {
+    outer::<u8>();
+}
diff --git a/tests/ui/privacy/decl-macro-infinite-global-import-cycle-ice-64784.rs b/tests/ui/privacy/decl-macro-infinite-global-import-cycle-ice-64784.rs
new file mode 100644
index 00000000000..72b1ea7ccc8
--- /dev/null
+++ b/tests/ui/privacy/decl-macro-infinite-global-import-cycle-ice-64784.rs
@@ -0,0 +1,16 @@
+// ICE #64784  already borrowed: BorrowMutError
+//@ check-pass
+// issue: rust-lang/rust#64784
+#![feature(decl_macro)]
+
+pub macro m($i:ident, $j:ident) {
+    mod $i {
+        pub use crate::$j::*;
+        pub struct A;
+    }
+}
+
+m!(x, y);
+m!(y, x);
+
+fn main() {}
diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs
new file mode 100644
index 00000000000..58297c92693
--- /dev/null
+++ b/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs
@@ -0,0 +1,6 @@
+//@ aux-crate:priv:foo=foo.rs
+//@ compile-flags: -Zunstable-options
+
+#![crate_type = "rlib"]
+extern crate foo;
+pub struct Bar(pub i32);
diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs
new file mode 100644
index 00000000000..6fd950619e6
--- /dev/null
+++ b/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs
@@ -0,0 +1,2 @@
+#![crate_type = "rlib"]
+pub struct Foo(pub i32);
diff --git a/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs
new file mode 100644
index 00000000000..d7ade7f0e96
--- /dev/null
+++ b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs
@@ -0,0 +1,12 @@
+//@ aux-build: bar.rs
+//@ aux-build: foo.rs
+//@ build-pass
+
+#![deny(exported_private_dependencies)]
+
+// Ensure the libbar.rlib is loaded first. If the command line parameter `--extern foo` does not
+// exist, previus version would fail to compile
+#![crate_type = "rlib"]
+extern crate bar;
+extern crate foo;
+pub fn baz() -> (Option<foo::Foo>, Option<bar::Bar>) { (None, None) }
diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr
index b2d20af883a..98cad18d442 100644
--- a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr
+++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr
@@ -18,8 +18,8 @@ LL | struct Dealigned<T>(u8, T);
    |
    = Box<dyn Any>
 query stack during panic:
-#0 [mir_const] preparing `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq` for borrow checking
-#1 [mir_promoted] promoting constants in MIR for `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq`
+#0 [mir_built] building MIR for `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq`
+#1 [check_unsafety] unsafety-checking `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq`
 end of query stack
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr
index 507e5867c90..4e716704610 100644
--- a/tests/ui/resolve/proc_macro_generated_packed.stderr
+++ b/tests/ui/resolve/proc_macro_generated_packed.stderr
@@ -9,8 +9,8 @@ LL | struct Dealigned<T>(u8, T);
    |
    = Box<dyn Any>
 query stack during panic:
-#0 [mir_const] preparing `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq` for borrow checking
-#1 [mir_promoted] promoting constants in MIR for `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq`
+#0 [mir_built] building MIR for `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq`
+#1 [check_unsafety] unsafety-checking `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq`
 end of query stack
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/sanitizer/cfi-complex-receiver.rs b/tests/ui/sanitizer/cfi-complex-receiver.rs
new file mode 100644
index 00000000000..c3e59258db2
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-complex-receiver.rs
@@ -0,0 +1,42 @@
+// Check that more complex receivers work:
+// * Arc<dyn Foo> as for custom receivers
+// * &dyn Bar<T=Baz> for type constraints
+
+//@ needs-sanitizer-cfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
+//@ run-pass
+
+use std::sync::Arc;
+
+trait Foo {
+    fn foo(self: Arc<Self>);
+}
+
+struct FooImpl;
+
+impl Foo for FooImpl {
+    fn foo(self: Arc<Self>) {}
+}
+
+trait Bar {
+    type T;
+    fn bar(&self) -> Self::T;
+}
+
+struct BarImpl;
+
+impl Bar for BarImpl {
+    type T = i32;
+    fn bar(&self) -> Self::T { 7 }
+}
+
+fn main() {
+    let foo: Arc<dyn Foo> = Arc::new(FooImpl);
+    foo.foo();
+
+    let bar: &dyn Bar<T=i32> = &BarImpl;
+    assert_eq!(bar.bar(), 7);
+}
diff --git a/tests/ui/sanitizer/cfi-drop-no-principal.rs b/tests/ui/sanitizer/cfi-drop-no-principal.rs
new file mode 100644
index 00000000000..c1c88c8c71c
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-drop-no-principal.rs
@@ -0,0 +1,21 @@
+// Check that dropping a trait object without a principal trait succeeds
+
+//@ needs-sanitizer-cfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries works
+//@ only-linux
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
+// FIXME(#118761) Should be run-pass once the labels on drop are compatible.
+// This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the
+// callsite for a drop, but the vtable doesn't have the correct label yet.
+//@ build-pass
+
+struct CustomDrop;
+
+impl Drop for CustomDrop {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    let _ = Box::new(CustomDrop) as Box<dyn Send>;
+}
diff --git a/tests/ui/sanitizer/cfi-self-ref.rs b/tests/ui/sanitizer/cfi-self-ref.rs
new file mode 100644
index 00000000000..32d0b100702
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-self-ref.rs
@@ -0,0 +1,33 @@
+// Check that encoding self-referential types works with #[repr(transparent)]
+
+//@ needs-sanitizer-cfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
+//@ run-pass
+
+use std::marker::PhantomData;
+
+struct X<T> {
+    _x: u8,
+    p: PhantomData<T>,
+}
+
+#[repr(transparent)]
+struct Y(X<Y>);
+
+trait Fooable {
+    fn foo(&self, y: Y);
+}
+
+struct Bar;
+
+impl Fooable for Bar {
+    fn foo(&self, _: Y) {}
+}
+
+fn main() {
+    let x = &Bar as &dyn Fooable;
+    x.foo(Y(X {_x: 0, p: PhantomData}));
+}
diff --git a/tests/ui/sanitizer/cfi-virtual-auto.rs b/tests/ui/sanitizer/cfi-virtual-auto.rs
new file mode 100644
index 00000000000..7a0c246a412
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-virtual-auto.rs
@@ -0,0 +1,22 @@
+// Tests that calling a trait object method on a trait object with additional auto traits works.
+
+//@ needs-sanitizer-cfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
+//@ run-pass
+
+trait Foo {
+    fn foo(&self);
+}
+
+struct Bar;
+impl Foo for Bar {
+    fn foo(&self) {}
+}
+
+pub fn main() {
+    let x: &(dyn Foo + Send) = &Bar;
+    x.foo();
+}
diff --git a/tests/ui/simd/array-trait.stderr b/tests/ui/simd/array-trait.stderr
index 16ff732396d..a63dbf37959 100644
--- a/tests/ui/simd/array-trait.stderr
+++ b/tests/ui/simd/array-trait.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    |                       ^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
+help: try adding a `where` bound
+   |
+LL | pub struct T<S: Simd>([S::Lane; S::SIZE]) where [(); S::SIZE]:;
+   |                                           ++++++++++++++++++++
 
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
   --> $DIR/array-trait.rs:23:1
@@ -20,7 +23,6 @@ LL | #[derive(Copy, Clone)]
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    |                       ^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
new file mode 100644
index 00000000000..3f8011d961a
--- /dev/null
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
@@ -0,0 +1,25 @@
+error[E0391]: cycle detected when computing layout of `Foo`
+   |
+   = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
+   = note: ...which again requires computing layout of `Foo`, completing the cycle
+note: cycle used when const-evaluating + checking `_`
+  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
+   |
+   = note: the raw bytes of the constant (size: 4, align: 4) {
+               00 00 00 00                                     │ ....
+           }
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
new file mode 100644
index 00000000000..04e2c4483bf
--- /dev/null
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
@@ -0,0 +1,25 @@
+error[E0391]: cycle detected when computing layout of `Foo`
+   |
+   = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
+   = note: ...which again requires computing layout of `Foo`, completing the cycle
+note: cycle used when const-evaluating + checking `_`
+  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
+   |
+   = note: the raw bytes of the constant (size: 8, align: 8) {
+               00 00 00 00 00 00 00 00                         │ ........
+           }
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.rs b/tests/ui/sized/stack-overflow-trait-infer-98842.rs
new file mode 100644
index 00000000000..54d50346cc8
--- /dev/null
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.rs
@@ -0,0 +1,18 @@
+// #98842 stack overflow in trait inference
+// issue: rust-lang/rust#98842
+//@ check-fail
+//@ edition:2021
+//@ stderr-per-bitwidth
+//@ ignore-endian-big
+//~^^^^^^ ERROR cycle detected when computing layout of `Foo`
+
+// If the inner `Foo` is named through an associated type,
+// the "infinite size" error does not occur.
+struct Foo(<&'static Foo as ::core::ops::Deref>::Target);
+// But Rust will be unable to know whether `Foo` is sized or not,
+// and it will infinitely recurse somewhere trying to figure out the
+// size of this pointer (is my guess):
+const _: *const Foo = 0 as _;
+//~^ ERROR it is undefined behavior to use this value
+
+pub fn main() {}
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr
new file mode 100644
index 00000000000..8ddddeb5bf2
--- /dev/null
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.stderr
@@ -0,0 +1,25 @@
+error[E0391]: cycle detected when computing layout of `Foo`
+   |
+   = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
+   = note: ...which again requires computing layout of `Foo`, completing the cycle
+note: cycle used when const-evaluating + checking `_`
+  --> $DIR/stack-overflow-trait-infer-98842.rs:13:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/stack-overflow-trait-infer-98842.rs:13:1
+   |
+LL | const _: *const Foo = 0 as _;
+   | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
+   |
+   = note: the raw bytes of the constant (size: 8, align: 8) {
+               00 00 00 00 00 00 00 00                         │ ........
+           }
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/specialization/issue-51892.stderr b/tests/ui/specialization/issue-51892.stderr
index 9553a04c8f6..b1cabc0ac0e 100644
--- a/tests/ui/specialization/issue-51892.stderr
+++ b/tests/ui/specialization/issue-51892.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<<T as Trait>::Type>()]:`
+help: try adding a `where` bound
+   |
+LL |     type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()] where [(); std::mem::size_of::<<T as Trait>::Type>()]:;
+   |                                                                 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index df466609a12..084008d8b2a 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -34,11 +34,6 @@ note: ...which requires const checking `Alpha::V3::{constant#0}`...
    |
 LL |     V3 = Self::V1 {} as u8 + 2,
    |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `Alpha::V3::{constant#0}` for borrow checking...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires building MIR for `Alpha::V3::{constant#0}`...
   --> $DIR/self-in-enum-definition.rs:5:10
    |
diff --git a/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs
new file mode 100644
index 00000000000..be743e8e270
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs
@@ -0,0 +1,28 @@
+//@ check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::ops::Deref;
+
+trait Trait {}
+impl<A, B> Trait for (A, B, u8) where A: Deref, B: Deref<Target = A::Target>, {}
+impl<A, B> Trait for (A, B, i8) {}
+
+type TaitSized = impl Sized;
+fn def_tait1() -> TaitSized {}
+
+type TaitCopy = impl Copy;
+fn def_tait2() -> TaitCopy {}
+
+fn impl_trait<T: Trait> () {}
+
+fn test() {
+    impl_trait::<(&TaitSized, &TaitCopy, _)>();
+    impl_trait::<(&TaitCopy, &TaitSized, _)>();
+
+    impl_trait::<(&TaitCopy, &String, _)>();
+    impl_trait::<(&TaitSized, &String, _)>();
+}
+
+fn main() {}
diff --git a/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.rs b/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.rs
new file mode 100644
index 00000000000..ec475673d0d
--- /dev/null
+++ b/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.rs
@@ -0,0 +1,21 @@
+// ICE size_and_align_of::<[closure@test.rs:15:5: 17:7]> not supported #88212
+// issue: rust-lang/rust#88212
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait Example {}
+struct Foo();
+
+impl Example for Foo {}
+
+fn example() -> Box<dyn Example> {
+    Box::new(Foo())
+}
+
+fn main() {
+    let x: dyn Example = *example();
+    (move || {
+        let _y = x;
+        //~^ ERROR the size for values of type `dyn Example` cannot be known at compilation time
+    })();
+}
diff --git a/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.stderr b/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.stderr
new file mode 100644
index 00000000000..a0253ac1f35
--- /dev/null
+++ b/tests/ui/unsized-locals/ice-size_and_align_of-closure-not-supported-88212.stderr
@@ -0,0 +1,23 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:3:12
+   |
+LL | #![feature(unsized_locals)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `dyn Example` cannot be known at compilation time
+  --> $DIR/ice-size_and_align_of-closure-not-supported-88212.rs:18:18
+   |
+LL |     (move || {
+   |           -- this closure captures all values by move
+LL |         let _y = x;
+   |                  ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Example`
+   = note: all values captured by value by a closure must have a statically known size
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/variance/variance-associated-consts.stderr b/tests/ui/variance/variance-associated-consts.stderr
index f41574ca3a3..b955a7686c2 100644
--- a/tests/ui/variance/variance-associated-consts.stderr
+++ b/tests/ui/variance/variance-associated-consts.stderr
@@ -4,7 +4,10 @@ error: unconstrained generic constant
 LL |     field: [u8; <T as Trait>::Const]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try adding a `where` bound using this expression: `where [(); <T as Trait>::Const]:`
+help: try adding a `where` bound
+   |
+LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: {
+   |                      ++++++++++++++++++++++++++++++++
 
 error: [o]
   --> $DIR/variance-associated-consts.rs:13:1
diff --git a/triagebot.toml b/triagebot.toml
index 2bcc77ae433..a42bafe148c 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -775,7 +775,6 @@ compiler-team = [
 compiler-team-contributors = [
     "@TaKO8Ki",
     "@Nadrieril",
-    "@nnethercote",
     "@fmease",
     "@fee1-dead",
 ]
@@ -831,17 +830,14 @@ parser = [
     "@compiler-errors",
     "@davidtwco",
     "@estebank",
-    "@nnethercote",
     "@petrochenkov",
     "@spastorino",
 ]
 lexer = [
-    "@nnethercote",
     "@petrochenkov",
     "@estebank",
 ]
 arena = [
-    "@nnethercote",
     "@spastorino",
 ]
 mir = [