about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-07-10 10:16:05 +0200
committerRalf Jung <post@ralfj.de>2023-07-10 10:16:05 +0200
commita3fdf75d126a02da4c27fd9e1cc16bdc93a5f133 (patch)
tree5803fda00e2ed5bfbff938e19453324144075fa4
parentd4034a2035d67637e044876c1e5801ef68d29889 (diff)
parent743333f3dd90721461c09387ec73d09c080d5f5f (diff)
downloadrust-a3fdf75d126a02da4c27fd9e1cc16bdc93a5f133.tar.gz
rust-a3fdf75d126a02da4c27fd9e1cc16bdc93a5f133.zip
Merge from rustc
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--Cargo.lock455
-rw-r--r--Cargo.toml1
-rw-r--r--README.md29
-rw-r--r--RELEASES.md143
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs14
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs22
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs29
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs16
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs2
-rw-r--r--compiler/rustc_driver/Cargo.toml3
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs4
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs6
-rw-r--r--compiler/rustc_middle/src/thir.rs9
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs16
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/category.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs10
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs64
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs2
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs2
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs12
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs44
-rw-r--r--compiler/rustc_session/src/config.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs36
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs36
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs66
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs20
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs4
-rw-r--r--config.example.toml14
-rw-r--r--library/core/src/default.rs45
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/std/src/f32.rs5
-rw-r--r--library/std/src/f64.rs35
-rw-r--r--library/std/src/io/copy.rs81
-rw-r--r--library/std/src/io/copy/tests.rs38
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/sys/mod.rs50
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs (renamed from library/std/src/personality/dwarf/eh.rs)0
-rw-r--r--library/std/src/sys/personality/dwarf/mod.rs (renamed from library/std/src/personality/dwarf/mod.rs)0
-rw-r--r--library/std/src/sys/personality/dwarf/tests.rs (renamed from library/std/src/personality/dwarf/tests.rs)0
-rw-r--r--library/std/src/sys/personality/emcc.rs (renamed from library/std/src/personality/emcc.rs)0
-rw-r--r--library/std/src/sys/personality/gcc.rs (renamed from library/std/src/personality/gcc.rs)0
-rw-r--r--library/std/src/sys/personality/mod.rs (renamed from library/std/src/personality.rs)0
-rw-r--r--src/bootstrap/Cargo.lock4
-rw-r--r--src/bootstrap/builder.rs1
-rw-r--r--src/bootstrap/compile.rs43
-rw-r--r--src/bootstrap/config.rs73
-rw-r--r--src/bootstrap/config/tests.rs5
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/llvm.rs2
-rw-r--r--src/bootstrap/metrics.rs98
-rw-r--r--src/bootstrap/render_tests.rs6
-rw-r--r--src/bootstrap/test.rs12
-rw-r--r--src/bootstrap/tool.rs1
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile7
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile6
-rw-r--r--src/ci/github-actions/ci.yml4
-rwxr-xr-xsrc/ci/stage-build.py1035
-rw-r--r--src/doc/unstable-book/src/library-features/default-free-fn.md47
-rw-r--r--src/tools/build_helper/Cargo.toml2
-rw-r--r--src/tools/build_helper/src/lib.rs1
-rw-r--r--src/tools/build_helper/src/metrics.rs92
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs10
-rw-r--r--src/tools/clippy/tests/ui/to_string_in_format_args_incremental.rs9
-rw-r--r--src/tools/clippy/tests/ui/to_string_in_format_args_incremental.stderr10
-rw-r--r--src/tools/compiletest/src/header.rs13
-rw-r--r--src/tools/compiletest/src/runtest.rs78
-rw-r--r--src/tools/compiletest/src/runtest/debugger.rs148
-rw-r--r--src/tools/miri/tests/fail/overlapping_assignment.rs23
-rw-r--r--src/tools/miri/tests/fail/overlapping_assignment.stderr20
-rw-r--r--src/tools/opt-dist/Cargo.toml22
-rw-r--r--src/tools/opt-dist/README.md7
-rw-r--r--src/tools/opt-dist/src/environment/linux.rs54
-rw-r--r--src/tools/opt-dist/src/environment/mod.rs75
-rw-r--r--src/tools/opt-dist/src/environment/windows.rs78
-rw-r--r--src/tools/opt-dist/src/exec.rs169
-rw-r--r--src/tools/opt-dist/src/main.rs175
-rw-r--r--src/tools/opt-dist/src/metrics.rs106
-rw-r--r--src/tools/opt-dist/src/tests.rs101
-rw-r--r--src/tools/opt-dist/src/timer.rs167
-rw-r--r--src/tools/opt-dist/src/training.rs202
-rw-r--r--src/tools/opt-dist/src/utils/io.rs48
-rw-r--r--src/tools/opt-dist/src/utils/mod.rs36
-rw-r--r--src/tools/tidy/src/deps.rs4
-rw-r--r--src/tools/tidy/src/pal.rs4
-rw-r--r--src/version2
-rw-r--r--tests/assembly/stack-protector/stack-protector-heuristics-effect.rs1
-rw-r--r--tests/assembly/wasm_exceptions.rs60
-rw-r--r--tests/codegen/array-codegen.rs6
-rw-r--r--tests/codegen/avr/avr-func-addrspace.rs2
-rw-r--r--tests/codegen/consts.rs5
-rw-r--r--tests/codegen/enum-match.rs2
-rw-r--r--tests/codegen/fewer-names.rs4
-rw-r--r--tests/codegen/function-arguments-noopt.rs4
-rw-r--r--tests/codegen/function-arguments.rs2
-rw-r--r--tests/codegen/intrinsics/transmute-niched.rs16
-rw-r--r--tests/codegen/intrinsics/transmute-x64.rs12
-rw-r--r--tests/codegen/intrinsics/transmute.rs90
-rw-r--r--tests/codegen/match-optimized.rs6
-rw-r--r--tests/codegen/mem-replace-big-type.rs2
-rw-r--r--tests/codegen/mem-replace-simple-type.rs2
-rw-r--r--tests/codegen/repeat-trusted-len.rs4
-rw-r--r--tests/codegen/repr-transparent-aggregates-1.rs1
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs2
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs166
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs7
-rw-r--r--tests/codegen/simd_arith_offset.rs2
-rw-r--r--tests/codegen/slice-iter-len-eq-zero.rs8
-rw-r--r--tests/codegen/transmute-scalar.rs20
-rw-r--r--tests/codegen/uninit-consts.rs11
-rw-r--r--tests/codegen/union-abi.rs2
-rw-r--r--tests/codegen/var-names.rs4
-rw-r--r--tests/codegen/wasm_exceptions.rs51
-rw-r--r--tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir26
-rw-r--r--tests/mir-opt/building/issue_110508.rs13
-rw-r--r--tests/mir-opt/building/issue_110508.{impl#0}-BAR.built.after.mir14
-rw-r--r--tests/mir-opt/building/issue_110508.{impl#0}-SELF_BAR.built.after.mir14
-rw-r--r--tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir4
-rw-r--r--tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir2
-rw-r--r--tests/mir-opt/casts.roundtrip.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff2
-rw-r--r--tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff2
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff2
-rw-r--r--tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff6
-rw-r--r--tests/run-coverage/uses_crate.coverage4
-rw-r--r--tests/run-coverage/uses_crate.rs4
-rw-r--r--tests/run-coverage/uses_inline_crate.coverage4
-rw-r--r--tests/run-coverage/uses_inline_crate.rs4
-rw-r--r--tests/run-make/wasm-exceptions-nostd/Makefile12
-rw-r--r--tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs67
-rw-r--r--tests/run-make/wasm-exceptions-nostd/src/lib.rs60
-rw-r--r--tests/run-make/wasm-exceptions-nostd/src/logging.rs9
-rw-r--r--tests/run-make/wasm-exceptions-nostd/src/panicking.rs29
-rw-r--r--tests/run-make/wasm-exceptions-nostd/verify.mjs75
-rw-r--r--tests/rustdoc-gui/sidebar-source-code.goml12
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs36
-rw-r--r--tests/ui/async-await/in-trait/async-associated-types2.rs30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.current.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.next.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.rs23
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs13
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr18
-rw-r--r--tests/ui/binop/binop-mul-i32-f32.stderr4
-rw-r--r--tests/ui/binop/shift-various-bad-types.stderr48
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-1.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-2.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-4.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-6.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-8.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-arg-invalid-9.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg-empty-codemap.rs2
-rw-r--r--tests/ui/const-generics/exhaustive-value.stderr14
-rw-r--r--tests/ui/const-generics/generic_arg_infer/issue-91614.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-67185-2.stderr12
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3b.stderr4
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4b.stderr4
-rw-r--r--tests/ui/consts/const_in_pattern/issue-73431.rs1
-rw-r--r--tests/ui/consts/missing-larger-array-impl.rs9
-rw-r--r--tests/ui/consts/missing-larger-array-impl.stderr20
-rw-r--r--tests/ui/consts/too_generic_eval_ice.stderr12
-rw-r--r--tests/ui/deriving/issue-103157.stderr10
-rw-r--r--tests/ui/diagnostic-flags/colored-session-opt-error.rs4
-rw-r--r--tests/ui/diagnostic-flags/colored-session-opt-error.stderr2
-rw-r--r--tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr4
-rw-r--r--tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr4
-rw-r--r--tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr16
-rw-r--r--tests/ui/dyn-star/param-env-region-infer.current.stderr2
-rw-r--r--tests/ui/dyn-star/param-env-region-infer.next.stderr29
-rw-r--r--tests/ui/dyn-star/param-env-region-infer.rs6
-rw-r--r--tests/ui/fmt/ifmt-unimpl.stderr16
-rw-r--r--tests/ui/impl-trait/equality.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs19
-rw-r--r--tests/ui/impl-trait/reveal-during-codegen.rs11
-rw-r--r--tests/ui/issues/issue-11771.stderr32
-rw-r--r--tests/ui/issues/issue-24352.stderr4
-rw-r--r--tests/ui/issues/issue-32709.stderr2
-rw-r--r--tests/ui/issues/issue-50582.stderr16
-rw-r--r--tests/ui/issues/issue-67552.rs1
-rw-r--r--tests/ui/issues/issue-67552.stderr4
-rw-r--r--tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr2
-rw-r--r--tests/ui/iterators/invalid-iterator-chain.stderr10
-rw-r--r--tests/ui/mismatched_types/binops.stderr72
-rw-r--r--tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr2
-rw-r--r--tests/ui/never_type/issue-13352.stderr4
-rw-r--r--tests/ui/nll/user-annotations/normalization-2.stderr2
-rw-r--r--tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr50
-rw-r--r--tests/ui/numbers-arithmetic/suggest-float-literal.stderr32
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.stderr18
-rw-r--r--tests/ui/on-unimplemented/slice-index.stderr2
-rw-r--r--tests/ui/on-unimplemented/sum.stderr4
-rw-r--r--tests/ui/pattern/issue-110508.rs38
-rw-r--r--tests/ui/range/range-1.stderr8
-rw-r--r--tests/ui/recursion/issue-95134.rs1
-rw-r--r--tests/ui/resolve/issue-2356.stderr21
-rw-r--r--tests/ui/span/multiline-span-simple.stderr4
-rw-r--r--tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr2
-rw-r--r--tests/ui/suggestions/into-str.stderr8
-rw-r--r--tests/ui/suggestions/issue-71394-no-from-impl.stderr8
-rw-r--r--tests/ui/thir-print/thir-flat-const-variant.rs18
-rw-r--r--tests/ui/thir-print/thir-flat-const-variant.stdout399
-rw-r--r--tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr6
-rw-r--r--tests/ui/traits/new-solver/slice-match-byte-lit.rs2
-rw-r--r--tests/ui/traits/new-solver/slice-match-byte-lit.stderr11
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr6
-rw-r--r--tests/ui/try-trait/option-to-result.stderr2
-rw-r--r--tests/ui/try-trait/try-on-option.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr2
-rw-r--r--tests/ui/type/type-check-defaults.stderr4
-rw-r--r--tests/ui/typeck/issue-81293.stderr4
-rw-r--r--tests/ui/typeck/issue-90101.stderr2
-rw-r--r--tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr8
-rw-r--r--triagebot.toml4
286 files changed, 4466 insertions, 2290 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3766adf7943..3929b064c26 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,7 +31,7 @@ defaults:
   run:
     shell: bash
 concurrency:
-  group: "${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}"
+  group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}"
   cancel-in-progress: true
 jobs:
   pr:
@@ -408,7 +408,7 @@ jobs:
           - name: dist-x86_64-msvc
             env:
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc --enable-full-tools --enable-profiler"
-              SCRIPT: PGO_HOST=x86_64-pc-windows-msvc python src/ci/stage-build.py python x.py dist bootstrap --include-default-paths
+              SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist python x.py dist bootstrap --include-default-paths
               DIST_REQUIRE_ALL_TOOLS: 1
             os: windows-2019-8core-32gb
           - name: dist-i686-msvc
diff --git a/Cargo.lock b/Cargo.lock
index ee10067e6db..96eda77abb2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -172,6 +172,9 @@ name = "anyhow"
 version = "1.0.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+dependencies = [
+ "backtrace",
+]
 
 [[package]]
 name = "ar_archive_writer"
@@ -259,6 +262,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "base64"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
+
+[[package]]
 name = "basic-toml"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -328,6 +337,10 @@ dependencies = [
 [[package]]
 name = "build_helper"
 version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
 
 [[package]]
 name = "bump-stage0"
@@ -686,6 +699,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
 name = "core-foundation-sys"
 version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -986,6 +1009,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
 name = "env_logger"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1175,6 +1207,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
 name = "form_urlencoded"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1200,6 +1247,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
 
 [[package]]
+name = "fs_extra"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
+
+[[package]]
 name = "futf"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1397,6 +1450,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "h2"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap 1.9.3",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
 name = "handlebars"
 version = "4.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1495,6 +1567,49 @@ dependencies = [
 ]
 
 [[package]]
+name = "http"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "humansize"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
+dependencies = [
+ "libm 0.2.7",
+]
+
+[[package]]
 name = "humantime"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1510,6 +1625,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
+name = "hyper"
+version = "0.14.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
+[[package]]
 name = "iana-time-zone"
 version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1718,13 +1870,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "ipnet"
+version = "2.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
+
+[[package]]
 name = "is-terminal"
 version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
 dependencies = [
  "hermit-abi 0.3.1",
- "rustix 0.38.1",
+ "rustix 0.38.2",
  "windows-sys 0.48.0",
 ]
 
@@ -1867,6 +2025,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
 
 [[package]]
+name = "libm"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
+
+[[package]]
 name = "libz-sys"
 version = "1.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2105,6 +2269,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
 name = "miow"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2142,6 +2317,24 @@ dependencies = [
 ]
 
 [[package]]
+name = "native-tls"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
 name = "new_debug_unreachable"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2170,6 +2363,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "ntapi"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "nu-ansi-term"
 version = "0.46.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2241,6 +2443,32 @@ dependencies = [
 ]
 
 [[package]]
+name = "openssl"
+version = "0.10.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
+dependencies = [
+ "bitflags 1.3.2",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.8",
+]
+
+[[package]]
 name = "openssl-probe"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2259,6 +2487,28 @@ dependencies = [
 ]
 
 [[package]]
+name = "opt-dist"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "build_helper",
+ "camino",
+ "env_logger 0.10.0",
+ "fs_extra",
+ "glob",
+ "humansize",
+ "humantime 2.1.0",
+ "log",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "sysinfo",
+ "tar",
+ "xz",
+ "zip",
+]
+
+[[package]]
 name = "overload"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2277,7 +2527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282"
 dependencies = [
  "cfg-if",
- "libm",
+ "libm 0.1.4",
 ]
 
 [[package]]
@@ -2731,6 +2981,43 @@ dependencies = [
 ]
 
 [[package]]
+name = "reqwest"
+version = "0.11.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-tls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
+[[package]]
 name = "rls"
 version = "2.0.0"
 dependencies = [
@@ -3159,7 +3446,6 @@ name = "rustc_driver"
 version = "0.0.0"
 dependencies = [
  "rustc_driver_impl",
- "rustix 0.37.11",
 ]
 
 [[package]]
@@ -4218,9 +4504,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.37.11"
+version = "0.37.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77"
+checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
 dependencies = [
  "bitflags 1.3.2",
  "errno",
@@ -4232,9 +4518,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.1"
+version = "0.38.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3"
+checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4"
 dependencies = [
  "bitflags 2.3.3",
  "errno",
@@ -4297,6 +4583,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
+name = "security-framework"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
 name = "self_cell"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4353,6 +4662,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
 name = "sha1"
 version = "0.10.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4631,6 +4952,20 @@ dependencies = [
 ]
 
 [[package]]
+name = "sysinfo"
+version = "0.29.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9557d0845b86eea8182f7b10dff120214fb6cd9fd937b6f4917714e546a38695"
+dependencies = [
+ "cfg-if",
+ "core-foundation-sys",
+ "libc",
+ "ntapi",
+ "once_cell",
+ "winapi",
+]
+
+[[package]]
 name = "sysroot"
 version = "0.0.0"
 dependencies = [
@@ -4660,7 +4995,7 @@ dependencies = [
  "cfg-if",
  "fastrand",
  "redox_syscall 0.3.5",
- "rustix 0.37.11",
+ "rustix 0.37.22",
  "windows-sys 0.48.0",
 ]
 
@@ -4701,7 +5036,7 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
 dependencies = [
- "rustix 0.37.11",
+ "rustix 0.37.22",
  "windows-sys 0.48.0",
 ]
 
@@ -4849,7 +5184,36 @@ dependencies = [
  "autocfg",
  "backtrace",
  "bytes",
+ "libc",
+ "mio",
+ "num_cpus",
+ "pin-project-lite",
+ "socket2",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
  "pin-project-lite",
+ "tokio",
+ "tracing",
 ]
 
 [[package]]
@@ -4902,6 +5266,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
 
 [[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
 name = "tracing"
 version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4987,6 +5357,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
 name = "twox-hash"
 version = "1.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5305,6 +5681,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
 name = "wasi"
 version = "0.11.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5341,6 +5726,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
 name = "wasm-bindgen-macro"
 version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5370,6 +5767,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
+name = "web-sys"
+version = "0.3.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5564,6 +5971,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "writeable"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5579,6 +5995,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "xz"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c887690ff2a2e233e8e49633461521f98ec57fbff9d59a884c9a4f04ec1da34"
+dependencies = [
+ "xz2",
+]
+
+[[package]]
 name = "xz2"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5683,3 +6108,15 @@ dependencies = [
  "syn 1.0.109",
  "synstructure 0.12.6",
 ]
+
+[[package]]
+name = "zip"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
+dependencies = [
+ "byteorder",
+ "crc32fast",
+ "crossbeam-utils",
+ "flate2",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 20b1c656d35..53bf9a8af2c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,6 +43,7 @@ members = [
   "src/tools/suggest-tests",
   "src/tools/generate-windows-sys",
   "src/tools/rustdoc-gui-test",
+  "src/tools/opt-dist",
 ]
 
 exclude = [
diff --git a/README.md b/README.md
index 901213d2ca9..8a6c559b0b3 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,9 @@ Read ["Installation"] from [The Book].
 
 The Rust build system uses a Python script called `x.py` to build the compiler,
 which manages the bootstrapping process. It lives at the root of the project.
-It also uses a file named `config.toml` to determine various configuration settings for the build.
-You can see a full list of options in `config.example.toml`.
+It also uses a file named `config.toml` to determine various configuration
+settings for the build. You can see a full list of options in
+`config.example.toml`.
 
 The `x.py` command can be run directly on most Unix systems in the following
 format:
@@ -33,7 +34,8 @@ format:
 ```
 
 This is how the documentation and examples assume you are running `x.py`.
-See the [rustc dev guide][rustcguidebuild] if this does not work on your platform.
+See the [rustc dev guide][rustcguidebuild] if this does not work on your
+platform.
 
 More information about `x.py` can be found by running it with the `--help` flag
 or reading the [rustc dev guide][rustcguidebuild].
@@ -105,24 +107,26 @@ See [the rustc-dev-guide for more info][sysllvm].
 
    When complete, `./x.py install` will place several programs into
    `$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
-   API-documentation tool. By default, it will also include [Cargo], Rust's package manager.
-   You can disable this behavior by passing `--set build.extended=false` to `./configure`.
+   API-documentation tool. By default, it will also include [Cargo], Rust's
+   package manager. You can disable this behavior by passing
+   `--set build.extended=false` to `./configure`.
 
 [Cargo]: https://github.com/rust-lang/cargo
 
 #### Configure and Make
 
-This project provides a configure script and makefile (the latter of which just invokes `x.py`).
-`./configure` is the recommended way to programatically generate a `config.toml`. `make` is not
-recommended (we suggest using `x.py` directly), but it is supported and we try not to break it
-unnecessarily.
+This project provides a configure script and makefile (the latter of which just
+invokes `x.py`). `./configure` is the recommended way to programatically
+generate a `config.toml`. `make` is not recommended (we suggest using `x.py`
+directly), but it is supported and we try not to break it unnecessarily.
 
 ```sh
 ./configure
 make && sudo make install
 ```
 
-`configure` generates a `config.toml` which can also be used with normal `x.py` invocations.
+`configure` generates a `config.toml` which can also be used with normal `x.py`
+invocations.
 
 ### Building on Windows
 
@@ -193,7 +197,7 @@ toolchain.
 #### MSVC
 
 MSVC builds of Rust additionally require an installation of Visual Studio 2017
-(or later) so `rustc` can use its linker.  The simplest way is to get
+(or later) so `rustc` can use its linker. The simplest way is to get
 [Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload.
 
 [Visual Studio]: https://visualstudio.microsoft.com/downloads/
@@ -234,7 +238,8 @@ Windows build triples are:
 
 The build triple can be specified by either specifying `--build=<triple>` when
 invoking `x.py` commands, or by creating a `config.toml` file (as described in
-[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing `--set build.build=<triple>` to `./configure`.
+[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing
+`--set build.build=<triple>` to `./configure`.
 
 ## Building Documentation
 
diff --git a/RELEASES.md b/RELEASES.md
index fa95df685aa..419c20b9071 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,146 @@
+Version 1.71.0 (2023-07-13)
+==========================
+
+<a id="1.71.0-Language"></a>
+
+Language
+--------
+
+- [Stabilize `raw-dylib`, `link_ordinal`, `import_name_type` and `-Cdlltool`.](https://github.com/rust-lang/rust/pull/109677/)
+- [Uplift `clippy::{drop,forget}_{ref,copy}` lints.](https://github.com/rust-lang/rust/pull/109732/)
+- [Type inference is more conservative around constrained vars.](https://github.com/rust-lang/rust/pull/110100/)
+- [Use fulfillment to check `Drop` impl compatibility](https://github.com/rust-lang/rust/pull/110577/)
+
+<a id="1.71.0-Compiler"></a>
+
+Compiler
+--------
+
+- [Evaluate place expression in `PlaceMention`](https://github.com/rust-lang/rust/pull/104844/),
+  making `let _ =` patterns more consistent with respect to the borrow checker.
+- [Add `--print deployment-target` flag for Apple targets.](https://github.com/rust-lang/rust/pull/105354/)
+- [Stabilize `extern "C-unwind"` and friends.](https://github.com/rust-lang/rust/pull/106075/)
+  The existing `extern "C"` etc. may change behavior for cross-language unwinding in a future release.
+- [Update the version of musl used on `*-linux-musl` targets to 1.2.3](https://github.com/rust-lang/rust/pull/107129/),
+  enabling [time64](https://musl.libc.org/time64.html) on 32-bit systems.
+- [Stabilize `debugger_visualizer`](https://github.com/rust-lang/rust/pull/108668/)
+  for embedding metadata like Microsoft's Natvis.
+- [Enable flatten-format-args by default.](https://github.com/rust-lang/rust/pull/109999/)
+- [Make `Self` respect tuple constructor privacy.](https://github.com/rust-lang/rust/pull/111245/)
+- [Improve niche placement by trying two strategies and picking the better result.](https://github.com/rust-lang/rust/pull/108106/)
+- [Use `apple-m1` as the target CPU for `aarch64-apple-darwin`.](https://github.com/rust-lang/rust/pull/109899/)
+- [Add Tier 3 support for the `x86_64h-apple-darwin` target.](https://github.com/rust-lang/rust/pull/108795/)
+- [Promote `loongarch64-unknown-linux-gnu` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/110936/)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+<a id="1.71.0-Libraries"></a>
+
+Libraries
+---------
+- [Rework handling of recursive panics.](https://github.com/rust-lang/rust/pull/110975/)
+  Additional panics are allowed while unwinding, as long as they are caught before escaping
+  a `Drop` implementation, but panicking within a panic hook is now an immediate abort.
+- [Loosen `From<&[T]> for Box<[T]>` bound to `T: Clone`.](https://github.com/rust-lang/rust/pull/103406/)
+- [Remove unnecessary `T: Send` bound](https://github.com/rust-lang/rust/pull/111134/)
+  in `Error for mpsc::SendError<T>` and `TrySendError<T>`.
+- [Fix docs for `alloc::realloc`](https://github.com/rust-lang/rust/pull/108630/)
+  to match `Layout` requirements that the size must not exceed `isize::MAX`.
+- [Document `const {}` syntax for `std::thread_local`.](https://github.com/rust-lang/rust/pull/110620/)
+  This syntax was stabilized in Rust 1.59, but not previously mentioned in release notes.
+
+<a id="1.71.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`CStr::is_empty`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.is_empty)
+- [`BuildHasher::hash_one`](https://doc.rust-lang.org/stable/std/hash/trait.BuildHasher.html#method.hash_one)
+- [`NonZeroI*::is_positive`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.is_positive)
+- [`NonZeroI*::is_negative`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.is_negative)
+- [`NonZeroI*::checked_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.checked_neg)
+- [`NonZeroI*::overflowing_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.overflowing_neg)
+- [`NonZeroI*::saturating_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.saturating_neg)
+- [`NonZeroI*::wrapping_neg`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#method.wrapping_neg)
+- [`Neg for NonZeroI*`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#impl-Neg-for-NonZeroI32)
+- [`Neg for &NonZeroI*`](https://doc.rust-lang.org/stable/std/num/struct.NonZeroI32.html#impl-Neg-for-%26NonZeroI32)
+- [`From<[T; N]> for (T...)`](https://doc.rust-lang.org/stable/std/primitive.array.html#impl-From%3C%5BT;+1%5D%3E-for-(T,))
+  (array to N-tuple for N in 1..=12)
+- [`From<(T...)> for [T; N]`](https://doc.rust-lang.org/stable/std/primitive.array.html#impl-From%3C(T,)%3E-for-%5BT;+1%5D)
+  (N-tuple to array for N in 1..=12)
+- [`windows::io::AsHandle for Box<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Box%3CT%3E)
+- [`windows::io::AsHandle for Rc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Rc%3CT%3E)
+- [`windows::io::AsHandle for Arc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsHandle.html#impl-AsHandle-for-Arc%3CT%3E)
+- [`windows::io::AsSocket for Box<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Box%3CT%3E)
+- [`windows::io::AsSocket for Rc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Rc%3CT%3E)
+- [`windows::io::AsSocket for Arc<T>`](https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html#impl-AsSocket-for-Arc%3CT%3E)
+
+These APIs are now stable in const contexts:
+
+- [`<*const T>::read`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read)
+- [`<*const T>::read_unaligned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read_unaligned)
+- [`<*mut T>::read`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read-1)
+- [`<*mut T>::read_unaligned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.read_unaligned-1)
+- [`ptr::read`](https://doc.rust-lang.org/stable/std/ptr/fn.read.html)
+- [`ptr::read_unaligned`](https://doc.rust-lang.org/stable/std/ptr/fn.read_unaligned.html)
+- [`<[T]>::split_at`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_at)
+
+<a id="1.71.0-Cargo"></a>
+
+Cargo
+-----
+- [Allow named debuginfo options in `Cargo.toml`.](https://github.com/rust-lang/cargo/pull/11958/)
+- [Add `workspace_default_members` to the output of `cargo metadata`.](https://github.com/rust-lang/cargo/pull/11978/)
+- [`cargo add` now considers `rust-version` when selecting packages.](https://github.com/rust-lang/cargo/pull/12078/)
+- [Automatically inherit workspace fields when running `cargo new`/`cargo init`.](https://github.com/rust-lang/cargo/pull/12069/)
+
+<a id="1.71.0-Rustdoc"></a>
+
+Rustdoc
+-------
+
+- [Add a new `rustdoc::unescaped_backticks` lint for broken inline code.](https://github.com/rust-lang/rust/pull/105848/)
+- [Support strikethrough with single tildes.](https://github.com/rust-lang/rust/pull/111152/) (`~~old~~` vs. `~new~`)
+
+<a id="1.71.0-Misc"></a>
+
+Misc
+----
+
+<a id="1.71.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+
+- [Remove structural match from `TypeId`.](https://github.com/rust-lang/rust/pull/103291/)
+  Code that uses a constant `TypeId` in a pattern will potentially be broken.
+  Known cases have already been fixed -- in particular, users of the `log`
+  crate's `kv_unstable` feature should update to `log v0.4.18` or later.
+- [Add a `sysroot` crate to represent the standard library crates.](https://github.com/rust-lang/rust/pull/108865/)
+  This does not affect stable users, but may require adjustment in tools that build their own standard library.
+- [Cargo optimizes its usage under `rustup`.](https://github.com/rust-lang/cargo/pull/11917/) When
+  Cargo detects it will run `rustc` pointing to a rustup proxy, it'll try bypassing the proxy and
+  use the underlying binary directly. There are assumptions around the interaction with rustup and
+  `RUSTUP_TOOLCHAIN`. However, it's not expected to affect normal users.
+- [When querying a package, Cargo tries only the original name, all hyphens, and all underscores to
+  handle misspellings.](https://github.com/rust-lang/cargo/pull/12083/) Previously, Cargo tried each
+  combination of hyphens and underscores, causing excessive requests to crates.io.
+- Cargo now [disallows `RUSTUP_HOME`](https://github.com/rust-lang/cargo/pull/12101/) and
+  [`RUSTUP_TOOLCHAIN`](https://github.com/rust-lang/cargo/pull/12107/) in the `[env]` configuration
+  table. This is considered to be not a use case Cargo would like to support, since it will likely
+  cause problems or lead to confusion.
+
+<a id="1.71.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+
 Version 1.70.0 (2023-06-01)
 ==========================
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 6c01fd63b1e..225c38efb2c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
     Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
     Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
 };
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, RegionVid, TyCtxt};
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{sym, DesugaringKind, Span};
@@ -584,7 +584,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         },
                         // If we see an unsized cast, then if it is our data we should check
                         // whether it is being cast to a trait object.
-                        Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), operand, ty) => {
+                        Rvalue::Cast(
+                            CastKind::PointerCoercion(PointerCoercion::Unsize),
+                            operand,
+                            ty,
+                        ) => {
                             match operand {
                                 Operand::Copy(place) | Operand::Move(place) => {
                                     if let Some(from) = place.as_local() {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 7ed7e125b3c..a15e1065c81 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -28,7 +28,7 @@ use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::*;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
 use rustc_middle::ty::visit::TypeVisitableExt;
@@ -1908,7 +1908,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.check_operand(op, location);
 
                 match cast_kind {
-                    CastKind::Pointer(PointerCast::ReifyFnPointer) => {
+                    CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
 
                         // The type that we see in the fcx is like
@@ -1937,7 +1937,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
+                    CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(unsafety)) => {
                         let sig = match op.ty(body, tcx).kind() {
                             ty::Closure(_, substs) => substs.as_closure().sig(),
                             _ => bug!(),
@@ -1962,7 +1962,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
+                    CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
 
                         // The type that we see in the fcx is like
@@ -1991,7 +1991,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::Pointer(PointerCast::Unsize) => {
+                    CastKind::PointerCoercion(PointerCoercion::Unsize) => {
                         let &ty = ty;
                         let trait_ref = ty::TraitRef::from_lang_item(
                             tcx,
@@ -2038,7 +2038,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         );
                     }
 
-                    CastKind::Pointer(PointerCast::MutToConstPointer) => {
+                    CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
                         let ty::RawPtr(ty::TypeAndMut {
                             ty: ty_from,
                             mutbl: hir::Mutability::Mut,
@@ -2080,7 +2080,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::Pointer(PointerCast::ArrayToPointer) => {
+                    CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
                         let ty_from = op.ty(body, tcx);
 
                         let opt_ty_elem_mut = match ty_from.kind() {
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 826ce60ed13..334b2780b49 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -2,7 +2,7 @@
 
 use rustc_ast::InlineAsmOptions;
 use rustc_index::IndexVec;
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 
@@ -571,7 +571,7 @@ fn codegen_stmt<'tcx>(
                     lval.write_cvalue(fx, res);
                 }
                 Rvalue::Cast(
-                    CastKind::Pointer(PointerCast::ReifyFnPointer),
+                    CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
                     ref operand,
                     to_ty,
                 ) => {
@@ -596,17 +596,17 @@ fn codegen_stmt<'tcx>(
                     }
                 }
                 Rvalue::Cast(
-                    CastKind::Pointer(PointerCast::UnsafeFnPointer),
+                    CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer),
                     ref operand,
                     to_ty,
                 )
                 | Rvalue::Cast(
-                    CastKind::Pointer(PointerCast::MutToConstPointer),
+                    CastKind::PointerCoercion(PointerCoercion::MutToConstPointer),
                     ref operand,
                     to_ty,
                 )
                 | Rvalue::Cast(
-                    CastKind::Pointer(PointerCast::ArrayToPointer),
+                    CastKind::PointerCoercion(PointerCoercion::ArrayToPointer),
                     ref operand,
                     to_ty,
                 ) => {
@@ -662,7 +662,7 @@ fn codegen_stmt<'tcx>(
                     }
                 }
                 Rvalue::Cast(
-                    CastKind::Pointer(PointerCast::ClosureFnPointer(_)),
+                    CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
                     ref operand,
                     _to_ty,
                 ) => {
@@ -684,7 +684,11 @@ fn codegen_stmt<'tcx>(
                         _ => bug!("{} cannot be cast to a fn ptr", operand.layout().ty),
                     }
                 }
-                Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), ref operand, _to_ty) => {
+                Rvalue::Cast(
+                    CastKind::PointerCoercion(PointerCoercion::Unsize),
+                    ref operand,
+                    _to_ty,
+                ) => {
                     let operand = codegen_operand(fx, operand);
                     crate::unsize::coerce_unsized_into(fx, operand, lval);
                 }
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index ff0e12410e7..6aeba13f639 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -1,6 +1,6 @@
-//! Codegen of the [`PointerCast::Unsize`] operation.
+//! Codegen of the [`PointerCoercion::Unsize`] operation.
 //!
-//! [`PointerCast::Unsize`]: `rustc_middle::ty::adjustment::PointerCast::Unsize`
+//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
 
 use crate::prelude::*;
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 1ee89b3d5e8..4b27b64962d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -328,8 +328,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         let local_ref = &self.locals[local];
 
-        // FIXME Should the return place be named?
-        let name = if bx.sess().fewer_names() || local == mir::RETURN_PLACE {
+        let name = if bx.sess().fewer_names() {
             None
         } else {
             Some(match whole_local_var.or(fallback_var.clone()) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index ab9eb421c5a..956f03d2578 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir;
 use rustc_middle::mir::Operand;
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
+use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_target::abi::{self, FIRST_VARIANT};
@@ -32,7 +32,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 cg_operand.val.store(bx, dest);
             }
 
-            mir::Rvalue::Cast(mir::CastKind::Pointer(PointerCast::Unsize), ref source, _) => {
+            mir::Rvalue::Cast(
+                mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
+                ref source,
+                _,
+            ) => {
                 // The destination necessarily contains a fat pointer, so if
                 // it's a scalar pair, it's a fat pointer or newtype thereof.
                 if bx.cx().is_backend_scalar_pair(dest.layout) {
@@ -411,7 +415,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         let lladdr = bx.ptrtoint(llptr, llcast_ty);
                         OperandValue::Immediate(lladdr)
                     }
-                    mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
+                    mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
                         match *operand.layout.ty.kind() {
                             ty::FnDef(def_id, substs) => {
                                 let instance = ty::Instance::resolve_for_fn_ptr(
@@ -427,7 +431,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             _ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty),
                         }
                     }
-                    mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
+                    mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
                         match *operand.layout.ty.kind() {
                             ty::Closure(def_id, substs) => {
                                 let instance = Instance::resolve_closure(
@@ -443,11 +447,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             _ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty),
                         }
                     }
-                    mir::CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
+                    mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
                         // This is a no-op at the LLVM level.
                         operand.val
                     }
-                    mir::CastKind::Pointer(PointerCast::Unsize) => {
+                    mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => {
                         assert!(bx.cx().is_backend_scalar_pair(cast));
                         let (lldata, llextra) = match operand.val {
                             OperandValue::Pair(lldata, llextra) => {
@@ -470,7 +474,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
                         OperandValue::Pair(lldata, llextra)
                     }
-                    mir::CastKind::Pointer(PointerCast::MutToConstPointer)
+                    mir::CastKind::PointerCoercion(PointerCoercion::MutToConstPointer)
                     | mir::CastKind::PtrToPtr
                         if bx.cx().is_backend_scalar_pair(operand.layout) =>
                     {
@@ -504,8 +508,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
                         OperandValue::Pair(lldata, llextra)
                     }
-                    mir::CastKind::Pointer(
-                        PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
+                    mir::CastKind::PointerCoercion(
+                        PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
                     )
                     | mir::CastKind::IntToInt
                     | mir::CastKind::FloatToInt
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index b4db3dff3ff..83a072d6f8b 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -4,7 +4,7 @@ use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
 use rustc_middle::mir::CastKind;
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut};
 use rustc_target::abi::Integer;
@@ -24,51 +24,52 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         cast_ty: Ty<'tcx>,
         dest: &PlaceTy<'tcx, M::Provenance>,
     ) -> InterpResult<'tcx> {
-        use rustc_middle::mir::CastKind::*;
         // FIXME: In which cases should we trigger UB when the source is uninit?
         match cast_kind {
-            Pointer(PointerCast::Unsize) => {
+            CastKind::PointerCoercion(PointerCoercion::Unsize) => {
                 let cast_ty = self.layout_of(cast_ty)?;
                 self.unsize_into(src, cast_ty, dest)?;
             }
 
-            PointerExposeAddress => {
+            CastKind::PointerExposeAddress => {
                 let src = self.read_immediate(src)?;
                 let res = self.pointer_expose_address_cast(&src, cast_ty)?;
                 self.write_immediate(res, dest)?;
             }
 
-            PointerFromExposedAddress => {
+            CastKind::PointerFromExposedAddress => {
                 let src = self.read_immediate(src)?;
                 let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
                 self.write_immediate(res, dest)?;
             }
 
-            IntToInt | IntToFloat => {
+            CastKind::IntToInt | CastKind::IntToFloat => {
                 let src = self.read_immediate(src)?;
                 let res = self.int_to_int_or_float(&src, cast_ty)?;
                 self.write_immediate(res, dest)?;
             }
 
-            FloatToFloat | FloatToInt => {
+            CastKind::FloatToFloat | CastKind::FloatToInt => {
                 let src = self.read_immediate(src)?;
                 let res = self.float_to_float_or_int(&src, cast_ty)?;
                 self.write_immediate(res, dest)?;
             }
 
-            FnPtrToPtr | PtrToPtr => {
+            CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
                 let src = self.read_immediate(&src)?;
                 let res = self.ptr_to_ptr(&src, cast_ty)?;
                 self.write_immediate(res, dest)?;
             }
 
-            Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer) => {
+            CastKind::PointerCoercion(
+                PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
+            ) => {
                 // These are NOPs, but can be wide pointers.
                 let v = self.read_immediate(src)?;
                 self.write_immediate(*v, dest)?;
             }
 
-            Pointer(PointerCast::ReifyFnPointer) => {
+            CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
                 // All reifications must be monomorphic, bail out otherwise.
                 ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
 
@@ -90,7 +91,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            Pointer(PointerCast::UnsafeFnPointer) => {
+            CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
                 let src = self.read_immediate(src)?;
                 match cast_ty.kind() {
                     ty::FnPtr(_) => {
@@ -101,7 +102,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            Pointer(PointerCast::ClosureFnPointer(_)) => {
+            CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
                 // All reifications must be monomorphic, bail out otherwise.
                 ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
 
@@ -122,7 +123,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            DynStar => {
+            CastKind::DynStar => {
                 if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() {
                     // Initial cast from sized to dyn trait
                     let vtable = self.get_vtable_ptr(src.layout.ty, data.principal())?;
@@ -136,7 +137,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            Transmute => {
+            CastKind::Transmute => {
                 assert!(src.layout.is_sized());
                 assert!(dest.layout.is_sized());
                 if src.layout.size != dest.layout.size {
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 24c1fe43d0c..ca1106384fd 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -700,8 +700,13 @@ where
             assert_eq!(src.layout.size, dest.layout.size);
         }
 
+        // Setting `nonoverlapping` here only has an effect when we don't hit the fast-path above,
+        // but that should at least match what LLVM does where `memcpy` is also only used when the
+        // type does not have Scalar/ScalarPair layout.
+        // (Or as the `Assign` docs put it, assignments "not producing primitives" must be
+        // non-overlapping.)
         self.mem_copy(
-            src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ false,
+            src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ true,
         )
     }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index b4f2ae5ca77..14540e8dfe7 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -9,7 +9,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
-use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
 use rustc_middle::ty::{TraitRef, TypeVisitableExt};
 use rustc_mir_dataflow::{self, Analysis};
 use rustc_span::{sym, Span, Symbol};
@@ -521,12 +521,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             }
 
             Rvalue::Cast(
-                CastKind::Pointer(
-                    PointerCast::MutToConstPointer
-                    | PointerCast::ArrayToPointer
-                    | PointerCast::UnsafeFnPointer
-                    | PointerCast::ClosureFnPointer(_)
-                    | PointerCast::ReifyFnPointer,
+                CastKind::PointerCoercion(
+                    PointerCoercion::MutToConstPointer
+                    | PointerCoercion::ArrayToPointer
+                    | PointerCoercion::UnsafeFnPointer
+                    | PointerCoercion::ClosureFnPointer(_)
+                    | PointerCoercion::ReifyFnPointer,
                 ),
                 _,
                 _,
@@ -534,7 +534,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // These are all okay; they only change the type, not the data.
             }
 
-            Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
+            Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => {
                 // Unsizing is implemented for CTFE.
             }
 
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 2a6c341b662..4cc923cd935 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -650,7 +650,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     // FIXME: Add Checks for these
                     CastKind::PointerFromExposedAddress
                     | CastKind::PointerExposeAddress
-                    | CastKind::Pointer(_) => {}
+                    | CastKind::PointerCoercion(_) => {}
                     CastKind::IntToInt | CastKind::IntToFloat => {
                         let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
                         let target_valid = target_type.is_numeric() || target_type.is_char();
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index 86a54f6befd..d7c295418ba 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -8,6 +8,3 @@ crate-type = ["dylib"]
 
 [dependencies]
 rustc_driver_impl = { path = "../rustc_driver_impl" }
-# FIXME(Nilstrieb): 0.37.12 adds eventfd support for FreeBSD,
-# but FreeBSD 12 does not support it: https://github.com/bytecodealliance/rustix/issues/716
-rustix = "=0.37.11"
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 270b90fa6b2..120545c8e5d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -722,7 +722,14 @@ pub(super) fn check_specialization_validity<'tcx>(
     let result = opt_result.unwrap_or(Ok(()));
 
     if let Err(parent_impl) = result {
-        report_forbidden_specialization(tcx, impl_item, parent_impl);
+        if !tcx.is_impl_trait_in_trait(impl_item) {
+            report_forbidden_specialization(tcx, impl_item, parent_impl);
+        } else {
+            tcx.sess.delay_span_bug(
+                DUMMY_SP,
+                format!("parent item: {:?} not marked as default", parent_impl),
+            );
+        }
     }
 }
 
@@ -1485,7 +1492,9 @@ fn opaque_type_cycle_error(
                 }
 
                 for closure_def_id in visitor.closures {
-                    let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
+                    let Some(closure_local_did) = closure_def_id.as_local() else {
+                        continue;
+                    };
                     let typeck_results = tcx.typeck(closure_local_did);
 
                     let mut label_match = |ty: Ty<'_>, span| {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 97a3e01c52a..acd0bcd8e5c 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_session::lint;
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Ident};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use std::fmt;
 
 use crate::errors;
@@ -338,7 +338,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
                 Scope::TraitRefBoundary { .. } => {
                     // We should only see super trait lifetimes if there is a `Binder` above
-                    assert!(supertrait_bound_vars.is_empty());
+                    // though this may happen when we call `poly_trait_ref_binder_info` with
+                    // an (erroneous, #113423) associated return type bound in an impl header.
+                    if !supertrait_bound_vars.is_empty() {
+                        self.tcx.sess.delay_span_bug(
+                            DUMMY_SP,
+                            format!(
+                                "found supertrait lifetimes without a binder to append \
+                                them to: {supertrait_bound_vars:?}"
+                            ),
+                        );
+                    }
                     break (vec![], BinderScopeType::Normal);
                 }
 
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 49aee6b59a2..066e7449189 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, CrateVariancesMap, ImplTraitInTraitData, SubstsRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
 use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
 use std::ops::ControlFlow;
 
@@ -59,13 +59,6 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
         DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
             return variance_of_opaque(tcx, item_def_id);
         }
-        DefKind::AssocTy => {
-            if let Some(ImplTraitInTraitData::Trait { .. }) =
-                tcx.opt_rpitit_info(item_def_id.to_def_id())
-            {
-                return variance_of_opaque(tcx, item_def_id);
-            }
-        }
         _ => {}
     }
 
@@ -125,7 +118,8 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
                 // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
                 // at all for RPITITs.
                 ty::Alias(_, ty::AliasTy { def_id, substs, .. })
-                    if self.tcx.is_impl_trait_in_trait(*def_id) =>
+                    if self.tcx.is_impl_trait_in_trait(*def_id)
+                        && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
                 {
                     self.visit_opaque(*def_id, substs)
                 }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 108e20ed145..dc58d99ed9d 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -47,7 +47,7 @@ use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::adjustment::{
-    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
+    Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
 };
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::RelateResult;
@@ -592,7 +592,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         };
         let coerce_target = self.next_ty_var(origin);
         let mut coercion = self.unify_and(coerce_target, target, |target| {
-            let unsize = Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target };
+            let unsize = Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), target };
             match reborrow {
                 None => vec![unsize],
                 Some((ref deref, ref autoref)) => vec![deref.clone(), autoref.clone(), unsize],
@@ -849,7 +849,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             a,
             fn_ty_a,
             b,
-            simple(Adjust::Pointer(PointerCast::UnsafeFnPointer)),
+            simple(Adjust::Pointer(PointerCoercion::UnsafeFnPointer)),
             identity,
         )
     }
@@ -893,16 +893,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     |unsafe_ty| {
                         vec![
                             Adjustment {
-                                kind: Adjust::Pointer(PointerCast::ReifyFnPointer),
+                                kind: Adjust::Pointer(PointerCoercion::ReifyFnPointer),
                                 target: a_fn_pointer,
                             },
                             Adjustment {
-                                kind: Adjust::Pointer(PointerCast::UnsafeFnPointer),
+                                kind: Adjust::Pointer(PointerCoercion::UnsafeFnPointer),
                                 target: unsafe_ty,
                             },
                         ]
                     },
-                    simple(Adjust::Pointer(PointerCast::ReifyFnPointer)),
+                    simple(Adjust::Pointer(PointerCoercion::ReifyFnPointer)),
                 )?;
 
                 obligations.extend(o2);
@@ -952,7 +952,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 self.unify_and(
                     pointer_ty,
                     b,
-                    simple(Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))),
+                    simple(Adjust::Pointer(PointerCoercion::ClosureFnPointer(unsafety))),
                 )
             }
             _ => self.unify_and(a, b, identity),
@@ -987,7 +987,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 ]
             })
         } else if mt_a.mutbl != mutbl_b {
-            self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCast::MutToConstPointer)))
+            self.unify_and(a_unsafe, b, simple(Adjust::Pointer(PointerCoercion::MutToConstPointer)))
         } else {
             self.unify_and(a_unsafe, b, identity)
         }
@@ -1187,13 +1187,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Reify both sides and return the reified fn pointer type.
             let fn_ptr = Ty::new_fn_ptr(self.tcx, sig);
             let prev_adjustment = match prev_ty.kind() {
-                ty::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(a_sig.unsafety())),
-                ty::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
+                ty::Closure(..) => {
+                    Adjust::Pointer(PointerCoercion::ClosureFnPointer(a_sig.unsafety()))
+                }
+                ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
                 _ => unreachable!(),
             };
             let next_adjustment = match new_ty.kind() {
-                ty::Closure(..) => Adjust::Pointer(PointerCast::ClosureFnPointer(b_sig.unsafety())),
-                ty::FnDef(..) => Adjust::Pointer(PointerCast::ReifyFnPointer),
+                ty::Closure(..) => {
+                    Adjust::Pointer(PointerCoercion::ClosureFnPointer(b_sig.unsafety()))
+                }
+                ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer),
                 _ => unreachable!(),
             };
             for expr in exprs.iter().map(|e| e.as_coercion_site()) {
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 55ad99e55af..87edb803148 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -10,7 +10,7 @@ use rustc_hir_analysis::astconv::generics::{
 use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
 use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
 use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
-use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{self, SubstsRef};
@@ -212,8 +212,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                         region,
                         ty::TypeAndMut { mutbl: mutbl.into(), ty: unsized_ty },
                     );
-                    adjustments
-                        .push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target });
+                    adjustments.push(Adjustment {
+                        kind: Adjust::Pointer(PointerCoercion::Unsize),
+                        target,
+                    });
                 }
             }
             Some(probe::AutorefOrPtrAdjustment::ToConstPtr) => {
@@ -226,7 +228,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 };
 
                 adjustments.push(Adjustment {
-                    kind: Adjust::Pointer(PointerCast::MutToConstPointer),
+                    kind: Adjust::Pointer(PointerCoercion::MutToConstPointer),
                     target,
                 });
             }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 19f82fbd3bf..42f4531c0ef 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -394,8 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut pat_ty = ty;
         if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind {
             let expected = self.structurally_resolve_type(span, expected);
-            if let ty::Ref(_, inner_ty, _) = expected.kind()
-                && matches!(inner_ty.kind(), ty::Slice(_))
+            if let ty::Ref(_, inner_ty, _) = *expected.kind()
+                && self.try_structurally_resolve_type(span, inner_ty).is_slice()
             {
                 let tcx = self.tcx;
                 trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index 826cee3f982..fd43b475e3a 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -6,7 +6,7 @@ use rustc_hir as hir;
 use rustc_hir_analysis::autoderef::Autoderef;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::InferOk;
-use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion};
 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{self, Ty};
 use rustc_span::symbol::{sym, Ident};
@@ -173,7 +173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 if unsize {
                     adjustments.push(Adjustment {
-                        kind: Adjust::Pointer(PointerCast::Unsize),
+                        kind: Adjust::Pointer(PointerCoercion::Unsize),
                         target: method.sig.inputs()[0],
                     });
                 }
@@ -441,7 +441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let [
                 ..,
                 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
-                Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target },
+                Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), ref mut target },
             ] = adjustments[..]
             {
                 *target = method.sig.inputs()[0];
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 01332483a06..10645753609 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -11,7 +11,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_middle::hir::place::Place as HirPlace;
 use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
@@ -251,7 +251,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                         // Since this is "after" the other adjustment to be
                         // discarded, we do an extra `pop()`
                         if let Some(Adjustment {
-                            kind: Adjust::Pointer(PointerCast::Unsize), ..
+                            kind: Adjust::Pointer(PointerCoercion::Unsize), ..
                         }) = a.pop()
                         {
                             // So the borrow discard actually happens here
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 3098b8bc2f9..5927f79a183 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -473,17 +473,6 @@ where
                 }
             }
 
-            ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
-                // Skip lifetime parameters that are not captures.
-                let variances = self.tcx.variances_of(proj.def_id);
-
-                for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
-                    if *v != ty::Variance::Bivariant {
-                        s.visit_with(self);
-                    }
-                }
-            }
-
             _ => {
                 ty.super_visit_with(self);
             }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index efb01b0faba..28c50587800 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2014,7 +2014,7 @@ impl<'tcx> Rvalue<'tcx> {
                 | CastKind::IntToFloat
                 | CastKind::FnPtrToPtr
                 | CastKind::PtrToPtr
-                | CastKind::Pointer(_)
+                | CastKind::PointerCoercion(_)
                 | CastKind::PointerFromExposedAddress
                 | CastKind::DynStar
                 | CastKind::Transmute,
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index abb3b3d953b..7f1d3820341 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -7,7 +7,7 @@ use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection};
 
 use crate::mir::coverage::{CodeRegion, CoverageKind};
 use crate::traits::Reveal;
-use crate::ty::adjustment::PointerCast;
+use crate::ty::adjustment::PointerCoercion;
 use crate::ty::subst::SubstsRef;
 use crate::ty::{self, List, Ty};
 use crate::ty::{Region, UserTypeAnnotationIndex};
@@ -1230,9 +1230,9 @@ pub enum CastKind {
     /// An address-to-pointer cast that picks up an exposed provenance.
     /// See the docs on `from_exposed_addr` for more details.
     PointerFromExposedAddress,
-    /// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
+    /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
     /// translated into `&raw mut/const *r`, i.e., they are not actually casts.
-    Pointer(PointerCast),
+    PointerCoercion(PointerCoercion),
     /// Cast into a dyn* object.
     DynStar,
     IntToInt,
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 0f3ad6d0151..e9af5070e5e 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -18,7 +18,7 @@ use rustc_index::IndexVec;
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
-use rustc_middle::ty::adjustment::PointerCast;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
 use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
@@ -329,9 +329,10 @@ pub enum ExprKind<'tcx> {
     NeverToAny {
         source: ExprId,
     },
-    /// A pointer cast. More information can be found in [`PointerCast`].
-    Pointer {
-        cast: PointerCast,
+    /// A pointer coercion. More information can be found in [`PointerCoercion`].
+    /// Pointer casts that cannot be done by coercions are represented by [`ExprKind::Cast`].
+    PointerCoercion {
+        cast: PointerCoercion,
         source: ExprId,
     },
     /// A `loop` expression.
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 9cc07677e0e..14bc1ac0ce7 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -65,7 +65,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
         Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
         Use { source } => visitor.visit_expr(&visitor.thir()[source]),
         NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
-        Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
+        PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
         Let { expr, .. } => {
             visitor.visit_expr(&visitor.thir()[expr]);
         }
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index a4893684bc8..76931ceaa69 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -6,7 +6,7 @@ use rustc_span::Span;
 use rustc_target::abi::FieldIdx;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
-pub enum PointerCast {
+pub enum PointerCoercion {
     /// Go from a fn-item type to a fn-pointer type.
     ReifyFnPointer,
 
@@ -99,7 +99,7 @@ pub enum Adjust<'tcx> {
     /// Take the address and produce either a `&` or `*` pointer.
     Borrow(AutoBorrow<'tcx>),
 
-    Pointer(PointerCast),
+    Pointer(PointerCoercion),
 
     /// Cast into a dyn* object.
     DynStar,
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 0fe801ad2ed..d95b05ef754 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1110,12 +1110,11 @@ where
 ///
 /// This takes two primary parameters:
 ///
-/// * `codegen_fn_attr_flags` - these are flags calculated as part of the
-///   codegen attrs for a defined function. For function pointers this set of
-///   flags is the empty set. This is only applicable for Rust-defined
-///   functions, and generally isn't needed except for small optimizations where
-///   we try to say a function which otherwise might look like it could unwind
-///   doesn't actually unwind (such as for intrinsics and such).
+/// * `fn_def_id` - the `DefId` of the function. If this is provided then we can
+///   determine more precisely if the function can unwind. If this is not provided
+///   then we will only infer whether the function can unwind or not based on the
+///   ABI of the function. For example, a function marked with `#[rustc_nounwind]`
+///   is known to not unwind even if it's using Rust ABI.
 ///
 /// * `abi` - this is the ABI that the function is defined with. This is the
 ///   primary factor for determining whether a function can unwind or not.
@@ -1147,11 +1146,6 @@ where
 ///   aborts the process.
 /// * This affects whether functions have the LLVM `nounwind` attribute, which
 ///   affects various optimizations and codegen.
-///
-/// FIXME: this is actually buggy with respect to Rust functions. Rust functions
-/// compiled with `-Cpanic=unwind` and referenced from another crate compiled
-/// with `-Cpanic=abort` will look like they can't unwind when in fact they
-/// might (from a foreign exception or similar).
 #[inline]
 #[tracing::instrument(level = "debug", skip(tcx))]
 pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 4a639a2a0fe..7220d133f68 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -332,7 +332,7 @@ TrivialTypeTraversalAndLiftImpls! {
     crate::ty::IntVarValue,
     crate::ty::ParamConst,
     crate::ty::ParamTy,
-    crate::ty::adjustment::PointerCast,
+    crate::ty::adjustment::PointerCoercion,
     crate::ty::RegionVid,
     crate::ty::UniverseIndex,
     crate::ty::Variance,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index ac2d099be50..60acd279f9e 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -535,7 +535,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Cast { .. }
             | ExprKind::Use { .. }
             | ExprKind::NeverToAny { .. }
-            | ExprKind::Pointer { .. }
+            | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
             | ExprKind::AddressOf { .. }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 5c886ac4d9b..32ffb990be6 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -300,7 +300,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let cast_kind = mir_cast_kind(ty, expr.ty);
                 block.and(Rvalue::Cast(cast_kind, source, expr.ty))
             }
-            ExprKind::Pointer { cast, source } => {
+            ExprKind::PointerCoercion { cast, source } => {
                 let source = unpack!(
                     block = this.as_operand(
                         block,
@@ -310,7 +310,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         NeedsTemporary::No
                     )
                 );
-                block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
+                block.and(Rvalue::Cast(CastKind::PointerCoercion(cast), source, expr.ty))
             }
             ExprKind::Array { ref fields } => {
                 // (*) We would (maybe) be closer to codegen if we
diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
index 2fe9cac6378..e07ba6b6e93 100644
--- a/compiler/rustc_mir_build/src/build/expr/category.rs
+++ b/compiler/rustc_mir_build/src/build/expr/category.rs
@@ -63,7 +63,7 @@ impl Category {
             | ExprKind::Binary { .. }
             | ExprKind::Box { .. }
             | ExprKind::Cast { .. }
-            | ExprKind::Pointer { .. }
+            | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 91c464252f1..e30fdcbbe18 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -556,7 +556,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Binary { .. }
             | ExprKind::Box { .. }
             | ExprKind::Cast { .. }
-            | ExprKind::Pointer { .. }
+            | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Array { .. }
             | ExprKind::Tuple { .. }
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 3a2c506bb98..e6806177dec 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -16,7 +16,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::GenericArg;
-use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
+use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
@@ -423,7 +423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         source_info,
                         temp,
                         Rvalue::Cast(
-                            CastKind::Pointer(PointerCast::Unsize),
+                            CastKind::PointerCoercion(PointerCoercion::Unsize),
                             Operand::Copy(val),
                             ty,
                         ),
@@ -436,7 +436,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         block,
                         source_info,
                         slice,
-                        Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty),
+                        Rvalue::Cast(
+                            CastKind::PointerCoercion(PointerCoercion::Unsize),
+                            expect,
+                            ty,
+                        ),
                     );
                     expect = Operand::Move(slice);
                 }
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 105564b7874..6b2b140fa25 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -303,7 +303,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             | ExprKind::NeverToAny { .. }
             | ExprKind::PlaceTypeAscription { .. }
             | ExprKind::ValueTypeAscription { .. }
-            | ExprKind::Pointer { .. }
+            | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::StaticRef { .. }
             | ExprKind::ThreadLocalRef { .. }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index a5c141b71f6..37537683f0d 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -13,7 +13,7 @@ use rustc_middle::middle::region;
 use rustc_middle::mir::{self, BinOp, BorrowKind, UnOp};
 use rustc_middle::thir::*;
 use rustc_middle::ty::adjustment::{
-    Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
+    Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCoercion,
 };
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{
@@ -125,11 +125,16 @@ impl<'tcx> Cx<'tcx> {
         };
 
         let kind = match adjustment.kind {
-            Adjust::Pointer(PointerCast::Unsize) => {
+            Adjust::Pointer(PointerCoercion::Unsize) => {
                 adjust_span(&mut expr);
-                ExprKind::Pointer { cast: PointerCast::Unsize, source: self.thir.exprs.push(expr) }
+                ExprKind::PointerCoercion {
+                    cast: PointerCoercion::Unsize,
+                    source: self.thir.exprs.push(expr),
+                }
+            }
+            Adjust::Pointer(cast) => {
+                ExprKind::PointerCoercion { cast, source: self.thir.exprs.push(expr) }
             }
-            Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: self.thir.exprs.push(expr) },
             Adjust::NeverToAny if adjustment.target.is_never() => return expr,
             Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
             Adjust::Deref(None) => {
@@ -192,9 +197,9 @@ impl<'tcx> Cx<'tcx> {
             // Special cased so that we can type check that the element
             // type of the source matches the pointed to type of the
             // destination.
-            ExprKind::Pointer {
+            ExprKind::PointerCoercion {
                 source: self.mirror_expr(source),
-                cast: PointerCast::ArrayToPointer,
+                cast: PointerCoercion::ArrayToPointer,
             }
         } else {
             // check whether this is casting an enum variant discriminant
@@ -210,17 +215,18 @@ impl<'tcx> Cx<'tcx> {
             // so we wouldn't have to compute and store the actual value
 
             let hir::ExprKind::Path(ref qpath) = source.kind else {
-                return ExprKind::Cast { source: self.mirror_expr(source)};
+                return ExprKind::Cast { source: self.mirror_expr(source) };
             };
 
             let res = self.typeck_results().qpath_res(qpath, source.hir_id);
             let ty = self.typeck_results().node_type(source.hir_id);
             let ty::Adt(adt_def, substs) = ty.kind() else {
-                return ExprKind::Cast { source: self.mirror_expr(source)};
+                return ExprKind::Cast { source: self.mirror_expr(source) };
             };
 
-            let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res else {
-                return ExprKind::Cast { source: self.mirror_expr(source)};
+            let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
+            else {
+                return ExprKind::Cast { source: self.mirror_expr(source) };
             };
 
             let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
@@ -353,19 +359,35 @@ impl<'tcx> Cx<'tcx> {
                             });
                         }
                     }
-                    let adt_data =
-                        if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind {
-                            // Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
-                            expr_ty.ty_adt_def().and_then(|adt_def| match path.res {
-                                Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
+
+                    // Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
+                    let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
+                    && let Some(adt_def) = expr_ty.ty_adt_def() {
+                        match qpath {
+                            hir::QPath::Resolved(_, ref path) => {
+                                match path.res {
+                                    Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
+                                        Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
+                                    }
+                                    Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
+                                    _ => None,
+                                }
+                            }
+                            hir::QPath::TypeRelative(_ty, _) => {
+                                if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
+                                    self.typeck_results().type_dependent_def(fun.hir_id)
+                                {
                                     Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
+                                } else {
+                                    None
                                 }
-                                Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
-                                _ => None,
-                            })
-                        } else {
-                            None
-                        };
+
+                            }
+                            _ => None,
+                        }
+                    } else {
+                        None
+                    };
                     if let Some((adt_def, index)) = adt_data {
                         let substs = self.typeck_results().node_substs(fun.hir_id);
                         let user_provided_types = self.typeck_results().user_provided_types();
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 0b6029bf388..8d7c624a805 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -301,7 +301,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 self.print_expr(*source, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl);
             }
-            Pointer { cast, source } => {
+            PointerCoercion { cast, source } => {
                 print_indented!(self, "Pointer {", depth_lvl);
                 print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
                 print_indented!(self, "source:", depth_lvl + 1);
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index 3d61d33ce35..6c3b7c58fab 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -41,7 +41,7 @@ fn compute_slice_length<'tcx>(
     for (local, rvalue, _) in ssa.assignments(body) {
         match rvalue {
             Rvalue::Cast(
-                CastKind::Pointer(ty::adjustment::PointerCast::Unsize),
+                CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize),
                 operand,
                 cast_ty,
             ) => {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 4a5953c1149..242269e9d1a 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -176,7 +176,7 @@ use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
 use rustc_middle::mir::visit::Visitor as MirVisitor;
 use rustc_middle::mir::{self, Local, Location};
 use rustc_middle::query::TyCtxtAt;
-use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast};
+use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::{
@@ -231,8 +231,8 @@ impl<'tcx> UsageMap<'tcx> {
         assert!(self.used_map.insert(user_item, used_items).is_none());
     }
 
-    pub fn get_user_items(&self, item: MonoItem<'tcx>) -> Option<&[MonoItem<'tcx>]> {
-        self.user_map.get(&item).map(|items| items.as_slice())
+    pub fn get_user_items(&self, item: MonoItem<'tcx>) -> &[MonoItem<'tcx>] {
+        self.user_map.get(&item).map(|items| items.as_slice()).unwrap_or(&[])
     }
 
     /// Internally iterate over all inlined items used by `item`.
@@ -617,7 +617,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
             // have to instantiate all methods of the trait being cast to, so we
             // can build the appropriate vtable.
             mir::Rvalue::Cast(
-                mir::CastKind::Pointer(PointerCast::Unsize),
+                mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
                 ref operand,
                 target_ty,
             )
@@ -643,7 +643,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
                 }
             }
             mir::Rvalue::Cast(
-                mir::CastKind::Pointer(PointerCast::ReifyFnPointer),
+                mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
                 ref operand,
                 _,
             ) => {
@@ -652,7 +652,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
                 visit_fn_use(self.tcx, fn_ty, false, span, &mut self.output);
             }
             mir::Rvalue::Cast(
-                mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)),
+                mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
                 ref operand,
                 _,
             ) => {
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index f4535fbd58f..da76cf2236c 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -427,9 +427,9 @@ fn merge_codegen_units<'tcx>(
         // zero-padded suffixes, which means they are automatically sorted by
         // names. The numeric suffix width depends on the number of CGUs, which
         // is always greater than zero:
-        // - [1,9]     CGUS: `0`, `1`, `2`, ...
-        // - [10,99]   CGUS: `00`, `01`, `02`, ...
-        // - [100,999] CGUS: `000`, `001`, `002`, ...
+        // - [1,9]     CGUs: `0`, `1`, `2`, ...
+        // - [10,99]   CGUs: `00`, `01`, `02`, ...
+        // - [100,999] CGUs: `000`, `001`, `002`, ...
         // - etc.
         //
         // If we didn't zero-pad the sorted-by-name order would be `XYZ-cgu.0`,
@@ -458,7 +458,7 @@ fn internalize_symbols<'tcx>(
     /// used to keep track of that.
     #[derive(Clone, PartialEq, Eq, Debug)]
     enum MonoItemPlacement {
-        SingleCgu { cgu_name: Symbol },
+        SingleCgu(Symbol),
         MultipleCgus,
     }
 
@@ -466,7 +466,7 @@ fn internalize_symbols<'tcx>(
     let single_codegen_unit = codegen_units.len() == 1;
 
     if !single_codegen_unit {
-        for cgu in codegen_units.iter_mut() {
+        for cgu in codegen_units.iter() {
             for item in cgu.items().keys() {
                 // If there is more than one codegen unit, we need to keep track
                 // in which codegen units each monomorphization is placed.
@@ -474,13 +474,13 @@ fn internalize_symbols<'tcx>(
                     Entry::Occupied(e) => {
                         let placement = e.into_mut();
                         debug_assert!(match *placement {
-                            MonoItemPlacement::SingleCgu { cgu_name } => cgu_name != cgu.name(),
+                            MonoItemPlacement::SingleCgu(cgu_name) => cgu_name != cgu.name(),
                             MonoItemPlacement::MultipleCgus => true,
                         });
                         *placement = MonoItemPlacement::MultipleCgus;
                     }
                     Entry::Vacant(e) => {
-                        e.insert(MonoItemPlacement::SingleCgu { cgu_name: cgu.name() });
+                        e.insert(MonoItemPlacement::SingleCgu(cgu.name()));
                     }
                 }
             }
@@ -490,7 +490,7 @@ fn internalize_symbols<'tcx>(
     // For each internalization candidates in each codegen unit, check if it is
     // used from outside its defining codegen unit.
     for cgu in codegen_units {
-        let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
+        let home_cgu = MonoItemPlacement::SingleCgu(cgu.name());
 
         for (item, linkage_and_visibility) in cgu.items_mut() {
             if !internalization_candidates.contains(item) {
@@ -501,20 +501,20 @@ fn internalize_symbols<'tcx>(
             if !single_codegen_unit {
                 debug_assert_eq!(mono_item_placements[item], home_cgu);
 
-                if let Some(user_items) = cx.usage_map.get_user_items(*item) {
-                    if user_items
-                        .iter()
-                        .filter_map(|user_item| {
-                            // Some user mono items might not have been
-                            // instantiated. We can safely ignore those.
-                            mono_item_placements.get(user_item)
-                        })
-                        .any(|placement| *placement != home_cgu)
-                    {
-                        // Found a user from another CGU, so skip to the next item
-                        // without marking this one as internal.
-                        continue;
-                    }
+                if cx
+                    .usage_map
+                    .get_user_items(*item)
+                    .iter()
+                    .filter_map(|user_item| {
+                        // Some user mono items might not have been
+                        // instantiated. We can safely ignore those.
+                        mono_item_placements.get(user_item)
+                    })
+                    .any(|placement| *placement != home_cgu)
+                {
+                    // Found a user from another CGU, so skip to the next item
+                    // without marking this one as internal.
+                    continue;
                 }
             }
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f97cb3440d2..593983f117d 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2524,6 +2524,8 @@ pub fn build_session_options(
 
     let error_format = parse_error_format(handler, matches, color, json_rendered);
 
+    handler.abort_if_error_and_set_error_format(error_format);
+
     let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
         handler.early_error("`--diagnostic-width` must be an positive integer");
     });
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 874e34bef60..85d5bb00c4e 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,7 +7,8 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use crate::stable_mir::{self, ty::TyKind, Context};
+use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy};
+use crate::stable_mir::{self, Context};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -69,11 +70,28 @@ pub struct Tables<'tcx> {
 impl<'tcx> Tables<'tcx> {
     fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind {
         match ty.kind() {
-            ty::Bool => TyKind::Bool,
-            ty::Char => todo!(),
-            ty::Int(_) => todo!(),
-            ty::Uint(_) => todo!(),
-            ty::Float(_) => todo!(),
+            ty::Bool => TyKind::RigidTy(RigidTy::Bool),
+            ty::Char => TyKind::RigidTy(RigidTy::Char),
+            ty::Int(int_ty) => match int_ty {
+                ty::IntTy::Isize => TyKind::RigidTy(RigidTy::Int(IntTy::Isize)),
+                ty::IntTy::I8 => TyKind::RigidTy(RigidTy::Int(IntTy::I8)),
+                ty::IntTy::I16 => TyKind::RigidTy(RigidTy::Int(IntTy::I16)),
+                ty::IntTy::I32 => TyKind::RigidTy(RigidTy::Int(IntTy::I32)),
+                ty::IntTy::I64 => TyKind::RigidTy(RigidTy::Int(IntTy::I64)),
+                ty::IntTy::I128 => TyKind::RigidTy(RigidTy::Int(IntTy::I128)),
+            },
+            ty::Uint(uint_ty) => match uint_ty {
+                ty::UintTy::Usize => TyKind::RigidTy(RigidTy::Uint(UintTy::Usize)),
+                ty::UintTy::U8 => TyKind::RigidTy(RigidTy::Uint(UintTy::U8)),
+                ty::UintTy::U16 => TyKind::RigidTy(RigidTy::Uint(UintTy::U16)),
+                ty::UintTy::U32 => TyKind::RigidTy(RigidTy::Uint(UintTy::U32)),
+                ty::UintTy::U64 => TyKind::RigidTy(RigidTy::Uint(UintTy::U64)),
+                ty::UintTy::U128 => TyKind::RigidTy(RigidTy::Uint(UintTy::U128)),
+            },
+            ty::Float(float_ty) => match float_ty {
+                ty::FloatTy::F32 => TyKind::RigidTy(RigidTy::Float(FloatTy::F32)),
+                ty::FloatTy::F64 => TyKind::RigidTy(RigidTy::Float(FloatTy::F64)),
+            },
             ty::Adt(_, _) => todo!(),
             ty::Foreign(_) => todo!(),
             ty::Str => todo!(),
@@ -90,9 +108,9 @@ impl<'tcx> Tables<'tcx> {
             ty::GeneratorWitness(_) => todo!(),
             ty::GeneratorWitnessMIR(_, _) => todo!(),
             ty::Never => todo!(),
-            ty::Tuple(fields) => {
-                TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect())
-            }
+            ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
+                fields.iter().map(|ty| self.intern_ty(ty)).collect(),
+            )),
             ty::Alias(_, _) => todo!(),
             ty::Param(_) => todo!(),
             ty::Bound(_, _) => todo!(),
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index f27801b0f6c..3181af46e9c 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -9,7 +9,43 @@ impl Ty {
     }
 }
 
+#[derive(Clone, Debug)]
 pub enum TyKind {
+    RigidTy(RigidTy),
+}
+
+#[derive(Clone, Debug)]
+pub enum RigidTy {
     Bool,
+    Char,
+    Int(IntTy),
+    Uint(UintTy),
+    Float(FloatTy),
     Tuple(Vec<Ty>),
 }
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum IntTy {
+    Isize,
+    I8,
+    I16,
+    I32,
+    I64,
+    I128,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum UintTy {
+    Usize,
+    U8,
+    U16,
+    U32,
+    U64,
+    U128,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum FloatTy {
+    F32,
+    F64,
+}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 66a627d5aac..5c6d43e50ea 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -759,7 +759,6 @@ symbols! {
         from_desugaring,
         from_fn,
         from_iter,
-        from_method,
         from_output,
         from_residual,
         from_size_align_unchecked,
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index c0ee1a576e5..c388850d831 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -167,9 +167,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
         // We don't normalize opaque types unless we have
         // `Reveal::All`, even if we're in the defining scope.
         let data = match *ty.kind() {
-            ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => {
-                alias_ty
-            }
+            ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::All => alias_ty,
             _ => return ty.try_super_fold_with(self),
         };
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 5b875e19996..f342180590f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -12,7 +12,6 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
 use crate::solve::{GenerateProofTree, InferCtxtEvalExt, UseGlobalCache};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
-use crate::traits::query::normalize::QueryNormalizeExt as _;
 use crate::traits::specialize::to_pretty_impl_header;
 use crate::traits::NormalizeExt;
 use on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _};
@@ -33,7 +32,7 @@ use rustc_middle::traits::solve::Goal;
 use rustc_middle::traits::{DefiningAnchor, SelectionOutputTypeParameterMismatch};
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
 use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
@@ -63,7 +62,7 @@ pub enum CandidateSimilarity {
     Fuzzy { ignoring_lifetimes: bool },
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct ImplCandidate<'tcx> {
     pub trait_ref: ty::TraitRef<'tcx>,
     pub similarity: CandidateSimilarity,
@@ -1941,10 +1940,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         other: bool,
     ) -> bool {
         let other = if other { "other " } else { "" };
-        let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
-            candidates.sort();
-            candidates.dedup();
-            let len = candidates.len();
+        let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
             if candidates.is_empty() {
                 return false;
             }
@@ -1973,11 +1969,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 candidates.iter().map(|c| c.print_only_trait_path().to_string()).collect();
             traits.sort();
             traits.dedup();
+            // FIXME: this could use a better heuristic, like just checking
+            // that substs[1..] is the same.
+            let all_traits_equal = traits.len() == 1;
 
-            let mut candidates: Vec<String> = candidates
+            let candidates: Vec<String> = candidates
                 .into_iter()
                 .map(|c| {
-                    if traits.len() == 1 {
+                    if all_traits_equal {
                         format!("\n  {}", c.self_ty())
                     } else {
                         format!("\n  {}", c)
@@ -1985,14 +1984,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 })
                 .collect();
 
-            candidates.sort();
-            candidates.dedup();
             let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
             err.help(format!(
                 "the following {other}types implement trait `{}`:{}{}",
                 trait_ref.print_only_trait_path(),
                 candidates[..end].join(""),
-                if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
+                if candidates.len() > 9 {
+                    format!("\nand {} others", candidates.len() - 8)
+                } else {
+                    String::new()
+                }
             ));
             true
         };
@@ -2006,7 +2007,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 // Mentioning implementers of `Copy`, `Debug` and friends is not useful.
                 return false;
             }
-            let normalized_impl_candidates: Vec<_> = self
+            let mut impl_candidates: Vec<_> = self
                 .tcx
                 .all_impls(def_id)
                 // Ignore automatically derived impls and `!Trait` impls.
@@ -2033,7 +2034,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     }
                 })
                 .collect();
-            return report(normalized_impl_candidates, err);
+
+            impl_candidates.sort();
+            impl_candidates.dedup();
+            return report(impl_candidates, err);
         }
 
         // Sort impl candidates so that ordering is consistent for UI tests.
@@ -2042,27 +2046,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         //
         // Prefer more similar candidates first, then sort lexicographically
         // by their normalized string representation.
-        let mut normalized_impl_candidates_and_similarities = impl_candidates
+        let mut impl_candidates: Vec<_> = impl_candidates
             .iter()
-            .copied()
-            .map(|ImplCandidate { trait_ref, similarity }| {
-                // FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
-                let normalized = self
-                    .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
-                    .query_normalize(trait_ref)
-                    .map_or(trait_ref, |normalized| normalized.value);
-                (similarity, normalized)
+            .cloned()
+            .map(|mut cand| {
+                // Fold the consts so that they shows up as, e.g., `10`
+                // instead of `core::::array::{impl#30}::{constant#0}`.
+                cand.trait_ref = cand.trait_ref.fold_with(&mut BottomUpFolder {
+                    tcx: self.tcx,
+                    ty_op: |ty| ty,
+                    lt_op: |lt| lt,
+                    ct_op: |ct| ct.eval(self.tcx, ty::ParamEnv::empty()),
+                });
+                cand
             })
-            .collect::<Vec<_>>();
-        normalized_impl_candidates_and_similarities.sort();
-        normalized_impl_candidates_and_similarities.dedup();
-
-        let normalized_impl_candidates = normalized_impl_candidates_and_similarities
-            .into_iter()
-            .map(|(_, normalized)| normalized)
-            .collect::<Vec<_>>();
+            .collect();
+        impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref));
+        impl_candidates.dedup();
 
-        report(normalized_impl_candidates, err)
+        report(impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(), err)
     }
 
     fn report_similar_impl_candidates_for_root_obligation(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index 1e4d30f48b2..b16d2eb5fc1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -41,7 +41,6 @@ pub trait TypeErrCtxtExt<'tcx> {
 static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
     kw::SelfUpper,
     sym::ItemContext,
-    sym::from_method,
     sym::from_desugaring,
     sym::direct,
     sym::cause,
@@ -172,23 +171,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        if let ObligationCauseCode::ItemObligation(item)
-        | ObligationCauseCode::BindingObligation(item, _)
-        | ObligationCauseCode::ExprItemObligation(item, ..)
-        | ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
-        {
-            // FIXME: maybe also have some way of handling methods
-            // from other traits? That would require name resolution,
-            // which we might want to be some sort of hygienic.
-            //
-            // Currently I'm leaving it for what I need for `try`.
-            if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
-                let method = self.tcx.item_name(item);
-                flags.push((sym::from_method, None));
-                flags.push((sym::from_method, Some(method.to_string())));
-            }
-        }
-
         if let Some(k) = obligation.cause.span.desugaring_kind() {
             flags.push((sym::from_desugaring, None));
             flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
@@ -672,7 +654,7 @@ impl<'tcx> OnUnimplementedFormatString {
                             None => {
                                 if let Some(val) = options.get(&s) {
                                     val
-                                } else if s == sym::from_desugaring || s == sym::from_method {
+                                } else if s == sym::from_desugaring {
                                     // don't break messages using these two arguments incorrectly
                                     &empty_string
                                 } else if s == sym::ItemContext {
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 8cc75a6e2e3..426c98012b3 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -221,7 +221,7 @@ fn recurse_build<'tcx>(
             maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?
         }
         // dont know if this is correct
-        ExprKind::Pointer { .. } => {
+        ExprKind::PointerCoercion { .. } => {
             error(GenericConstantTooComplexSub::PointerNotSupported(node.span))?
         }
         ExprKind::Yield { .. } => {
@@ -324,7 +324,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
             | thir::ExprKind::Cast { .. }
             | thir::ExprKind::Use { .. }
             | thir::ExprKind::NeverToAny { .. }
-            | thir::ExprKind::Pointer { .. }
+            | thir::ExprKind::PointerCoercion { .. }
             | thir::ExprKind::Loop { .. }
             | thir::ExprKind::Let { .. }
             | thir::ExprKind::Match { .. }
diff --git a/config.example.toml b/config.example.toml
index 0c65b25fe13..367f95b156f 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -400,10 +400,20 @@ changelog-seen = 2
 # =============================================================================
 [rust]
 
-# Whether or not to optimize the compiler and standard library.
+# Whether or not to optimize when compiling the compiler and standard library,
+# and what level of optimization to use.
 # WARNING: Building with optimize = false is NOT SUPPORTED. Due to bootstrapping,
 # building without optimizations takes much longer than optimizing. Further, some platforms
 # fail to build without this optimization (c.f. #65352).
+# The valid options are:
+# true - Enable optimizations.
+# false - Disable optimizations.
+# 0 - Disable optimizations.
+# 1 - Basic optimizations.
+# 2 - Some optimizations.
+# 3 - All optimizations.
+# "s" - Optimize for binary size.
+# "z" - Optimize for binary size, but also turn off loop vectorization.
 #optimize = true
 
 # Indicates that the build should be configured for debugging Rust. A
@@ -757,7 +767,7 @@ changelog-seen = 2
 # This option will override the same option under [build] section.
 #profiler = build.profiler (bool)
 
-# This option supports enable `rpath` in each target independently, 
+# This option supports enable `rpath` in each target independently,
 # and will override the same option under [rust] section. It only works on Unix platforms
 #rpath = rust.rpath (bool)
 
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 1f7be85d38a..5242e97eb9a 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -133,51 +133,6 @@ pub trait Default: Sized {
     fn default() -> Self;
 }
 
-/// Return the default value of a type according to the `Default` trait.
-///
-/// The type to return is inferred from context; this is equivalent to
-/// `Default::default()` but shorter to type.
-///
-/// For example:
-/// ```
-/// #![feature(default_free_fn)]
-///
-/// use std::default::default;
-///
-/// #[derive(Default)]
-/// struct AppConfig {
-///     foo: FooConfig,
-///     bar: BarConfig,
-/// }
-///
-/// #[derive(Default)]
-/// struct FooConfig {
-///     foo: i32,
-/// }
-///
-/// #[derive(Default)]
-/// struct BarConfig {
-///     bar: f32,
-///     baz: u8,
-/// }
-///
-/// fn main() {
-///     let options = AppConfig {
-///         foo: default(),
-///         bar: BarConfig {
-///             bar: 10.1,
-///             ..default()
-///         },
-///     };
-/// }
-/// ```
-#[unstable(feature = "default_free_fn", issue = "73014")]
-#[must_use]
-#[inline]
-pub fn default<T: Default>() -> T {
-    Default::default()
-}
-
 /// Derive macro generating an impl of the trait `Default`.
 #[rustc_builtin_macro(Default, attributes(default))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 5d6e7dcfcee..e2a2428fbc2 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -851,6 +851,8 @@ impl<T> [T] {
 
     /// Swaps two elements in the slice.
     ///
+    /// If `a` equals to `b`, it's guaranteed that elements won't change value.
+    ///
     /// # Arguments
     ///
     /// * a - The index of the first element
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index bed90418be1..bc532990e94 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -500,10 +500,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f32 {
-        #[cfg(target_os = "android")]
-        return crate::sys::android::log2f32(self);
-        #[cfg(not(target_os = "android"))]
-        return unsafe { intrinsics::log2f32(self) };
+        crate::sys::log2f32(self)
     }
 
     /// Returns the base 10 logarithm of the number.
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index e72de05ca41..5af9f8bcb23 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -456,7 +456,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f64 {
-        self.log_wrapper(|n| unsafe { intrinsics::logf64(n) })
+        crate::sys::log_wrapper(self, |n| unsafe { intrinsics::logf64(n) })
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -500,12 +500,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f64 {
-        self.log_wrapper(|n| {
-            #[cfg(target_os = "android")]
-            return crate::sys::android::log2f64(n);
-            #[cfg(not(target_os = "android"))]
-            return unsafe { intrinsics::log2f64(n) };
-        })
+        crate::sys::log_wrapper(self, crate::sys::log2f64)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -525,7 +520,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f64 {
-        self.log_wrapper(|n| unsafe { intrinsics::log10f64(n) })
+        crate::sys::log_wrapper(self, |n| unsafe { intrinsics::log10f64(n) })
     }
 
     /// The positive difference of two numbers.
@@ -962,28 +957,4 @@ impl f64 {
     pub fn atanh(self) -> f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
-
-    // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
-    // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
-    // of expected NaN).
-    #[rustc_allow_incoherent_impl]
-    fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
-        if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
-            log_fn(self)
-        } else if self.is_finite() {
-            if self > 0.0 {
-                log_fn(self)
-            } else if self == 0.0 {
-                Self::NEG_INFINITY // log(0) = -Inf
-            } else {
-                Self::NAN // log(-n) = NaN
-            }
-        } else if self.is_nan() {
-            self // log(NaN) = NaN
-        } else if self > 0.0 {
-            self // log(Inf) = Inf
-        } else {
-            Self::NAN // log(-Inf) = NaN
-        }
-    }
 }
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs
index ef1f4031ef2..3322940d245 100644
--- a/library/std/src/io/copy.rs
+++ b/library/std/src/io/copy.rs
@@ -1,4 +1,8 @@
 use super::{BorrowedBuf, BufReader, BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
+use crate::alloc::Allocator;
+use crate::cmp;
+use crate::collections::VecDeque;
+use crate::io::IoSlice;
 use crate::mem::MaybeUninit;
 
 #[cfg(test)]
@@ -86,7 +90,7 @@ where
 
 /// Specialization of the read-write loop that reuses the internal
 /// buffer of a BufReader. If there's no buffer then the writer side
-/// should be used intead.
+/// should be used instead.
 trait BufferedReaderSpec {
     fn buffer_size(&self) -> usize;
 
@@ -104,7 +108,39 @@ where
     }
 
     default fn copy_to(&mut self, _to: &mut (impl Write + ?Sized)) -> Result<u64> {
-        unimplemented!("only called from specializations");
+        unreachable!("only called from specializations")
+    }
+}
+
+impl BufferedReaderSpec for &[u8] {
+    fn buffer_size(&self) -> usize {
+        // prefer this specialization since the source "buffer" is all we'll ever need,
+        // even if it's small
+        usize::MAX
+    }
+
+    fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
+        let len = self.len();
+        to.write_all(self)?;
+        *self = &self[len..];
+        Ok(len as u64)
+    }
+}
+
+impl<A: Allocator> BufferedReaderSpec for VecDeque<u8, A> {
+    fn buffer_size(&self) -> usize {
+        // prefer this specialization since the source "buffer" is all we'll ever need,
+        // even if it's small
+        usize::MAX
+    }
+
+    fn copy_to(&mut self, to: &mut (impl Write + ?Sized)) -> Result<u64> {
+        let len = self.len();
+        let (front, back) = self.as_slices();
+        let bufs = &mut [IoSlice::new(front), IoSlice::new(back)];
+        to.write_all_vectored(bufs)?;
+        self.clear();
+        Ok(len as u64)
     }
 }
 
@@ -218,6 +254,47 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
     }
 }
 
+impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
+    fn buffer_size(&self) -> usize {
+        cmp::max(DEFAULT_BUF_SIZE, self.capacity() - self.len())
+    }
+
+    fn copy_from<R: Read + ?Sized>(&mut self, reader: &mut R) -> Result<u64> {
+        let mut bytes = 0;
+
+        // avoid allocating before we have determined that there's anything to read
+        if self.capacity() == 0 {
+            bytes = stack_buffer_copy(&mut reader.take(DEFAULT_BUF_SIZE as u64), self)?;
+            if bytes == 0 {
+                return Ok(0);
+            }
+        }
+
+        loop {
+            self.reserve(DEFAULT_BUF_SIZE);
+            let mut buf: BorrowedBuf<'_> = self.spare_capacity_mut().into();
+            match reader.read_buf(buf.unfilled()) {
+                Ok(()) => {}
+                Err(e) if e.kind() == ErrorKind::Interrupted => continue,
+                Err(e) => return Err(e),
+            };
+
+            let read = buf.filled().len();
+            if read == 0 {
+                break;
+            }
+
+            // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
+            // and the number of read bytes can't exceed the spare capacity since
+            // that's what the buffer is borrowing from.
+            unsafe { self.set_len(self.len() + read) };
+            bytes += read as u64;
+        }
+
+        Ok(bytes)
+    }
+}
+
 fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
     reader: &mut R,
     writer: &mut W,
diff --git a/library/std/src/io/copy/tests.rs b/library/std/src/io/copy/tests.rs
index 8c816af15b8..af137eaf856 100644
--- a/library/std/src/io/copy/tests.rs
+++ b/library/std/src/io/copy/tests.rs
@@ -1,4 +1,6 @@
 use crate::cmp::{max, min};
+use crate::collections::VecDeque;
+use crate::io;
 use crate::io::*;
 
 #[test]
@@ -19,7 +21,7 @@ struct ShortReader {
 
 impl Read for ShortReader {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
-        let bytes = min(self.cap, self.read_size);
+        let bytes = min(self.cap, self.read_size).min(buf.len());
         self.cap -= bytes;
         self.observed_buffer = max(self.observed_buffer, buf.len());
         Ok(bytes)
@@ -78,6 +80,40 @@ fn copy_specializes_bufreader() {
     );
 }
 
+#[test]
+fn copy_specializes_to_vec() {
+    let cap = 123456;
+    let mut source = ShortReader { cap, observed_buffer: 0, read_size: 1337 };
+    let mut sink = Vec::new();
+    assert_eq!(cap as u64, io::copy(&mut source, &mut sink).unwrap());
+    assert!(
+        source.observed_buffer > DEFAULT_BUF_SIZE,
+        "expected a large buffer to be provided to the reader"
+    );
+}
+
+#[test]
+fn copy_specializes_from_vecdeque() {
+    let mut source = VecDeque::with_capacity(100 * 1024);
+    for _ in 0..20 * 1024 {
+        source.push_front(0);
+    }
+    for _ in 0..20 * 1024 {
+        source.push_back(0);
+    }
+    let mut sink = WriteObserver { observed_buffer: 0 };
+    assert_eq!(40 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
+    assert_eq!(20 * 1024, sink.observed_buffer);
+}
+
+#[test]
+fn copy_specializes_from_slice() {
+    let mut source = [1; 60 * 1024].as_slice();
+    let mut sink = WriteObserver { observed_buffer: 0 };
+    assert_eq!(60 * 1024u64, io::copy(&mut source, &mut sink).unwrap());
+    assert_eq!(60 * 1024, sink.observed_buffer);
+}
+
 #[cfg(unix)]
 mod io_benches {
     use crate::fs::File;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 72b9ad3480b..d287397aab3 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -603,7 +603,6 @@ pub mod alloc;
 
 // Private support modules
 mod panicking;
-mod personality;
 
 #[path = "../../backtrace/src/lib.rs"]
 #[allow(dead_code, unused_attributes, fuzzy_provenance_casts)]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index c72be13804d..beea3f23c2d 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -23,6 +23,7 @@
 #![allow(missing_debug_implementations)]
 
 pub mod common;
+mod personality;
 
 cfg_if::cfg_if! {
     if #[cfg(unix)] {
@@ -60,3 +61,52 @@ cfg_if::cfg_if! {
         pub const FULL_BACKTRACE_DEFAULT: bool = false;
     }
 }
+
+#[cfg(not(test))]
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "android")] {
+        pub use self::android::log2f32;
+        pub use self::android::log2f64;
+    } else {
+        #[inline]
+        pub fn log2f32(n: f32) -> f32 {
+            unsafe { crate::intrinsics::log2f32(n) }
+        }
+
+        #[inline]
+        pub fn log2f64(n: f64) -> f64 {
+            unsafe { crate::intrinsics::log2f64(n) }
+        }
+    }
+}
+
+// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
+// because of their non-standard behavior (e.g., log(-n) returns -Inf instead
+// of expected NaN).
+#[cfg(not(test))]
+#[cfg(any(target_os = "solaris", target_os = "illumos"))]
+#[inline]
+pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
+    if n.is_finite() {
+        if n > 0.0 {
+            log_fn(n)
+        } else if n == 0.0 {
+            f64::NEG_INFINITY // log(0) = -Inf
+        } else {
+            f64::NAN // log(-n) = NaN
+        }
+    } else if n.is_nan() {
+        n // log(NaN) = NaN
+    } else if n > 0.0 {
+        n // log(Inf) = Inf
+    } else {
+        f64::NAN // log(-Inf) = NaN
+    }
+}
+
+#[cfg(not(test))]
+#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
+#[inline]
+pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
+    log_fn(n)
+}
diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index 79624703a4c..79624703a4c 100644
--- a/library/std/src/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
diff --git a/library/std/src/personality/dwarf/mod.rs b/library/std/src/sys/personality/dwarf/mod.rs
index 652fbe95a14..652fbe95a14 100644
--- a/library/std/src/personality/dwarf/mod.rs
+++ b/library/std/src/sys/personality/dwarf/mod.rs
diff --git a/library/std/src/personality/dwarf/tests.rs b/library/std/src/sys/personality/dwarf/tests.rs
index 1644f37083a..1644f37083a 100644
--- a/library/std/src/personality/dwarf/tests.rs
+++ b/library/std/src/sys/personality/dwarf/tests.rs
diff --git a/library/std/src/personality/emcc.rs b/library/std/src/sys/personality/emcc.rs
index cb52ae89b19..cb52ae89b19 100644
--- a/library/std/src/personality/emcc.rs
+++ b/library/std/src/sys/personality/emcc.rs
diff --git a/library/std/src/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index 6552d96ca69..6552d96ca69 100644
--- a/library/std/src/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
diff --git a/library/std/src/personality.rs b/library/std/src/sys/personality/mod.rs
index 386a399f532..386a399f532 100644
--- a/library/std/src/personality.rs
+++ b/library/std/src/sys/personality/mod.rs
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 2b2e9e9f988..66d97a2a0d0 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -85,6 +85,10 @@ dependencies = [
 [[package]]
 name = "build_helper"
 version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
 
 [[package]]
 name = "cc"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 05b66f94727..c9bd329d430 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -665,6 +665,7 @@ impl<'a> Builder<'a> {
                 llvm::Lld,
                 llvm::CrtBeginEnd,
                 tool::RustdocGUITest,
+                tool::OptimizedDist
             ),
             Kind::Check | Kind::Clippy | Kind::Fix => describe!(
                 check::Std,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 14c3ef79a78..efe621bdb7d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -508,6 +508,49 @@ impl Step for StdLink {
         };
 
         add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
+
+        // Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0`
+        // work for stage0-sysroot. We only do this if the stage0 compiler comes from beta,
+        // and is not set to a custom path.
+        if compiler.stage == 0
+            && builder
+                .build
+                .config
+                .initial_rustc
+                .starts_with(builder.out.join(&compiler.host.triple).join("stage0/bin"))
+        {
+            // Copy bin files from stage0/bin to stage0-sysroot/bin
+            let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot");
+
+            let host = compiler.host.triple;
+            let stage0_bin_dir = builder.out.join(&host).join("stage0/bin");
+            let sysroot_bin_dir = sysroot.join("bin");
+            t!(fs::create_dir_all(&sysroot_bin_dir));
+            builder.cp_r(&stage0_bin_dir, &sysroot_bin_dir);
+
+            // Copy all *.so files from stage0/lib to stage0-sysroot/lib
+            let stage0_lib_dir = builder.out.join(&host).join("stage0/lib");
+            if let Ok(files) = fs::read_dir(&stage0_lib_dir) {
+                for file in files {
+                    let file = t!(file);
+                    let path = file.path();
+                    if path.is_file() && is_dylib(&file.file_name().into_string().unwrap()) {
+                        builder.copy(&path, &sysroot.join("lib").join(path.file_name().unwrap()));
+                    }
+                }
+            }
+
+            // Copy codegen-backends from stage0
+            let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
+            t!(fs::create_dir_all(&sysroot_codegen_backends));
+            let stage0_codegen_backends = builder
+                .out
+                .join(&host)
+                .join("stage0/lib/rustlib")
+                .join(&host)
+                .join("codegen-backends");
+            builder.cp_r(&stage0_codegen_backends, &sysroot_codegen_backends);
+        }
     }
 }
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 5f5f7ea25fb..28ae46efefe 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -875,11 +875,10 @@ impl Default for StringOrBool {
     }
 }
 
-#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
-#[serde(untagged)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub enum RustOptimize {
-    #[serde(deserialize_with = "deserialize_and_validate_opt_level")]
     String(String),
+    Int(u8),
     Bool(bool),
 }
 
@@ -889,26 +888,74 @@ impl Default for RustOptimize {
     }
 }
 
-fn deserialize_and_validate_opt_level<'de, D>(d: D) -> Result<String, D::Error>
-where
-    D: serde::de::Deserializer<'de>,
-{
-    let v = String::deserialize(d)?;
-    if ["0", "1", "2", "3", "s", "z"].iter().find(|x| **x == v).is_some() {
-        Ok(v)
-    } else {
-        Err(format!(r#"unrecognized option for rust optimize: "{}", expected one of "0", "1", "2", "3", "s", "z""#, v)).map_err(serde::de::Error::custom)
+impl<'de> Deserialize<'de> for RustOptimize {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        deserializer.deserialize_any(OptimizeVisitor)
+    }
+}
+
+struct OptimizeVisitor;
+
+impl<'de> serde::de::Visitor<'de> for OptimizeVisitor {
+    type Value = RustOptimize;
+
+    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        formatter.write_str(r#"one of: 0, 1, 2, 3, "s", "z", true, false"#)
+    }
+
+    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        if ["s", "z"].iter().find(|x| **x == value).is_some() {
+            Ok(RustOptimize::String(value.to_string()))
+        } else {
+            Err(format_optimize_error_msg(value)).map_err(serde::de::Error::custom)
+        }
+    }
+
+    fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        if matches!(value, 0..=3) {
+            Ok(RustOptimize::Int(value as u8))
+        } else {
+            Err(format_optimize_error_msg(value)).map_err(serde::de::Error::custom)
+        }
+    }
+
+    fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
+    where
+        E: serde::de::Error,
+    {
+        Ok(RustOptimize::Bool(value))
     }
 }
 
+fn format_optimize_error_msg(v: impl std::fmt::Display) -> String {
+    format!(
+        r#"unrecognized option for rust optimize: "{}", expected one of 0, 1, 2, 3, "s", "z", true, false"#,
+        v
+    )
+}
+
 impl RustOptimize {
     pub(crate) fn is_release(&self) -> bool {
-        if let RustOptimize::Bool(true) | RustOptimize::String(_) = &self { true } else { false }
+        match &self {
+            RustOptimize::Bool(true) | RustOptimize::String(_) => true,
+            RustOptimize::Int(i) => *i > 0,
+            RustOptimize::Bool(false) => false,
+        }
     }
 
     pub(crate) fn get_opt_level(&self) -> Option<String> {
         match &self {
             RustOptimize::String(s) => Some(s.clone()),
+            RustOptimize::Int(i) => Some(i.to_string()),
             RustOptimize::Bool(_) => None,
         }
     }
diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs
index 732df54cdac..c340bb2982a 100644
--- a/src/bootstrap/config/tests.rs
+++ b/src/bootstrap/config/tests.rs
@@ -184,7 +184,10 @@ fn rust_optimize() {
     assert_eq!(parse("").rust_optimize.is_release(), true);
     assert_eq!(parse("rust.optimize = false").rust_optimize.is_release(), false);
     assert_eq!(parse("rust.optimize = true").rust_optimize.is_release(), true);
-    assert_eq!(parse("rust.optimize = \"1\"").rust_optimize.get_opt_level(), Some("1".to_string()));
+    assert_eq!(parse("rust.optimize = 0").rust_optimize.is_release(), false);
+    assert_eq!(parse("rust.optimize = 1").rust_optimize.is_release(), true);
+    assert_eq!(parse("rust.optimize = 1").rust_optimize.get_opt_level(), Some("1".to_string()));
+    assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.is_release(), true);
     assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.get_opt_level(), Some("s".to_string()));
 }
 
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index 4111b7cc0d3..120b3c9c4d2 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/96971
+Last change is for: https://github.com/rust-lang/rust/pull/112931
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index c4916a21c0f..7e27960f3e9 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -352,7 +352,7 @@ impl Step for Llvm {
         // Disable zstd to avoid a dependency on libzstd.so.
         cfg.define("LLVM_ENABLE_ZSTD", "OFF");
 
-        if target != "aarch64-apple-darwin" && !target.contains("windows") {
+        if !target.contains("windows") {
             cfg.define("LLVM_ENABLE_ZLIB", "ON");
         } else {
             cfg.define("LLVM_ENABLE_ZLIB", "OFF");
diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs
index 5990f33b9bc..b73df7fe822 100644
--- a/src/bootstrap/metrics.rs
+++ b/src/bootstrap/metrics.rs
@@ -7,7 +7,10 @@
 use crate::builder::{Builder, Step};
 use crate::util::t;
 use crate::Build;
-use serde_derive::{Deserialize, Serialize};
+use build_helper::metrics::{
+    JsonInvocation, JsonInvocationSystemStats, JsonNode, JsonRoot, JsonStepSystemStats, Test,
+    TestOutcome, TestSuite, TestSuiteMetadata,
+};
 use std::cell::RefCell;
 use std::fs::File;
 use std::io::BufWriter;
@@ -241,98 +244,7 @@ struct StepMetrics {
     test_suites: Vec<TestSuite>,
 }
 
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-struct JsonRoot {
-    #[serde(default)] // For version 0 the field was not present.
-    format_version: usize,
-    system_stats: JsonInvocationSystemStats,
-    invocations: Vec<JsonInvocation>,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-struct JsonInvocation {
-    // Unix timestamp in seconds
-    //
-    // This is necessary to easily correlate this invocation with logs or other data.
-    start_time: u64,
-    duration_including_children_sec: f64,
-    children: Vec<JsonNode>,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(tag = "kind", rename_all = "snake_case")]
-enum JsonNode {
-    RustbuildStep {
-        #[serde(rename = "type")]
-        type_: String,
-        debug_repr: String,
-
-        duration_excluding_children_sec: f64,
-        system_stats: JsonStepSystemStats,
-
-        children: Vec<JsonNode>,
-    },
-    TestSuite(TestSuite),
-}
-
-#[derive(Serialize, Deserialize)]
-struct TestSuite {
-    metadata: TestSuiteMetadata,
-    tests: Vec<Test>,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(tag = "kind", rename_all = "snake_case")]
-pub(crate) enum TestSuiteMetadata {
-    CargoPackage {
-        crates: Vec<String>,
-        target: String,
-        host: String,
-        stage: u32,
-    },
-    Compiletest {
-        suite: String,
-        mode: String,
-        compare_mode: Option<String>,
-        target: String,
-        host: String,
-        stage: u32,
-    },
-}
-
-#[derive(Serialize, Deserialize)]
-pub(crate) struct Test {
-    name: String,
-    #[serde(flatten)]
-    outcome: TestOutcome,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(tag = "outcome", rename_all = "snake_case")]
-pub(crate) enum TestOutcome {
-    Passed,
-    Failed,
-    Ignored { ignore_reason: Option<String> },
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-struct JsonInvocationSystemStats {
-    cpu_threads_count: usize,
-    cpu_model: String,
-
-    memory_total_bytes: u64,
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-struct JsonStepSystemStats {
-    cpu_utilization_percent: f64,
-}
-
-#[derive(Deserialize)]
+#[derive(serde_derive::Deserialize)]
 struct OnlyFormatVersion {
     #[serde(default)] // For version 0 the field was not present.
     format_version: usize,
diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs
index 98a468c883d..ccd067053ef 100644
--- a/src/bootstrap/render_tests.rs
+++ b/src/bootstrap/render_tests.rs
@@ -141,9 +141,9 @@ impl<'a> Renderer<'a> {
         self.builder.metrics.record_test(
             &test.name,
             match outcome {
-                Outcome::Ok | Outcome::BenchOk => crate::metrics::TestOutcome::Passed,
-                Outcome::Failed => crate::metrics::TestOutcome::Failed,
-                Outcome::Ignored { reason } => crate::metrics::TestOutcome::Ignored {
+                Outcome::Ok | Outcome::BenchOk => build_helper::metrics::TestOutcome::Passed,
+                Outcome::Failed => build_helper::metrics::TestOutcome::Failed,
+                Outcome::Ignored { reason } => build_helper::metrics::TestOutcome::Ignored {
                     ignore_reason: reason.map(|s| s.to_string()),
                 },
             },
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index e4cc88c64a5..0907291b54d 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -340,7 +340,7 @@ impl Step for Cargo {
 
         #[cfg(feature = "build-metrics")]
         builder.metrics.begin_test_suite(
-            crate::metrics::TestSuiteMetadata::CargoPackage {
+            build_helper::metrics::TestSuiteMetadata::CargoPackage {
                 crates: vec!["cargo".into()],
                 target: self.host.triple.to_string(),
                 host: self.host.triple.to_string(),
@@ -799,6 +799,10 @@ impl Step for Clippy {
             // The tests succeeded; nothing to do.
             return;
         }
+
+        if !builder.config.cmd.bless() {
+            crate::detail_exit_macro!(1);
+        }
     }
 }
 
@@ -1823,7 +1827,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
 
         #[cfg(feature = "build-metrics")]
         builder.metrics.begin_test_suite(
-            crate::metrics::TestSuiteMetadata::Compiletest {
+            build_helper::metrics::TestSuiteMetadata::Compiletest {
                 suite: suite.into(),
                 mode: mode.into(),
                 compare_mode: None,
@@ -1848,7 +1852,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
 
             #[cfg(feature = "build-metrics")]
             builder.metrics.begin_test_suite(
-                crate::metrics::TestSuiteMetadata::Compiletest {
+                build_helper::metrics::TestSuiteMetadata::Compiletest {
                     suite: suite.into(),
                     mode: mode.into(),
                     compare_mode: Some(compare_mode.into()),
@@ -2196,7 +2200,7 @@ fn run_cargo_test(
 
     #[cfg(feature = "build-metrics")]
     builder.metrics.begin_test_suite(
-        crate::metrics::TestSuiteMetadata::CargoPackage {
+        build_helper::metrics::TestSuiteMetadata::CargoPackage {
             crates: crates.iter().map(|c| c.to_string()).collect(),
             target: target.triple.to_string(),
             host: compiler.host.triple.to_string(),
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 06c03178862..915dceae389 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -303,6 +303,7 @@ bootstrap_tool!(
     SuggestTests, "src/tools/suggest-tests", "suggest-tests";
     GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
     RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test";
+    OptimizedDist, "src/tools/opt-dist", "opt-dist";
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index c2fd2e3a91a..1fcb99f6d5f 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -54,7 +54,8 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
 RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
-# rustc-perf version from 2023-03-15
+# rustc-perf version from 2023-05-30
+# Should also be changed in the opt-dist tool for other environments.
 ENV PERF_COMMIT 8b2ac3042e1ff2c0074455a0a3618adef97156b1
 RUN curl -LS -o perf.zip https://github.com/rust-lang/rustc-perf/archive/$PERF_COMMIT.zip && \
     unzip perf.zip && \
@@ -81,7 +82,9 @@ ENV RUST_CONFIGURE_ARGS \
       --set rust.jemalloc \
       --set rust.use-lld=true \
       --set rust.lto=thin
-ENV SCRIPT python3 ../src/ci/stage-build.py python3 ../x.py dist \
+
+ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
+    ./build/$HOSTS/stage0-tools-bin/opt-dist python3 ../x.py dist \
     --host $HOSTS --target $HOSTS \
     --include-default-paths \
     build-manifest bootstrap
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index 1dc7b798724..a1d06ab1844 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -24,7 +24,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
   qemu-system-x86 \
   && rm -rf /var/lib/apt/lists/*
 
-RUN curl -sL https://nodejs.org/dist/v15.14.0/node-v15.14.0-linux-x64.tar.xz | \
+RUN curl -sL https://nodejs.org/dist/v18.12.0/node-v18.12.0-linux-x64.tar.xz | \
   tar -xJ
 
 # Install 32-bit OVMF files for the i686-unknown-uefi test. This package
@@ -42,7 +42,7 @@ RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS \
   --musl-root-x86_64=/usr/local/x86_64-linux-musl \
-  --set build.nodejs=/node-v15.14.0-linux-x64/bin/node \
+  --set build.nodejs=/node-v18.12.0-linux-x64/bin/node \
   --set rust.lld
 
 # Some run-make tests have assertions about code size, and enabling debug
@@ -58,6 +58,8 @@ ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_T
   tests/ui \
   tests/mir-opt \
   tests/codegen-units \
+  tests/codegen \
+  tests/assembly \
   library/core
 
 ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 24fc72e660a..b5b478e60f4 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -302,7 +302,7 @@ concurrency:
   # For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
   # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
   # are all triggered on the same branch, but which should be able to run concurrently.
-  group: ${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
+  group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
   cancel-in-progress: true
 
 jobs:
@@ -643,7 +643,7 @@ jobs:
                 --target=x86_64-pc-windows-msvc
                 --enable-full-tools
                 --enable-profiler
-              SCRIPT: PGO_HOST=x86_64-pc-windows-msvc python src/ci/stage-build.py python x.py dist bootstrap --include-default-paths
+              SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist python x.py dist bootstrap --include-default-paths
               DIST_REQUIRE_ALL_TOOLS: 1
             <<: *job-windows-8c
 
diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py
deleted file mode 100755
index 8640a3e0f34..00000000000
--- a/src/ci/stage-build.py
+++ /dev/null
@@ -1,1035 +0,0 @@
-#!/usr/bin/env python3
-# ignore-tidy-linelength
-
-# Compatible with Python 3.6+
-
-import contextlib
-import getpass
-import glob
-import json
-import logging
-import os
-import pprint
-import shutil
-import subprocess
-import sys
-import time
-import traceback
-import urllib.request
-from io import StringIO
-from pathlib import Path
-from typing import Callable, ContextManager, Dict, Iterable, Iterator, List, Optional, \
-    Tuple, Union
-
-PGO_HOST = os.environ["PGO_HOST"]
-
-LOGGER = logging.getLogger("stage-build")
-
-LLVM_PGO_CRATES = [
-    "syn-1.0.89",
-    "cargo-0.60.0",
-    "serde-1.0.136",
-    "ripgrep-13.0.0",
-    "regex-1.5.5",
-    "clap-3.1.6",
-    "hyper-0.14.18"
-]
-
-RUSTC_PGO_CRATES = [
-    "externs",
-    "ctfe-stress-5",
-    "cargo-0.60.0",
-    "token-stream-stress",
-    "match-stress",
-    "tuple-stress",
-    "diesel-1.4.8",
-    "bitmaps-3.1.0"
-]
-
-LLVM_BOLT_CRATES = LLVM_PGO_CRATES
-
-
-def is_try_build() -> bool:
-    return os.environ.get("DIST_TRY_BUILD", "0") != "0"
-
-
-class Pipeline:
-    # Paths
-    def checkout_path(self) -> Path:
-        """
-        The root checkout, where the source is located.
-        """
-        raise NotImplementedError
-
-    def downloaded_llvm_dir(self) -> Path:
-        """
-        Directory where the host LLVM is located.
-        """
-        raise NotImplementedError
-
-    def build_root(self) -> Path:
-        """
-        The main directory where the build occurs.
-        """
-        raise NotImplementedError
-
-    def build_artifacts(self) -> Path:
-        return self.build_root() / "build" / PGO_HOST
-
-    def rustc_stage_0(self) -> Path:
-        return self.build_artifacts() / "stage0" / "bin" / "rustc"
-
-    def cargo_stage_0(self) -> Path:
-        return self.build_artifacts() / "stage0" / "bin" / "cargo"
-
-    def rustc_stage_2(self) -> Path:
-        return self.build_artifacts() / "stage2" / "bin" / "rustc"
-
-    def opt_artifacts(self) -> Path:
-        raise NotImplementedError
-
-    def llvm_profile_dir_root(self) -> Path:
-        return self.opt_artifacts() / "llvm-pgo"
-
-    def llvm_profile_merged_file(self) -> Path:
-        return self.opt_artifacts() / "llvm-pgo.profdata"
-
-    def rustc_perf_dir(self) -> Path:
-        return self.opt_artifacts() / "rustc-perf"
-
-    def build_rustc_perf(self):
-        raise NotImplementedError()
-
-    def rustc_profile_dir_root(self) -> Path:
-        return self.opt_artifacts() / "rustc-pgo"
-
-    def rustc_profile_merged_file(self) -> Path:
-        return self.opt_artifacts() / "rustc-pgo.profdata"
-
-    def rustc_profile_template_path(self) -> Path:
-        """
-        The profile data is written into a single filepath that is being repeatedly merged when each
-        rustc invocation ends. Empirically, this can result in some profiling data being lost. That's
-        why we override the profile path to include the PID. This will produce many more profiling
-        files, but the resulting profile will produce a slightly faster rustc binary.
-        """
-        return self.rustc_profile_dir_root() / "default_%m_%p.profraw"
-
-    def supports_bolt(self) -> bool:
-        raise NotImplementedError
-
-    def llvm_bolt_profile_merged_file(self) -> Path:
-        return self.opt_artifacts() / "bolt.profdata"
-
-    def metrics_path(self) -> Path:
-        return self.build_root() / "build" / "metrics.json"
-
-    def executable_extension(self) -> str:
-        raise NotImplementedError
-
-    def skipped_tests(self) -> Iterable[str]:
-        return ()
-
-
-class LinuxPipeline(Pipeline):
-    def checkout_path(self) -> Path:
-        return Path("/checkout")
-
-    def downloaded_llvm_dir(self) -> Path:
-        return Path("/rustroot")
-
-    def build_root(self) -> Path:
-        return self.checkout_path() / "obj"
-
-    def opt_artifacts(self) -> Path:
-        return Path("/tmp/tmp-multistage/opt-artifacts")
-
-    def build_rustc_perf(self):
-        # /tmp/rustc-perf comes from the Dockerfile
-        shutil.copytree("/tmp/rustc-perf", self.rustc_perf_dir())
-        cmd(["chown", "-R", f"{getpass.getuser()}:", self.rustc_perf_dir()])
-
-        with change_cwd(self.rustc_perf_dir()):
-            cmd([self.cargo_stage_0(), "build", "-p", "collector"], env=dict(
-                RUSTC=str(self.rustc_stage_0()),
-                RUSTC_BOOTSTRAP="1"
-            ))
-
-    def supports_bolt(self) -> bool:
-        return True
-
-    def executable_extension(self) -> str:
-        return ""
-
-    def skipped_tests(self) -> Iterable[str]:
-        # This test fails because of linker errors, as of June 2023.
-        yield "tests/ui/process/nofile-limit.rs"
-
-
-class WindowsPipeline(Pipeline):
-    def __init__(self):
-        self.checkout_dir = Path(os.getcwd())
-
-    def checkout_path(self) -> Path:
-        return self.checkout_dir
-
-    def downloaded_llvm_dir(self) -> Path:
-        return self.checkout_path() / "citools" / "clang-rust"
-
-    def build_root(self) -> Path:
-        return self.checkout_path()
-
-    def opt_artifacts(self) -> Path:
-        return self.checkout_path() / "opt-artifacts"
-
-    def rustc_stage_0(self) -> Path:
-        return super().rustc_stage_0().with_suffix(".exe")
-
-    def cargo_stage_0(self) -> Path:
-        return super().cargo_stage_0().with_suffix(".exe")
-
-    def rustc_stage_2(self) -> Path:
-        return super().rustc_stage_2().with_suffix(".exe")
-
-    def build_rustc_perf(self):
-        # rustc-perf version from 2023-03-15
-        perf_commit = "8b2ac3042e1ff2c0074455a0a3618adef97156b1"
-        rustc_perf_zip_path = self.opt_artifacts() / "perf.zip"
-
-        def download_rustc_perf():
-            download_file(
-                f"https://github.com/rust-lang/rustc-perf/archive/{perf_commit}.zip",
-                rustc_perf_zip_path
-            )
-            with change_cwd(self.opt_artifacts()):
-                unpack_archive(rustc_perf_zip_path)
-                move_path(Path(f"rustc-perf-{perf_commit}"), self.rustc_perf_dir())
-                delete_file(rustc_perf_zip_path)
-
-        retry_action(download_rustc_perf, "Download rustc-perf")
-
-        with change_cwd(self.rustc_perf_dir()):
-            cmd([self.cargo_stage_0(), "build", "-p", "collector"], env=dict(
-                RUSTC=str(self.rustc_stage_0()),
-                RUSTC_BOOTSTRAP="1"
-            ))
-
-    def rustc_profile_template_path(self) -> Path:
-        """
-        On Windows, we don't have enough space to use separate files for each rustc invocation.
-        Therefore, we use a single file for the generated profiles.
-        """
-        return self.rustc_profile_dir_root() / "default_%m.profraw"
-
-    def supports_bolt(self) -> bool:
-        return False
-
-    def executable_extension(self) -> str:
-        return ".exe"
-
-    def skipped_tests(self) -> Iterable[str]:
-        # This test fails as of June 2023
-        yield "tests\\codegen\\vec-shrink-panik.rs"
-
-
-def get_timestamp() -> float:
-    return time.time()
-
-
-Duration = float
-
-
-def iterate_timers(timer: "Timer", name: str, level: int = 0) -> Iterator[
-    Tuple[int, str, Duration]]:
-    """
-    Hierarchically iterate the children of a timer, in a depth-first order.
-    """
-    yield (level, name, timer.total_duration())
-    for (child_name, child_timer) in timer.children:
-        yield from iterate_timers(child_timer, child_name, level=level + 1)
-
-
-class Timer:
-    def __init__(self, parent_names: Tuple[str, ...] = ()):
-        self.children: List[Tuple[str, Timer]] = []
-        self.section_active = False
-        self.parent_names = parent_names
-        self.duration_excluding_children: Duration = 0
-
-    @contextlib.contextmanager
-    def section(self, name: str) -> ContextManager["Timer"]:
-        assert not self.section_active
-        self.section_active = True
-
-        start = get_timestamp()
-        exc = None
-
-        child_timer = Timer(parent_names=self.parent_names + (name,))
-        full_name = " > ".join(child_timer.parent_names)
-        try:
-            LOGGER.info(f"Section `{full_name}` starts")
-            yield child_timer
-        except BaseException as exception:
-            exc = exception
-            raise
-        finally:
-            end = get_timestamp()
-            duration = end - start
-
-            child_timer.duration_excluding_children = duration - child_timer.total_duration()
-            self.add_child(name, child_timer)
-            if exc is None:
-                LOGGER.info(f"Section `{full_name}` ended: OK ({duration:.2f}s)")
-            else:
-                LOGGER.info(f"Section `{full_name}` ended: FAIL ({duration:.2f}s)")
-            self.section_active = False
-
-    def total_duration(self) -> Duration:
-        return self.duration_excluding_children + sum(
-            c.total_duration() for (_, c) in self.children)
-
-    def has_children(self) -> bool:
-        return len(self.children) > 0
-
-    def print_stats(self):
-        rows = []
-        for (child_name, child_timer) in self.children:
-            for (level, name, duration) in iterate_timers(child_timer, child_name, level=0):
-                label = f"{'  ' * level}{name}:"
-                rows.append((label, duration))
-
-        # Empty row
-        rows.append(("", ""))
-
-        total_duration_label = "Total duration:"
-        total_duration = self.total_duration()
-        rows.append((total_duration_label, humantime(total_duration)))
-
-        space_after_label = 2
-        max_label_length = max(16, max(len(label) for (label, _) in rows)) + space_after_label
-
-        table_width = max_label_length + 23
-        divider = "-" * table_width
-
-        with StringIO() as output:
-            print(divider, file=output)
-            for (label, duration) in rows:
-                if isinstance(duration, Duration):
-                    pct = (duration / total_duration) * 100
-                    value = f"{duration:>12.2f}s ({pct:>5.2f}%)"
-                else:
-                    value = f"{duration:>{len(total_duration_label) + 7}}"
-                print(f"{label:<{max_label_length}} {value}", file=output)
-            print(divider, file=output, end="")
-            LOGGER.info(f"Timer results\n{output.getvalue()}")
-
-    def add_child(self, name: str, timer: "Timer"):
-        self.children.append((name, timer))
-
-    def add_duration(self, name: str, duration: Duration):
-        timer = Timer(parent_names=self.parent_names + (name,))
-        timer.duration_excluding_children = duration
-        self.add_child(name, timer)
-
-
-class BuildStep:
-    def __init__(self, type: str, children: List["BuildStep"], duration: float):
-        self.type = type
-        self.children = children
-        self.duration = duration
-
-    def find_all_by_type(self, type: str) -> Iterator["BuildStep"]:
-        if type == self.type:
-            yield self
-        for child in self.children:
-            yield from child.find_all_by_type(type)
-
-    def __repr__(self):
-        return f"BuildStep(type={self.type}, duration={self.duration}, children={len(self.children)})"
-
-
-def load_last_metrics(path: Path) -> BuildStep:
-    """
-    Loads the metrics of the most recent bootstrap execution from a metrics.json file.
-    """
-    with open(path, "r") as f:
-        metrics = json.load(f)
-    invocation = metrics["invocations"][-1]
-
-    def parse(entry) -> Optional[BuildStep]:
-        if "kind" not in entry or entry["kind"] != "rustbuild_step":
-            return None
-        type = entry.get("type", "")
-        duration = entry.get("duration_excluding_children_sec", 0)
-        children = []
-
-        for child in entry.get("children", ()):
-            step = parse(child)
-            if step is not None:
-                children.append(step)
-                duration += step.duration
-        return BuildStep(type=type, children=children, duration=duration)
-
-    children = [parse(child) for child in invocation.get("children", ())]
-    return BuildStep(
-        type="root",
-        children=children,
-        duration=invocation.get("duration_including_children_sec", 0)
-    )
-
-
-@contextlib.contextmanager
-def change_cwd(dir: Path):
-    """
-    Temporarily change working directory to `dir`.
-    """
-    cwd = os.getcwd()
-    LOGGER.debug(f"Changing working dir from `{cwd}` to `{dir}`")
-    os.chdir(dir)
-    try:
-        yield
-    finally:
-        LOGGER.debug(f"Reverting working dir to `{cwd}`")
-        os.chdir(cwd)
-
-
-def humantime(time_s: float) -> str:
-    hours = time_s // 3600
-    time_s = time_s % 3600
-    minutes = time_s // 60
-    seconds = time_s % 60
-
-    result = ""
-    if hours > 0:
-        result += f"{int(hours)}h "
-    if minutes > 0:
-        result += f"{int(minutes)}m "
-    result += f"{round(seconds)}s"
-    return result
-
-
-def move_path(src: Path, dst: Path):
-    LOGGER.info(f"Moving `{src}` to `{dst}`")
-    shutil.move(src, dst)
-
-
-def delete_file(path: Path):
-    LOGGER.info(f"Deleting file `{path}`")
-    os.unlink(path)
-
-
-def delete_directory(path: Path):
-    LOGGER.info(f"Deleting directory `{path}`")
-    shutil.rmtree(path)
-
-
-def unpack_archive(archive: Path, target_dir: Optional[Path] = None):
-    LOGGER.info(f"Unpacking archive `{archive}`")
-    shutil.unpack_archive(str(archive), extract_dir=str(target_dir) if target_dir is not None else None)
-
-
-def download_file(src: str, target: Path):
-    LOGGER.info(f"Downloading `{src}` into `{target}`")
-    urllib.request.urlretrieve(src, str(target))
-
-
-def retry_action(action, name: str, max_fails: int = 5):
-    LOGGER.info(f"Attempting to perform action `{name}` with retry")
-    for iteration in range(max_fails):
-        LOGGER.info(f"Attempt {iteration + 1}/{max_fails}")
-        try:
-            action()
-            return
-        except BaseException: # also catch ctrl+c/sysexit
-            LOGGER.error(f"Action `{name}` has failed\n{traceback.format_exc()}")
-
-    raise Exception(f"Action `{name}` has failed after {max_fails} attempts")
-
-
-def cmd(
-        args: List[Union[str, Path]],
-        env: Optional[Dict[str, str]] = None,
-        output_path: Optional[Path] = None
-):
-    args = [str(arg) for arg in args]
-
-    environment = os.environ.copy()
-
-    cmd_str = ""
-    if env is not None:
-        environment.update(env)
-        cmd_str += " ".join(f"{k}={v}" for (k, v) in (env or {}).items())
-        cmd_str += " "
-    cmd_str += " ".join(args)
-    if output_path is not None:
-        cmd_str += f" > {output_path}"
-    LOGGER.info(f"Executing `{cmd_str}`")
-
-    if output_path is not None:
-        with open(output_path, "w") as f:
-            return subprocess.run(
-                args,
-                env=environment,
-                check=True,
-                stdout=f
-            )
-    return subprocess.run(args, env=environment, check=True)
-
-
-class BenchmarkRunner:
-    def run_rustc(self, pipeline: Pipeline):
-        raise NotImplementedError
-
-    def run_llvm(self, pipeline: Pipeline):
-        raise NotImplementedError
-
-    def run_bolt(self, pipeline: Pipeline):
-        raise NotImplementedError
-
-
-class DefaultBenchmarkRunner(BenchmarkRunner):
-    def run_rustc(self, pipeline: Pipeline):
-        # Here we're profiling the `rustc` frontend, so we also include `Check`.
-        # The benchmark set includes various stress tests that put the frontend under pressure.
-        run_compiler_benchmarks(
-            pipeline,
-            profiles=["Check", "Debug", "Opt"],
-            scenarios=["All"],
-            crates=RUSTC_PGO_CRATES,
-            env=dict(
-                LLVM_PROFILE_FILE=str(pipeline.rustc_profile_template_path())
-            )
-        )
-
-    def run_llvm(self, pipeline: Pipeline):
-        run_compiler_benchmarks(
-            pipeline,
-            profiles=["Debug", "Opt"],
-            scenarios=["Full"],
-            crates=LLVM_PGO_CRATES
-        )
-
-    def run_bolt(self, pipeline: Pipeline):
-        run_compiler_benchmarks(
-            pipeline,
-            profiles=["Check", "Debug", "Opt"],
-            scenarios=["Full"],
-            crates=LLVM_BOLT_CRATES
-        )
-
-
-def run_compiler_benchmarks(
-        pipeline: Pipeline,
-        profiles: List[str],
-        scenarios: List[str],
-        crates: List[str],
-        env: Optional[Dict[str, str]] = None
-):
-    env = env if env is not None else {}
-
-    # Compile libcore, both in opt-level=0 and opt-level=3
-    with change_cwd(pipeline.build_root()):
-        cmd([
-            pipeline.rustc_stage_2(),
-            "--edition", "2021",
-            "--crate-type", "lib",
-            str(pipeline.checkout_path() / "library/core/src/lib.rs"),
-            "--out-dir", pipeline.opt_artifacts()
-        ], env=dict(RUSTC_BOOTSTRAP="1", **env))
-
-        cmd([
-            pipeline.rustc_stage_2(),
-            "--edition", "2021",
-            "--crate-type", "lib",
-            "-Copt-level=3",
-            str(pipeline.checkout_path() / "library/core/src/lib.rs"),
-            "--out-dir", pipeline.opt_artifacts()
-        ], env=dict(RUSTC_BOOTSTRAP="1", **env))
-
-    # Run rustc-perf benchmarks
-    # Benchmark using profile_local with eprintln, which essentially just means
-    # don't actually benchmark -- just make sure we run rustc a bunch of times.
-    with change_cwd(pipeline.rustc_perf_dir()):
-        cmd([
-            pipeline.cargo_stage_0(),
-            "run",
-            "-p", "collector", "--bin", "collector", "--",
-            "profile_local", "eprintln",
-            pipeline.rustc_stage_2(),
-            "--id", "Test",
-            "--cargo", pipeline.cargo_stage_0(),
-            "--profiles", ",".join(profiles),
-            "--scenarios", ",".join(scenarios),
-            "--include", ",".join(crates)
-        ], env=dict(
-            RUST_LOG="collector=debug",
-            RUSTC=str(pipeline.rustc_stage_0()),
-            RUSTC_BOOTSTRAP="1",
-            **env
-        ))
-
-
-# https://stackoverflow.com/a/31631711/1107768
-def format_bytes(size: int) -> str:
-    """Return the given bytes as a human friendly KiB, MiB or GiB string."""
-    KB = 1024
-    MB = KB ** 2  # 1,048,576
-    GB = KB ** 3  # 1,073,741,824
-    TB = KB ** 4  # 1,099,511,627,776
-
-    if size < KB:
-        return f"{size} B"
-    elif KB <= size < MB:
-        return f"{size / KB:.2f} KiB"
-    elif MB <= size < GB:
-        return f"{size / MB:.2f} MiB"
-    elif GB <= size < TB:
-        return f"{size / GB:.2f} GiB"
-    else:
-        return str(size)
-
-
-# https://stackoverflow.com/a/63307131/1107768
-def count_files(path: Path) -> int:
-    return sum(1 for p in path.rglob("*") if p.is_file())
-
-
-def count_files_with_prefix(path: Path) -> int:
-    return sum(1 for p in glob.glob(f"{path}*") if Path(p).is_file())
-
-
-# https://stackoverflow.com/a/55659577/1107768
-def get_path_size(path: Path) -> int:
-    if path.is_dir():
-        return sum(p.stat().st_size for p in path.rglob("*"))
-    return path.stat().st_size
-
-
-def get_path_prefix_size(path: Path) -> int:
-    """
-    Get size of all files beginning with the prefix `path`.
-    Alternative to shell `du -sh <path>*`.
-    """
-    return sum(Path(p).stat().st_size for p in glob.glob(f"{path}*"))
-
-
-def get_files(directory: Path, filter: Optional[Callable[[Path], bool]] = None) -> Iterable[Path]:
-    for file in os.listdir(directory):
-        path = directory / file
-        if filter is None or filter(path):
-            yield path
-
-
-def bootstrap_build(
-        pipeline: Pipeline,
-        args: List[str],
-        env: Optional[Dict[str, str]] = None,
-        targets: Iterable[str] = ("library/std", )
-):
-    if env is None:
-        env = {}
-    else:
-        env = dict(env)
-    env["RUST_BACKTRACE"] = "1"
-    arguments = [
-                    sys.executable,
-                    pipeline.checkout_path() / "x.py",
-                    "build",
-                    "--target", PGO_HOST,
-                    "--host", PGO_HOST,
-                    "--stage", "2",
-                    ] + list(targets) + args
-    cmd(arguments, env=env)
-
-
-def create_pipeline() -> Pipeline:
-    if sys.platform == "linux":
-        return LinuxPipeline()
-    elif sys.platform in ("cygwin", "win32"):
-        return WindowsPipeline()
-    else:
-        raise Exception(f"Optimized build is not supported for platform {sys.platform}")
-
-
-def gather_llvm_profiles(pipeline: Pipeline, runner: BenchmarkRunner):
-    LOGGER.info("Running benchmarks with PGO instrumented LLVM")
-
-    runner.run_llvm(pipeline)
-
-    profile_path = pipeline.llvm_profile_merged_file()
-    LOGGER.info(f"Merging LLVM PGO profiles to {profile_path}")
-    cmd([
-        pipeline.downloaded_llvm_dir() / "bin" / "llvm-profdata",
-        "merge",
-        "-o", profile_path,
-        pipeline.llvm_profile_dir_root()
-    ])
-
-    LOGGER.info("LLVM PGO statistics")
-    LOGGER.info(f"{profile_path}: {format_bytes(get_path_size(profile_path))}")
-    LOGGER.info(
-        f"{pipeline.llvm_profile_dir_root()}: {format_bytes(get_path_size(pipeline.llvm_profile_dir_root()))}")
-    LOGGER.info(f"Profile file count: {count_files(pipeline.llvm_profile_dir_root())}")
-
-    # We don't need the individual .profraw files now that they have been merged
-    # into a final .profdata
-    delete_directory(pipeline.llvm_profile_dir_root())
-
-
-def gather_rustc_profiles(pipeline: Pipeline, runner: BenchmarkRunner):
-    LOGGER.info("Running benchmarks with PGO instrumented rustc")
-
-    runner.run_rustc(pipeline)
-
-    profile_path = pipeline.rustc_profile_merged_file()
-    LOGGER.info(f"Merging Rustc PGO profiles to {profile_path}")
-    cmd([
-        pipeline.build_artifacts() / "llvm" / "bin" / "llvm-profdata",
-        "merge",
-        "-o", profile_path,
-        pipeline.rustc_profile_dir_root()
-    ])
-
-    LOGGER.info("Rustc PGO statistics")
-    LOGGER.info(f"{profile_path}: {format_bytes(get_path_size(profile_path))}")
-    LOGGER.info(
-        f"{pipeline.rustc_profile_dir_root()}: {format_bytes(get_path_size(pipeline.rustc_profile_dir_root()))}")
-    LOGGER.info(f"Profile file count: {count_files(pipeline.rustc_profile_dir_root())}")
-
-    # We don't need the individual .profraw files now that they have been merged
-    # into a final .profdata
-    delete_directory(pipeline.rustc_profile_dir_root())
-
-
-def gather_llvm_bolt_profiles(pipeline: Pipeline, runner: BenchmarkRunner):
-    LOGGER.info("Running benchmarks with BOLT instrumented LLVM")
-
-    runner.run_bolt(pipeline)
-
-    merged_profile_path = pipeline.llvm_bolt_profile_merged_file()
-    profile_files_path = Path("/tmp/prof.fdata")
-    LOGGER.info(f"Merging LLVM BOLT profiles to {merged_profile_path}")
-
-    profile_files = sorted(glob.glob(f"{profile_files_path}*"))
-    cmd([
-        "merge-fdata",
-        *profile_files,
-    ], output_path=merged_profile_path)
-
-    LOGGER.info("LLVM BOLT statistics")
-    LOGGER.info(f"{merged_profile_path}: {format_bytes(get_path_size(merged_profile_path))}")
-    LOGGER.info(
-        f"{profile_files_path}: {format_bytes(get_path_prefix_size(profile_files_path))}")
-    LOGGER.info(f"Profile file count: {count_files_with_prefix(profile_files_path)}")
-
-
-def clear_llvm_files(pipeline: Pipeline):
-    """
-    Rustbuild currently doesn't support rebuilding LLVM when PGO options
-    change (or any other llvm-related options); so just clear out the relevant
-    directories ourselves.
-    """
-    LOGGER.info("Clearing LLVM build files")
-    delete_directory(pipeline.build_artifacts() / "llvm")
-    delete_directory(pipeline.build_artifacts() / "lld")
-
-
-def print_binary_sizes(pipeline: Pipeline):
-    bin_dir = pipeline.build_artifacts() / "stage2" / "bin"
-    binaries = get_files(bin_dir)
-
-    lib_dir = pipeline.build_artifacts() / "stage2" / "lib"
-    libraries = get_files(lib_dir, lambda p: p.suffix == ".so")
-
-    paths = sorted(binaries) + sorted(libraries)
-    with StringIO() as output:
-        for path in paths:
-            path_str = f"{path.name}:"
-            print(f"{path_str:<50}{format_bytes(path.stat().st_size):>14}", file=output)
-        LOGGER.info(f"Rustc binary size\n{output.getvalue()}")
-
-
-def print_free_disk_space(pipeline: Pipeline):
-    usage = shutil.disk_usage(pipeline.opt_artifacts())
-    total = usage.total
-    used = usage.used
-    free = usage.free
-
-    logging.info(
-        f"Free disk space: {format_bytes(free)} out of total {format_bytes(total)} ({(used / total) * 100:.2f}% used)")
-
-
-def log_metrics(step: BuildStep):
-    substeps: List[Tuple[int, BuildStep]] = []
-
-    def visit(step: BuildStep, level: int):
-        substeps.append((level, step))
-        for child in step.children:
-            visit(child, level=level + 1)
-
-    visit(step, 0)
-
-    output = StringIO()
-    for (level, step) in substeps:
-        label = f"{'.' * level}{step.type}"
-        print(f"{label:<65}{step.duration:>8.2f}s", file=output)
-    logging.info(f"Build step durations\n{output.getvalue()}")
-
-
-def record_metrics(pipeline: Pipeline, timer: Timer):
-    metrics = load_last_metrics(pipeline.metrics_path())
-    if metrics is None:
-        return
-    llvm_steps = tuple(metrics.find_all_by_type("bootstrap::llvm::Llvm"))
-    llvm_duration = sum(step.duration for step in llvm_steps)
-
-    rustc_steps = tuple(metrics.find_all_by_type("bootstrap::compile::Rustc"))
-    rustc_duration = sum(step.duration for step in rustc_steps)
-
-    # The LLVM step is part of the Rustc step
-    rustc_duration = max(0, rustc_duration - llvm_duration)
-
-    if llvm_duration > 0:
-        timer.add_duration("LLVM", llvm_duration)
-    if rustc_duration > 0:
-        timer.add_duration("Rustc", rustc_duration)
-
-    log_metrics(metrics)
-
-
-def run_tests(pipeline: Pipeline):
-    """
-    After `dist` is executed, we extract its archived components into a sysroot directory,
-    and then use that extracted rustc as a stage0 compiler.
-    Then we run a subset of tests using that compiler, to have a basic smoke test which checks
-    whether the optimization pipeline hasn't broken something.
-    """
-    build_dir = pipeline.build_root() / "build"
-    dist_dir = build_dir / "dist"
-
-    def extract_dist_dir(name: str) -> Path:
-        target_dir = build_dir / "optimized-dist"
-        target_dir.mkdir(parents=True, exist_ok=True)
-        unpack_archive(dist_dir / f"{name}.tar.xz", target_dir=target_dir)
-        extracted_path = target_dir / name
-        assert extracted_path.is_dir()
-        return extracted_path
-
-    # Extract rustc, libstd, cargo and src archives to create the optimized sysroot
-    rustc_dir = extract_dist_dir(f"rustc-nightly-{PGO_HOST}") / "rustc"
-    libstd_dir = extract_dist_dir(f"rust-std-nightly-{PGO_HOST}") / f"rust-std-{PGO_HOST}"
-    cargo_dir = extract_dist_dir(f"cargo-nightly-{PGO_HOST}") / "cargo"
-    extracted_src_dir = extract_dist_dir("rust-src-nightly") / "rust-src"
-
-    # We need to manually copy libstd to the extracted rustc sysroot
-    shutil.copytree(
-        libstd_dir / "lib" / "rustlib" / PGO_HOST / "lib",
-        rustc_dir / "lib" / "rustlib" / PGO_HOST / "lib"
-    )
-
-    # Extract sources - they aren't in the `rustc-nightly-{host}` tarball, so we need to manually copy libstd
-    # sources to the extracted sysroot. We need sources available so that `-Zsimulate-remapped-rust-src-base`
-    # works correctly.
-    shutil.copytree(
-        extracted_src_dir / "lib" / "rustlib" / "src",
-        rustc_dir / "lib" / "rustlib" / "src"
-    )
-
-    rustc_path = rustc_dir / "bin" / f"rustc{pipeline.executable_extension()}"
-    assert rustc_path.is_file()
-    cargo_path = cargo_dir / "bin" / f"cargo{pipeline.executable_extension()}"
-    assert cargo_path.is_file()
-
-    # Specify path to a LLVM config so that LLVM is not rebuilt.
-    # It doesn't really matter which LLVM config we choose, because no sysroot will be compiled.
-    llvm_config = pipeline.build_artifacts() / "llvm" / "bin" / f"llvm-config{pipeline.executable_extension()}"
-    assert llvm_config.is_file()
-
-    config_content = f"""profile = "user"
-changelog-seen = 2
-
-[build]
-rustc = "{rustc_path.as_posix()}"
-cargo = "{cargo_path.as_posix()}"
-
-[target.{PGO_HOST}]
-llvm-config = "{llvm_config.as_posix()}"
-"""
-    logging.info(f"Using following `config.toml` for running tests:\n{config_content}")
-
-    # Simulate a stage 0 compiler with the extracted optimized dist artifacts.
-    with open("config.toml", "w") as f:
-        f.write(config_content)
-
-    args = [
-        sys.executable,
-        pipeline.checkout_path() / "x.py",
-        "test",
-        "--stage", "0",
-        "tests/assembly",
-        "tests/codegen",
-        "tests/codegen-units",
-        "tests/incremental",
-        "tests/mir-opt",
-        "tests/pretty",
-        "tests/run-pass-valgrind",
-        "tests/ui",
-        ]
-    for test_path in pipeline.skipped_tests():
-        args.extend(["--exclude", test_path])
-    cmd(args=args, env=dict(
-        COMPILETEST_FORCE_STAGE0="1"
-    ))
-
-
-def execute_build_pipeline(timer: Timer, pipeline: Pipeline, runner: BenchmarkRunner, dist_build_args: List[str]):
-    # Clear and prepare tmp directory
-    shutil.rmtree(pipeline.opt_artifacts(), ignore_errors=True)
-    os.makedirs(pipeline.opt_artifacts(), exist_ok=True)
-
-    pipeline.build_rustc_perf()
-
-    """
-    Stage 1: Build PGO instrumented rustc
-
-    We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the same time
-    can cause issues.
-    """
-    with timer.section("Stage 1 (rustc PGO)") as stage1:
-        with stage1.section("Build PGO instrumented rustc and LLVM") as rustc_pgo_instrument:
-            bootstrap_build(pipeline, args=[
-                "--rust-profile-generate",
-                pipeline.rustc_profile_dir_root()
-            ])
-            record_metrics(pipeline, rustc_pgo_instrument)
-
-        with stage1.section("Gather profiles"):
-            gather_rustc_profiles(pipeline, runner)
-        print_free_disk_space(pipeline)
-
-        with stage1.section("Build PGO optimized rustc") as rustc_pgo_use:
-            bootstrap_build(pipeline, args=[
-                "--rust-profile-use",
-                pipeline.rustc_profile_merged_file()
-            ])
-            record_metrics(pipeline, rustc_pgo_use)
-        dist_build_args += [
-            "--rust-profile-use",
-            pipeline.rustc_profile_merged_file()
-        ]
-
-    """
-    Stage 2: Gather LLVM PGO profiles
-    """
-    with timer.section("Stage 2 (LLVM PGO)") as stage2:
-        # Clear normal LLVM artifacts
-        clear_llvm_files(pipeline)
-
-        with stage2.section("Build PGO instrumented LLVM") as llvm_pgo_instrument:
-            bootstrap_build(pipeline, args=[
-                "--llvm-profile-generate",
-                # We want to keep the already built PGO-optimized `rustc`.
-                "--keep-stage", "0",
-                "--keep-stage", "1"
-            ], env=dict(
-                LLVM_PROFILE_DIR=str(pipeline.llvm_profile_dir_root() / "prof-%p")
-            ))
-            record_metrics(pipeline, llvm_pgo_instrument)
-
-        with stage2.section("Gather profiles"):
-            gather_llvm_profiles(pipeline, runner)
-
-        dist_build_args += [
-            "--llvm-profile-use",
-            pipeline.llvm_profile_merged_file(),
-        ]
-        print_free_disk_space(pipeline)
-
-        # Clear PGO-instrumented LLVM artifacts
-        clear_llvm_files(pipeline)
-
-    """
-    Stage 3: Build BOLT instrumented LLVM
-
-    We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
-    Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
-    BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
-    therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
-    """
-    if pipeline.supports_bolt():
-        with timer.section("Stage 3 (LLVM BOLT)") as stage3:
-            with stage3.section("Build BOLT instrumented LLVM") as llvm_bolt_instrument:
-                bootstrap_build(pipeline, args=[
-                    "--llvm-profile-use",
-                    pipeline.llvm_profile_merged_file(),
-                    "--llvm-bolt-profile-generate",
-                    # We want to keep the already built PGO-optimized `rustc`.
-                    "--keep-stage", "0",
-                    "--keep-stage", "1"
-                ])
-                record_metrics(pipeline, llvm_bolt_instrument)
-
-            with stage3.section("Gather profiles"):
-                gather_llvm_bolt_profiles(pipeline, runner)
-
-            dist_build_args += [
-                "--llvm-bolt-profile-use",
-                pipeline.llvm_bolt_profile_merged_file()
-            ]
-            print_free_disk_space(pipeline)
-
-    # We want to keep the already built PGO-optimized `rustc`.
-    dist_build_args += [
-        "--keep-stage", "0",
-        "--keep-stage", "1"
-    ]
-
-    """
-    Final stage: Build PGO optimized rustc + PGO/BOLT optimized LLVM
-    """
-    with timer.section("Final stage (dist build)") as final_stage:
-        cmd(dist_build_args)
-        record_metrics(pipeline, final_stage)
-
-    # Try builds can be in various broken states, so we don't want to gatekeep them with tests
-    if not is_try_build():
-        with timer.section("Run tests"):
-            run_tests(pipeline)
-
-
-def run(runner: BenchmarkRunner):
-    logging.basicConfig(
-        level=logging.DEBUG,
-        format="%(name)s %(levelname)-4s: %(message)s",
-    )
-
-    LOGGER.info(f"Running multi-stage build using Python {sys.version}")
-    LOGGER.info(f"Environment values\n{pprint.pformat(dict(os.environ), indent=2)}")
-
-    build_args = sys.argv[1:]
-
-    # Skip components that are not needed for try builds to speed them up
-    if is_try_build():
-        LOGGER.info("Skipping building of unimportant components for a try build")
-        for target in ("rust-docs", "rustc-docs", "rust-docs-json", "rust-analyzer",
-                       "rustc-src", "clippy", "miri", "rustfmt"):
-            build_args.extend(["--exclude", target])
-
-    timer = Timer()
-    pipeline = create_pipeline()
-
-    try:
-        execute_build_pipeline(timer, pipeline, runner, build_args)
-    except BaseException as e:
-        LOGGER.error("The multi-stage build has failed")
-        raise e
-    finally:
-        timer.print_stats()
-        print_free_disk_space(pipeline)
-
-    print_binary_sizes(pipeline)
-
-
-if __name__ == "__main__":
-    runner = DefaultBenchmarkRunner()
-    run(runner)
diff --git a/src/doc/unstable-book/src/library-features/default-free-fn.md b/src/doc/unstable-book/src/library-features/default-free-fn.md
deleted file mode 100644
index bafc9ac4d0d..00000000000
--- a/src/doc/unstable-book/src/library-features/default-free-fn.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# `default_free_fn`
-
-The tracking issue for this feature is: [#73014]
-
-[#73014]: https://github.com/rust-lang/rust/issues/73014
-
-------------------------
-
-Adds a free `default()` function to the `std::default` module.  This function
-just forwards to [`Default::default()`], but may remove repetition of the word
-"default" from the call site.
-
-[`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default
-
-Here is an example:
-
-```rust
-#![feature(default_free_fn)]
-use std::default::default;
-
-#[derive(Default)]
-struct AppConfig {
-    foo: FooConfig,
-    bar: BarConfig,
-}
-
-#[derive(Default)]
-struct FooConfig {
-    foo: i32,
-}
-
-#[derive(Default)]
-struct BarConfig {
-    bar: f32,
-    baz: u8,
-}
-
-fn main() {
-    let options = AppConfig {
-        foo: default(),
-        bar: BarConfig {
-            bar: 10.1,
-            ..default()
-        },
-    };
-}
-```
diff --git a/src/tools/build_helper/Cargo.toml b/src/tools/build_helper/Cargo.toml
index 99f6fea2ecf..66894e1abc4 100644
--- a/src/tools/build_helper/Cargo.toml
+++ b/src/tools/build_helper/Cargo.toml
@@ -6,3 +6,5 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+serde = "1"
+serde_derive = "1"
diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs
index 3fa970373b3..575f3677155 100644
--- a/src/tools/build_helper/src/lib.rs
+++ b/src/tools/build_helper/src/lib.rs
@@ -1,3 +1,4 @@
 pub mod ci;
 pub mod git;
+pub mod metrics;
 pub mod util;
diff --git a/src/tools/build_helper/src/metrics.rs b/src/tools/build_helper/src/metrics.rs
new file mode 100644
index 00000000000..2d0c66a8f33
--- /dev/null
+++ b/src/tools/build_helper/src/metrics.rs
@@ -0,0 +1,92 @@
+use serde_derive::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub struct JsonRoot {
+    #[serde(default)] // For version 0 the field was not present.
+    pub format_version: usize,
+    pub system_stats: JsonInvocationSystemStats,
+    pub invocations: Vec<JsonInvocation>,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub struct JsonInvocation {
+    // Unix timestamp in seconds
+    //
+    // This is necessary to easily correlate this invocation with logs or other data.
+    pub start_time: u64,
+    pub duration_including_children_sec: f64,
+    pub children: Vec<JsonNode>,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(tag = "kind", rename_all = "snake_case")]
+pub enum JsonNode {
+    RustbuildStep {
+        #[serde(rename = "type")]
+        type_: String,
+        debug_repr: String,
+
+        duration_excluding_children_sec: f64,
+        system_stats: JsonStepSystemStats,
+
+        children: Vec<JsonNode>,
+    },
+    TestSuite(TestSuite),
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct TestSuite {
+    pub metadata: TestSuiteMetadata,
+    pub tests: Vec<Test>,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(tag = "kind", rename_all = "snake_case")]
+pub enum TestSuiteMetadata {
+    CargoPackage {
+        crates: Vec<String>,
+        target: String,
+        host: String,
+        stage: u32,
+    },
+    Compiletest {
+        suite: String,
+        mode: String,
+        compare_mode: Option<String>,
+        target: String,
+        host: String,
+        stage: u32,
+    },
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct Test {
+    pub name: String,
+    #[serde(flatten)]
+    pub outcome: TestOutcome,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(tag = "outcome", rename_all = "snake_case")]
+pub enum TestOutcome {
+    Passed,
+    Failed,
+    Ignored { ignore_reason: Option<String> },
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub struct JsonInvocationSystemStats {
+    pub cpu_threads_count: usize,
+    pub cpu_model: String,
+
+    pub memory_total_bytes: u64,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub struct JsonStepSystemStats {
+    pub cpu_utilization_percent: f64,
+}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 5b377cece0e0dd0af686cf53ce4637d5d85c2a1
+Subproject 45782b6b8afd1da042d45c2daeec9c0744f72cc
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index ec0ca50cfec..020ffe7f8fa 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -9,7 +9,7 @@ use rustc_hir::{
     Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::adjustment::{Adjust, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
 use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::sym;
@@ -116,7 +116,7 @@ fn check_struct<'tcx>(
     let is_default_without_adjusts = |expr| {
         is_default_equivalent(cx, expr)
             && typeck_results.expr_adjustments(expr).iter().all(|adj| {
-                !matches!(adj.kind, Adjust::Pointer(PointerCast::Unsize)
+                !matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)
                     if contains_trait_object(adj.target))
             })
     };
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 0d78c3048ba..eab725de17f 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -14,7 +14,7 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::adjustment::{Adjust, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, RegionKind};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -195,7 +195,7 @@ impl<'tcx> PassByRefOrValue {
                                     .adjustments()
                                     .items()
                                     .flat_map(|(_, a)| a)
-                                    .any(|a| matches!(a.kind, Adjust::Pointer(PointerCast::UnsafeFnPointer)))
+                                    .any(|a| matches!(a.kind, Adjust::Pointer(PointerCoercion::UnsafeFnPointer)))
                             {
                                 continue;
                             }
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index c9938caefb0..fbf4ab2722e 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -16,7 +16,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::traits::{ImplSource, ObligationCause};
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
+use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
 use rustc_middle::ty::{BoundConstness, TraitRef};
 use rustc_semver::RustcVersion;
 use rustc_span::symbol::sym;
@@ -119,18 +119,18 @@ fn check_rvalue<'tcx>(
             | CastKind::FloatToFloat
             | CastKind::FnPtrToPtr
             | CastKind::PtrToPtr
-            | CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
+            | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer),
             operand,
             _,
         ) => check_operand(tcx, operand, span, body),
         Rvalue::Cast(
-            CastKind::Pointer(
-                PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
+            CastKind::PointerCoercion(
+                PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) | PointerCoercion::ReifyFnPointer,
             ),
             _,
             _,
         ) => Err((span, "function pointer casts are not allowed in const fn".into())),
-        Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
+        Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => {
             let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) {
                 deref_ty.ty
             } else {
diff --git a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.rs b/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.rs
deleted file mode 100644
index 67115f7c5a7..00000000000
--- a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@run-rustfix
-//@compile-flags: -C incremental=target/debug/test/incr
-
-// see https://github.com/rust-lang/rust-clippy/issues/10969
-
-fn main() {
-    let s = "Hello, world!";
-    println!("{}", s.to_string());
-}
diff --git a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.stderr b/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.stderr
deleted file mode 100644
index a992c542914..00000000000
--- a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/to_string_in_format_args_incremental.rs:8:21
-   |
-LL |     println!("{}", s.to_string());
-   |                     ^^^^^^^^^^^^ help: remove this
-   |
-   = note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
-
-error: aborting due to previous error
-
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index c835962ad12..ad10c3e07ce 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -588,21 +588,22 @@ impl TestProps {
     }
 }
 
+/// Extract a `(Option<line_config>, directive)` directive from a line if comment is present.
 pub fn line_directive<'line>(
     comment: &str,
     ln: &'line str,
 ) -> Option<(Option<&'line str>, &'line str)> {
+    let ln = ln.trim_start();
     if ln.starts_with(comment) {
         let ln = ln[comment.len()..].trim_start();
         if ln.starts_with('[') {
             // A comment like `//[foo]` is specific to revision `foo`
-            if let Some(close_brace) = ln.find(']') {
-                let lncfg = &ln[1..close_brace];
+            let Some(close_brace) = ln.find(']') else {
+                panic!("malformed condition directive: expected `{}[foo]`, found `{}`", comment, ln);
+            };
 
-                Some((Some(lncfg), ln[(close_brace + 1)..].trim_start()))
-            } else {
-                panic!("malformed condition directive: expected `{}[foo]`, found `{}`", comment, ln)
-            }
+            let lncfg = &ln[1..close_brace];
+            Some((Some(lncfg), ln[(close_brace + 1)..].trim_start()))
         } else {
             Some((None, ln))
         }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 672779325ae..ac19fe078f0 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -41,7 +41,7 @@ use crate::extract_gdb_version;
 use crate::is_android_gdb_target;
 
 mod debugger;
-use debugger::{check_debugger_output, DebuggerCommands};
+use debugger::DebuggerCommands;
 
 #[cfg(test)]
 mod tests;
@@ -997,16 +997,13 @@ impl<'test> TestCx<'test> {
         };
 
         // Parse debugger commands etc from test files
-        let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            match DebuggerCommands::parse_from(
-                &self.testpaths.file,
-                self.config,
-                prefixes,
-                self.revision,
-            ) {
-                Ok(cmds) => cmds,
-                Err(e) => self.fatal(&e),
-            };
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            prefixes,
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
 
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
         let mut script_str = String::with_capacity(2048);
@@ -1023,12 +1020,12 @@ impl<'test> TestCx<'test> {
 
         // Set breakpoints on every line that contains the string "#break"
         let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
-        for line in &breakpoint_lines {
+        for line in &dbg_cmds.breakpoint_lines {
             script_str.push_str(&format!("bp `{}:{}`\n", source_file_name, line));
         }
 
         // Append the other `cdb-command:`s
-        for line in &commands {
+        for line in &dbg_cmds.commands {
             script_str.push_str(line);
             script_str.push_str("\n");
         }
@@ -1058,7 +1055,7 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
         }
 
-        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
             self.fatal_proc_rec(&e, &debugger_run_result);
         }
     }
@@ -1088,17 +1085,14 @@ impl<'test> TestCx<'test> {
             PREFIXES
         };
 
-        let DebuggerCommands { commands, check_lines, breakpoint_lines } =
-            match DebuggerCommands::parse_from(
-                &self.testpaths.file,
-                self.config,
-                prefixes,
-                self.revision,
-            ) {
-                Ok(cmds) => cmds,
-                Err(e) => self.fatal(&e),
-            };
-        let mut cmds = commands.join("\n");
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            prefixes,
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
+        let mut cmds = dbg_cmds.commands.join("\n");
 
         // compile test file (it should have 'compile-flags:-g' in the header)
         let should_run = self.run_if_enabled();
@@ -1132,13 +1126,14 @@ impl<'test> TestCx<'test> {
                  ./{}/stage2/lib/rustlib/{}/lib/\n",
                 self.config.host, self.config.target
             ));
-            for line in &breakpoint_lines {
+            for line in &dbg_cmds.breakpoint_lines {
                 script_str.push_str(
-                    &format!(
+                    format!(
                         "break {:?}:{}\n",
                         self.testpaths.file.file_name().unwrap().to_string_lossy(),
                         *line
-                    )[..],
+                    )
+                    .as_str(),
                 );
             }
             script_str.push_str(&cmds);
@@ -1279,7 +1274,7 @@ impl<'test> TestCx<'test> {
             }
 
             // Add line breakpoints
-            for line in &breakpoint_lines {
+            for line in &dbg_cmds.breakpoint_lines {
                 script_str.push_str(&format!(
                     "break '{}':{}\n",
                     self.testpaths.file.file_name().unwrap().to_string_lossy(),
@@ -1315,7 +1310,7 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
         }
 
-        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
             self.fatal_proc_rec(&e, &debugger_run_result);
         }
     }
@@ -1372,16 +1367,13 @@ impl<'test> TestCx<'test> {
         };
 
         // Parse debugger commands etc from test files
-        let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            match DebuggerCommands::parse_from(
-                &self.testpaths.file,
-                self.config,
-                prefixes,
-                self.revision,
-            ) {
-                Ok(cmds) => cmds,
-                Err(e) => self.fatal(&e),
-            };
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            prefixes,
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
 
         // Write debugger script:
         // We don't want to hang when calling `quit` while the process is still running
@@ -1430,7 +1422,7 @@ impl<'test> TestCx<'test> {
 
         // Set breakpoints on every line that contains the string "#break"
         let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
-        for line in &breakpoint_lines {
+        for line in &dbg_cmds.breakpoint_lines {
             script_str.push_str(&format!(
                 "breakpoint set --file '{}' --line {}\n",
                 source_file_name, line
@@ -1438,7 +1430,7 @@ impl<'test> TestCx<'test> {
         }
 
         // Append the other commands
-        for line in &commands {
+        for line in &dbg_cmds.commands {
             script_str.push_str(line);
             script_str.push_str("\n");
         }
@@ -1458,7 +1450,7 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
         }
 
-        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
             self.fatal_proc_rec(&e, &debugger_run_result);
         }
     }
diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs
index 379ff0bab40..eebe5f3580b 100644
--- a/src/tools/compiletest/src/runtest/debugger.rs
+++ b/src/tools/compiletest/src/runtest/debugger.rs
@@ -2,18 +2,25 @@ use crate::common::Config;
 use crate::header::line_directive;
 use crate::runtest::ProcRes;
 
+use std::fmt::Write;
 use std::fs::File;
 use std::io::{BufRead, BufReader};
-use std::path::Path;
+use std::path::{Path, PathBuf};
 
+/// Representation of information to invoke a debugger and check its output
 pub(super) struct DebuggerCommands {
+    /// Commands for the debuuger
     pub commands: Vec<String>,
-    pub check_lines: Vec<String>,
+    /// Lines to insert breakpoints at
     pub breakpoint_lines: Vec<usize>,
+    /// Contains the source line number to check and the line itself
+    check_lines: Vec<(usize, String)>,
+    /// Source file name
+    file: PathBuf,
 }
 
 impl DebuggerCommands {
-    pub(super) fn parse_from(
+    pub fn parse_from(
         file: &Path,
         config: &Config,
         debugger_prefixes: &[&str],
@@ -21,7 +28,7 @@ impl DebuggerCommands {
     ) -> Result<Self, String> {
         let directives = debugger_prefixes
             .iter()
-            .map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
+            .map(|prefix| (format!("{prefix}-command"), format!("{prefix}-check")))
             .collect::<Vec<_>>();
 
         let mut breakpoint_lines = vec![];
@@ -29,63 +36,88 @@ impl DebuggerCommands {
         let mut check_lines = vec![];
         let mut counter = 0;
         let reader = BufReader::new(File::open(file).unwrap());
-        for line in reader.lines() {
+        for (line_no, line) in reader.lines().enumerate() {
             counter += 1;
-            match line {
-                Ok(line) => {
-                    let (lnrev, line) = line_directive("//", &line).unwrap_or((None, &line));
-
-                    // Skip any revision specific directive that doesn't match the current
-                    // revision being tested
-                    if lnrev.is_some() && lnrev != rev {
-                        continue;
-                    }
-
-                    if line.contains("#break") {
-                        breakpoint_lines.push(counter);
-                    }
-
-                    for &(ref command_directive, ref check_directive) in &directives {
-                        config
-                            .parse_name_value_directive(&line, command_directive)
-                            .map(|cmd| commands.push(cmd));
-
-                        config
-                            .parse_name_value_directive(&line, check_directive)
-                            .map(|cmd| check_lines.push(cmd));
-                    }
-                }
-                Err(e) => return Err(format!("Error while parsing debugger commands: {}", e)),
+            let line = line.map_err(|e| format!("Error while parsing debugger commands: {}", e))?;
+            let (lnrev, line) = line_directive("//", &line).unwrap_or((None, &line));
+
+            // Skip any revision specific directive that doesn't match the current
+            // revision being tested
+            if lnrev.is_some() && lnrev != rev {
+                continue;
+            }
+
+            if line.contains("#break") {
+                breakpoint_lines.push(counter);
+            }
+
+            for &(ref command_directive, ref check_directive) in &directives {
+                config
+                    .parse_name_value_directive(&line, command_directive)
+                    .map(|cmd| commands.push(cmd));
+
+                config
+                    .parse_name_value_directive(&line, check_directive)
+                    .map(|cmd| check_lines.push((line_no, cmd)));
             }
         }
 
-        Ok(Self { commands, check_lines, breakpoint_lines })
+        Ok(Self { commands, breakpoint_lines, check_lines, file: file.to_owned() })
     }
-}
 
-pub(super) fn check_debugger_output(
-    debugger_run_result: &ProcRes,
-    check_lines: &[String],
-) -> Result<(), String> {
-    let num_check_lines = check_lines.len();
-
-    let mut check_line_index = 0;
-    for line in debugger_run_result.stdout.lines() {
-        if check_line_index >= num_check_lines {
-            break;
+    /// Given debugger output and lines to check, ensure that every line is
+    /// contained in the debugger output. The check lines need to be found in
+    /// order, but there can be extra lines between.
+    pub fn check_output(&self, debugger_run_result: &ProcRes) -> Result<(), String> {
+        // (src_lineno, ck_line)  that we did find
+        let mut found = vec![];
+        // (src_lineno, ck_line) that we couldn't find
+        let mut missing = vec![];
+        //  We can find our any current match anywhere after our last match
+        let mut last_idx = 0;
+        let dbg_lines: Vec<&str> = debugger_run_result.stdout.lines().collect();
+
+        for (src_lineno, ck_line) in &self.check_lines {
+            if let Some(offset) = dbg_lines
+                .iter()
+                .skip(last_idx)
+                .position(|out_line| check_single_line(out_line, &ck_line))
+            {
+                last_idx += offset;
+                found.push((src_lineno, dbg_lines[last_idx]));
+            } else {
+                missing.push((src_lineno, ck_line));
+            }
         }
 
-        if check_single_line(line, &(check_lines[check_line_index])[..]) {
-            check_line_index += 1;
+        if missing.is_empty() {
+            Ok(())
+        } else {
+            let fname = self.file.file_name().unwrap().to_string_lossy();
+            let mut msg = format!(
+                "check directive(s) from `{}` not found in debugger output. errors:",
+                self.file.display()
+            );
+
+            for (src_lineno, err_line) in missing {
+                write!(msg, "\n    ({fname}:{num}) `{err_line}`", num = src_lineno + 1).unwrap();
+            }
+
+            if !found.is_empty() {
+                let init = "\nthe following subset of check directive(s) was found successfully:";
+                msg.push_str(init);
+                for (src_lineno, found_line) in found {
+                    write!(msg, "\n    ({fname}:{num}) `{found_line}`", num = src_lineno + 1)
+                        .unwrap();
+                }
+            }
+
+            Err(msg)
         }
     }
-    if check_line_index != num_check_lines && num_check_lines > 0 {
-        Err(format!("line not found in debugger output: {}", check_lines[check_line_index]))
-    } else {
-        Ok(())
-    }
 }
 
+/// Check that the pattern in `check_line` applies to `line`. Returns `true` if they do match.
 fn check_single_line(line: &str, check_line: &str) -> bool {
     // Allow check lines to leave parts unspecified (e.g., uninitialized
     // bits in the  wrong case of an enum) with the notation "[...]".
@@ -101,21 +133,19 @@ fn check_single_line(line: &str, check_line: &str) -> bool {
     }
 
     let (mut rest, first_fragment) = if can_start_anywhere {
-        match line.find(check_fragments[0]) {
-            Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
-            None => return false,
-        }
+        let Some(pos) = line.find(check_fragments[0]) else {
+            return false;
+        };
+        (&line[pos + check_fragments[0].len()..], 1)
     } else {
         (line, 0)
     };
 
     for current_fragment in &check_fragments[first_fragment..] {
-        match rest.find(current_fragment) {
-            Some(pos) => {
-                rest = &rest[pos + current_fragment.len()..];
-            }
-            None => return false,
-        }
+        let Some(pos) = rest.find(current_fragment) else {
+            return false;
+        };
+        rest = &rest[pos + current_fragment.len()..];
     }
 
     if !can_end_anywhere && !rest.is_empty() { false } else { true }
diff --git a/src/tools/miri/tests/fail/overlapping_assignment.rs b/src/tools/miri/tests/fail/overlapping_assignment.rs
new file mode 100644
index 00000000000..84994c179f9
--- /dev/null
+++ b/src/tools/miri/tests/fail/overlapping_assignment.rs
@@ -0,0 +1,23 @@
+#![feature(core_intrinsics)]
+#![feature(custom_mir)]
+
+use std::intrinsics::mir::*;
+
+// It's not that easy to fool the MIR validity check
+// which wants to prevent overlapping assignments...
+// So we use two separate pointer arguments, and then arrange for them to alias.
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn self_copy(ptr1: *mut [i32; 4], ptr2: *mut [i32; 4]) {
+    mir! {
+        {
+            *ptr1 = *ptr2; //~ERROR: overlapping ranges
+            Return()
+        }
+    }
+}
+
+pub fn main() {
+    let mut x = [0; 4];
+    let ptr = std::ptr::addr_of_mut!(x);
+    self_copy(ptr, ptr);
+}
diff --git a/src/tools/miri/tests/fail/overlapping_assignment.stderr b/src/tools/miri/tests/fail/overlapping_assignment.stderr
new file mode 100644
index 00000000000..42a000dfcc6
--- /dev/null
+++ b/src/tools/miri/tests/fail/overlapping_assignment.stderr
@@ -0,0 +1,20 @@
+error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
+  --> $DIR/overlapping_assignment.rs:LL:CC
+   |
+LL |             *ptr1 = *ptr2;
+   |             ^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `self_copy` at $DIR/overlapping_assignment.rs:LL:CC
+note: inside `main`
+  --> $DIR/overlapping_assignment.rs:LL:CC
+   |
+LL |     self_copy(ptr, ptr);
+   |     ^^^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml
new file mode 100644
index 00000000000..5a1794d3336
--- /dev/null
+++ b/src/tools/opt-dist/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "opt-dist"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+build_helper = { path = "../build_helper" }
+env_logger = "0.10"
+log = "0.4"
+anyhow = { version = "1", features = ["backtrace"] }
+humantime = "2"
+humansize = "2"
+sysinfo = { version = "0.29", default-features = false }
+fs_extra = "1"
+camino = "1"
+reqwest = { version = "0.11", features = ["blocking"] }
+zip = { version = "0.6", default-features = false, features = ["deflate"] }
+tar = "0.4"
+xz = "0.1"
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+glob = "0.3"
diff --git a/src/tools/opt-dist/README.md b/src/tools/opt-dist/README.md
new file mode 100644
index 00000000000..05a75870da1
--- /dev/null
+++ b/src/tools/opt-dist/README.md
@@ -0,0 +1,7 @@
+# Optimized build pipeline
+This binary implements a heavily optimized build pipeline for `rustc` and `LLVM` artifacts that are used for both for
+benchmarking using the perf. bot and for final distribution to users.
+
+It uses LTO, PGO and BOLT to optimize the compiler and LLVM as much as possible.
+This logic is not part of bootstrap, because it needs to invoke bootstrap multiple times, force-rebuild various
+artifacts repeatedly and sometimes go around bootstrap's cache mechanism.
diff --git a/src/tools/opt-dist/src/environment/linux.rs b/src/tools/opt-dist/src/environment/linux.rs
new file mode 100644
index 00000000000..d4c55c46f7c
--- /dev/null
+++ b/src/tools/opt-dist/src/environment/linux.rs
@@ -0,0 +1,54 @@
+use crate::environment::Environment;
+use crate::exec::cmd;
+use crate::utils::io::copy_directory;
+use camino::{Utf8Path, Utf8PathBuf};
+
+pub(super) struct LinuxEnvironment;
+
+impl Environment for LinuxEnvironment {
+    fn python_binary(&self) -> &'static str {
+        "python3"
+    }
+
+    fn checkout_path(&self) -> Utf8PathBuf {
+        Utf8PathBuf::from("/checkout")
+    }
+
+    fn downloaded_llvm_dir(&self) -> Utf8PathBuf {
+        Utf8PathBuf::from("/rustroot")
+    }
+
+    fn opt_artifacts(&self) -> Utf8PathBuf {
+        Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts")
+    }
+
+    fn build_root(&self) -> Utf8PathBuf {
+        self.checkout_path().join("obj")
+    }
+
+    fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
+        // /tmp/rustc-perf comes from the x64 dist Dockerfile
+        copy_directory(Utf8Path::new("/tmp/rustc-perf"), &self.rustc_perf_dir())?;
+        cmd(&[self.cargo_stage_0().as_str(), "build", "-p", "collector"])
+            .workdir(&self.rustc_perf_dir())
+            .env("RUSTC", &self.rustc_stage_0().into_string())
+            .env("RUSTC_BOOTSTRAP", "1")
+            .run()?;
+        Ok(())
+    }
+
+    fn supports_bolt(&self) -> bool {
+        true
+    }
+
+    fn executable_extension(&self) -> &'static str {
+        ""
+    }
+
+    fn skipped_tests(&self) -> &'static [&'static str] {
+        &[
+            // Fails because of linker errors, as of June 2023.
+            "tests/ui/process/nofile-limit.rs",
+        ]
+    }
+}
diff --git a/src/tools/opt-dist/src/environment/mod.rs b/src/tools/opt-dist/src/environment/mod.rs
new file mode 100644
index 00000000000..f66b9ab41ea
--- /dev/null
+++ b/src/tools/opt-dist/src/environment/mod.rs
@@ -0,0 +1,75 @@
+use camino::Utf8PathBuf;
+
+#[cfg(target_family = "unix")]
+mod linux;
+#[cfg(target_family = "windows")]
+mod windows;
+
+pub trait Environment {
+    fn host_triple(&self) -> String {
+        std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing")
+    }
+
+    fn python_binary(&self) -> &'static str;
+
+    /// The rustc checkout, where the compiler source is located.
+    fn checkout_path(&self) -> Utf8PathBuf;
+
+    /// Path to the downloaded host LLVM.
+    fn downloaded_llvm_dir(&self) -> Utf8PathBuf;
+
+    /// Directory where the optimization artifacts (PGO/BOLT profiles, etc.)
+    /// will be stored.
+    fn opt_artifacts(&self) -> Utf8PathBuf;
+
+    /// The main directory where the build occurs.
+    fn build_root(&self) -> Utf8PathBuf;
+
+    fn build_artifacts(&self) -> Utf8PathBuf {
+        self.build_root().join("build").join(self.host_triple())
+    }
+
+    fn cargo_stage_0(&self) -> Utf8PathBuf {
+        self.build_artifacts()
+            .join("stage0")
+            .join("bin")
+            .join(format!("cargo{}", self.executable_extension()))
+    }
+
+    fn rustc_stage_0(&self) -> Utf8PathBuf {
+        self.build_artifacts()
+            .join("stage0")
+            .join("bin")
+            .join(format!("rustc{}", self.executable_extension()))
+    }
+
+    fn rustc_stage_2(&self) -> Utf8PathBuf {
+        self.build_artifacts()
+            .join("stage2")
+            .join("bin")
+            .join(format!("rustc{}", self.executable_extension()))
+    }
+
+    /// Path to the built rustc-perf benchmark suite.
+    fn rustc_perf_dir(&self) -> Utf8PathBuf {
+        self.opt_artifacts().join("rustc-perf")
+    }
+
+    /// Download and/or compile rustc-perf.
+    fn prepare_rustc_perf(&self) -> anyhow::Result<()>;
+
+    fn supports_bolt(&self) -> bool;
+
+    /// What is the extension of binary executables in this environment?
+    fn executable_extension(&self) -> &'static str;
+
+    /// List of test paths that should be skipped when testing the optimized artifacts.
+    fn skipped_tests(&self) -> &'static [&'static str];
+}
+
+pub fn create_environment() -> Box<dyn Environment> {
+    #[cfg(target_family = "unix")]
+    return Box::new(linux::LinuxEnvironment);
+    #[cfg(target_family = "windows")]
+    return Box::new(windows::WindowsEnvironment::new());
+}
diff --git a/src/tools/opt-dist/src/environment/windows.rs b/src/tools/opt-dist/src/environment/windows.rs
new file mode 100644
index 00000000000..36f4c0f29cc
--- /dev/null
+++ b/src/tools/opt-dist/src/environment/windows.rs
@@ -0,0 +1,78 @@
+use crate::environment::Environment;
+use crate::exec::cmd;
+use crate::utils::io::move_directory;
+use camino::Utf8PathBuf;
+use std::io::Cursor;
+use zip::ZipArchive;
+
+pub(super) struct WindowsEnvironment {
+    checkout_dir: Utf8PathBuf,
+}
+
+impl WindowsEnvironment {
+    pub fn new() -> Self {
+        Self { checkout_dir: std::env::current_dir().unwrap().try_into().unwrap() }
+    }
+}
+
+impl Environment for WindowsEnvironment {
+    fn python_binary(&self) -> &'static str {
+        "python"
+    }
+
+    fn checkout_path(&self) -> Utf8PathBuf {
+        self.checkout_dir.clone()
+    }
+
+    fn downloaded_llvm_dir(&self) -> Utf8PathBuf {
+        self.checkout_path().join("citools").join("clang-rust")
+    }
+
+    fn opt_artifacts(&self) -> Utf8PathBuf {
+        self.checkout_path().join("opt-artifacts")
+    }
+
+    fn build_root(&self) -> Utf8PathBuf {
+        self.checkout_path()
+    }
+
+    fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
+        // FIXME: add some mechanism for synchronization of this commit SHA with
+        // Linux (which builds rustc-perf in a Dockerfile)
+        // rustc-perf version from 2023-05-30
+        const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1";
+
+        let url = format!("https://github.com/rust-lang/rustc-perf/archive/{PERF_COMMIT}.zip");
+        let response = reqwest::blocking::get(url)?.error_for_status()?.bytes()?.to_vec();
+
+        let mut archive = ZipArchive::new(Cursor::new(response))?;
+        archive.extract(self.rustc_perf_dir())?;
+        move_directory(
+            &self.rustc_perf_dir().join(format!("rustc-perf-{PERF_COMMIT}")),
+            &self.rustc_perf_dir(),
+        )?;
+
+        cmd(&[self.cargo_stage_0().as_str(), "build", "-p", "collector"])
+            .workdir(&self.rustc_perf_dir())
+            .env("RUSTC", &self.rustc_stage_0().into_string())
+            .env("RUSTC_BOOTSTRAP", "1")
+            .run()?;
+
+        Ok(())
+    }
+
+    fn supports_bolt(&self) -> bool {
+        false
+    }
+
+    fn executable_extension(&self) -> &'static str {
+        ".exe"
+    }
+
+    fn skipped_tests(&self) -> &'static [&'static str] {
+        &[
+            // Fails as of June 2023.
+            "tests\\codegen\\vec-shrink-panik.rs",
+        ]
+    }
+}
diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs
new file mode 100644
index 00000000000..d05ddbd4c0e
--- /dev/null
+++ b/src/tools/opt-dist/src/exec.rs
@@ -0,0 +1,169 @@
+use crate::environment::Environment;
+use crate::metrics::{load_metrics, record_metrics};
+use crate::timer::TimerSection;
+use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile};
+use camino::{Utf8Path, Utf8PathBuf};
+use std::collections::BTreeMap;
+use std::fs::File;
+use std::process::{Command, Stdio};
+
+#[derive(Default)]
+pub struct CmdBuilder {
+    args: Vec<String>,
+    env: BTreeMap<String, String>,
+    workdir: Option<Utf8PathBuf>,
+    output: Option<Utf8PathBuf>,
+}
+
+impl CmdBuilder {
+    pub fn arg(mut self, arg: &str) -> Self {
+        self.args.push(arg.to_string());
+        self
+    }
+
+    pub fn env(mut self, name: &str, value: &str) -> Self {
+        self.env.insert(name.to_string(), value.to_string());
+        self
+    }
+
+    pub fn workdir(mut self, path: &Utf8Path) -> Self {
+        self.workdir = Some(path.to_path_buf());
+        self
+    }
+
+    pub fn redirect_output(mut self, path: Utf8PathBuf) -> Self {
+        self.output = Some(path);
+        self
+    }
+
+    pub fn run(self) -> anyhow::Result<()> {
+        let mut cmd_str = String::new();
+        cmd_str.push_str(
+            &self
+                .env
+                .iter()
+                .map(|(key, value)| format!("{key}={value}"))
+                .collect::<Vec<_>>()
+                .join(" "),
+        );
+        if !self.env.is_empty() {
+            cmd_str.push(' ');
+        }
+        cmd_str.push_str(&self.args.join(" "));
+        if let Some(ref path) = self.output {
+            cmd_str.push_str(&format!(" > {path:?}"));
+        }
+        cmd_str.push_str(&format!(
+            " [at {}]",
+            self.workdir
+                .clone()
+                .unwrap_or_else(|| std::env::current_dir().unwrap().try_into().unwrap())
+        ));
+        log::info!("Executing `{cmd_str}`");
+
+        let mut cmd = Command::new(&self.args[0]);
+        cmd.stdin(Stdio::null());
+        cmd.args(self.args.iter().skip(1));
+        for (key, value) in &self.env {
+            cmd.env(key, value);
+        }
+        if let Some(ref output) = self.output {
+            cmd.stdout(File::create(output.clone().into_std_path_buf())?);
+        }
+        if let Some(ref workdir) = self.workdir {
+            cmd.current_dir(workdir.clone().into_std_path_buf());
+        }
+        let exit_status = cmd.spawn()?.wait()?;
+        if !exit_status.success() {
+            Err(anyhow::anyhow!(
+                "Command {cmd_str} has failed with exit code {:?}",
+                exit_status.code(),
+            ))
+        } else {
+            Ok(())
+        }
+    }
+}
+
+pub fn cmd(args: &[&str]) -> CmdBuilder {
+    assert!(!args.is_empty());
+    CmdBuilder { args: args.iter().map(|s| s.to_string()).collect(), ..Default::default() }
+}
+
+pub struct Bootstrap {
+    cmd: CmdBuilder,
+    metrics_path: Utf8PathBuf,
+}
+
+impl Bootstrap {
+    pub fn build(env: &dyn Environment) -> Self {
+        let metrics_path = env.build_root().join("build").join("metrics.json");
+        let cmd = cmd(&[
+            env.python_binary(),
+            env.checkout_path().join("x.py").as_str(),
+            "build",
+            "--target",
+            &env.host_triple(),
+            "--host",
+            &env.host_triple(),
+            "--stage",
+            "2",
+            "library/std",
+        ])
+        .env("RUST_BACKTRACE", "full");
+        Self { cmd, metrics_path }
+    }
+
+    pub fn dist(env: &dyn Environment, dist_args: &[String]) -> Self {
+        let metrics_path = env.build_root().join("build").join("metrics.json");
+        let cmd = cmd(&dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>())
+            .env("RUST_BACKTRACE", "full");
+        Self { cmd, metrics_path }
+    }
+
+    pub fn llvm_pgo_instrument(mut self, profile_dir: &Utf8Path) -> Self {
+        self.cmd = self
+            .cmd
+            .arg("--llvm-profile-generate")
+            .env("LLVM_PROFILE_DIR", profile_dir.join("prof-%p").as_str());
+        self
+    }
+
+    pub fn llvm_pgo_optimize(mut self, profile: &LlvmPGOProfile) -> Self {
+        self.cmd = self.cmd.arg("--llvm-profile-use").arg(profile.0.as_str());
+        self
+    }
+
+    pub fn rustc_pgo_instrument(mut self, profile_dir: &Utf8Path) -> Self {
+        self.cmd = self.cmd.arg("--rust-profile-generate").arg(profile_dir.as_str());
+        self
+    }
+
+    pub fn rustc_pgo_optimize(mut self, profile: &RustcPGOProfile) -> Self {
+        self.cmd = self.cmd.arg("--rust-profile-use").arg(profile.0.as_str());
+        self
+    }
+
+    pub fn llvm_bolt_instrument(mut self) -> Self {
+        self.cmd = self.cmd.arg("--llvm-bolt-profile-generate");
+        self
+    }
+
+    pub fn llvm_bolt_optimize(mut self, profile: &LlvmBoltProfile) -> Self {
+        self.cmd = self.cmd.arg("--llvm-bolt-profile-use").arg(profile.0.as_str());
+        self
+    }
+
+    /// Do not rebuild rustc, and use a previously built rustc sysroot instead.
+    pub fn avoid_rustc_rebuild(mut self) -> Self {
+        self.cmd = self.cmd.arg("--keep-stage").arg("0").arg("--keep-stage").arg("1");
+        self
+    }
+
+    pub fn run(self, timer: &mut TimerSection) -> anyhow::Result<()> {
+        self.cmd.run()?;
+        let metrics = load_metrics(&self.metrics_path)?;
+        record_metrics(&metrics, timer);
+        Ok(())
+    }
+}
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
new file mode 100644
index 00000000000..39fa7e1fb2a
--- /dev/null
+++ b/src/tools/opt-dist/src/main.rs
@@ -0,0 +1,175 @@
+use anyhow::Context;
+use log::LevelFilter;
+
+use crate::environment::{create_environment, Environment};
+use crate::exec::Bootstrap;
+use crate::tests::run_tests;
+use crate::timer::Timer;
+use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles};
+use crate::utils::io::reset_directory;
+use crate::utils::{clear_llvm_files, format_env_variables, print_free_disk_space};
+
+mod environment;
+mod exec;
+mod metrics;
+mod tests;
+mod timer;
+mod training;
+mod utils;
+
+fn is_try_build() -> bool {
+    std::env::var("DIST_TRY_BUILD").unwrap_or_else(|_| "0".to_string()) != "0"
+}
+
+fn execute_pipeline(
+    env: &dyn Environment,
+    timer: &mut Timer,
+    dist_args: Vec<String>,
+) -> anyhow::Result<()> {
+    reset_directory(&env.opt_artifacts())?;
+    env.prepare_rustc_perf()?;
+
+    // Stage 1: Build PGO instrumented rustc
+    // We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the
+    // same time can cause issues, because the host and in-tree LLVM versions can diverge.
+    let rustc_pgo_profile = timer.section("Stage 1 (Rustc PGO)", |stage| {
+        let rustc_profile_dir_root = env.opt_artifacts().join("rustc-pgo");
+
+        stage.section("Build PGO instrumented rustc and LLVM", |section| {
+            Bootstrap::build(env).rustc_pgo_instrument(&rustc_profile_dir_root).run(section)
+        })?;
+
+        let profile = stage
+            .section("Gather profiles", |_| gather_rustc_profiles(env, &rustc_profile_dir_root))?;
+        print_free_disk_space()?;
+
+        stage.section("Build PGO optimized rustc", |section| {
+            Bootstrap::build(env).rustc_pgo_optimize(&profile).run(section)
+        })?;
+
+        Ok(profile)
+    })?;
+
+    // Stage 2: Gather LLVM PGO profiles
+    // Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc.
+    // Then we use the instrumented LLVM to gather LLVM PGO profiles.
+    let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| {
+        // Remove the previous, uninstrumented build of LLVM.
+        clear_llvm_files(env)?;
+
+        let llvm_profile_dir_root = env.opt_artifacts().join("llvm-pgo");
+
+        stage.section("Build PGO instrumented LLVM", |section| {
+            Bootstrap::build(env)
+                .llvm_pgo_instrument(&llvm_profile_dir_root)
+                .avoid_rustc_rebuild()
+                .run(section)
+        })?;
+
+        let profile = stage
+            .section("Gather profiles", |_| gather_llvm_profiles(env, &llvm_profile_dir_root))?;
+
+        print_free_disk_space()?;
+
+        // Proactively delete the instrumented artifacts, to avoid using them by accident in
+        // follow-up stages.
+        clear_llvm_files(env)?;
+
+        Ok(profile)
+    })?;
+
+    let llvm_bolt_profile = if env.supports_bolt() {
+        // Stage 3: Build BOLT instrumented LLVM
+        // We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
+        // Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
+        // BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
+        // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
+        timer.section("Stage 3 (LLVM BOLT)", |stage| {
+            stage.section("Build BOLT instrumented LLVM", |stage| {
+                Bootstrap::build(env)
+                    .llvm_bolt_instrument()
+                    .llvm_pgo_optimize(&llvm_pgo_profile)
+                    .avoid_rustc_rebuild()
+                    .run(stage)
+            })?;
+
+            let profile = stage.section("Gather profiles", |_| gather_llvm_bolt_profiles(env))?;
+            print_free_disk_space()?;
+
+            // LLVM is not being cleared here, we want to reuse the previous PGO-optimized build
+
+            Ok(Some(profile))
+        })?
+    } else {
+        None
+    };
+
+    let mut dist = Bootstrap::dist(env, &dist_args)
+        .llvm_pgo_optimize(&llvm_pgo_profile)
+        .rustc_pgo_optimize(&rustc_pgo_profile)
+        .avoid_rustc_rebuild();
+
+    if let Some(llvm_bolt_profile) = llvm_bolt_profile {
+        dist = dist.llvm_bolt_optimize(&llvm_bolt_profile);
+    }
+
+    // Final stage: Assemble the dist artifacts
+    // The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
+    timer.section("Stage 4 (final build)", |stage| dist.run(stage))?;
+
+    // After dist has finished, run a subset of the test suite on the optimized artifacts to discover
+    // possible regressions.
+    // The tests are not executed for try builds, which can be in various broken states, so we don't
+    // want to gatekeep them with tests.
+    if !is_try_build() {
+        timer.section("Run tests", |_| run_tests(env))?;
+    }
+
+    Ok(())
+}
+
+fn main() -> anyhow::Result<()> {
+    // Make sure that we get backtraces for easier debugging in CI
+    std::env::set_var("RUST_BACKTRACE", "1");
+
+    env_logger::builder()
+        .filter_level(LevelFilter::Info)
+        .format_timestamp_millis()
+        .parse_default_env()
+        .init();
+
+    let mut build_args: Vec<String> = std::env::args().skip(1).collect();
+    log::info!("Running optimized build pipeline with args `{}`", build_args.join(" "));
+    log::info!("Environment values\n{}", format_env_variables());
+
+    if let Ok(config) = std::fs::read_to_string("config.toml") {
+        log::info!("Contents of `config.toml`:\n{config}");
+    }
+
+    // Skip components that are not needed for try builds to speed them up
+    if is_try_build() {
+        log::info!("Skipping building of unimportant components for a try build");
+        for target in [
+            "rust-docs",
+            "rustc-docs",
+            "rust-docs-json",
+            "rust-analyzer",
+            "rustc-src",
+            "clippy",
+            "miri",
+            "rustfmt",
+        ] {
+            build_args.extend(["--exclude".to_string(), target.to_string()]);
+        }
+    }
+
+    let mut timer = Timer::new();
+    let env = create_environment();
+
+    let result = execute_pipeline(env.as_ref(), &mut timer, build_args);
+    log::info!("Timer results\n{}", timer.format_stats());
+
+    print_free_disk_space()?;
+
+    result.context("Optimized build pipeline has failed")
+}
diff --git a/src/tools/opt-dist/src/metrics.rs b/src/tools/opt-dist/src/metrics.rs
new file mode 100644
index 00000000000..cabe07eda32
--- /dev/null
+++ b/src/tools/opt-dist/src/metrics.rs
@@ -0,0 +1,106 @@
+use crate::timer::TimerSection;
+use build_helper::metrics::{JsonNode, JsonRoot};
+use camino::Utf8Path;
+use std::time::Duration;
+
+#[derive(Clone, Debug)]
+pub struct BuildStep {
+    r#type: String,
+    children: Vec<BuildStep>,
+    duration: Duration,
+}
+
+impl BuildStep {
+    pub fn find_all_by_type(&self, r#type: &str) -> Vec<&BuildStep> {
+        let mut result = Vec::new();
+        self.find_by_type(r#type, &mut result);
+        result
+    }
+    fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a BuildStep>) {
+        if self.r#type == r#type {
+            result.push(self);
+        }
+        for child in &self.children {
+            child.find_by_type(r#type, result);
+        }
+    }
+}
+
+/// Loads the metrics of the most recent bootstrap execution from a metrics.json file.
+pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> {
+    let content = std::fs::read(path.as_std_path())?;
+    let mut metrics = serde_json::from_slice::<JsonRoot>(&content)?;
+    let invocation = metrics
+        .invocations
+        .pop()
+        .ok_or_else(|| anyhow::anyhow!("No bootstrap invocation found in metrics file"))?;
+
+    fn parse(node: JsonNode) -> Option<BuildStep> {
+        match node {
+            JsonNode::RustbuildStep {
+                type_: kind,
+                children,
+                duration_excluding_children_sec,
+                ..
+            } => {
+                let children: Vec<_> = children.into_iter().filter_map(parse).collect();
+                let children_duration = children.iter().map(|c| c.duration).sum::<Duration>();
+                Some(BuildStep {
+                    r#type: kind.to_string(),
+                    children,
+                    duration: children_duration
+                        + Duration::from_secs_f64(duration_excluding_children_sec),
+                })
+            }
+            JsonNode::TestSuite(_) => None,
+        }
+    }
+
+    let duration = Duration::from_secs_f64(invocation.duration_including_children_sec);
+    let children: Vec<_> = invocation.children.into_iter().filter_map(parse).collect();
+    Ok(BuildStep { r#type: "root".to_string(), children, duration })
+}
+
+/// Logs the individual metrics in a table and add Rustc and LLVM durations to the passed
+/// timer.
+pub fn record_metrics(metrics: &BuildStep, timer: &mut TimerSection) {
+    let llvm_steps = metrics.find_all_by_type("bootstrap::llvm::Llvm");
+    let llvm_duration: Duration = llvm_steps.into_iter().map(|s| s.duration).sum();
+
+    let rustc_steps = metrics.find_all_by_type("bootstrap::compile::Rustc");
+    let rustc_duration: Duration = rustc_steps.into_iter().map(|s| s.duration).sum();
+
+    // The LLVM step is part of the Rustc step
+    let rustc_duration = rustc_duration.saturating_sub(llvm_duration);
+
+    if !llvm_duration.is_zero() {
+        timer.add_duration("LLVM", llvm_duration);
+    }
+    if !rustc_duration.is_zero() {
+        timer.add_duration("Rustc", rustc_duration);
+    }
+
+    log_metrics(metrics);
+}
+
+fn log_metrics(metrics: &BuildStep) {
+    use std::fmt::Write;
+
+    let mut substeps: Vec<(u32, &BuildStep)> = Vec::new();
+
+    fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) {
+        substeps.push((level, step));
+        for child in &step.children {
+            visit(child, level + 1, substeps);
+        }
+    }
+
+    visit(metrics, 0, &mut substeps);
+
+    let mut output = String::new();
+    for (level, step) in substeps {
+        let label = format!("{}{}", ".".repeat(level as usize), step.r#type);
+        writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
+    }
+    log::info!("Build step durations\n{output}");
+}
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
new file mode 100644
index 00000000000..6b35b13e586
--- /dev/null
+++ b/src/tools/opt-dist/src/tests.rs
@@ -0,0 +1,101 @@
+use crate::environment::Environment;
+use crate::exec::cmd;
+use crate::utils::io::{copy_directory, unpack_archive};
+use anyhow::Context;
+use camino::Utf8PathBuf;
+
+/// Run tests on optimized dist artifacts.
+pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
+    // After `dist` is executed, we extract its archived components into a sysroot directory,
+    // and then use that extracted rustc as a stage0 compiler.
+    // Then we run a subset of tests using that compiler, to have a basic smoke test which checks
+    // whether the optimization pipeline hasn't broken something.
+    let build_dir = env.build_root().join("build");
+    let dist_dir = build_dir.join("dist");
+    let unpacked_dist_dir = build_dir.join("unpacked-dist");
+    std::fs::create_dir_all(&unpacked_dist_dir)?;
+
+    let extract_dist_dir = |name: &str| -> anyhow::Result<Utf8PathBuf> {
+        unpack_archive(&dist_dir.join(format!("{name}.tar.xz")), &unpacked_dist_dir)?;
+        let extracted_path = unpacked_dist_dir.join(name);
+        assert!(extracted_path.is_dir());
+        Ok(extracted_path)
+    };
+    let host_triple = env.host_triple();
+
+    // Extract rustc, libstd, cargo and src archives to create the optimized sysroot
+    let rustc_dir = extract_dist_dir(&format!("rustc-nightly-{host_triple}"))?.join("rustc");
+    let libstd_dir = extract_dist_dir(&format!("rust-std-nightly-{host_triple}"))?
+        .join(format!("rust-std-{host_triple}"));
+    let cargo_dir = extract_dist_dir(&format!("cargo-nightly-{host_triple}"))?.join("cargo");
+    let extracted_src_dir = extract_dist_dir("rust-src-nightly")?.join("rust-src");
+
+    // We need to manually copy libstd to the extracted rustc sysroot
+    copy_directory(
+        &libstd_dir.join("lib").join("rustlib").join(&host_triple).join("lib"),
+        &rustc_dir.join("lib").join("rustlib").join(&host_triple).join("lib"),
+    )?;
+
+    // Extract sources - they aren't in the `rustc-nightly-{host}` tarball, so we need to manually copy libstd
+    // sources to the extracted sysroot. We need sources available so that `-Zsimulate-remapped-rust-src-base`
+    // works correctly.
+    copy_directory(
+        &extracted_src_dir.join("lib").join("rustlib").join("src"),
+        &rustc_dir.join("lib").join("rustlib").join("src"),
+    )?;
+
+    let rustc_path = rustc_dir.join("bin").join(format!("rustc{}", env.executable_extension()));
+    assert!(rustc_path.is_file());
+    let cargo_path = cargo_dir.join("bin").join(format!("cargo{}", env.executable_extension()));
+    assert!(cargo_path.is_file());
+
+    // Specify path to a LLVM config so that LLVM is not rebuilt.
+    // It doesn't really matter which LLVM config we choose, because no sysroot will be compiled.
+    let llvm_config = env
+        .build_artifacts()
+        .join("llvm")
+        .join("bin")
+        .join(format!("llvm-config{}", env.executable_extension()));
+    assert!(llvm_config.is_file());
+
+    let config_content = format!(
+        r#"profile = "user"
+changelog-seen = 2
+
+[build]
+rustc = "{rustc}"
+cargo = "{cargo}"
+
+[target.{host_triple}]
+llvm-config = "{llvm_config}"
+"#,
+        rustc = rustc_path.to_string().replace('\\', "/"),
+        cargo = cargo_path.to_string().replace('\\', "/"),
+        llvm_config = llvm_config.to_string().replace('\\', "/")
+    );
+    log::info!("Using following `config.toml` for running tests:\n{config_content}");
+
+    // Simulate a stage 0 compiler with the extracted optimized dist artifacts.
+    std::fs::write("config.toml", config_content)?;
+
+    let x_py = env.checkout_path().join("x.py");
+    let mut args = vec![
+        env.python_binary(),
+        x_py.as_str(),
+        "test",
+        "--stage",
+        "0",
+        "tests/assembly",
+        "tests/codegen",
+        "tests/codegen-units",
+        "tests/incremental",
+        "tests/mir-opt",
+        "tests/pretty",
+        "tests/run-pass-valgrind",
+        "tests/ui",
+    ];
+    for test_path in env.skipped_tests() {
+        args.extend(["--exclude", test_path]);
+    }
+    cmd(&args).env("COMPILETEST_FORCE_STAGE0", "1").run().context("Cannot execute tests")
+}
diff --git a/src/tools/opt-dist/src/timer.rs b/src/tools/opt-dist/src/timer.rs
new file mode 100644
index 00000000000..2b29ba8d59f
--- /dev/null
+++ b/src/tools/opt-dist/src/timer.rs
@@ -0,0 +1,167 @@
+use std::ops::{Deref, DerefMut};
+use std::time::{Duration, SystemTime};
+
+pub struct Timer {
+    root: TimerSection,
+}
+
+impl Timer {
+    pub fn new() -> Self {
+        Timer { root: TimerSection::new(None) }
+    }
+
+    pub fn format_stats(&self) -> String {
+        use std::fmt::Write;
+
+        let mut items = Vec::new();
+        for (name, child) in &self.root.children {
+            match child {
+                SectionEntry::SubSection(section) => {
+                    section.collect_levels(0, name, &mut items);
+                }
+                SectionEntry::Duration(duration) => items.push((0, name, *duration)),
+            }
+        }
+
+        let rows: Vec<(String, Duration)> = items
+            .into_iter()
+            .map(|(level, name, duration)| (format!("{}{name}:", "  ".repeat(level)), duration))
+            .collect();
+
+        let total_duration = self.total_duration();
+        let total_duration_label = "Total duration:".to_string();
+
+        const SPACE_AFTER_LABEL: usize = 2;
+        let max_label_length = 16.max(rows.iter().map(|(label, _)| label.len()).max().unwrap_or(0))
+            + SPACE_AFTER_LABEL;
+
+        let table_width = max_label_length + 23;
+        let divider = "-".repeat(table_width);
+
+        let mut output = String::new();
+        writeln!(output, "{divider}").unwrap();
+        for (label, duration) in rows {
+            let pct = (duration.as_millis() as f64 / total_duration.as_millis() as f64) * 100.0;
+            let duration_fmt = format!("{:>12.2}s ({pct:>5.2}%)", duration.as_secs_f64());
+            writeln!(output, "{label:<0$} {duration_fmt}", max_label_length).unwrap();
+        }
+        output.push('\n');
+
+        let total_duration = Duration::new(total_duration.as_secs(), 0);
+        let total_duration = format!(
+            "{:>1$}",
+            humantime::format_duration(total_duration).to_string(),
+            table_width - total_duration_label.len()
+        );
+        writeln!(output, "{total_duration_label}{total_duration}").unwrap();
+
+        writeln!(output, "{divider}").unwrap();
+        output
+    }
+}
+
+impl Deref for Timer {
+    type Target = TimerSection;
+
+    fn deref(&self) -> &Self::Target {
+        &self.root
+    }
+}
+
+impl DerefMut for Timer {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.root
+    }
+}
+
+pub struct TimerSection {
+    name: Option<String>,
+    children: Vec<(String, SectionEntry)>,
+    duration_excluding_children: Duration,
+}
+
+impl TimerSection {
+    pub fn new(name: Option<String>) -> Self {
+        TimerSection {
+            name,
+            children: Default::default(),
+            duration_excluding_children: Duration::ZERO,
+        }
+    }
+
+    pub fn section<F: FnOnce(&mut TimerSection) -> anyhow::Result<R>, R>(
+        &mut self,
+        name: &str,
+        func: F,
+    ) -> anyhow::Result<R> {
+        let full_name = match &self.name {
+            Some(current_name) => {
+                format!("{current_name} > {name}")
+            }
+            None => name.to_string(),
+        };
+        log::info!("Section `{full_name}` starts");
+        let mut child = TimerSection {
+            name: Some(full_name.clone()),
+            children: Default::default(),
+            duration_excluding_children: Duration::ZERO,
+        };
+
+        let start = SystemTime::now();
+        let result = func(&mut child);
+        let duration = start.elapsed().unwrap();
+
+        let msg = match result {
+            Ok(_) => "OK",
+            Err(_) => "FAIL",
+        };
+
+        child.duration_excluding_children = duration.saturating_sub(child.total_duration());
+
+        log::info!("Section `{full_name}` ended: {msg} ({:.2}s)`", duration.as_secs_f64());
+        self.children.push((name.to_string(), SectionEntry::SubSection(child)));
+        result
+    }
+
+    pub fn add_duration(&mut self, name: &str, duration: Duration) {
+        self.children.push((name.to_string(), SectionEntry::Duration(duration)));
+    }
+
+    fn total_duration(&self) -> Duration {
+        self.duration_excluding_children
+            + self.children.iter().map(|(_, child)| child.total_duration()).sum::<Duration>()
+    }
+
+    fn collect_levels<'a>(
+        &'a self,
+        level: usize,
+        name: &'a str,
+        items: &mut Vec<(usize, &'a str, Duration)>,
+    ) {
+        items.push((level, name, self.total_duration()));
+        for (name, child) in &self.children {
+            match &child {
+                SectionEntry::Duration(duration) => {
+                    items.push((level + 1, name, *duration));
+                }
+                SectionEntry::SubSection(section) => {
+                    section.collect_levels(level + 1, name, items);
+                }
+            }
+        }
+    }
+}
+
+enum SectionEntry {
+    Duration(Duration),
+    SubSection(TimerSection),
+}
+
+impl SectionEntry {
+    fn total_duration(&self) -> Duration {
+        match self {
+            SectionEntry::Duration(duration) => *duration,
+            SectionEntry::SubSection(timer) => timer.total_duration(),
+        }
+    }
+}
diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs
new file mode 100644
index 00000000000..10f4a603695
--- /dev/null
+++ b/src/tools/opt-dist/src/training.rs
@@ -0,0 +1,202 @@
+use crate::environment::Environment;
+use crate::exec::{cmd, CmdBuilder};
+use crate::utils::io::{count_files, delete_directory};
+use anyhow::Context;
+use camino::{Utf8Path, Utf8PathBuf};
+use humansize::BINARY;
+
+const LLVM_PGO_CRATES: &[&str] = &[
+    "syn-1.0.89",
+    "cargo-0.60.0",
+    "serde-1.0.136",
+    "ripgrep-13.0.0",
+    "regex-1.5.5",
+    "clap-3.1.6",
+    "hyper-0.14.18",
+];
+
+const RUSTC_PGO_CRATES: &[&str] = &[
+    "externs",
+    "ctfe-stress-5",
+    "cargo-0.60.0",
+    "token-stream-stress",
+    "match-stress",
+    "tuple-stress",
+    "diesel-1.4.8",
+    "bitmaps-3.1.0",
+];
+
+const LLVM_BOLT_CRATES: &[&str] = LLVM_PGO_CRATES;
+
+fn init_compiler_benchmarks(
+    env: &dyn Environment,
+    profiles: &[&str],
+    scenarios: &[&str],
+    crates: &[&str],
+) -> CmdBuilder {
+    // Run rustc-perf benchmarks
+    // Benchmark using profile_local with eprintln, which essentially just means
+    // don't actually benchmark -- just make sure we run rustc a bunch of times.
+    cmd(&[
+        env.cargo_stage_0().as_str(),
+        "run",
+        "-p",
+        "collector",
+        "--bin",
+        "collector",
+        "--",
+        "profile_local",
+        "eprintln",
+        env.rustc_stage_2().as_str(),
+        "--id",
+        "Test",
+        "--cargo",
+        env.cargo_stage_0().as_str(),
+        "--profiles",
+        profiles.join(",").as_str(),
+        "--scenarios",
+        scenarios.join(",").as_str(),
+        "--include",
+        crates.join(",").as_str(),
+    ])
+    .env("RUST_LOG", "collector=debug")
+    .env("RUSTC", env.rustc_stage_0().as_str())
+    .env("RUSTC_BOOTSTRAP", "1")
+    .workdir(&env.rustc_perf_dir())
+}
+
+fn merge_llvm_profiles(
+    env: &dyn Environment,
+    merged_path: &Utf8Path,
+    profile_dir: &Utf8Path,
+) -> anyhow::Result<()> {
+    cmd(&[
+        env.downloaded_llvm_dir().join("bin/llvm-profdata").as_str(),
+        "merge",
+        "-o",
+        merged_path.as_str(),
+        profile_dir.as_str(),
+    ])
+    .run()
+    .context("Cannot merge LLVM profiles")?;
+    Ok(())
+}
+
+fn log_profile_stats(
+    name: &str,
+    merged_profile: &Utf8Path,
+    profile_root: &Utf8Path,
+) -> anyhow::Result<()> {
+    log::info!("{name} PGO statistics");
+    log::info!(
+        "{merged_profile}: {}",
+        humansize::format_size(std::fs::metadata(merged_profile.as_std_path())?.len(), BINARY)
+    );
+    log::info!(
+        "{profile_root}: {}",
+        humansize::format_size(fs_extra::dir::get_size(profile_root.as_std_path())?, BINARY)
+    );
+    log::info!("Profile file count: {}", count_files(profile_root)?);
+    Ok(())
+}
+
+pub struct LlvmPGOProfile(pub Utf8PathBuf);
+
+pub fn gather_llvm_profiles(
+    env: &dyn Environment,
+    profile_root: &Utf8Path,
+) -> anyhow::Result<LlvmPGOProfile> {
+    log::info!("Running benchmarks with PGO instrumented LLVM");
+
+    init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES)
+        .run()
+        .context("Cannot gather LLVM PGO profiles")?;
+
+    let merged_profile = env.opt_artifacts().join("llvm-pgo.profdata");
+    log::info!("Merging LLVM PGO profiles to {merged_profile}");
+
+    merge_llvm_profiles(env, &merged_profile, profile_root)?;
+    log_profile_stats("LLVM", &merged_profile, profile_root)?;
+
+    // We don't need the individual .profraw files now that they have been merged
+    // into a final .profdata
+    delete_directory(profile_root)?;
+
+    Ok(LlvmPGOProfile(merged_profile))
+}
+
+pub struct RustcPGOProfile(pub Utf8PathBuf);
+
+pub fn gather_rustc_profiles(
+    env: &dyn Environment,
+    profile_root: &Utf8Path,
+) -> anyhow::Result<RustcPGOProfile> {
+    log::info!("Running benchmarks with PGO instrumented rustc");
+
+    // The profile data is written into a single filepath that is being repeatedly merged when each
+    // rustc invocation ends. Empirically, this can result in some profiling data being lost. That's
+    // why we override the profile path to include the PID. This will produce many more profiling
+    // files, but the resulting profile will produce a slightly faster rustc binary.
+    let profile_template = profile_root.join("default_%m_%p.profraw");
+
+    // Here we're profiling the `rustc` frontend, so we also include `Check`.
+    // The benchmark set includes various stress tests that put the frontend under pressure.
+    init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES)
+        .env("LLVM_PROFILE_FILE", profile_template.as_str())
+        .run()
+        .context("Cannot gather rustc PGO profiles")?;
+
+    let merged_profile = env.opt_artifacts().join("rustc-pgo.profdata");
+    log::info!("Merging Rustc PGO profiles to {merged_profile}");
+
+    merge_llvm_profiles(env, &merged_profile, profile_root)?;
+    log_profile_stats("Rustc", &merged_profile, profile_root)?;
+
+    // We don't need the individual .profraw files now that they have been merged
+    // into a final .profdata
+    delete_directory(profile_root)?;
+
+    Ok(RustcPGOProfile(merged_profile))
+}
+
+pub struct LlvmBoltProfile(pub Utf8PathBuf);
+
+pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBoltProfile> {
+    log::info!("Running benchmarks with BOLT instrumented LLVM");
+
+    init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["Full"], LLVM_BOLT_CRATES)
+        .run()
+        .context("Cannot gather LLVM BOLT profiles")?;
+
+    let merged_profile = env.opt_artifacts().join("bolt.profdata");
+    let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
+    log::info!("Merging LLVM BOLT profiles to {merged_profile}");
+
+    let profiles: Vec<_> =
+        glob::glob(&format!("{profile_root}*"))?.into_iter().collect::<Result<Vec<_>, _>>()?;
+
+    let mut merge_args = vec!["merge-fdata"];
+    merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap()));
+
+    cmd(&merge_args)
+        .redirect_output(merged_profile.clone())
+        .run()
+        .context("Cannot merge BOLT profiles")?;
+
+    log::info!("LLVM BOLT statistics");
+    log::info!(
+        "{merged_profile}: {}",
+        humansize::format_size(std::fs::metadata(merged_profile.as_std_path())?.len(), BINARY)
+    );
+
+    let size = profiles
+        .iter()
+        .map(|p| std::fs::metadata(p).map(|metadata| metadata.len()))
+        .collect::<Result<Vec<_>, _>>()?
+        .into_iter()
+        .sum::<u64>();
+    log::info!("{profile_root}: {}", humansize::format_size(size, BINARY));
+    log::info!("Profile file count: {}", profiles.len());
+
+    Ok(LlvmBoltProfile(merged_profile))
+}
diff --git a/src/tools/opt-dist/src/utils/io.rs b/src/tools/opt-dist/src/utils/io.rs
new file mode 100644
index 00000000000..43546e5fcfa
--- /dev/null
+++ b/src/tools/opt-dist/src/utils/io.rs
@@ -0,0 +1,48 @@
+use anyhow::Context;
+use camino::Utf8Path;
+use fs_extra::dir::CopyOptions;
+use std::fs::File;
+
+/// Delete and re-create the directory.
+pub fn reset_directory(path: &Utf8Path) -> anyhow::Result<()> {
+    log::info!("Resetting directory {path}");
+    let _ = std::fs::remove_dir(path);
+    std::fs::create_dir_all(path)?;
+    Ok(())
+}
+
+pub fn copy_directory(src: &Utf8Path, dst: &Utf8Path) -> anyhow::Result<()> {
+    log::info!("Copying directory {src} to {dst}");
+    fs_extra::dir::copy(src, dst, &CopyOptions::default().copy_inside(true))?;
+    Ok(())
+}
+
+#[allow(unused)]
+pub fn move_directory(src: &Utf8Path, dst: &Utf8Path) -> anyhow::Result<()> {
+    log::info!("Moving directory {src} to {dst}");
+    fs_extra::dir::move_dir(src, dst, &CopyOptions::default().content_only(true))?;
+    Ok(())
+}
+
+/// Counts all children of a directory (non-recursively).
+pub fn count_files(dir: &Utf8Path) -> anyhow::Result<u64> {
+    Ok(std::fs::read_dir(dir)?.count() as u64)
+}
+
+pub fn delete_directory(path: &Utf8Path) -> anyhow::Result<()> {
+    log::info!("Deleting directory `{path}`");
+    std::fs::remove_dir_all(path.as_std_path())
+        .context(format!("Cannot remove directory {path}"))?;
+    Ok(())
+}
+
+pub fn unpack_archive(path: &Utf8Path, dest_dir: &Utf8Path) -> anyhow::Result<()> {
+    log::info!("Unpacking directory `{path}` into `{dest_dir}`");
+
+    assert!(path.as_str().ends_with(".tar.xz"));
+    let file = File::open(path.as_std_path())?;
+    let file = xz::read::XzDecoder::new(file);
+    let mut archive = tar::Archive::new(file);
+    archive.unpack(dest_dir.as_std_path())?;
+    Ok(())
+}
diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs
new file mode 100644
index 00000000000..9305d4989aa
--- /dev/null
+++ b/src/tools/opt-dist/src/utils/mod.rs
@@ -0,0 +1,36 @@
+pub mod io;
+
+use crate::environment::Environment;
+use crate::utils::io::delete_directory;
+use humansize::BINARY;
+use sysinfo::{DiskExt, RefreshKind, System, SystemExt};
+
+pub fn format_env_variables() -> String {
+    let vars = std::env::vars().map(|(key, value)| format!("{key}={value}")).collect::<Vec<_>>();
+    vars.join("\n")
+}
+
+pub fn print_free_disk_space() -> anyhow::Result<()> {
+    let sys = System::new_with_specifics(RefreshKind::default().with_disks_list().with_disks());
+    let available_space: u64 = sys.disks().iter().map(|d| d.available_space()).sum();
+    let total_space: u64 = sys.disks().iter().map(|d| d.total_space()).sum();
+    let used_space = total_space - available_space;
+
+    log::info!(
+        "Free disk space: {} out of total {} ({:.2}% used)",
+        humansize::format_size(available_space, BINARY),
+        humansize::format_size(total_space, BINARY),
+        (used_space as f64 / total_space as f64) * 100.0
+    );
+    Ok(())
+}
+
+pub fn clear_llvm_files(env: &dyn Environment) -> anyhow::Result<()> {
+    // Bootstrap currently doesn't support rebuilding LLVM when PGO options
+    // change (or any other llvm-related options); so just clear out the relevant
+    // directories ourselves.
+    log::info!("Clearing LLVM build files");
+    delete_directory(&env.build_artifacts().join("llvm"))?;
+    delete_directory(&env.build_artifacts().join("lld"))?;
+    Ok(())
+}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index ecc84c1618c..2c237c418b1 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -40,10 +40,12 @@ const EXCEPTIONS: &[(&str, &str)] = &[
     ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
     ("colored", "MPL-2.0"),                                  // rustfmt
     ("dissimilar", "Apache-2.0"),                            // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
+    ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), // opt-dist
     ("fluent-langneg", "Apache-2.0"),                        // rustc (fluent translations)
     ("fortanix-sgx-abi", "MPL-2.0"),                         // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above.
     ("instant", "BSD-3-Clause"),                             // rustc_driver/tracing-subscriber/parking_lot
     ("mdbook", "MPL-2.0"),                                   // mdbook
+    ("openssl", "Apache-2.0"),                               // opt-dist
     ("ryu", "Apache-2.0 OR BSL-1.0"),                        // cargo/... (because of serde)
     ("self_cell", "Apache-2.0"),                             // rustc (fluent translations)
     ("snap", "BSD-3-Clause"),                                // rustc
@@ -142,6 +144,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "elsa",
     "ena",
     "equivalent",
+    "errno",
+    "errno-dragonfly",
     "expect-test",
     "fallible-iterator", // dependency of `thorin`
     "fastrand",
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 6fd41e83362..62c070221dc 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -53,13 +53,9 @@ const EXCEPTION_PATHS: &[&str] = &[
     // FIXME: platform-specific code should be moved to `sys`
     "library/std/src/io/copy.rs",
     "library/std/src/io/stdio.rs",
-    "library/std/src/f32.rs",
-    "library/std/src/f64.rs",
     "library/std/src/path.rs",
     "library/std/src/sys_common", // Should only contain abstractions over platforms
     "library/std/src/net/test.rs", // Utility helpers for tests
-    "library/std/src/personality.rs",
-    "library/std/src/personality/",
 ];
 
 pub fn check(path: &Path, bad: &mut bool) {
diff --git a/src/version b/src/version
index 0834888f558..5e3a4256626 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.72.0
+1.73.0
diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
index 011a253c6ff..a7c9e4845c7 100644
--- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
+++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
@@ -3,6 +3,7 @@
 // ignore-macos slightly different policy on stack protection of arrays
 // ignore-windows stack check code uses different function names
 // ignore-nvptx64 stack protector is not supported
+// ignore-wasm32-bare
 // [all] compile-flags: -Z stack-protector=all
 // [strong] compile-flags: -Z stack-protector=strong
 // [basic] compile-flags: -Z stack-protector=basic
diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs
new file mode 100644
index 00000000000..b7d20881b62
--- /dev/null
+++ b/tests/assembly/wasm_exceptions.rs
@@ -0,0 +1,60 @@
+// only-wasm32-bare
+// assembly-output: emit-asm
+// compile-flags: -C target-feature=+exception-handling
+// compile-flags: -C panic=unwind
+// compile-flags: -C llvm-args=-wasm-enable-eh
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+#![feature(rustc_attrs)]
+
+extern {
+    fn may_panic();
+
+    #[rustc_nounwind]
+    fn log_number(number: usize);
+}
+
+struct LogOnDrop;
+
+impl Drop for LogOnDrop {
+    fn drop(&mut self) {
+        unsafe { log_number(0); }
+    }
+}
+
+// CHECK-LABEL: test_cleanup:
+#[no_mangle]
+pub fn test_cleanup() {
+    let _log_on_drop = LogOnDrop;
+    unsafe { may_panic(); }
+
+    // CHECK-NOT: call
+    // CHECK: try
+    // CHECK: call may_panic
+    // CHECK: catch_all
+    // CHECK: rethrow
+    // CHECK: end_try
+}
+
+// CHECK-LABEL: test_rtry:
+#[no_mangle]
+pub fn test_rtry() {
+    unsafe {
+        core::intrinsics::r#try(|_| {
+            may_panic();
+        }, core::ptr::null_mut(), |data, exception| {
+            log_number(data as usize);
+            log_number(exception as usize);
+        });
+    }
+
+    // CHECK-NOT: call
+    // CHECK: try
+    // CHECK: call may_panic
+    // CHECK: catch
+    // CHECK: call log_number
+    // CHECK: call log_number
+    // CHECK-NOT: rethrow
+    // CHECK: end_try
+}
diff --git a/tests/codegen/array-codegen.rs b/tests/codegen/array-codegen.rs
index 98488eb92ee..71acd781549 100644
--- a/tests/codegen/array-codegen.rs
+++ b/tests/codegen/array-codegen.rs
@@ -6,10 +6,10 @@
 // CHECK-LABEL: @array_load
 #[no_mangle]
 pub fn array_load(a: &[u8; 4]) -> [u8; 4] {
-    // CHECK: %0 = alloca [4 x i8], align 1
+    // CHECK: %_0 = alloca [4 x i8], align 1
     // CHECK: %[[TEMP1:.+]] = load <4 x i8>, ptr %a, align 1
-    // CHECK: store <4 x i8> %[[TEMP1]], ptr %0, align 1
-    // CHECK: %[[TEMP2:.+]] = load i32, ptr %0, align 1
+    // CHECK: store <4 x i8> %[[TEMP1]], ptr %_0, align 1
+    // CHECK: %[[TEMP2:.+]] = load i32, ptr %_0, align 1
     // CHECK: ret i32 %[[TEMP2]]
     *a
 }
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index bc11e108124..83baae9e432 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -116,7 +116,7 @@ pub enum Either<T, U> { A(T), B(U) }
 // with the `ptr` field representing both `&i32` and `fn()` depending on the variant.
 // This is incorrect, because `fn()` should be `ptr addrspace(1)`, not `ptr`.
 
-// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%0, {{.+\*|ptr}}{{.+}}%x)
+// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%_0, {{.+\*|ptr}}{{.+}}%x)
 #[no_mangle]
 #[inline(never)]
 pub fn should_not_combine_addrspace(x: Either<&i32, fn()>) -> Either<&i32, fn()> {
diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs
index fc2badc417c..810da581ce9 100644
--- a/tests/codegen/consts.rs
+++ b/tests/codegen/consts.rs
@@ -1,4 +1,5 @@
 // compile-flags: -C no-prepopulate-passes
+// min-llvm-version: 15.0 (for opaque pointers)
 
 #![crate_type = "lib"]
 
@@ -42,7 +43,7 @@ pub fn inline_enum_const() -> E<i8, i16> {
 #[no_mangle]
 pub fn low_align_const() -> E<i16, [i16; 3]> {
     // Check that low_align_const and high_align_const use the same constant
-    // CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 2 %{{[0-9]+}}, {{i8\*|ptr}} align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
+    // CHECK: memcpy.{{.+}}(ptr align 2 %_0, ptr align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
     *&E::A(0)
 }
 
@@ -50,6 +51,6 @@ pub fn low_align_const() -> E<i16, [i16; 3]> {
 #[no_mangle]
 pub fn high_align_const() -> E<i16, i32> {
     // Check that low_align_const and high_align_const use the same constant
-    // CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
+    // CHECK: memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false)
     *&E::A(0)
 }
diff --git a/tests/codegen/enum-match.rs b/tests/codegen/enum-match.rs
index 36c6be19012..5548cd25147 100644
--- a/tests/codegen/enum-match.rs
+++ b/tests/codegen/enum-match.rs
@@ -15,7 +15,7 @@ pub enum Enum0 {
 // CHECK-NEXT: start:
 // CHECK-NEXT: %1 = icmp eq i8 %0, 2
 // CHECK-NEXT: %2 = and i8 %0, 1
-// CHECK-NEXT: %.0 = select i1 %1, i8 13, i8 %2
+// CHECK-NEXT: %_0.0 = select i1 %1, i8 13, i8 %2
 #[no_mangle]
 pub fn match0(e: Enum0) -> u8 {
     use Enum0::*;
diff --git a/tests/codegen/fewer-names.rs b/tests/codegen/fewer-names.rs
index a09c795924c..df1080bff2b 100644
--- a/tests/codegen/fewer-names.rs
+++ b/tests/codegen/fewer-names.rs
@@ -13,8 +13,8 @@ pub fn sum(x: u32, y: u32) -> u32 {
 
     // NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
     // NO-NEXT:  start:
-    // NO-NEXT:    %0 = add i32 %y, %x
-    // NO-NEXT:    ret i32 %0
+    // NO-NEXT:    %z = add i32 %y, %x
+    // NO-NEXT:    ret i32 %z
     let z = x + y;
     z
 }
diff --git a/tests/codegen/function-arguments-noopt.rs b/tests/codegen/function-arguments-noopt.rs
index 0c62e0d35e3..35f31eba3b1 100644
--- a/tests/codegen/function-arguments-noopt.rs
+++ b/tests/codegen/function-arguments-noopt.rs
@@ -42,7 +42,7 @@ pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 {
   f(x)
 }
 
-// CHECK: void @struct_({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %x)
+// CHECK: void @struct_({{%S\*|ptr}} sret(%S){{( %_0)?}}, {{%S\*|ptr}} %x)
 #[no_mangle]
 pub fn struct_(x: S) -> S {
   x
@@ -51,7 +51,7 @@ pub fn struct_(x: S) -> S {
 // CHECK-LABEL: @struct_call
 #[no_mangle]
 pub fn struct_call(x: S, f: fn(S) -> S) -> S {
-  // CHECK: call void %f({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %{{.+}})
+  // CHECK: call void %f({{%S\*|ptr}} sret(%S){{( %_0)?}}, {{%S\*|ptr}} %{{.+}})
   f(x)
 }
 
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index d6f019016a5..ccf4a5de327 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -188,7 +188,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
   x
 }
 
-// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %0)?}})
+// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %_0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
   S {
diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs
index 69e9b1d1206..fffc24a1181 100644
--- a/tests/codegen/intrinsics/transmute-niched.rs
+++ b/tests/codegen/intrinsics/transmute-niched.rs
@@ -169,16 +169,16 @@ pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool {
 // CHECK-LABEL: @check_bool_to_ordering(
 #[no_mangle]
 pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering {
-    // CHECK: %0 = zext i1 %x to i8
-    // OPT: %1 = icmp ule i8 %0, 1
-    // OPT: call void @llvm.assume(i1 %1)
-    // OPT: %2 = icmp uge i8 %0, -1
-    // OPT: %3 = icmp ule i8 %0, 1
-    // OPT: %4 = or i1 %2, %3
-    // OPT: call void @llvm.assume(i1 %4)
+    // CHECK: %_0 = zext i1 %x to i8
+    // OPT: %0 = icmp ule i8 %_0, 1
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = icmp uge i8 %_0, -1
+    // OPT: %2 = icmp ule i8 %_0, 1
+    // OPT: %3 = or i1 %1, %2
+    // OPT: call void @llvm.assume(i1 %3)
     // DBG-NOT: icmp
     // DBG-NOT: assume
-    // CHECK: ret i8 %0
+    // CHECK: ret i8 %_0
 
     transmute(x)
 }
diff --git a/tests/codegen/intrinsics/transmute-x64.rs b/tests/codegen/intrinsics/transmute-x64.rs
index 99d258c6204..168838ef497 100644
--- a/tests/codegen/intrinsics/transmute-x64.rs
+++ b/tests/codegen/intrinsics/transmute-x64.rs
@@ -11,8 +11,8 @@ use std::mem::transmute;
 #[no_mangle]
 pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i {
     // CHECK-NOT: alloca
-    // CHECK: %1 = load <4 x float>, ptr %x, align 16
-    // CHECK: store <4 x float> %1, ptr %0, align 16
+    // CHECK: %0 = load <4 x float>, ptr %x, align 16
+    // CHECK: store <4 x float> %0, ptr %_0, align 16
     transmute(x)
 }
 
@@ -20,8 +20,8 @@ pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i {
 #[no_mangle]
 pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i {
     // CHECK-NOT: alloca
-    // CHECK: %1 = load <4 x i64>, ptr %x, align 16
-    // CHECK: store <4 x i64> %1, ptr %0, align 32
+    // CHECK: %0 = load <4 x i64>, ptr %x, align 16
+    // CHECK: store <4 x i64> %0, ptr %_0, align 32
     transmute(x)
 }
 
@@ -29,7 +29,7 @@ pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i {
 #[no_mangle]
 pub unsafe fn check_sse_pair_from_avx(x: __m256i) -> (__m128i, __m128i) {
     // CHECK-NOT: alloca
-    // CHECK: %1 = load <4 x i64>, ptr %x, align 32
-    // CHECK: store <4 x i64> %1, ptr %0, align 16
+    // CHECK: %0 = load <4 x i64>, ptr %x, align 32
+    // CHECK: store <4 x i64> %0, ptr %_0, align 16
     transmute(x)
 }
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index fe42494000e..f8c20960660 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -8,8 +8,8 @@
 #![feature(inline_const)]
 #![allow(unreachable_code)]
 
-use std::mem::MaybeUninit;
 use std::intrinsics::{transmute, transmute_unchecked};
+use std::mem::MaybeUninit;
 
 // Some of these need custom MIR to not get removed by MIR optimizations.
 use std::intrinsics::mir::*;
@@ -63,7 +63,7 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] {
     // CHECK-NOT: trap
     // CHECK: call void @llvm.trap
     // CHECK-NOT: trap
-    mir!{
+    mir! {
         {
             RET = CastTransmute(x);
             Return()
@@ -78,7 +78,7 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] {
     // CHECK-NOT: trap
     // CHECK: call void @llvm.trap
     // CHECK-NOT: trap
-    mir!{
+    mir! {
         {
             RET = CastTransmute(x);
             Return()
@@ -93,7 +93,7 @@ pub unsafe fn check_to_uninhabited(x: u16) {
     // CHECK-NOT: trap
     // CHECK: call void @llvm.trap
     // CHECK-NOT: trap
-    mir!{
+    mir! {
         let temp: BigNever;
         {
             temp = CastTransmute(x);
@@ -107,7 +107,7 @@ pub unsafe fn check_to_uninhabited(x: u16) {
 #[custom_mir(dialect = "runtime", phase = "optimized")]
 pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 {
     // CHECK: ret i16 poison
-    mir!{
+    mir! {
         {
             RET = CastTransmute(x);
             Return()
@@ -122,9 +122,7 @@ pub unsafe fn check_intermediate_passthrough(x: u32) -> i32 {
     // CHECK: %[[TMP:.+]] = add i32 1, %x
     // CHECK: %[[RET:.+]] = add i32 %[[TMP]], 1
     // CHECK: ret i32 %[[RET]]
-    unsafe {
-        transmute::<u32, i32>(1 + x) + 1
-    }
+    unsafe { transmute::<u32, i32>(1 + x) + 1 }
 }
 
 // CHECK-LABEL: @check_nop_pair(
@@ -134,9 +132,7 @@ pub unsafe fn check_nop_pair(x: (u8, i8)) -> (i8, u8) {
     // CHECK: %0 = insertvalue { i8, i8 } poison, i8 %x.0, 0
     // CHECK: %1 = insertvalue { i8, i8 } %0, i8 %x.1, 1
     // CHECK: ret { i8, i8 } %1
-    unsafe {
-        transmute(x)
-    }
+    unsafe { transmute(x) }
 }
 
 // CHECK-LABEL: @check_to_newtype(
@@ -168,9 +164,9 @@ pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool {
 // CHECK-LABEL: @check_aggregate_from_bool(
 #[no_mangle]
 pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 {
-    // CHECK: %0 = alloca %Aggregate8, align 1
+    // CHECK: %_0 = alloca %Aggregate8, align 1
     // CHECK: %[[BYTE:.+]] = zext i1 %x to i8
-    // CHECK: store i8 %[[BYTE]], ptr %0, align 1
+    // CHECK: store i8 %[[BYTE]], ptr %_0, align 1
     transmute(x)
 }
 
@@ -195,8 +191,8 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 {
 // CHECK-LABEL: @check_to_pair(
 #[no_mangle]
 pub unsafe fn check_to_pair(x: u64) -> Option<i32> {
-    // CHECK: %0 = alloca { i32, i32 }, align 4
-    // CHECK: store i64 %x, ptr %0, align 4
+    // CHECK: %_0 = alloca { i32, i32 }, align 4
+    // CHECK: store i64 %x, ptr %_0, align 4
     transmute(x)
 }
 
@@ -207,11 +203,11 @@ pub unsafe fn check_from_pair(x: Option<i32>) -> u64 {
     // immediates so we can write using the destination alloca's alignment.
     const { assert!(std::mem::align_of::<Option<i32>>() == 4) };
 
-    // CHECK: %0 = alloca i64, align 8
-    // CHECK: store i32 %x.0, ptr %1, align 8
-    // CHECK: store i32 %x.1, ptr %2, align 4
-    // CHECK: %3 = load i64, ptr %0, align 8
-    // CHECK: ret i64 %3
+    // CHECK: %_0 = alloca i64, align 8
+    // CHECK: store i32 %x.0, ptr %0, align 8
+    // CHECK: store i32 %x.1, ptr %1, align 4
+    // CHECK: %2 = load i64, ptr %_0, align 8
+    // CHECK: ret i64 %2
     transmute(x)
 }
 
@@ -219,8 +215,8 @@ pub unsafe fn check_from_pair(x: Option<i32>) -> u64 {
 #[no_mangle]
 pub unsafe fn check_to_float(x: u32) -> f32 {
     // CHECK-NOT: alloca
-    // CHECK: %0 = bitcast i32 %x to float
-    // CHECK: ret float %0
+    // CHECK: %_0 = bitcast i32 %x to float
+    // CHECK: ret float %_0
     transmute(x)
 }
 
@@ -228,16 +224,16 @@ pub unsafe fn check_to_float(x: u32) -> f32 {
 #[no_mangle]
 pub unsafe fn check_from_float(x: f32) -> u32 {
     // CHECK-NOT: alloca
-    // CHECK: %0 = bitcast float %x to i32
-    // CHECK: ret i32 %0
+    // CHECK: %_0 = bitcast float %x to i32
+    // CHECK: ret i32 %_0
     transmute(x)
 }
 
 // CHECK-LABEL: @check_to_bytes(
 #[no_mangle]
 pub unsafe fn check_to_bytes(x: u32) -> [u8; 4] {
-    // CHECK: %0 = alloca [4 x i8], align 1
-    // CHECK: store i32 %x, ptr %0, align 1
+    // CHECK: %_0 = alloca [4 x i8], align 1
+    // CHECK: store i32 %x, ptr %_0, align 1
     transmute(x)
 }
 
@@ -253,10 +249,10 @@ pub unsafe fn check_from_bytes(x: [u8; 4]) -> u32 {
 // CHECK-LABEL: @check_to_aggregate(
 #[no_mangle]
 pub unsafe fn check_to_aggregate(x: u64) -> Aggregate64 {
-    // CHECK: %0 = alloca %Aggregate64, align 4
-    // CHECK: store i64 %x, ptr %0, align 4
-    // CHECK: %1 = load i64, ptr %0, align 4
-    // CHECK: ret i64 %1
+    // CHECK: %_0 = alloca %Aggregate64, align 4
+    // CHECK: store i64 %x, ptr %_0, align 4
+    // CHECK: %0 = load i64, ptr %_0, align 4
+    // CHECK: ret i64 %0
     transmute(x)
 }
 
@@ -273,7 +269,7 @@ pub unsafe fn check_from_aggregate(x: Aggregate64) -> u64 {
 #[no_mangle]
 pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] {
     // CHECK-NEXT: start
-    // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %0, ptr align 8 %x, i64 800, i1 false)
+    // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %_0, ptr align 8 %x, i64 800, i1 false)
     // CHECK-NEXT: ret void
     transmute(x)
 }
@@ -282,7 +278,7 @@ pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] {
 #[no_mangle]
 pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] {
     // CHECK-NEXT: start
-    // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 1 %x, i64 100, i1 false)
+    // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %_0, ptr align 1 %x, i64 100, i1 false)
     // CHECK-NEXT: ret void
     transmute(x)
 }
@@ -301,8 +297,8 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) {
 pub unsafe fn check_float_to_pointer(x: f64) -> *const () {
     // CHECK-NOT: alloca
     // CHECK: %0 = bitcast double %x to i64
-    // CHECK: %1 = inttoptr i64 %0 to ptr
-    // CHECK: ret ptr %1
+    // CHECK: %_0 = inttoptr i64 %0 to ptr
+    // CHECK: ret ptr %_0
     transmute(x)
 }
 
@@ -311,8 +307,8 @@ pub unsafe fn check_float_to_pointer(x: f64) -> *const () {
 pub unsafe fn check_float_from_pointer(x: *const ()) -> f64 {
     // CHECK-NOT: alloca
     // CHECK: %0 = ptrtoint ptr %x to i64
-    // CHECK: %1 = bitcast i64 %0 to double
-    // CHECK: ret double %1
+    // CHECK: %_0 = bitcast i64 %0 to double
+    // CHECK: ret double %_0
     transmute(x)
 }
 
@@ -376,10 +372,10 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option<Box<[u8]>> {
 // CHECK-LABEL: @check_pair_to_dst_ref(
 #[no_mangle]
 pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] {
-    // CHECK: %0 = inttoptr i64 %x.0 to ptr
-    // CHECK: %1 = insertvalue { ptr, i64 } poison, ptr %0, 0
-    // CHECK: %2 = insertvalue { ptr, i64 } %1, i64 %x.1, 1
-    // CHECK: ret { ptr, i64 } %2
+    // CHECK: %_0.0 = inttoptr i64 %x.0 to ptr
+    // CHECK: %0 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0
+    // CHECK: %1 = insertvalue { ptr, i64 } %0, i64 %x.1, 1
+    // CHECK: ret { ptr, i64 } %1
     transmute(x)
 }
 
@@ -391,7 +387,7 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] {
 
     // CHECK: start
     // CHECK-NEXT: ret void
-    mir!{
+    mir! {
         {
             RET = CastTransmute(x);
             Return()
@@ -408,7 +404,7 @@ pub unsafe fn check_unit_to_never(x: ()) {
     // CHECK-NOT: trap
     // CHECK: call void @llvm.trap
     // CHECK-NOT: trap
-    mir!{
+    mir! {
         let temp: ZstNever;
         {
             temp = CastTransmute(x);
@@ -425,7 +421,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () {
 
     // CHECK: start
     // CHECK-NEXT: ret void
-    mir!{
+    mir! {
         {
             RET = CastTransmute(x);
             Return()
@@ -457,10 +453,10 @@ pub struct HighAlignScalar(u8);
 // CHECK-LABEL: @check_to_overalign(
 #[no_mangle]
 pub unsafe fn check_to_overalign(x: u64) -> HighAlignScalar {
-    // CHECK: %0 = alloca %HighAlignScalar, align 8
-    // CHECK: store i64 %x, ptr %0, align 8
-    // CHECK: %1 = load i64, ptr %0, align 8
-    // CHECK: ret i64 %1
+    // CHECK: %_0 = alloca %HighAlignScalar, align 8
+    // CHECK: store i64 %x, ptr %_0, align 8
+    // CHECK: %0 = load i64, ptr %_0, align 8
+    // CHECK: ret i64 %0
     transmute(x)
 }
 
diff --git a/tests/codegen/match-optimized.rs b/tests/codegen/match-optimized.rs
index 520c46a0d57..59e6eeb7c5d 100644
--- a/tests/codegen/match-optimized.rs
+++ b/tests/codegen/match-optimized.rs
@@ -20,13 +20,13 @@ pub fn exhaustive_match(e: E) -> u8 {
 // CHECK-NEXT: unreachable
 //
 // CHECK: [[A]]:
-// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %_0, align 1
 // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
 // CHECK: [[B]]:
-// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %_0, align 1
 // CHECK-NEXT: br label %[[EXIT]]
 // CHECK: [[C]]:
-// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %_0, align 1
 // CHECK-NEXT: br label %[[EXIT]]
     match e {
         E::A => 0,
diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs
index c6b920cf599..55c2741faaf 100644
--- a/tests/codegen/mem-replace-big-type.rs
+++ b/tests/codegen/mem-replace-big-type.rs
@@ -25,7 +25,7 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
 // For a large type, we expect exactly three `memcpy`s
 // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big)
 // CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %result, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
 // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
diff --git a/tests/codegen/mem-replace-simple-type.rs b/tests/codegen/mem-replace-simple-type.rs
index 6151177de15..5c4acf813ea 100644
--- a/tests/codegen/mem-replace-simple-type.rs
+++ b/tests/codegen/mem-replace-simple-type.rs
@@ -38,7 +38,7 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str {
 pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
     // CHECK-NOT: alloca
     // CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4
-    // CHECK: store <3 x i32> %[[R]], ptr %0
+    // CHECK: store <3 x i32> %[[R]], ptr %result
     // CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4
     // CHECK: store <3 x i32> %[[V]], ptr %r
     std::mem::replace(r, v)
diff --git a/tests/codegen/repeat-trusted-len.rs b/tests/codegen/repeat-trusted-len.rs
index 87c8fe1354d..d06978f2435 100644
--- a/tests/codegen/repeat-trusted-len.rs
+++ b/tests/codegen/repeat-trusted-len.rs
@@ -8,13 +8,13 @@ use std::iter;
 // CHECK-LABEL: @repeat_take_collect
 #[no_mangle]
 pub fn repeat_take_collect() -> Vec<u8> {
-// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false)
+    // CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 42, i{{[0-9]+}} 100000, i1 false)
     iter::repeat(42).take(100000).collect()
 }
 
 // CHECK-LABEL: @repeat_with_take_collect
 #[no_mangle]
 pub fn repeat_with_take_collect() -> Vec<u8> {
-// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 13, i{{[0-9]+}} 12345, i1 false)
+    // CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 13, i{{[0-9]+}} 12345, i1 false)
     iter::repeat_with(|| 13).take(12345).collect()
 }
diff --git a/tests/codegen/repr-transparent-aggregates-1.rs b/tests/codegen/repr-transparent-aggregates-1.rs
index 9c4b0e58e71..ba3ba272efb 100644
--- a/tests/codegen/repr-transparent-aggregates-1.rs
+++ b/tests/codegen/repr-transparent-aggregates-1.rs
@@ -11,6 +11,7 @@
 // ignore-s390x
 // ignore-windows
 // ignore-loongarch64
+// ignore-wasm32-bare
 // See repr-transparent.rs
 
 #![feature(transparent_unions)]
diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
index 045f01985a5..ec18fa9a328 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs
@@ -152,7 +152,7 @@ pub extern "C" fn f_scalar_stack_1(
 ) {
 }
 
-// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %0, i64 noundef %a, i128 %1, i128 %2, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
+// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %_0, i64 noundef %a, i128 %0, i128 %1, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
 #[no_mangle]
 pub extern "C" fn f_scalar_stack_2(
     a: u64,
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
index faac7566a0c..0bcfacec6d7 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
@@ -116,150 +116,150 @@ extern "platform-intrinsic" {
     fn simd_saturating_sub<T>(x: T, y: T) -> T;
 }
 
-// NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM)
+// NOTE(eddyb) `%{{x|0}}` is used because on some targets (e.g. WASM)
 // SIMD vectors are passed directly, resulting in `%x` being a vector,
 // while on others they're passed indirectly, resulting in `%x` being
-// a pointer to a vector, and `%1` a vector loaded from that pointer.
+// a pointer to a vector, and `%0` a vector loaded from that pointer.
 // This is controlled by the target spec option `simd_types_indirect`.
-// The same applies to `%{{y|2}}` as well.
+// The same applies to `%{{y|1}}` as well.
 
 // CHECK-LABEL: @sadd_i8x2
 #[no_mangle]
 pub unsafe fn sadd_i8x2(x: i8x2, y: i8x2) -> i8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x4
 #[no_mangle]
 pub unsafe fn sadd_i8x4(x: i8x4, y: i8x4) -> i8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x8
 #[no_mangle]
 pub unsafe fn sadd_i8x8(x: i8x8, y: i8x8) -> i8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x16
 #[no_mangle]
 pub unsafe fn sadd_i8x16(x: i8x16, y: i8x16) -> i8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x32
 #[no_mangle]
 pub unsafe fn sadd_i8x32(x: i8x32, y: i8x32) -> i8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x64
 #[no_mangle]
 pub unsafe fn sadd_i8x64(x: i8x64, y: i8x64) -> i8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x2
 #[no_mangle]
 pub unsafe fn sadd_i16x2(x: i16x2, y: i16x2) -> i16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x4
 #[no_mangle]
 pub unsafe fn sadd_i16x4(x: i16x4, y: i16x4) -> i16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x8
 #[no_mangle]
 pub unsafe fn sadd_i16x8(x: i16x8, y: i16x8) -> i16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x16
 #[no_mangle]
 pub unsafe fn sadd_i16x16(x: i16x16, y: i16x16) -> i16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x32
 #[no_mangle]
 pub unsafe fn sadd_i16x32(x: i16x32, y: i16x32) -> i16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x2
 #[no_mangle]
 pub unsafe fn sadd_i32x2(x: i32x2, y: i32x2) -> i32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x4
 #[no_mangle]
 pub unsafe fn sadd_i32x4(x: i32x4, y: i32x4) -> i32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x8
 #[no_mangle]
 pub unsafe fn sadd_i32x8(x: i32x8, y: i32x8) -> i32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x16
 #[no_mangle]
 pub unsafe fn sadd_i32x16(x: i32x16, y: i32x16) -> i32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x2
 #[no_mangle]
 pub unsafe fn sadd_i64x2(x: i64x2, y: i64x2) -> i64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x4
 #[no_mangle]
 pub unsafe fn sadd_i64x4(x: i64x4, y: i64x4) -> i64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x8
 #[no_mangle]
 pub unsafe fn sadd_i64x8(x: i64x8, y: i64x8) -> i64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i128x2
 #[no_mangle]
 pub unsafe fn sadd_i128x2(x: i128x2, y: i128x2) -> i128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i128x4
 #[no_mangle]
 pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
@@ -268,140 +268,140 @@ pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 {
 // CHECK-LABEL: @uadd_u8x2
 #[no_mangle]
 pub unsafe fn uadd_u8x2(x: u8x2, y: u8x2) -> u8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x4
 #[no_mangle]
 pub unsafe fn uadd_u8x4(x: u8x4, y: u8x4) -> u8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x8
 #[no_mangle]
 pub unsafe fn uadd_u8x8(x: u8x8, y: u8x8) -> u8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x16
 #[no_mangle]
 pub unsafe fn uadd_u8x16(x: u8x16, y: u8x16) -> u8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x32
 #[no_mangle]
 pub unsafe fn uadd_u8x32(x: u8x32, y: u8x32) -> u8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x64
 #[no_mangle]
 pub unsafe fn uadd_u8x64(x: u8x64, y: u8x64) -> u8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x2
 #[no_mangle]
 pub unsafe fn uadd_u16x2(x: u16x2, y: u16x2) -> u16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x4
 #[no_mangle]
 pub unsafe fn uadd_u16x4(x: u16x4, y: u16x4) -> u16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x8
 #[no_mangle]
 pub unsafe fn uadd_u16x8(x: u16x8, y: u16x8) -> u16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x16
 #[no_mangle]
 pub unsafe fn uadd_u16x16(x: u16x16, y: u16x16) -> u16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x32
 #[no_mangle]
 pub unsafe fn uadd_u16x32(x: u16x32, y: u16x32) -> u16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x2
 #[no_mangle]
 pub unsafe fn uadd_u32x2(x: u32x2, y: u32x2) -> u32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x4
 #[no_mangle]
 pub unsafe fn uadd_u32x4(x: u32x4, y: u32x4) -> u32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x8
 #[no_mangle]
 pub unsafe fn uadd_u32x8(x: u32x8, y: u32x8) -> u32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x16
 #[no_mangle]
 pub unsafe fn uadd_u32x16(x: u32x16, y: u32x16) -> u32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x2
 #[no_mangle]
 pub unsafe fn uadd_u64x2(x: u64x2, y: u64x2) -> u64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x4
 #[no_mangle]
 pub unsafe fn uadd_u64x4(x: u64x4, y: u64x4) -> u64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x8
 #[no_mangle]
 pub unsafe fn uadd_u64x8(x: u64x8, y: u64x8) -> u64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u128x2
 #[no_mangle]
 pub unsafe fn uadd_u128x2(x: u128x2, y: u128x2) -> u128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u128x4
 #[no_mangle]
 pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}})
     simd_saturating_add(x, y)
 }
 
@@ -412,140 +412,140 @@ pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 {
 // CHECK-LABEL: @ssub_i8x2
 #[no_mangle]
 pub unsafe fn ssub_i8x2(x: i8x2, y: i8x2) -> i8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x4
 #[no_mangle]
 pub unsafe fn ssub_i8x4(x: i8x4, y: i8x4) -> i8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x8
 #[no_mangle]
 pub unsafe fn ssub_i8x8(x: i8x8, y: i8x8) -> i8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x16
 #[no_mangle]
 pub unsafe fn ssub_i8x16(x: i8x16, y: i8x16) -> i8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x32
 #[no_mangle]
 pub unsafe fn ssub_i8x32(x: i8x32, y: i8x32) -> i8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x64
 #[no_mangle]
 pub unsafe fn ssub_i8x64(x: i8x64, y: i8x64) -> i8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x2
 #[no_mangle]
 pub unsafe fn ssub_i16x2(x: i16x2, y: i16x2) -> i16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x4
 #[no_mangle]
 pub unsafe fn ssub_i16x4(x: i16x4, y: i16x4) -> i16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x8
 #[no_mangle]
 pub unsafe fn ssub_i16x8(x: i16x8, y: i16x8) -> i16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x16
 #[no_mangle]
 pub unsafe fn ssub_i16x16(x: i16x16, y: i16x16) -> i16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x32
 #[no_mangle]
 pub unsafe fn ssub_i16x32(x: i16x32, y: i16x32) -> i16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x2
 #[no_mangle]
 pub unsafe fn ssub_i32x2(x: i32x2, y: i32x2) -> i32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x4
 #[no_mangle]
 pub unsafe fn ssub_i32x4(x: i32x4, y: i32x4) -> i32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x8
 #[no_mangle]
 pub unsafe fn ssub_i32x8(x: i32x8, y: i32x8) -> i32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x16
 #[no_mangle]
 pub unsafe fn ssub_i32x16(x: i32x16, y: i32x16) -> i32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x2
 #[no_mangle]
 pub unsafe fn ssub_i64x2(x: i64x2, y: i64x2) -> i64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x4
 #[no_mangle]
 pub unsafe fn ssub_i64x4(x: i64x4, y: i64x4) -> i64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x8
 #[no_mangle]
 pub unsafe fn ssub_i64x8(x: i64x8, y: i64x8) -> i64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i128x2
 #[no_mangle]
 pub unsafe fn ssub_i128x2(x: i128x2, y: i128x2) -> i128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i128x4
 #[no_mangle]
 pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
@@ -554,139 +554,139 @@ pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 {
 // CHECK-LABEL: @usub_u8x2
 #[no_mangle]
 pub unsafe fn usub_u8x2(x: u8x2, y: u8x2) -> u8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x4
 #[no_mangle]
 pub unsafe fn usub_u8x4(x: u8x4, y: u8x4) -> u8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x8
 #[no_mangle]
 pub unsafe fn usub_u8x8(x: u8x8, y: u8x8) -> u8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x16
 #[no_mangle]
 pub unsafe fn usub_u8x16(x: u8x16, y: u8x16) -> u8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x32
 #[no_mangle]
 pub unsafe fn usub_u8x32(x: u8x32, y: u8x32) -> u8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x64
 #[no_mangle]
 pub unsafe fn usub_u8x64(x: u8x64, y: u8x64) -> u8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x2
 #[no_mangle]
 pub unsafe fn usub_u16x2(x: u16x2, y: u16x2) -> u16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x4
 #[no_mangle]
 pub unsafe fn usub_u16x4(x: u16x4, y: u16x4) -> u16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x8
 #[no_mangle]
 pub unsafe fn usub_u16x8(x: u16x8, y: u16x8) -> u16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x16
 #[no_mangle]
 pub unsafe fn usub_u16x16(x: u16x16, y: u16x16) -> u16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x32
 #[no_mangle]
 pub unsafe fn usub_u16x32(x: u16x32, y: u16x32) -> u16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x2
 #[no_mangle]
 pub unsafe fn usub_u32x2(x: u32x2, y: u32x2) -> u32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x4
 #[no_mangle]
 pub unsafe fn usub_u32x4(x: u32x4, y: u32x4) -> u32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x8
 #[no_mangle]
 pub unsafe fn usub_u32x8(x: u32x8, y: u32x8) -> u32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x16
 #[no_mangle]
 pub unsafe fn usub_u32x16(x: u32x16, y: u32x16) -> u32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x2
 #[no_mangle]
 pub unsafe fn usub_u64x2(x: u64x2, y: u64x2) -> u64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x4
 #[no_mangle]
 pub unsafe fn usub_u64x4(x: u64x4, y: u64x4) -> u64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x8
 #[no_mangle]
 pub unsafe fn usub_u64x8(x: u64x8, y: u64x8) -> u64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u128x2
 #[no_mangle]
 pub unsafe fn usub_u128x2(x: u128x2, y: u128x2) -> u128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u128x4
 #[no_mangle]
 pub unsafe fn usub_u128x4(x: u128x4, y: u128x4) -> u128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}})
     simd_saturating_sub(x, y)
 }
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs
index 80583dec195..a5d2509d000 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs
@@ -35,13 +35,13 @@ pub unsafe fn extract_s(v: S<4>, i: u32) -> f32  {
 // CHECK-LABEL: @insert_m
 #[no_mangle]
 pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M  {
-    // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i
+    // CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i
     simd_insert(v, i, j)
 }
 
 // CHECK-LABEL: @insert_s
 #[no_mangle]
 pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4>  {
-    // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i
+    // CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i
     simd_insert(v, i, j)
 }
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
index fd488a14bd3..3a0e37de2f3 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
@@ -2,7 +2,6 @@
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
-
 #![allow(non_camel_case_types)]
 #![feature(repr_simd, platform_intrinsics)]
 #![feature(inline_const)]
@@ -44,7 +43,7 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> {
 #[no_mangle]
 pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> {
     // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
-    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
+    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
     unsafe { std::mem::transmute(x) }
 }
 
@@ -59,7 +58,7 @@ pub fn build_array_t(x: [f32; 4]) -> T {
 #[no_mangle]
 pub fn build_array_transmute_t(x: [f32; 4]) -> T {
     // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
-    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
+    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
     unsafe { std::mem::transmute(x) }
 }
 
@@ -78,6 +77,6 @@ pub fn build_array_u(x: [f32; 4]) -> U {
 #[no_mangle]
 pub fn build_array_transmute_u(x: [f32; 4]) -> U {
     // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
-    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
+    // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
     unsafe { std::mem::transmute(x) }
 }
diff --git a/tests/codegen/simd_arith_offset.rs b/tests/codegen/simd_arith_offset.rs
index f2333777391..74d7edc70d7 100644
--- a/tests/codegen/simd_arith_offset.rs
+++ b/tests/codegen/simd_arith_offset.rs
@@ -21,6 +21,6 @@ pub struct Simd<T, const LANES: usize>([T; LANES]);
 // CHECK-LABEL: smoke
 #[no_mangle]
 pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> {
-    // CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %1, <8 x i64> %2
+    // CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %0, <8 x i64> %1
     unsafe { simd_arith_offset(ptrs, offsets) }
 }
diff --git a/tests/codegen/slice-iter-len-eq-zero.rs b/tests/codegen/slice-iter-len-eq-zero.rs
index 894b0ec3de4..69f78cea564 100644
--- a/tests/codegen/slice-iter-len-eq-zero.rs
+++ b/tests/codegen/slice-iter-len-eq-zero.rs
@@ -9,8 +9,8 @@ type Demo = [u8; 3];
 #[no_mangle]
 pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool {
     // CHECK-NOT: sub
-    // CHECK: %2 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
-    // CHECK: ret i1 %2
+    // CHECK: %_0 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
+    // CHECK: ret i1 %_0
     y.len() == 0
 }
 
@@ -22,7 +22,7 @@ pub fn array_into_iter_len_eq_zero(y: std::array::IntoIter<Demo, 123>) -> bool {
 
     // CHECK-NOT: icmp
     // CHECK-NOT: sub
-    // CHECK: %1 = icmp eq {{i16|i32|i64}}
-    // CHECK: ret i1 %1
+    // CHECK: %_0 = icmp eq {{i16|i32|i64}}
+    // CHECK: ret i1 %_0
     y.len() == 0
 }
diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs
index a0894a505c7..293b0d664f6 100644
--- a/tests/codegen/transmute-scalar.rs
+++ b/tests/codegen/transmute-scalar.rs
@@ -11,24 +11,24 @@
 // that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`.
 
 // CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x)
-// CHECK: %0 = bitcast float %x to i32
-// CHECK-NEXT: ret i32 %0
+// CHECK: %_0 = bitcast float %x to i32
+// CHECK-NEXT: ret i32 %_0
 #[no_mangle]
 pub fn f32_to_bits(x: f32) -> u32 {
     unsafe { std::mem::transmute(x) }
 }
 
 // CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b)
-// CHECK: %0 = zext i1 %b to i8
-// CHECK-NEXT: ret i8 %0
+// CHECK: %_0 = zext i1 %b to i8
+// CHECK-NEXT: ret i8 %_0
 #[no_mangle]
 pub fn bool_to_byte(b: bool) -> u8 {
     unsafe { std::mem::transmute(b) }
 }
 
 // CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte)
-// CHECK: %0 = trunc i8 %byte to i1
-// CHECK-NEXT: ret i1 %0
+// CHECK: %_0 = trunc i8 %byte to i1
+// CHECK-NEXT: ret i1 %_0
 #[no_mangle]
 pub unsafe fn byte_to_bool(byte: u8) -> bool {
     std::mem::transmute(byte)
@@ -42,16 +42,16 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
 }
 
 // CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p)
-// CHECK: %0 = ptrtoint ptr %p to [[USIZE]]
-// CHECK-NEXT: ret [[USIZE]] %0
+// CHECK: %_0 = ptrtoint ptr %p to [[USIZE]]
+// CHECK-NEXT: ret [[USIZE]] %_0
 #[no_mangle]
 pub fn ptr_to_int(p: *mut u16) -> usize {
     unsafe { std::mem::transmute(p) }
 }
 
 // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i)
-// CHECK: %0 = inttoptr [[USIZE]] %i to ptr
-// CHECK-NEXT: ret ptr %0
+// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr
+// CHECK-NEXT: ret ptr %_0
 #[no_mangle]
 pub fn int_to_ptr(i: usize) -> *mut u16 {
     unsafe { std::mem::transmute(i) }
diff --git a/tests/codegen/uninit-consts.rs b/tests/codegen/uninit-consts.rs
index 54e9a9e9bb8..f169988e1f5 100644
--- a/tests/codegen/uninit-consts.rs
+++ b/tests/codegen/uninit-consts.rs
@@ -1,4 +1,5 @@
 // compile-flags: -C no-prepopulate-passes
+// min-llvm-version: 15.0 (for opaque pointers)
 
 // Check that we use undef (and not zero) for uninitialized bytes in constants.
 
@@ -8,7 +9,7 @@ use std::mem::MaybeUninit;
 
 pub struct PartiallyUninit {
     x: u32,
-    y: MaybeUninit<[u8; 10]>
+    y: MaybeUninit<[u8; 10]>,
 }
 
 // CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef
@@ -25,7 +26,7 @@ pub struct PartiallyUninit {
 #[no_mangle]
 pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> {
     const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit();
-    // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{[0-9]+}}, {{i8\*|ptr}} align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false)
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 1 %_0, ptr align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false)
     M
 }
 
@@ -33,7 +34,7 @@ pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> {
 #[no_mangle]
 pub const fn partially_uninit() -> PartiallyUninit {
     const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeef, y: MaybeUninit::uninit() };
-    // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false)
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false)
     X
 }
 
@@ -41,7 +42,7 @@ pub const fn partially_uninit() -> PartiallyUninit {
 #[no_mangle]
 pub const fn uninit_padding_huge() -> [(u32, u8); 4096] {
     const X: [(u32, u8); 4096] = [(123, 45); 4096];
-    // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false)
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false)
     X
 }
 
@@ -49,6 +50,6 @@ pub const fn uninit_padding_huge() -> [(u32, u8); 4096] {
 #[no_mangle]
 pub const fn fully_uninit_huge() -> MaybeUninit<[u32; 4096]> {
     const F: MaybeUninit<[u32; 4096]> = MaybeUninit::uninit();
-    // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false)
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false)
     F
 }
diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs
index 8481ca8ccfa..653c5837daf 100644
--- a/tests/codegen/union-abi.rs
+++ b/tests/codegen/union-abi.rs
@@ -73,4 +73,4 @@ pub union UnionBool { b:bool }
 // CHECK: define {{(dso_local )?}}noundef zeroext i1 @test_UnionBool(i8 %b)
 #[no_mangle]
 pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b }  }
-// CHECK: %0 = trunc i8 %b to i1
+// CHECK: %_0 = trunc i8 %b to i1
diff --git a/tests/codegen/var-names.rs b/tests/codegen/var-names.rs
index 53841df32e8..d4715efad73 100644
--- a/tests/codegen/var-names.rs
+++ b/tests/codegen/var-names.rs
@@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 {
     // CHECK: %c = add i32 %a, %b
     let d = c;
     let e = d * a;
-    // CHECK-NEXT: %0 = mul i32 %c, %a
+    // CHECK-NEXT: %e = mul i32 %c, %a
     e
-    // CHECK-NEXT: ret i32 %0
+    // CHECK-NEXT: ret i32 %e
 }
diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs
new file mode 100644
index 00000000000..2b2359f5b6c
--- /dev/null
+++ b/tests/codegen/wasm_exceptions.rs
@@ -0,0 +1,51 @@
+// only-wasm32-bare
+// compile-flags: -C panic=unwind
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+#![feature(rustc_attrs)]
+
+extern {
+    fn may_panic();
+
+    #[rustc_nounwind]
+    fn log_number(number: usize);
+}
+
+struct LogOnDrop;
+
+impl Drop for LogOnDrop {
+    fn drop(&mut self) {
+        unsafe { log_number(0); }
+    }
+}
+
+// CHECK-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0
+#[no_mangle]
+pub fn test_cleanup() {
+    let _log_on_drop = LogOnDrop;
+    unsafe { may_panic(); }
+
+    // CHECK-NOT: call
+    // CHECK: invoke void @may_panic()
+    // CHECK: %cleanuppad = cleanuppad within none []
+}
+
+// CHECK-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0
+#[no_mangle]
+pub fn test_rtry() {
+    unsafe {
+        core::intrinsics::r#try(|_| {
+            may_panic();
+        }, core::ptr::null_mut(), |data, exception| {
+            log_number(data as usize);
+            log_number(exception as usize);
+        });
+    }
+
+    // CHECK-NOT: call
+    // CHECK: invoke void @may_panic()
+    // CHECK: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller
+    // CHECK: {{.*}} = catchpad within {{.*}} [ptr null]
+    // CHECK: catchret
+}
diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
index 93bf2b64deb..61aa89e445f 100644
--- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
@@ -150,7 +150,7 @@ fn address_of_reborrow() -> () {
         StorageLive(_9);
         StorageLive(_10);
         _10 = &raw const (*_1);
-        _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize));
+        _9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_10);
         AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] });
         _8 = _9;
@@ -159,13 +159,13 @@ fn address_of_reborrow() -> () {
         StorageLive(_11);
         StorageLive(_12);
         _12 = &raw const (*_1);
-        _11 = move _12 as *const [i32] (Pointer(Unsize));
+        _11 = move _12 as *const [i32] (PointerCoercion(Unsize));
         StorageDead(_12);
         StorageDead(_11);
         StorageLive(_13);
         StorageLive(_14);
         _14 = &raw const (*_1);
-        _13 = move _14 as *const i32 (Pointer(ArrayToPointer));
+        _13 = move _14 as *const i32 (PointerCoercion(ArrayToPointer));
         StorageDead(_14);
         StorageDead(_13);
         StorageLive(_15);
@@ -179,14 +179,14 @@ fn address_of_reborrow() -> () {
         StorageLive(_17);
         StorageLive(_18);
         _18 = &raw const (*_1);
-        _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize));
+        _17 = move _18 as *const dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_18);
         FakeRead(ForLet(None), _17);
         AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] });
         StorageLive(_19);
         StorageLive(_20);
         _20 = &raw const (*_1);
-        _19 = move _20 as *const [i32] (Pointer(Unsize));
+        _19 = move _20 as *const [i32] (PointerCoercion(Unsize));
         StorageDead(_20);
         FakeRead(ForLet(None), _19);
         AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] });
@@ -204,7 +204,7 @@ fn address_of_reborrow() -> () {
         StorageLive(_25);
         StorageLive(_26);
         _26 = &raw const (*_3);
-        _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize));
+        _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_26);
         AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] });
         _24 = _25;
@@ -213,7 +213,7 @@ fn address_of_reborrow() -> () {
         StorageLive(_27);
         StorageLive(_28);
         _28 = &raw const (*_3);
-        _27 = move _28 as *const [i32] (Pointer(Unsize));
+        _27 = move _28 as *const [i32] (PointerCoercion(Unsize));
         StorageDead(_28);
         StorageDead(_27);
         StorageLive(_29);
@@ -227,14 +227,14 @@ fn address_of_reborrow() -> () {
         StorageLive(_31);
         StorageLive(_32);
         _32 = &raw const (*_3);
-        _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize));
+        _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_32);
         FakeRead(ForLet(None), _31);
         AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] });
         StorageLive(_33);
         StorageLive(_34);
         _34 = &raw const (*_3);
-        _33 = move _34 as *const [i32] (Pointer(Unsize));
+        _33 = move _34 as *const [i32] (PointerCoercion(Unsize));
         StorageDead(_34);
         FakeRead(ForLet(None), _33);
         AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] });
@@ -252,7 +252,7 @@ fn address_of_reborrow() -> () {
         StorageLive(_39);
         StorageLive(_40);
         _40 = &raw mut (*_3);
-        _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize));
+        _39 = move _40 as *mut dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_40);
         AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] });
         _38 = _39;
@@ -261,7 +261,7 @@ fn address_of_reborrow() -> () {
         StorageLive(_41);
         StorageLive(_42);
         _42 = &raw mut (*_3);
-        _41 = move _42 as *mut [i32] (Pointer(Unsize));
+        _41 = move _42 as *mut [i32] (PointerCoercion(Unsize));
         StorageDead(_42);
         StorageDead(_41);
         StorageLive(_43);
@@ -275,14 +275,14 @@ fn address_of_reborrow() -> () {
         StorageLive(_45);
         StorageLive(_46);
         _46 = &raw mut (*_3);
-        _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize));
+        _45 = move _46 as *mut dyn std::marker::Send (PointerCoercion(Unsize));
         StorageDead(_46);
         FakeRead(ForLet(None), _45);
         AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] });
         StorageLive(_47);
         StorageLive(_48);
         _48 = &raw mut (*_3);
-        _47 = move _48 as *mut [i32] (Pointer(Unsize));
+        _47 = move _48 as *mut [i32] (PointerCoercion(Unsize));
         StorageDead(_48);
         FakeRead(ForLet(None), _47);
         AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] });
diff --git a/tests/mir-opt/building/issue_110508.rs b/tests/mir-opt/building/issue_110508.rs
new file mode 100644
index 00000000000..bcbb1c29830
--- /dev/null
+++ b/tests/mir-opt/building/issue_110508.rs
@@ -0,0 +1,13 @@
+// EMIT_MIR issue_110508.{impl#0}-BAR.built.after.mir
+// EMIT_MIR issue_110508.{impl#0}-SELF_BAR.built.after.mir
+
+enum Foo {
+    Bar(()),
+}
+
+impl Foo {
+    const BAR: Foo = Foo::Bar(());
+    const SELF_BAR: Foo = Self::Bar(());
+}
+
+fn main() {}
diff --git a/tests/mir-opt/building/issue_110508.{impl#0}-BAR.built.after.mir b/tests/mir-opt/building/issue_110508.{impl#0}-BAR.built.after.mir
new file mode 100644
index 00000000000..5fc6d911af3
--- /dev/null
+++ b/tests/mir-opt/building/issue_110508.{impl#0}-BAR.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR` after built
+
+const <impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR: Foo = {
+    let mut _0: Foo;
+    let mut _1: ();
+
+    bb0: {
+        StorageLive(_1);
+        _1 = ();
+        _0 = Foo::Bar(move _1);
+        StorageDead(_1);
+        return;
+    }
+}
diff --git a/tests/mir-opt/building/issue_110508.{impl#0}-SELF_BAR.built.after.mir b/tests/mir-opt/building/issue_110508.{impl#0}-SELF_BAR.built.after.mir
new file mode 100644
index 00000000000..1a892559971
--- /dev/null
+++ b/tests/mir-opt/building/issue_110508.{impl#0}-SELF_BAR.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR` after built
+
+const <impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR: Foo = {
+    let mut _0: Foo;
+    let mut _1: ();
+
+    bb0: {
+        StorageLive(_1);
+        _1 = ();
+        _0 = Foo::Bar(move _1);
+        StorageDead(_1);
+        return;
+    }
+}
diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
index b3db1d76ca7..fed5e68c3c9 100644
--- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
+++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
@@ -39,7 +39,7 @@ fn main() -> () {
         StorageLive(_3);
         StorageLive(_4);
         _4 = _1;
-        _3 = move _4 as *const Test (Pointer(MutToConstPointer));
+        _3 = move _4 as *const Test (PointerCoercion(MutToConstPointer));
         StorageDead(_4);
         _2 = Test::x(move _3) -> [return: bb2, unwind: bb4];
     }
@@ -64,7 +64,7 @@ fn main() -> () {
         StorageLive(_11);
         StorageLive(_12);
         _12 = (*(*(*(*_5))));
-        _11 = move _12 as *const Test (Pointer(MutToConstPointer));
+        _11 = move _12 as *const Test (PointerCoercion(MutToConstPointer));
         StorageDead(_12);
         _10 = Test::x(move _11) -> [return: bb3, unwind: bb4];
     }
diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
index 1d7adfde4ed..683f63065f7 100644
--- a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
+++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
@@ -187,7 +187,7 @@ static XXX: &Foo = {
         StorageDead(_7);
         _5 = &_6;
         _4 = &(*_5);
-        _3 = move _4 as &[(u32, u32)] (Pointer(Unsize));
+        _3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize));
         StorageDead(_4);
         _2 = Foo { tup: const "hi", data: move _3 };
         StorageDead(_3);
diff --git a/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
index aca7b12c4c6..f0c35fe9782 100644
--- a/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
+++ b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
@@ -8,7 +8,7 @@ fn roundtrip(_1: *const u8) -> *const u8 {
     bb0: {
         StorageLive(_2);
         _2 = _1 as *mut u8 (PtrToPtr);
-        _0 = move _2 as *const u8 (Pointer(MutToConstPointer));
+        _0 = move _2 as *const u8 (PointerCoercion(MutToConstPointer));
         StorageDead(_2);
         return;
     }
diff --git a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index 0eee91469e6..14d2d7fc85c 100644
--- a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -22,7 +22,7 @@
 -         _2 = &_3;
 +         _6 = const _;
 +         _2 = &(*_6);
-          _1 = move _2 as &[&i32] (Pointer(Unsize));
+          _1 = move _2 as &[&i32] (PointerCoercion(Unsize));
 -         StorageDead(_4);
           StorageDead(_2);
           _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2];
diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 0b117f4aaa5..ffdd195eca3 100644
--- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -24,7 +24,7 @@
 -         _2 = &_3;
 +         _6 = const _;
 +         _2 = &(*_6);
-          _1 = move _2 as &[&i32] (Pointer(Unsize));
+          _1 = move _2 as &[&i32] (PointerCoercion(Unsize));
 -         StorageDead(_4);
           StorageDead(_2);
           _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2];
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff
index 6d5e34f23e8..30402df47c2 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-abort.diff
@@ -28,7 +28,7 @@
           _9 = const _;
           _3 = &(*_9);
           _2 = &raw const (*_3);
-          _1 = move _2 as *const [i32] (Pointer(Unsize));
+          _1 = move _2 as *const [i32] (PointerCoercion(Unsize));
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
index 2c0e4844ecc..16d62daed29 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.panic-unwind.diff
@@ -28,7 +28,7 @@
           _9 = const _;
           _3 = &(*_9);
           _2 = &raw const (*_3);
-          _1 = move _2 as *const [i32] (Pointer(Unsize));
+          _1 = move _2 as *const [i32] (PointerCoercion(Unsize));
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff
index 6d5e34f23e8..30402df47c2 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-abort.diff
@@ -28,7 +28,7 @@
           _9 = const _;
           _3 = &(*_9);
           _2 = &raw const (*_3);
-          _1 = move _2 as *const [i32] (Pointer(Unsize));
+          _1 = move _2 as *const [i32] (PointerCoercion(Unsize));
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
index 2c0e4844ecc..16d62daed29 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.panic-unwind.diff
@@ -28,7 +28,7 @@
           _9 = const _;
           _3 = &(*_9);
           _2 = &raw const (*_3);
-          _1 = move _2 as *const [i32] (Pointer(Unsize));
+          _1 = move _2 as *const [i32] (PointerCoercion(Unsize));
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
index 533a92f78a5..e7aa015d078 100644
--- a/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -13,7 +13,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          _3 = main as fn() (Pointer(ReifyFnPointer));
+          _3 = main as fn() (PointerCoercion(ReifyFnPointer));
           _2 = move _3 as usize (PointerExposeAddress);
           StorageDead(_3);
           _1 = move _2 as *const fn() (PointerFromExposedAddress);
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff
index 2f64a185106..3c2b8e111cb 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-abort.diff
@@ -21,7 +21,7 @@
           _9 = const _;
           _4 = _9;
           _3 = _4;
-          _2 = move _3 as &[u32] (Pointer(Unsize));
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
index c0f290a9ab4..303096030b4 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.panic-unwind.diff
@@ -21,7 +21,7 @@
           _9 = const _;
           _4 = _9;
           _3 = _4;
-          _2 = move _3 as &[u32] (Pointer(Unsize));
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff
index 2f64a185106..3c2b8e111cb 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-abort.diff
@@ -21,7 +21,7 @@
           _9 = const _;
           _4 = _9;
           _3 = _4;
-          _2 = move _3 as &[u32] (Pointer(Unsize));
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
index c0f290a9ab4..303096030b4 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.panic-unwind.diff
@@ -21,7 +21,7 @@
           _9 = const _;
           _4 = _9;
           _3 = _4;
-          _2 = move _3 as &[u32] (Pointer(Unsize));
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
index a16d79d0e64..a802d0256d4 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
@@ -47,7 +47,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &_2;
-          _6 = move _7 as &[i32] (Pointer(Unsize));
+          _6 = move _7 as &[i32] (PointerCoercion(Unsize));
           StorageDead(_7);
           _5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind unreachable];
       }
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
index c2d892be35d..35f852098c3 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
@@ -47,7 +47,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &_2;
-          _6 = move _7 as &[i32] (Pointer(Unsize));
+          _6 = move _7 as &[i32] (PointerCoercion(Unsize));
           StorageDead(_7);
           _5 = core::slice::<impl [i32]>::len(move _6) -> [return: bb1, unwind continue];
       }
diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff
index 1f5e2428095..57b0849e111 100644
--- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff
@@ -31,7 +31,7 @@
           _4 = &(*_2);
 -         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind unreachable];
 +         StorageLive(_5);
-+         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize));
++         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
 +         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(_5) -> [return: bb2, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
index 941ba24605c..706c1d48195 100644
--- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff
@@ -31,7 +31,7 @@
           _4 = &(*_2);
 -         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind continue];
 +         StorageLive(_5);
-+         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize));
++         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
 +         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(_5) -> [return: bb2, unwind continue];
       }
   
diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff
index 1e4c6fcca7a..9a6d3596fb9 100644
--- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff
@@ -14,7 +14,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize));
+          _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind unreachable];
 +         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(_2) -> [return: bb1, unwind unreachable];
diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
index 5e30da400d2..1a08df2b09b 100644
--- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff
@@ -14,7 +14,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize));
+          _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind continue];
 +         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(_2) -> [return: bb1, unwind continue];
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
index f3a6923415a..dfc00026ad0 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff
@@ -164,7 +164,7 @@
 +         StorageDead(_17);
 +         StorageLive(_19);
 +         StorageLive(_20);
-+         _19 = _16 as *const u8 (Pointer(MutToConstPointer));
++         _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer));
 +         _15 = NonNull::<u8> { pointer: _19 };
 +         StorageDead(_20);
 +         StorageDead(_19);
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
index 0b643b3c7a9..f582adda88f 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
@@ -181,7 +181,7 @@
 +         StorageDead(_17);
 +         StorageLive(_19);
 +         StorageLive(_20);
-+         _19 = _16 as *const u8 (Pointer(MutToConstPointer));
++         _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer));
 +         _15 = NonNull::<u8> { pointer: _19 };
 +         StorageDead(_20);
 +         StorageDead(_19);
diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir
index 62c0805548b..503f153089c 100644
--- a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir
+++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-abort.mir
@@ -13,7 +13,7 @@ fn test2(_1: &dyn X) -> bool {
         StorageLive(_2);
         StorageLive(_3);
         _3 = &(*_1);
-        _2 = move _3 as &dyn X (Pointer(Unsize));
+        _2 = move _3 as &dyn X (PointerCoercion(Unsize));
         StorageDead(_3);
         _0 = <dyn X as X>::y(_2) -> [return: bb1, unwind unreachable];
     }
diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
index 5d4979680a4..37bb53e79c6 100644
--- a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.panic-unwind.mir
@@ -13,7 +13,7 @@ fn test2(_1: &dyn X) -> bool {
         StorageLive(_2);
         StorageLive(_3);
         _3 = &(*_1);
-        _2 = move _3 as &dyn X (Pointer(Unsize));
+        _2 = move _3 as &dyn X (PointerCoercion(Unsize));
         StorageDead(_3);
         _0 = <dyn X as X>::y(_2) -> [return: bb1, unwind continue];
     }
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
index f2a925273db..1cc44ce06cf 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
@@ -32,7 +32,7 @@
           StorageLive(_5);
           _5 = [_1, _1, _1];
           _4 = &_5;
-          _2 = _4 as &[T] (Pointer(Unsize));
+          _2 = _4 as &[T] (PointerCoercion(Unsize));
           _9 = Len((*_2));
           _10 = const 3_usize;
 -         _11 = Eq(move _9, const 3_usize);
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
index 25df839c2db..b708f667438 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
@@ -32,7 +32,7 @@
           StorageLive(_5);
           _5 = [_1, _1, _1];
           _4 = &_5;
-          _2 = _4 as &[T] (Pointer(Unsize));
+          _2 = _4 as &[T] (PointerCoercion(Unsize));
           _9 = Len((*_2));
           _10 = const 3_usize;
 -         _11 = Eq(move _9, const 3_usize);
diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
index de6c2366dbb..6174d5259d0 100644
--- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff
@@ -22,7 +22,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
-          _6 = move _7 as &[u8] (Pointer(Unsize));
+          _6 = move _7 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_7);
 -         _5 = Len((*_6));
 +         _5 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
index 1cba0f27afa..60c0772d8ec 100644
--- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff
@@ -22,7 +22,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
-          _6 = move _7 as &[u8] (Pointer(Unsize));
+          _6 = move _7 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_7);
 -         _5 = Len((*_6));
 +         _5 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
index 76175afc2f8..e2de1845296 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff
@@ -25,7 +25,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
-          _6 = move _7 as &[u8] (Pointer(Unsize));
+          _6 = move _7 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_7);
 -         _5 = Len((*_6));
 +         _5 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
index 6c450067cc4..eb81e0eea2c 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff
@@ -25,7 +25,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
-          _6 = move _7 as &[u8] (Pointer(Unsize));
+          _6 = move _7 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_7);
 -         _5 = Len((*_6));
 +         _5 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff
index a20d5288c40..1bdc62183c3 100644
--- a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = Len((*_2));
 +         _0 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff
index a20d5288c40..1bdc62183c3 100644
--- a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = Len((*_2));
 +         _0 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff
index c3842bf4edc..9862b2fad8e 100644
--- a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &_1;
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = Len((*_2));
 +         _0 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff
index c3842bf4edc..9862b2fad8e 100644
--- a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = &_1;
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
 -         _0 = Len((*_2));
 +         _0 = const N;
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
index c407482d17b..f9f73bf991d 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
@@ -25,7 +25,7 @@
           StorageLive(_4);
           _4 = &_1;
           _3 = &(*_4);
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageDead(_4);
           StorageLive(_5);
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
index c407482d17b..f9f73bf991d 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
@@ -25,7 +25,7 @@
           StorageLive(_4);
           _4 = &_1;
           _3 = &(*_4);
-          _2 = move _3 as &[u8] (Pointer(Unsize));
+          _2 = move _3 as &[u8] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageDead(_4);
           StorageLive(_5);
diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff
index f50f7baa6e3..ecba06a2e4d 100644
--- a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff
@@ -22,7 +22,7 @@
           StorageLive(_4);
           _4 = &mut _1;
           _3 = &mut (*_4);
-          _2 = move _3 as &mut [u8] (Pointer(Unsize));
+          _2 = move _3 as &mut [u8] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageDead(_4);
           StorageLive(_5);
diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff
index f50f7baa6e3..ecba06a2e4d 100644
--- a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff
@@ -22,7 +22,7 @@
           StorageLive(_4);
           _4 = &mut _1;
           _3 = &mut (*_4);
-          _2 = move _3 as &mut [u8] (Pointer(Unsize));
+          _2 = move _3 as &mut [u8] (PointerCoercion(Unsize));
           StorageDead(_3);
           StorageDead(_4);
           StorageLive(_5);
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
index a337ca89992..e07e2bb7bfe 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
@@ -78,7 +78,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageLive(_12);
         StorageLive(_11);
         StorageLive(_10);
-        _10 = _9 as *const () (Pointer(MutToConstPointer));
+        _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
         _11 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 };
         StorageDead(_10);
         _12 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
index a337ca89992..e07e2bb7bfe 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
@@ -78,7 +78,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageLive(_12);
         StorageLive(_11);
         StorageLive(_10);
-        _10 = _9 as *const () (Pointer(MutToConstPointer));
+        _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
         _11 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 };
         StorageDead(_10);
         _12 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index 1e401c60bf3..d1ab16697a6 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -131,7 +131,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_24);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_24);
         StorageDead(_10);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 8294a5cb6dc..03751f7fdf7 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -131,7 +131,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_24);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_24);
         StorageDead(_10);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index c1c7861b9c9..db971e10f32 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -121,7 +121,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_22);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_22);
         StorageDead(_10);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index ff40e450968..74597799168 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -121,7 +121,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_22);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_22);
         StorageDead(_10);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 851d3311365..e546140e0c1 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -133,7 +133,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_24);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_24);
         StorageDead(_10);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index b40d9209d25..551cac46bdf 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -133,7 +133,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);
         StorageLive(_10);
         StorageLive(_24);
-        _10 = _9 as *const T (Pointer(MutToConstPointer));
+        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
         _11 = NonNull::<T> { pointer: _10 };
         StorageDead(_24);
         StorageDead(_10);
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
index 3c48e798ef7..70efdbf4b34 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-abort.mir
@@ -69,7 +69,7 @@ fn array_casts() -> () {
         StorageLive(_4);
         _4 = &mut _1;
         _3 = &raw mut (*_4);
-        _2 = move _3 as *mut usize (Pointer(ArrayToPointer));
+        _2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
         StorageDead(_3);
         StorageDead(_4);
         StorageLive(_5);
@@ -92,7 +92,7 @@ fn array_casts() -> () {
         StorageLive(_11);
         _11 = &_8;
         _10 = &raw const (*_11);
-        _9 = move _10 as *const usize (Pointer(ArrayToPointer));
+        _9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
         StorageDead(_10);
         StorageDead(_11);
         StorageLive(_12);
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 93f14af29b4..cfa9628d498 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -69,7 +69,7 @@ fn array_casts() -> () {
         StorageLive(_4);
         _4 = &mut _1;
         _3 = &raw mut (*_4);
-        _2 = move _3 as *mut usize (Pointer(ArrayToPointer));
+        _2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer));
         StorageDead(_3);
         StorageDead(_4);
         StorageLive(_5);
@@ -92,7 +92,7 @@ fn array_casts() -> () {
         StorageLive(_11);
         _11 = &_8;
         _10 = &raw const (*_11);
-        _9 = move _10 as *const usize (Pointer(ArrayToPointer));
+        _9 = move _10 as *const usize (PointerCoercion(ArrayToPointer));
         StorageDead(_10);
         StorageDead(_11);
         StorageLive(_12);
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
index 606a8ec44ec..fb37bec109a 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
@@ -105,7 +105,7 @@ fn main() -> () {
         StorageLive(_14);
         _14 = [closure@main::{closure#0}];
         Retag(_14);
-        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (Pointer(ClosureFnPointer(Normal)));
+        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
         StorageDead(_14);
         StorageLive(_15);
         StorageLive(_16);
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 45034946328..508f964099a 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -105,7 +105,7 @@ fn main() -> () {
         StorageLive(_14);
         _14 = [closure@main::{closure#0}];
         Retag(_14);
-        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (Pointer(ClosureFnPointer(Normal)));
+        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
         StorageDead(_14);
         StorageLive(_15);
         StorageLive(_16);
diff --git a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff
index 7546b3878d6..7cc5e335cb0 100644
--- a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff
@@ -21,7 +21,7 @@
 -         StorageLive(_4);
 -         _4 = &_1;
 -         _3 = &(*_4);
--         _2 = move _3 as &[u8] (Pointer(Unsize));
+-         _2 = move _3 as &[u8] (PointerCoercion(Unsize));
 -         StorageDead(_3);
 -         StorageDead(_4);
 -         StorageDead(_2);
diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
index 84247c0e8d5..bb14b909a95 100644
--- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff
@@ -62,7 +62,7 @@
       }
   
       bb1: {
-          _3 = move _4 as std::boxed::Box<dyn std::fmt::Display> (Pointer(Unsize));
+          _3 = move _4 as std::boxed::Box<dyn std::fmt::Display> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Result::<Box<dyn std::fmt::Display>, <T as Err>::Err>::Ok(move _3);
           StorageDead(_3);
@@ -95,7 +95,7 @@
           _26 = const _;
           _14 = &(*_26);
           _13 = &(*_14);
-          _12 = move _13 as &[&str] (Pointer(Unsize));
+          _12 = move _13 as &[&str] (PointerCoercion(Unsize));
           StorageDead(_13);
           StorageLive(_16);
           StorageLive(_17);
@@ -126,7 +126,7 @@
           StorageDead(_20);
           _18 = &_19;
           _17 = &(*_18);
-          _16 = move _17 as &[core::fmt::rt::Argument<'_>] (Pointer(Unsize));
+          _16 = move _17 as &[core::fmt::rt::Argument<'_>] (PointerCoercion(Unsize));
           StorageDead(_17);
           _11 = Arguments::<'_>::new_v1(move _12, move _16) -> [return: bb5, unwind unreachable];
       }
diff --git a/tests/run-coverage/uses_crate.coverage b/tests/run-coverage/uses_crate.coverage
index a3b78e21405..ccdcf350334 100644
--- a/tests/run-coverage/uses_crate.coverage
+++ b/tests/run-coverage/uses_crate.coverage
@@ -148,8 +148,8 @@ $DIR/auxiliary/used_crate.rs:
   100|       |// `unused_generic_function<T>()`, below.
 
 $DIR/uses_crate.rs:
-    1|       |// FIXME #110395
-    2|       |// ignore-linux
+    1|       |// This test was failing on Linux for a while due to #110393 somehow making
+    2|       |// the unused functions not instrumented, but it seems to be fine now.
     3|       |
     4|       |// Validates coverage now works with optimizations
     5|       |// compile-flags: -C opt-level=3
diff --git a/tests/run-coverage/uses_crate.rs b/tests/run-coverage/uses_crate.rs
index ab466970f8e..ab203ad781d 100644
--- a/tests/run-coverage/uses_crate.rs
+++ b/tests/run-coverage/uses_crate.rs
@@ -1,5 +1,5 @@
-// FIXME #110395
-// ignore-linux
+// This test was failing on Linux for a while due to #110393 somehow making
+// the unused functions not instrumented, but it seems to be fine now.
 
 // Validates coverage now works with optimizations
 // compile-flags: -C opt-level=3
diff --git a/tests/run-coverage/uses_inline_crate.coverage b/tests/run-coverage/uses_inline_crate.coverage
index f878d8107c5..64308c796d6 100644
--- a/tests/run-coverage/uses_inline_crate.coverage
+++ b/tests/run-coverage/uses_inline_crate.coverage
@@ -139,8 +139,8 @@ $DIR/auxiliary/used_inline_crate.rs:
    90|      2|}
 
 $DIR/uses_inline_crate.rs:
-    1|       |// FIXME #110395
-    2|       |// ignore-linux
+    1|       |// This test was failing on Linux for a while due to #110393 somehow making
+    2|       |// the unused functions not instrumented, but it seems to be fine now.
     3|       |
     4|       |// Validates coverage now works with optimizations
     5|       |// compile-flags: -C opt-level=3
diff --git a/tests/run-coverage/uses_inline_crate.rs b/tests/run-coverage/uses_inline_crate.rs
index 4bd66d2f89c..d7b4c3c057f 100644
--- a/tests/run-coverage/uses_inline_crate.rs
+++ b/tests/run-coverage/uses_inline_crate.rs
@@ -1,5 +1,5 @@
-// FIXME #110395
-// ignore-linux
+// This test was failing on Linux for a while due to #110393 somehow making
+// the unused functions not instrumented, but it seems to be fine now.
 
 // Validates coverage now works with optimizations
 // compile-flags: -C opt-level=3
diff --git a/tests/run-make/wasm-exceptions-nostd/Makefile b/tests/run-make/wasm-exceptions-nostd/Makefile
new file mode 100644
index 00000000000..34755ec14b7
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/Makefile
@@ -0,0 +1,12 @@
+include ../tools.mk
+
+# only-wasm32-bare
+
+# Add a few command line args to make exceptions work
+RUSTC := $(RUSTC) -C llvm-args=-wasm-enable-eh
+RUSTC := $(RUSTC) -C target-feature=+exception-handling
+RUSTC := $(RUSTC) -C panic=unwind
+
+all:
+	$(RUSTC) src/lib.rs --target wasm32-unknown-unknown
+	$(NODE) verify.mjs $(TMPDIR)/lib.wasm
diff --git a/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs b/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs
new file mode 100644
index 00000000000..572d253309c
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/src/arena_alloc.rs
@@ -0,0 +1,67 @@
+use core::alloc::{GlobalAlloc, Layout};
+use core::cell::UnsafeCell;
+
+#[global_allocator]
+static ALLOCATOR: ArenaAllocator = ArenaAllocator::new();
+
+/// Very simple allocator which never deallocates memory
+///
+/// Based on the example from
+/// https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html
+pub struct ArenaAllocator {
+    arena: UnsafeCell<Arena>,
+}
+
+impl ArenaAllocator {
+    pub const fn new() -> Self {
+        Self {
+            arena: UnsafeCell::new(Arena::new()),
+        }
+    }
+}
+
+/// Safe because we are singlethreaded
+unsafe impl Sync for ArenaAllocator {}
+
+unsafe impl GlobalAlloc for ArenaAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        let arena = &mut *self.arena.get();
+        arena.alloc(layout)
+    }
+
+    unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+}
+
+const ARENA_SIZE: usize = 64 * 1024; // more than enough
+
+#[repr(C, align(4096))]
+struct Arena {
+    buf: [u8; ARENA_SIZE], // aligned at 4096
+    allocated: usize,
+}
+
+impl Arena {
+    pub const fn new() -> Self {
+        Self {
+            buf: [0x55; ARENA_SIZE],
+            allocated: 0,
+        }
+    }
+
+    pub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8 {
+        if layout.align() > 4096 || layout.size() > ARENA_SIZE {
+            return core::ptr::null_mut();
+        }
+
+        let align_minus_one = layout.align() - 1;
+        let start = (self.allocated + align_minus_one) & !align_minus_one; // round up
+        let new_cursor = start + layout.size();
+
+        if new_cursor >= ARENA_SIZE {
+            return core::ptr::null_mut();
+        }
+
+        self.allocated = new_cursor;
+        self.buf.as_mut_ptr().add(start)
+    }
+}
diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
new file mode 100644
index 00000000000..7049d2fd9e0
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
@@ -0,0 +1,60 @@
+#![no_std]
+#![crate_type = "cdylib"]
+
+// Allow a few unstable features because we create a panic
+// runtime for native wasm exceptions from scratch
+
+#![feature(core_intrinsics)]
+#![feature(lang_items)]
+#![feature(link_llvm_intrinsics)]
+#![feature(panic_info_message)]
+
+extern crate alloc;
+
+/// This module allows us to use `Box`, `String`, ... even in no-std
+mod arena_alloc;
+
+/// This module allows logging text, even in no-std
+mod logging;
+
+/// This module allows exceptions, even in no-std
+#[cfg(target_arch = "wasm32")]
+mod panicking;
+
+use alloc::boxed::Box;
+use alloc::string::String;
+
+struct LogOnDrop;
+
+impl Drop for LogOnDrop {
+    fn drop(&mut self) {
+        logging::log_str("Dropped");
+    }
+}
+
+#[allow(unreachable_code)]
+#[allow(unconditional_panic)]
+#[no_mangle]
+pub extern "C" fn start() -> usize {
+    let data = 0x1234usize as *mut u8; // Something to recognize
+
+    unsafe {
+        core::intrinsics::r#try(|data: *mut u8| {
+            let _log_on_drop = LogOnDrop;
+
+            logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data));
+            let x = [12];
+            let _ = x[4]; // should panic
+
+            logging::log_str("This line should not be visible! :(");
+        }, data, |data, exception| {
+            let exception = *Box::from_raw(exception as *mut String);
+            logging::log_str("Caught something!");
+            logging::log_str(&alloc::format!("  data     : {:?}", data));
+            logging::log_str(&alloc::format!("  exception: {:?}", exception));
+        });
+    }
+
+    logging::log_str("This program terminates correctly.");
+    0
+}
diff --git a/tests/run-make/wasm-exceptions-nostd/src/logging.rs b/tests/run-make/wasm-exceptions-nostd/src/logging.rs
new file mode 100644
index 00000000000..569d03ec82f
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/src/logging.rs
@@ -0,0 +1,9 @@
+extern "C" {
+    fn __log_utf8(ptr: *const u8, size: usize);
+}
+
+pub fn log_str(text: &str) {
+    unsafe {
+        __log_utf8(text.as_ptr(), text.len());
+    }
+}
diff --git a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs
new file mode 100644
index 00000000000..4a8923fd43d
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs
@@ -0,0 +1,29 @@
+#[lang = "eh_personality"]
+fn eh_personality() {}
+
+mod internal {
+    extern "C" {
+        #[link_name = "llvm.wasm.throw"]
+        pub fn wasm_throw(tag: i32, ptr: *mut u8) -> !;
+    }
+}
+
+unsafe fn wasm_throw(ptr: *mut u8) -> ! {
+    internal::wasm_throw(0, ptr);
+}
+
+#[panic_handler]
+fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
+    use alloc::boxed::Box;
+    use alloc::string::ToString;
+
+    let msg = info
+        .message()
+        .map(|msg| msg.to_string())
+        .unwrap_or("(no message)".to_string());
+    let exception = Box::new(msg.to_string());
+    unsafe {
+        let exception_raw = Box::into_raw(exception);
+        wasm_throw(exception_raw as *mut u8);
+    }
+}
diff --git a/tests/run-make/wasm-exceptions-nostd/verify.mjs b/tests/run-make/wasm-exceptions-nostd/verify.mjs
new file mode 100644
index 00000000000..e6c44d89d33
--- /dev/null
+++ b/tests/run-make/wasm-exceptions-nostd/verify.mjs
@@ -0,0 +1,75 @@
+import fs from 'fs';
+
+const dec = new TextDecoder("utf-8");
+
+if (process.argv.length != 3) {
+    console.log("Usage: node verify.mjs <wasm-file>");
+    process.exit(0);
+}
+
+const wasmfile = process.argv[2];
+if (!fs.existsSync(wasmfile)) {
+    console.log("Error: File not found:", wasmfile);
+    process.exit(1);
+}
+
+const wasmBuffer = fs.readFileSync(wasmfile);
+
+async function main() {
+
+    let memory = new ArrayBuffer(0) // will be changed after instantiate
+
+    const captured_output = [];
+
+    const imports = {
+        env: {
+            __log_utf8: (ptr, size) => {
+                const str = dec.decode(new DataView(memory, ptr, size));
+                captured_output.push(str);
+                console.log(str);
+            }
+        }
+    };
+
+    const wasmModule = await WebAssembly.instantiate(wasmBuffer, imports);
+    memory = wasmModule.instance.exports.memory.buffer;
+
+    const start = wasmModule.instance.exports.start;
+    const return_code = start();
+
+    console.log("Return-Code:", return_code);
+
+    if (return_code !== 0) {
+        console.error("Expected return code 0");
+        process.exit(return_code);
+    }
+
+    const expected_output = [
+        '`r#try` called with ptr 0x1234',
+        'Dropped',
+        'Caught something!',
+        '  data     : 0x1234',
+        '  exception: "index out of bounds: the len is 1 but the index is 4"',
+        'This program terminates correctly.',
+    ];
+    
+    assert_equal(captured_output, expected_output);
+}
+
+function assert_equal(captured_output, expected_output) {
+    if (captured_output.length != expected_output.length) {
+        console.error("Unexpected number of output lines. Got", captured_output.length, "but expected", expected_output.length);
+        process.exit(1); // exit with error
+    }
+
+    for (let idx = 0; idx < expected_output.length; ++idx) {
+        if (captured_output[idx] !== expected_output[idx]) {
+            console.error("Unexpected output");
+            console.error("[got]     ", captured_output[idx]);
+            console.error("[expected]", expected_output[idx]);
+            process.exit(2); // exit with error
+        }
+    }
+}
+
+await main();
\ No newline at end of file
diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml
index 520b2c59b0f..2cb88817884 100644
--- a/tests/rustdoc-gui/sidebar-source-code.goml
+++ b/tests/rustdoc-gui/sidebar-source-code.goml
@@ -25,24 +25,24 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "color": "rgb(197, 197, 197)",
-        "background_color": "rgb(20, 25, 31)",
+        "color": "#c5c5c5",
+        "background_color": "#14191f",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "color": "rgb(221, 221, 221)",
-        "background_color": "rgb(80, 80, 80)",
+        "color": "#ddd",
+        "background_color": "#505050",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "color": "rgb(0, 0, 0)",
-        "background_color": "rgb(245, 245, 245)",
+        "color": "black",
+        "background_color": "#F5F5F5",
     }
 )
 
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 9ef208a14b2..f55d7d599f1 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -7,6 +7,7 @@
 // edition: 2021
 
 #![feature(rustc_private)]
+#![feature(assert_matches)]
 
 extern crate rustc_driver;
 extern crate rustc_hir;
@@ -21,6 +22,7 @@ use rustc_interface::{interface, Queries};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::EarlyErrorHandler;
 use rustc_smir::{rustc_internal, stable_mir};
+use std::assert_matches::assert_matches;
 use std::io::Write;
 
 const CRATE_NAME: &str = "input";
@@ -65,6 +67,36 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
         other => panic!("{other:?}"),
     }
 
+    let types = get_item(tcx, &items, (DefKind::Fn, "types")).unwrap();
+    let body = types.body();
+    assert_eq!(body.locals.len(), 6);
+    assert_matches!(
+        body.locals[0].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Bool)
+    );
+    assert_matches!(
+        body.locals[1].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Bool)
+    );
+    assert_matches!(
+        body.locals[2].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Char)
+    );
+    assert_matches!(
+        body.locals[3].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Int(stable_mir::ty::IntTy::I32))
+    );
+    assert_matches!(
+        body.locals[4].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Uint(stable_mir::ty::UintTy::U64))
+    );
+    assert_matches!(
+        body.locals[5].kind(),
+        stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::Float(
+            stable_mir::ty::FloatTy::F64
+        ))
+    );
+
     let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap();
     let body = drop.body();
     assert_eq!(body.blocks.len(), 2);
@@ -156,6 +188,10 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         x_64.wrapping_add(y_64)
     }}
 
+    pub fn types(b: bool, _: char, _: i32, _: u64, _: f64) -> bool {{
+        b
+    }}
+
     pub fn drop(_: String) {{}}
 
     pub fn assert(x: i32) -> i32 {{
diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs
deleted file mode 100644
index b889f616a03..00000000000
--- a/tests/ui/async-await/in-trait/async-associated-types2.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// check-pass
-// edition: 2021
-// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
-// revisions: current next
-
-#![feature(async_fn_in_trait)]
-#![feature(impl_trait_in_assoc_type)]
-#![allow(incomplete_features)]
-
-use std::future::Future;
-
-trait MyTrait {
-    type Fut<'a>: Future<Output = i32>
-    where
-        Self: 'a;
-
-    fn foo<'a>(&'a self) -> Self::Fut<'a>;
-}
-
-impl MyTrait for i32 {
-    type Fut<'a> = impl Future<Output = i32> + 'a
-    where
-        Self: 'a;
-
-    fn foo<'a>(&'a self) -> Self::Fut<'a> {
-        async { *self }
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
new file mode 100644
index 00000000000..e6ac9bc2277
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
@@ -0,0 +1,30 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/missing-feature-flag.rs:14:1
+   |
+LL |     async fn foo(_: T) -> &'static str;
+   |     ----------------------------------- `foo` from trait
+...
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+  --> $DIR/missing-feature-flag.rs:18:5
+   |
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ------------------------------- parent `impl` is here
+...
+LL |     async fn foo(_: i32) -> &'static str {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+   |
+   = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0308]: mismatched types
+  --> $DIR/missing-feature-flag.rs:18:42
+   |
+LL |     async fn foo(_: i32) -> &'static str {}
+   |                                          ^^ expected `&str`, found `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0046, E0308, E0520.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
new file mode 100644
index 00000000000..e6ac9bc2277
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
@@ -0,0 +1,30 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/missing-feature-flag.rs:14:1
+   |
+LL |     async fn foo(_: T) -> &'static str;
+   |     ----------------------------------- `foo` from trait
+...
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+  --> $DIR/missing-feature-flag.rs:18:5
+   |
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ------------------------------- parent `impl` is here
+...
+LL |     async fn foo(_: i32) -> &'static str {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+   |
+   = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0308]: mismatched types
+  --> $DIR/missing-feature-flag.rs:18:42
+   |
+LL |     async fn foo(_: i32) -> &'static str {}
+   |                                          ^^ expected `&str`, found `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0046, E0308, E0520.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.rs b/tests/ui/async-await/in-trait/missing-feature-flag.rs
new file mode 100644
index 00000000000..6481f4a7059
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.rs
@@ -0,0 +1,23 @@
+// edition:2018
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(async_fn_in_trait)]
+#![feature(min_specialization)]
+
+struct MyStruct;
+
+trait MyTrait<T> {
+    async fn foo(_: T) -> &'static str;
+}
+
+impl<T> MyTrait<T> for MyStruct {}
+//~^ ERROR: not all trait items implemented, missing: `foo` [E0046]
+
+impl MyTrait<i32> for MyStruct {
+    async fn foo(_: i32) -> &'static str {}
+    //~^ ERROR: `foo` specializes an item from a parent `impl`, but that item is not marked `default` [E0520]
+    //~| ERROR: mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
new file mode 100644
index 00000000000..1b16a492a7a
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
@@ -0,0 +1,13 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+// Shouldn't ICE when we have a (bad) RTN in an impl header
+
+trait Super1<'a> {
+    fn bar<'b>() -> bool;
+}
+
+impl Super1<'_, bar(): Send> for () {}
+//~^ ERROR associated type bindings are not allowed here
+
+fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
new file mode 100644
index 00000000000..52d8168c9d8
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
@@ -0,0 +1,18 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/rtn-in-impl-signature.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/rtn-in-impl-signature.rs:10:17
+   |
+LL | impl Super1<'_, bar(): Send> for () {}
+   |                 ^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr
index c986bc3fd1e..115e7000619 100644
--- a/tests/ui/binop/binop-mul-i32-f32.stderr
+++ b/tests/ui/binop/binop-mul-i32-f32.stderr
@@ -6,10 +6,10 @@ LL |     x * y
    |
    = help: the trait `Mul<f32>` is not implemented for `i32`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <i32 as Mul>
+             <i32 as Mul<&i32>>
              <&'a i32 as Mul<i32>>
              <&i32 as Mul<&i32>>
-             <i32 as Mul<&i32>>
-             <i32 as Mul>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/binop/shift-various-bad-types.stderr b/tests/ui/binop/shift-various-bad-types.stderr
index 38db66f86b4..b43672ef3b5 100644
--- a/tests/ui/binop/shift-various-bad-types.stderr
+++ b/tests/ui/binop/shift-various-bad-types.stderr
@@ -6,14 +6,14 @@ LL |     22 >> p.char;
    |
    = help: the trait `Shr<char>` is not implemented for `{integer}`
    = help: the following other types implement trait `Shr<Rhs>`:
-             <&'a i128 as Shr<i128>>
-             <&'a i128 as Shr<i16>>
-             <&'a i128 as Shr<i32>>
-             <&'a i128 as Shr<i64>>
-             <&'a i128 as Shr<i8>>
-             <&'a i128 as Shr<isize>>
-             <&'a i128 as Shr<u128>>
-             <&'a i128 as Shr<u16>>
+             <isize as Shr>
+             <isize as Shr<i8>>
+             <isize as Shr<i16>>
+             <isize as Shr<i32>>
+             <isize as Shr<i64>>
+             <isize as Shr<i128>>
+             <isize as Shr<usize>>
+             <isize as Shr<u8>>
            and 568 others
 
 error[E0277]: no implementation for `{integer} >> &str`
@@ -24,14 +24,14 @@ LL |     22 >> p.str;
    |
    = help: the trait `Shr<&str>` is not implemented for `{integer}`
    = help: the following other types implement trait `Shr<Rhs>`:
-             <&'a i128 as Shr<i128>>
-             <&'a i128 as Shr<i16>>
-             <&'a i128 as Shr<i32>>
-             <&'a i128 as Shr<i64>>
-             <&'a i128 as Shr<i8>>
-             <&'a i128 as Shr<isize>>
-             <&'a i128 as Shr<u128>>
-             <&'a i128 as Shr<u16>>
+             <isize as Shr>
+             <isize as Shr<i8>>
+             <isize as Shr<i16>>
+             <isize as Shr<i32>>
+             <isize as Shr<i64>>
+             <isize as Shr<i128>>
+             <isize as Shr<usize>>
+             <isize as Shr<u8>>
            and 568 others
 
 error[E0277]: no implementation for `{integer} >> &Panolpy`
@@ -42,14 +42,14 @@ LL |     22 >> p;
    |
    = help: the trait `Shr<&Panolpy>` is not implemented for `{integer}`
    = help: the following other types implement trait `Shr<Rhs>`:
-             <&'a i128 as Shr<i128>>
-             <&'a i128 as Shr<i16>>
-             <&'a i128 as Shr<i32>>
-             <&'a i128 as Shr<i64>>
-             <&'a i128 as Shr<i8>>
-             <&'a i128 as Shr<isize>>
-             <&'a i128 as Shr<u128>>
-             <&'a i128 as Shr<u16>>
+             <isize as Shr>
+             <isize as Shr<i8>>
+             <isize as Shr<i16>>
+             <isize as Shr<i32>>
+             <isize as Shr<i64>>
+             <isize as Shr<i128>>
+             <isize as Shr<usize>>
+             <isize as Shr<u8>>
            and 568 others
 
 error[E0308]: mismatched types
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-1.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-1.rs
index d20e79b9db3..0898ca9cda4 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-1.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-1.rs
@@ -1,3 +1,3 @@
-// compile-flags: --cfg a(b=c)
+// compile-flags: --error-format=human --cfg a(b=c)
 // error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\")
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-2.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-2.rs
index 48d656a4a28..70e42560066 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-2.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-2.rs
@@ -1,3 +1,3 @@
-// compile-flags: --cfg a{b}
+// compile-flags: --error-format=human --cfg a{b}
 // error-pattern: invalid `--cfg` argument: `a{b}` (expected `key` or `key="value"`)
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-4.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-4.rs
index e7dfa17b4b6..2adc27eb932 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-4.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-4.rs
@@ -1,3 +1,3 @@
-// compile-flags: --cfg a(b)
+// compile-flags: --error-format=human --cfg a(b)
 // error-pattern: invalid `--cfg` argument: `a(b)` (expected `key` or `key="value"`)
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-6.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-6.rs
index 9fa726f93e3..be3ded7dd8b 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-6.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-6.rs
@@ -1,3 +1,3 @@
-// compile-flags: --cfg a{
+// compile-flags: --error-format=human --cfg a{
 // error-pattern: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`)
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-8.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-8.rs
index 1d7fa788534..4a2f16f1133 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-8.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-8.rs
@@ -1,3 +1,3 @@
-// compile-flags: --cfg )
+// compile-flags: --error-format=human --cfg )
 // error-pattern: invalid `--cfg` argument: `)` (expected `key` or `key="value"`)
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-arg-invalid-9.rs b/tests/ui/conditional-compilation/cfg-arg-invalid-9.rs
index 628b335c873..a61989a3e9f 100644
--- a/tests/ui/conditional-compilation/cfg-arg-invalid-9.rs
+++ b/tests/ui/conditional-compilation/cfg-arg-invalid-9.rs
@@ -1,4 +1,4 @@
 // Test for missing quotes around value, issue #66450.
-// compile-flags: --cfg key=value
+// compile-flags: --error-format=human --cfg key=value
 // error-pattern: invalid `--cfg` argument: `key=value` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\")
 fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-empty-codemap.rs b/tests/ui/conditional-compilation/cfg-empty-codemap.rs
index 9e34cacf74d..c7aded7338a 100644
--- a/tests/ui/conditional-compilation/cfg-empty-codemap.rs
+++ b/tests/ui/conditional-compilation/cfg-empty-codemap.rs
@@ -1,6 +1,6 @@
 // Tests that empty source_maps don't ICE (#23301)
 
-// compile-flags: --cfg ""
+// compile-flags: --error-format=human --cfg ""
 
 // error-pattern: invalid `--cfg` argument: `""` (expected `key` or `key="value"`)
 
diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr
index 76a83ba67ce..4a26e09772d 100644
--- a/tests/ui/const-generics/exhaustive-value.stderr
+++ b/tests/ui/const-generics/exhaustive-value.stderr
@@ -6,13 +6,13 @@ LL |     <() as Foo<N>>::test()
    |
    = help: the following other types implement trait `Foo<N>`:
              <() as Foo<0>>
-             <() as Foo<100>>
-             <() as Foo<101>>
-             <() as Foo<102>>
-             <() as Foo<103>>
-             <() as Foo<104>>
-             <() as Foo<105>>
-             <() as Foo<106>>
+             <() as Foo<1>>
+             <() as Foo<2>>
+             <() as Foo<3>>
+             <() as Foo<4>>
+             <() as Foo<5>>
+             <() as Foo<6>>
+             <() as Foo<7>>
            and 248 others
 
 error: aborting due to previous error
diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 13ea4a295af..0096d4ee23d 100644
--- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -6,11 +6,11 @@ LL |     let y = Mask::<_, _>::splat(false);
    |
    = note: cannot satisfy `_: MaskElement`
    = help: the following types implement trait `MaskElement`:
+             isize
+             i8
              i16
              i32
              i64
-             i8
-             isize
 note: required by a bound in `Mask::<T, LANES>::splat`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
 help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
diff --git a/tests/ui/const-generics/issues/issue-67185-2.stderr b/tests/ui/const-generics/issues/issue-67185-2.stderr
index 032b0c41047..a2e5b805368 100644
--- a/tests/ui/const-generics/issues/issue-67185-2.stderr
+++ b/tests/ui/const-generics/issues/issue-67185-2.stderr
@@ -5,8 +5,8 @@ LL |     <u8 as Baz>::Quaks: Bar,
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[u16; 3]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
@@ -17,8 +17,8 @@ LL |     [<u8 as Baz>::Quaks; 2]: Bar,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
@@ -29,8 +29,8 @@ LL | impl Foo for FooImpl {}
    |      ^^^ the trait `Bar` is not implemented for `[u16; 3]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
 note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:15:25
    |
@@ -47,8 +47,8 @@ LL | impl Foo for FooImpl {}
    |      ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
 note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:14:30
    |
@@ -65,8 +65,8 @@ LL | fn f(_: impl Foo) {}
    |              ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
 note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:14:30
    |
@@ -83,8 +83,8 @@ LL | fn f(_: impl Foo) {}
    |              ^^^ the trait `Bar` is not implemented for `[u16; 3]`
    |
    = help: the following other types implement trait `Bar`:
-             [[u16; 3]; 3]
              [u16; 4]
+             [[u16; 3]; 3]
 note: required by a bound in `Foo`
   --> $DIR/issue-67185-2.rs:15:25
    |
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr
index 05f33c33946..06e398edca9 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr
@@ -12,10 +12,10 @@ LL |     = [0; (i8::MAX + 1u8) as usize];
    |
    = help: the trait `Add<u8>` is not implemented for `i8`
    = help: the following other types implement trait `Add<Rhs>`:
+             <i8 as Add>
+             <i8 as Add<&i8>>
              <&'a i8 as Add<i8>>
              <&i8 as Add<&i8>>
-             <i8 as Add<&i8>>
-             <i8 as Add>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
index d019f5920b5..07ef2ac090f 100644
--- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
@@ -12,10 +12,10 @@ LL |     : [u32; (i8::MAX as i8 + 1u8) as usize]
    |
    = help: the trait `Add<u8>` is not implemented for `i8`
    = help: the following other types implement trait `Add<Rhs>`:
+             <i8 as Add>
+             <i8 as Add<&i8>>
              <&'a i8 as Add<i8>>
              <&i8 as Add<&i8>>
-             <i8 as Add<&i8>>
-             <i8 as Add>
 
 error[E0604]: only `u8` can be cast as `char`, not `i8`
   --> $DIR/const-eval-overflow-4b.rs:22:13
diff --git a/tests/ui/consts/const_in_pattern/issue-73431.rs b/tests/ui/consts/const_in_pattern/issue-73431.rs
index fa18a3af1b0..835f502b407 100644
--- a/tests/ui/consts/const_in_pattern/issue-73431.rs
+++ b/tests/ui/consts/const_in_pattern/issue-73431.rs
@@ -1,4 +1,5 @@
 // run-pass
+// unset-rustc-env:RUSTC_LOG_COLOR
 
 // Regression test for https://github.com/rust-lang/rust/issues/73431.
 
diff --git a/tests/ui/consts/missing-larger-array-impl.rs b/tests/ui/consts/missing-larger-array-impl.rs
new file mode 100644
index 00000000000..e6c879c8ebd
--- /dev/null
+++ b/tests/ui/consts/missing-larger-array-impl.rs
@@ -0,0 +1,9 @@
+struct X;
+
+// Make sure that we show the impl trait refs in the help message with
+// their evaluated constants, rather than `core::::array::{impl#30}::{constant#0}`
+
+fn main() {
+    <[X; 35] as Default>::default();
+    //~^ ERROR the trait bound `[X; 35]: Default` is not satisfied
+}
diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr
new file mode 100644
index 00000000000..b8f6cb5ef97
--- /dev/null
+++ b/tests/ui/consts/missing-larger-array-impl.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `[X; 35]: Default` is not satisfied
+  --> $DIR/missing-larger-array-impl.rs:7:5
+   |
+LL |     <[X; 35] as Default>::default();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
+   |
+   = help: the following other types implement trait `Default`:
+             [T; 0]
+             [T; 1]
+             [T; 2]
+             [T; 3]
+             [T; 4]
+             [T; 5]
+             [T; 6]
+             [T; 7]
+           and 27 others
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/too_generic_eval_ice.stderr b/tests/ui/consts/too_generic_eval_ice.stderr
index 5af82a3e34b..843d6d9e04b 100644
--- a/tests/ui/consts/too_generic_eval_ice.stderr
+++ b/tests/ui/consts/too_generic_eval_ice.stderr
@@ -22,14 +22,14 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
    |
    = help: the trait `PartialEq<[{integer}; 0]>` is not implemented for `[{integer}; Self::HOST_SIZE]`
    = help: the following other types implement trait `PartialEq<Rhs>`:
-             <&[B] as PartialEq<[A; N]>>
-             <&[T] as PartialEq<Vec<U, A>>>
-             <&mut [B] as PartialEq<[A; N]>>
-             <&mut [T] as PartialEq<Vec<U, A>>>
-             <[A; N] as PartialEq<&[B]>>
-             <[A; N] as PartialEq<&mut [B]>>
              <[A; N] as PartialEq<[B; N]>>
              <[A; N] as PartialEq<[B]>>
+             <[A; N] as PartialEq<&[B]>>
+             <[A; N] as PartialEq<&mut [B]>>
+             <[T] as PartialEq<Vec<U, A>>>
+             <[A] as PartialEq<[B]>>
+             <[B] as PartialEq<[A; N]>>
+             <&[T] as PartialEq<Vec<U, A>>>
            and 3 others
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/deriving/issue-103157.stderr b/tests/ui/deriving/issue-103157.stderr
index b18e1e5098b..01cce2a397a 100644
--- a/tests/ui/deriving/issue-103157.stderr
+++ b/tests/ui/deriving/issue-103157.stderr
@@ -8,14 +8,14 @@ LL |     Float(Option<f64>),
    |           ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`
    |
    = help: the following other types implement trait `Eq`:
-             i128
+             isize
+             i8
              i16
              i32
              i64
-             i8
-             isize
-             u128
-             u16
+             i128
+             usize
+             u8
            and 4 others
    = note: required for `Option<f64>` to implement `Eq`
 note: required by a bound in `AssertParamIsEq`
diff --git a/tests/ui/diagnostic-flags/colored-session-opt-error.rs b/tests/ui/diagnostic-flags/colored-session-opt-error.rs
new file mode 100644
index 00000000000..b9f47285c14
--- /dev/null
+++ b/tests/ui/diagnostic-flags/colored-session-opt-error.rs
@@ -0,0 +1,4 @@
+// check-pass
+// ignore-windows
+// compile-flags: -Cremark=foo --error-format=human --color always
+fn main() {}
diff --git a/tests/ui/diagnostic-flags/colored-session-opt-error.stderr b/tests/ui/diagnostic-flags/colored-session-opt-error.stderr
new file mode 100644
index 00000000000..ef79d5b0f2f
--- /dev/null
+++ b/tests/ui/diagnostic-flags/colored-session-opt-error.stderr
@@ -0,0 +1,2 @@
+warning: -C remark requires "-C debuginfo=n" to show source locations
+
diff --git a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index 5e0e4a0115a..2d50c09645d 100644
--- a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -7,12 +7,12 @@ LL |     f1.foo(1usize);
    |        required by a bound introduced by this call
    |
    = help: the following other types implement trait `Foo<A>`:
+             <Bar as Foo<i8>>
              <Bar as Foo<i16>>
              <Bar as Foo<i32>>
-             <Bar as Foo<i8>>
+             <Bar as Foo<u8>>
              <Bar as Foo<u16>>
              <Bar as Foo<u32>>
-             <Bar as Foo<u8>>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 7229b9ac986..ae15e054f62 100644
--- a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -8,10 +8,10 @@ LL |     Foo::<i32>::bar(&1i8);
    |
    = help: the following other types implement trait `Foo<B>`:
              <i8 as Foo<bool>>
+             <i8 as Foo<u8>>
              <i8 as Foo<u16>>
              <i8 as Foo<u32>>
              <i8 as Foo<u64>>
-             <i8 as Foo<u8>>
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:25:21
@@ -38,10 +38,10 @@ LL |     Foo::<i32>::bar(&true);
    = help: the following other types implement trait `Foo<B>`:
              <bool as Foo<bool>>
              <bool as Foo<i8>>
+             <bool as Foo<u8>>
              <bool as Foo<u16>>
              <bool as Foo<u32>>
              <bool as Foo<u64>>
-             <bool as Foo<u8>>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
index 26986684f0c..44bdbb93ff5 100644
--- a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
+++ b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
@@ -23,14 +23,14 @@ LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹
    |
    = help: the trait `Sub<{integer}>` is not implemented for `{float}`
    = help: the following other types implement trait `Sub<Rhs>`:
-             <&'a f32 as Sub<f32>>
-             <&'a f64 as Sub<f64>>
-             <&'a i128 as Sub<i128>>
-             <&'a i16 as Sub<i16>>
-             <&'a i32 as Sub<i32>>
-             <&'a i64 as Sub<i64>>
-             <&'a i8 as Sub<i8>>
-             <&'a isize as Sub<isize>>
+             <isize as Sub>
+             <isize as Sub<&isize>>
+             <i8 as Sub>
+             <i8 as Sub<&i8>>
+             <i16 as Sub>
+             <i16 as Sub<&i16>>
+             <i32 as Sub>
+             <i32 as Sub<&i32>>
            and 48 others
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/dyn-star/param-env-region-infer.current.stderr b/tests/ui/dyn-star/param-env-region-infer.current.stderr
index c606a50c8a9..902053ecfef 100644
--- a/tests/ui/dyn-star/param-env-region-infer.current.stderr
+++ b/tests/ui/dyn-star/param-env-region-infer.current.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/param-env-region-infer.rs:16:10
+  --> $DIR/param-env-region-infer.rs:18:10
    |
 LL |     t as _
    |          ^ cannot infer type
diff --git a/tests/ui/dyn-star/param-env-region-infer.next.stderr b/tests/ui/dyn-star/param-env-region-infer.next.stderr
new file mode 100644
index 00000000000..dd724a65908
--- /dev/null
+++ b/tests/ui/dyn-star/param-env-region-infer.next.stderr
@@ -0,0 +1,29 @@
+error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}`
+  --> $DIR/param-env-region-infer.rs:16:60
+   |
+LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
+   |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires type-checking `make_dyn_star`...
+  --> $DIR/param-env-region-infer.rs:16:1
+   |
+LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which requires computing layout of `make_dyn_star::{opaque#0}`...
+   = note: ...which requires normalizing `make_dyn_star::{opaque#0}`...
+   = note: ...which again requires computing type of `make_dyn_star::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+  --> $DIR/param-env-region-infer.rs:10:1
+   |
+LL | / #![feature(dyn_star, pointer_like_trait)]
+LL | | #![allow(incomplete_features)]
+LL | |
+LL | | use std::fmt::Debug;
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs
index 9c337e4a89b..537473abc3a 100644
--- a/tests/ui/dyn-star/param-env-region-infer.rs
+++ b/tests/ui/dyn-star/param-env-region-infer.rs
@@ -1,6 +1,7 @@
 // revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
-//[next] check-pass
+// Need `-Zdeduplicate-diagnostics=yes` because the number of cycle errors
+// emitted is for some horrible reason platform-specific.
+//[next] compile-flags: -Ztrait-solver=next -Zdeduplicate-diagnostics=yes
 // incremental
 
 // checks that we don't ICE if there are region inference variables in the environment
@@ -13,6 +14,7 @@ use std::fmt::Debug;
 use std::marker::PointerLike;
 
 fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
+    //[next]~^ ERROR cycle detected when computing
     t as _
     //[current]~^ ERROR type annotations needed
 }
diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr
index b0dddd3b1e8..4c0ac52865d 100644
--- a/tests/ui/fmt/ifmt-unimpl.stderr
+++ b/tests/ui/fmt/ifmt-unimpl.stderr
@@ -7,14 +7,14 @@ LL |     format!("{:X}", "3");
    |              required by a bound introduced by this call
    |
    = help: the following other types implement trait `UpperHex`:
-             &T
-             &mut T
-             NonZeroI128
-             NonZeroI16
-             NonZeroI32
-             NonZeroI64
-             NonZeroI8
-             NonZeroIsize
+             isize
+             i8
+             i16
+             i32
+             i64
+             i128
+             usize
+             u8
            and 20 others
    = note: required for `&str` to implement `UpperHex`
 note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr
index 69f4cbbbf42..9b8bff215e0 100644
--- a/tests/ui/impl-trait/equality.stderr
+++ b/tests/ui/impl-trait/equality.stderr
@@ -30,10 +30,10 @@ LL |         n + sum_to(n - 1)
    |
    = help: the trait `Add<impl Foo>` is not implemented for `u32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <u32 as Add>
+             <u32 as Add<&u32>>
              <&'a u32 as Add<u32>>
              <&u32 as Add<&u32>>
-             <u32 as Add<&u32>>
-             <u32 as Add>
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
new file mode 100644
index 00000000000..ff30103b771
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
+  --> $DIR/return-dont-satisfy-bounds.rs:13:34
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
+   |
+   = help: the trait `Foo<char>` is implemented for `Bar`
+note: required by a bound in `Foo::foo::{opaque#0}`
+  --> $DIR/return-dont-satisfy-bounds.rs:7:30
+   |
+LL |     fn foo<F2>(self) -> impl Foo<T>;
+   |                              ^^^^^^ required by this bound in `Foo::foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
new file mode 100644
index 00000000000..7c7f7feaa55
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
+  --> $DIR/return-dont-satisfy-bounds.rs:13:34
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
+   |
+   = help: the trait `Foo<char>` is implemented for `Bar`
+note: required by a bound in `Foo::{opaque#0}`
+  --> $DIR/return-dont-satisfy-bounds.rs:7:30
+   |
+LL |     fn foo<F2>(self) -> impl Foo<T>;
+   |                              ^^^^^^ required by this bound in `Foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
new file mode 100644
index 00000000000..65528f212e2
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
@@ -0,0 +1,19 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Foo<T> {
+    fn foo<F2>(self) -> impl Foo<T>;
+}
+
+struct Bar;
+
+impl Foo<char> for Bar {
+    fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+        //~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
+        self
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/reveal-during-codegen.rs b/tests/ui/impl-trait/reveal-during-codegen.rs
new file mode 100644
index 00000000000..11463772eb3
--- /dev/null
+++ b/tests/ui/impl-trait/reveal-during-codegen.rs
@@ -0,0 +1,11 @@
+// build-pass
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+fn test() -> Option<impl Sized> {
+    Some("")
+}
+
+fn main() {
+    test();
+}
diff --git a/tests/ui/issues/issue-11771.stderr b/tests/ui/issues/issue-11771.stderr
index 161fce4b031..b37140f60f9 100644
--- a/tests/ui/issues/issue-11771.stderr
+++ b/tests/ui/issues/issue-11771.stderr
@@ -6,14 +6,14 @@ LL |     1 +
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
-             <&'a f32 as Add<f32>>
-             <&'a f64 as Add<f64>>
-             <&'a i128 as Add<i128>>
-             <&'a i16 as Add<i16>>
-             <&'a i32 as Add<i32>>
-             <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
+             <isize as Add>
+             <isize as Add<&isize>>
+             <i8 as Add>
+             <i8 as Add<&i8>>
+             <i16 as Add>
+             <i16 as Add<&i16>>
+             <i32 as Add>
+             <i32 as Add<&i32>>
            and 48 others
 
 error[E0277]: cannot add `()` to `{integer}`
@@ -24,14 +24,14 @@ LL |     1 +
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
-             <&'a f32 as Add<f32>>
-             <&'a f64 as Add<f64>>
-             <&'a i128 as Add<i128>>
-             <&'a i16 as Add<i16>>
-             <&'a i32 as Add<i32>>
-             <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
+             <isize as Add>
+             <isize as Add<&isize>>
+             <i8 as Add>
+             <i8 as Add<&i8>>
+             <i16 as Add>
+             <i16 as Add<&i16>>
+             <i32 as Add>
+             <i32 as Add<&i32>>
            and 48 others
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/issues/issue-24352.stderr b/tests/ui/issues/issue-24352.stderr
index 1f51b6e2905..f1c3891b870 100644
--- a/tests/ui/issues/issue-24352.stderr
+++ b/tests/ui/issues/issue-24352.stderr
@@ -6,10 +6,10 @@ LL |     1.0f64 - 1
    |
    = help: the trait `Sub<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <f64 as Sub>
+             <f64 as Sub<&f64>>
              <&'a f64 as Sub<f64>>
              <&f64 as Sub<&f64>>
-             <f64 as Sub<&f64>>
-             <f64 as Sub>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     1.0f64 - 1.0
diff --git a/tests/ui/issues/issue-32709.stderr b/tests/ui/issues/issue-32709.stderr
index a4ba5da4d87..94e8f9295fd 100644
--- a/tests/ui/issues/issue-32709.stderr
+++ b/tests/ui/issues/issue-32709.stderr
@@ -8,6 +8,7 @@ LL |     Err(5)?;
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
+             <(T,) as From<[T; 1]>>
              <(T, T) as From<[T; 2]>>
              <(T, T, T) as From<[T; 3]>>
              <(T, T, T, T) as From<[T; 4]>>
@@ -15,7 +16,6 @@ LL |     Err(5)?;
              <(T, T, T, T, T, T) as From<[T; 6]>>
              <(T, T, T, T, T, T, T) as From<[T; 7]>>
              <(T, T, T, T, T, T, T, T) as From<[T; 8]>>
-             <(T, T, T, T, T, T, T, T, T) as From<[T; 9]>>
            and 4 others
    = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
 
diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr
index 3d527eb6b4e..9eafd7ab4f0 100644
--- a/tests/ui/issues/issue-50582.stderr
+++ b/tests/ui/issues/issue-50582.stderr
@@ -15,14 +15,14 @@ LL |     Vec::<[(); 1 + for x in 0..1 {}]>::new();
    |
    = help: the trait `Add<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
-             <&'a f32 as Add<f32>>
-             <&'a f64 as Add<f64>>
-             <&'a i128 as Add<i128>>
-             <&'a i16 as Add<i16>>
-             <&'a i32 as Add<i32>>
-             <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
+             <isize as Add>
+             <isize as Add<&isize>>
+             <i8 as Add>
+             <i8 as Add<&i8>>
+             <i16 as Add>
+             <i16 as Add<&i16>>
+             <i32 as Add>
+             <i32 as Add<&i32>>
            and 48 others
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs
index ec1997ccd5d..7336b873dd6 100644
--- a/tests/ui/issues/issue-67552.rs
+++ b/tests/ui/issues/issue-67552.rs
@@ -1,6 +1,7 @@
 // build-fail
 // compile-flags: -Copt-level=0
 // normalize-stderr-test: ".nll/" -> "/"
+// ignore-compare-mode-next-solver (hangs)
 
 fn main() {
     rec(Empty);
diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr
index 4746f918bf8..f93ed67dab2 100644
--- a/tests/ui/issues/issue-67552.stderr
+++ b/tests/ui/issues/issue-67552.stderr
@@ -1,11 +1,11 @@
 error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>`
-  --> $DIR/issue-67552.rs:29:9
+  --> $DIR/issue-67552.rs:30:9
    |
 LL |         rec(identity(&mut it))
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `rec` defined here
-  --> $DIR/issue-67552.rs:22:1
+  --> $DIR/issue-67552.rs:23:1
    |
 LL | / fn rec<T>(mut it: T)
 LL | | where
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
index 3cb5e44c711..7f1b9c38e67 100644
--- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
+++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
@@ -6,8 +6,8 @@ LL |     let x = Some(()).iter().map(|()| 1).sum::<f32>();
    |
    = help: the trait `Sum<{integer}>` is not implemented for `f32`
    = help: the following other types implement trait `Sum<A>`:
-             <f32 as Sum<&'a f32>>
              <f32 as Sum>
+             <f32 as Sum<&'a f32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29
    |
diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr
index f3dceca7e41..a2688107d10 100644
--- a/tests/ui/iterators/invalid-iterator-chain.stderr
+++ b/tests/ui/iterators/invalid-iterator-chain.stderr
@@ -24,8 +24,8 @@ LL |     println!("{}", scores.sum::<i32>());
    |
    = help: the trait `Sum<()>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:12:10
    |
@@ -49,8 +49,8 @@ LL |             .sum::<i32>(),
    |
    = help: the trait `Sum<()>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:25:14
    |
@@ -81,8 +81,8 @@ LL |             .sum::<i32>(),
    |
    = help: the trait `Sum<f64>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:33:14
    |
@@ -109,8 +109,8 @@ LL |     println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
    |
    = help: the trait `Sum<()>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:38:38
    |
@@ -130,8 +130,8 @@ LL |     println!("{}", vec![(), ()].iter().sum::<i32>());
    |
    = help: the trait `Sum<&()>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:39:33
    |
diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr
index 3585587ed4c..b18ab7f7608 100644
--- a/tests/ui/mismatched_types/binops.stderr
+++ b/tests/ui/mismatched_types/binops.stderr
@@ -6,14 +6,14 @@ LL |     1 + Some(1);
    |
    = help: the trait `Add<Option<{integer}>>` is not implemented for `{integer}`
    = help: the following other types implement trait `Add<Rhs>`:
-             <&'a f32 as Add<f32>>
-             <&'a f64 as Add<f64>>
-             <&'a i128 as Add<i128>>
-             <&'a i16 as Add<i16>>
-             <&'a i32 as Add<i32>>
-             <&'a i64 as Add<i64>>
-             <&'a i8 as Add<i8>>
-             <&'a isize as Add<isize>>
+             <isize as Add>
+             <isize as Add<&isize>>
+             <i8 as Add>
+             <i8 as Add<&i8>>
+             <i16 as Add>
+             <i16 as Add<&i16>>
+             <i32 as Add>
+             <i32 as Add<&i32>>
            and 48 others
 
 error[E0277]: cannot subtract `Option<{integer}>` from `usize`
@@ -24,10 +24,10 @@ LL |     2 as usize - Some(1);
    |
    = help: the trait `Sub<Option<{integer}>>` is not implemented for `usize`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <usize as Sub>
+             <usize as Sub<&usize>>
              <&'a usize as Sub<usize>>
              <&usize as Sub<&usize>>
-             <usize as Sub<&usize>>
-             <usize as Sub>
 
 error[E0277]: cannot multiply `{integer}` by `()`
   --> $DIR/binops.rs:4:7
@@ -37,14 +37,14 @@ LL |     3 * ();
    |
    = help: the trait `Mul<()>` is not implemented for `{integer}`
    = help: the following other types implement trait `Mul<Rhs>`:
-             <&'a f32 as Mul<f32>>
-             <&'a f64 as Mul<f64>>
-             <&'a i128 as Mul<i128>>
-             <&'a i16 as Mul<i16>>
-             <&'a i32 as Mul<i32>>
-             <&'a i64 as Mul<i64>>
-             <&'a i8 as Mul<i8>>
-             <&'a isize as Mul<isize>>
+             <isize as Mul>
+             <isize as Mul<&isize>>
+             <i8 as Mul>
+             <i8 as Mul<&i8>>
+             <i16 as Mul>
+             <i16 as Mul<&i16>>
+             <i32 as Mul>
+             <i32 as Mul<&i32>>
            and 49 others
 
 error[E0277]: cannot divide `{integer}` by `&str`
@@ -55,14 +55,14 @@ LL |     4 / "";
    |
    = help: the trait `Div<&str>` is not implemented for `{integer}`
    = help: the following other types implement trait `Div<Rhs>`:
-             <&'a f32 as Div<f32>>
-             <&'a f64 as Div<f64>>
-             <&'a i128 as Div<i128>>
-             <&'a i16 as Div<i16>>
-             <&'a i32 as Div<i32>>
-             <&'a i64 as Div<i64>>
-             <&'a i8 as Div<i8>>
-             <&'a isize as Div<isize>>
+             <isize as Div>
+             <isize as Div<&isize>>
+             <i8 as Div>
+             <i8 as Div<&i8>>
+             <i16 as Div>
+             <i16 as Div<&i16>>
+             <i32 as Div>
+             <i32 as Div<&i32>>
            and 54 others
 
 error[E0277]: can't compare `{integer}` with `String`
@@ -73,14 +73,14 @@ LL |     5 < String::new();
    |
    = help: the trait `PartialOrd<String>` is not implemented for `{integer}`
    = help: the following other types implement trait `PartialOrd<Rhs>`:
-             f32
-             f64
-             i128
+             isize
+             i8
              i16
              i32
              i64
-             i8
-             isize
+             i128
+             usize
+             u8
            and 6 others
 
 error[E0277]: can't compare `{integer}` with `Result<{integer}, _>`
@@ -91,14 +91,14 @@ LL |     6 == Ok(1);
    |
    = help: the trait `PartialEq<Result<{integer}, _>>` is not implemented for `{integer}`
    = help: the following other types implement trait `PartialEq<Rhs>`:
-             f32
-             f64
-             i128
+             isize
+             i8
              i16
              i32
              i64
-             i8
-             isize
+             i128
+             usize
+             u8
            and 6 others
 
 error: aborting due to 6 previous errors
diff --git a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr
index 3215c4669d5..df29fe22713 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr
@@ -7,8 +7,8 @@ LL |     unconstrained_arg(return);
    |     required by a bound introduced by this call
    |
    = help: the following other types implement trait `Test`:
-             ()
              i32
+             ()
    = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
    = help: did you intend to use the type `()` here instead?
 note: required by a bound in `unconstrained_arg`
diff --git a/tests/ui/never_type/issue-13352.stderr b/tests/ui/never_type/issue-13352.stderr
index 2d22da0b420..406785bfea0 100644
--- a/tests/ui/never_type/issue-13352.stderr
+++ b/tests/ui/never_type/issue-13352.stderr
@@ -6,10 +6,10 @@ LL |     2_usize + (loop {});
    |
    = help: the trait `Add<()>` is not implemented for `usize`
    = help: the following other types implement trait `Add<Rhs>`:
+             <usize as Add>
+             <usize as Add<&usize>>
              <&'a usize as Add<usize>>
              <&usize as Add<&usize>>
-             <usize as Add<&usize>>
-             <usize as Add>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/nll/user-annotations/normalization-2.stderr b/tests/ui/nll/user-annotations/normalization-2.stderr
index 5299282ea15..6b0dcb414ae 100644
--- a/tests/ui/nll/user-annotations/normalization-2.stderr
+++ b/tests/ui/nll/user-annotations/normalization-2.stderr
@@ -147,7 +147,7 @@ LL | fn test_variants<'a, 'b, 'c>() {
    |                      -- lifetime `'b` defined here
 ...
 LL |     <Ty<'b>>::Tuple();
-   |     ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
+   |     ^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
 
 error: lifetime may not live long enough
   --> $DIR/normalization-2.rs:93:5
diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
index 8f0eef237cf..e1825eb5b54 100644
--- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
+++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
@@ -6,10 +6,10 @@ LL |     x + 100.0
    |
    = help: the trait `Add<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Add<Rhs>`:
+             <u8 as Add>
+             <u8 as Add<&u8>>
              <&'a u8 as Add<u8>>
              <&u8 as Add<&u8>>
-             <u8 as Add<&u8>>
-             <u8 as Add>
 
 error[E0277]: cannot add `&str` to `f64`
   --> $DIR/not-suggest-float-literal.rs:6:7
@@ -19,10 +19,10 @@ LL |     x + "foo"
    |
    = help: the trait `Add<&str>` is not implemented for `f64`
    = help: the following other types implement trait `Add<Rhs>`:
+             <f64 as Add>
+             <f64 as Add<&f64>>
              <&'a f64 as Add<f64>>
              <&f64 as Add<&f64>>
-             <f64 as Add<&f64>>
-             <f64 as Add>
 
 error[E0277]: cannot add `{integer}` to `f64`
   --> $DIR/not-suggest-float-literal.rs:11:7
@@ -32,10 +32,10 @@ LL |     x + y
    |
    = help: the trait `Add<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Add<Rhs>`:
+             <f64 as Add>
+             <f64 as Add<&f64>>
              <&'a f64 as Add<f64>>
              <&f64 as Add<&f64>>
-             <f64 as Add<&f64>>
-             <f64 as Add>
 
 error[E0277]: cannot subtract `{float}` from `u8`
   --> $DIR/not-suggest-float-literal.rs:15:7
@@ -45,10 +45,10 @@ LL |     x - 100.0
    |
    = help: the trait `Sub<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <u8 as Sub>
+             <u8 as Sub<&u8>>
              <&'a u8 as Sub<u8>>
              <&u8 as Sub<&u8>>
-             <u8 as Sub<&u8>>
-             <u8 as Sub>
 
 error[E0277]: cannot subtract `&str` from `f64`
   --> $DIR/not-suggest-float-literal.rs:19:7
@@ -58,10 +58,10 @@ LL |     x - "foo"
    |
    = help: the trait `Sub<&str>` is not implemented for `f64`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <f64 as Sub>
+             <f64 as Sub<&f64>>
              <&'a f64 as Sub<f64>>
              <&f64 as Sub<&f64>>
-             <f64 as Sub<&f64>>
-             <f64 as Sub>
 
 error[E0277]: cannot subtract `{integer}` from `f64`
   --> $DIR/not-suggest-float-literal.rs:24:7
@@ -71,10 +71,10 @@ LL |     x - y
    |
    = help: the trait `Sub<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <f64 as Sub>
+             <f64 as Sub<&f64>>
              <&'a f64 as Sub<f64>>
              <&f64 as Sub<&f64>>
-             <f64 as Sub<&f64>>
-             <f64 as Sub>
 
 error[E0277]: cannot multiply `u8` by `{float}`
   --> $DIR/not-suggest-float-literal.rs:28:7
@@ -84,10 +84,10 @@ LL |     x * 100.0
    |
    = help: the trait `Mul<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <u8 as Mul>
+             <u8 as Mul<&u8>>
              <&'a u8 as Mul<u8>>
              <&u8 as Mul<&u8>>
-             <u8 as Mul<&u8>>
-             <u8 as Mul>
 
 error[E0277]: cannot multiply `f64` by `&str`
   --> $DIR/not-suggest-float-literal.rs:32:7
@@ -97,10 +97,10 @@ LL |     x * "foo"
    |
    = help: the trait `Mul<&str>` is not implemented for `f64`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <f64 as Mul>
+             <f64 as Mul<&f64>>
              <&'a f64 as Mul<f64>>
              <&f64 as Mul<&f64>>
-             <f64 as Mul<&f64>>
-             <f64 as Mul>
 
 error[E0277]: cannot multiply `f64` by `{integer}`
   --> $DIR/not-suggest-float-literal.rs:37:7
@@ -110,10 +110,10 @@ LL |     x * y
    |
    = help: the trait `Mul<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <f64 as Mul>
+             <f64 as Mul<&f64>>
              <&'a f64 as Mul<f64>>
              <&f64 as Mul<&f64>>
-             <f64 as Mul<&f64>>
-             <f64 as Mul>
 
 error[E0277]: cannot divide `u8` by `{float}`
   --> $DIR/not-suggest-float-literal.rs:41:7
@@ -123,11 +123,11 @@ LL |     x / 100.0
    |
    = help: the trait `Div<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Div<Rhs>`:
+             <u8 as Div>
+             <u8 as Div<NonZeroU8>>
+             <u8 as Div<&u8>>
              <&'a u8 as Div<u8>>
              <&u8 as Div<&u8>>
-             <u8 as Div<&u8>>
-             <u8 as Div<NonZeroU8>>
-             <u8 as Div>
 
 error[E0277]: cannot divide `f64` by `&str`
   --> $DIR/not-suggest-float-literal.rs:45:7
@@ -137,10 +137,10 @@ LL |     x / "foo"
    |
    = help: the trait `Div<&str>` is not implemented for `f64`
    = help: the following other types implement trait `Div<Rhs>`:
+             <f64 as Div>
+             <f64 as Div<&f64>>
              <&'a f64 as Div<f64>>
              <&f64 as Div<&f64>>
-             <f64 as Div<&f64>>
-             <f64 as Div>
 
 error[E0277]: cannot divide `f64` by `{integer}`
   --> $DIR/not-suggest-float-literal.rs:50:7
@@ -150,10 +150,10 @@ LL |     x / y
    |
    = help: the trait `Div<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Div<Rhs>`:
+             <f64 as Div>
+             <f64 as Div<&f64>>
              <&'a f64 as Div<f64>>
              <&f64 as Div<&f64>>
-             <f64 as Div<&f64>>
-             <f64 as Div>
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr
index 03779d35637..929a9e3b595 100644
--- a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr
+++ b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr
@@ -6,10 +6,10 @@ LL |     x + 100
    |
    = help: the trait `Add<{integer}>` is not implemented for `f32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <f32 as Add>
+             <f32 as Add<&f32>>
              <&'a f32 as Add<f32>>
              <&f32 as Add<&f32>>
-             <f32 as Add<&f32>>
-             <f32 as Add>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x + 100.0
@@ -23,10 +23,10 @@ LL |     x + 100
    |
    = help: the trait `Add<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Add<Rhs>`:
+             <f64 as Add>
+             <f64 as Add<&f64>>
              <&'a f64 as Add<f64>>
              <&f64 as Add<&f64>>
-             <f64 as Add<&f64>>
-             <f64 as Add>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x + 100.0
@@ -40,10 +40,10 @@ LL |     x - 100
    |
    = help: the trait `Sub<{integer}>` is not implemented for `f32`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <f32 as Sub>
+             <f32 as Sub<&f32>>
              <&'a f32 as Sub<f32>>
              <&f32 as Sub<&f32>>
-             <f32 as Sub<&f32>>
-             <f32 as Sub>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x - 100.0
@@ -57,10 +57,10 @@ LL |     x - 100
    |
    = help: the trait `Sub<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Sub<Rhs>`:
+             <f64 as Sub>
+             <f64 as Sub<&f64>>
              <&'a f64 as Sub<f64>>
              <&f64 as Sub<&f64>>
-             <f64 as Sub<&f64>>
-             <f64 as Sub>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x - 100.0
@@ -74,10 +74,10 @@ LL |     x * 100
    |
    = help: the trait `Mul<{integer}>` is not implemented for `f32`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <f32 as Mul>
+             <f32 as Mul<&f32>>
              <&'a f32 as Mul<f32>>
              <&f32 as Mul<&f32>>
-             <f32 as Mul<&f32>>
-             <f32 as Mul>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x * 100.0
@@ -91,10 +91,10 @@ LL |     x * 100
    |
    = help: the trait `Mul<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Mul<Rhs>`:
+             <f64 as Mul>
+             <f64 as Mul<&f64>>
              <&'a f64 as Mul<f64>>
              <&f64 as Mul<&f64>>
-             <f64 as Mul<&f64>>
-             <f64 as Mul>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x * 100.0
@@ -108,10 +108,10 @@ LL |     x / 100
    |
    = help: the trait `Div<{integer}>` is not implemented for `f32`
    = help: the following other types implement trait `Div<Rhs>`:
+             <f32 as Div>
+             <f32 as Div<&f32>>
              <&'a f32 as Div<f32>>
              <&f32 as Div<&f32>>
-             <f32 as Div<&f32>>
-             <f32 as Div>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x / 100.0
@@ -125,10 +125,10 @@ LL |     x / 100
    |
    = help: the trait `Div<{integer}>` is not implemented for `f64`
    = help: the following other types implement trait `Div<Rhs>`:
+             <f64 as Div>
+             <f64 as Div<&f64>>
              <&'a f64 as Div<f64>>
              <&f64 as Div<&f64>>
-             <f64 as Div<&f64>>
-             <f64 as Div>
 help: consider using a floating-point literal by writing it with `.0`
    |
 LL |     x / 100.0
diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr
index d628b159a66..3d0e36db752 100644
--- a/tests/ui/on-unimplemented/multiple-impls.stderr
+++ b/tests/ui/on-unimplemented/multiple-impls.stderr
@@ -8,8 +8,8 @@ LL |     Index::index(&[] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
@@ -19,8 +19,8 @@ LL |     Index::index(&[] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:37:33
@@ -32,8 +32,8 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:37:5
@@ -43,8 +43,8 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:41:33
@@ -56,8 +56,8 @@ LL |     Index::index(&[] as &[i32], Bar(2u32));
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:41:5
@@ -67,8 +67,8 @@ LL |     Index::index(&[] as &[i32], Bar(2u32));
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
@@ -78,8 +78,8 @@ LL |     Index::index(&[] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:37:5
@@ -89,8 +89,8 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:41:5
@@ -100,8 +100,8 @@ LL |     Index::index(&[] as &[i32], Bar(2u32));
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
+             <[i32] as Index<Bar<usize>>>
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr
index a7ec3bda85e..b9bca211f43 100644
--- a/tests/ui/on-unimplemented/slice-index.stderr
+++ b/tests/ui/on-unimplemented/slice-index.stderr
@@ -16,8 +16,8 @@ LL |     x[..1i32];
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
    = help: the following other types implement trait `SliceIndex<T>`:
-             <RangeTo<usize> as SliceIndex<[T]>>
              <RangeTo<usize> as SliceIndex<str>>
+             <RangeTo<usize> as SliceIndex<[T]>>
    = note: required for `[i32]` to implement `Index<RangeTo<i32>>`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr
index 2a316dba778..a2357e49b07 100644
--- a/tests/ui/on-unimplemented/sum.stderr
+++ b/tests/ui/on-unimplemented/sum.stderr
@@ -6,8 +6,8 @@ LL |     vec![(), ()].iter().sum::<i32>();
    |
    = help: the trait `Sum<&()>` is not implemented for `i32`
    = help: the following other types implement trait `Sum<A>`:
-             <i32 as Sum<&'a i32>>
              <i32 as Sum>
+             <i32 as Sum<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/sum.rs:4:18
    |
@@ -26,8 +26,8 @@ LL |     vec![(), ()].iter().product::<i32>();
    |
    = help: the trait `Product<&()>` is not implemented for `i32`
    = help: the following other types implement trait `Product<A>`:
-             <i32 as Product<&'a i32>>
              <i32 as Product>
+             <i32 as Product<&'a i32>>
 note: the method call chain might not have had the expected associated types
   --> $DIR/sum.rs:7:18
    |
diff --git a/tests/ui/pattern/issue-110508.rs b/tests/ui/pattern/issue-110508.rs
new file mode 100644
index 00000000000..1024ff05578
--- /dev/null
+++ b/tests/ui/pattern/issue-110508.rs
@@ -0,0 +1,38 @@
+// run-pass
+
+#[derive(PartialEq, Eq)]
+pub enum Foo {
+    FooA(()),
+    FooB(Vec<()>),
+}
+
+impl Foo {
+    const A1: Foo = Foo::FooA(());
+    const A2: Foo = Self::FooA(());
+    const A3: Self = Foo::FooA(());
+    const A4: Self = Self::FooA(());
+}
+
+fn main() {
+    let foo = Foo::FooA(());
+
+    match foo {
+        Foo::A1 => {},
+        _ => {},
+    }
+
+    match foo {
+        Foo::A2 => {},
+        _ => {},
+    }
+
+    match foo {
+        Foo::A3 => {},
+        _ => {},
+    }
+
+    match foo {
+        Foo::A4 => {},
+        _ => {},
+    }
+}
diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
index 3956390368f..277d9b2682d 100644
--- a/tests/ui/range/range-1.stderr
+++ b/tests/ui/range/range-1.stderr
@@ -12,13 +12,13 @@ LL |     for i in false..true {}
    |
    = help: the following other types implement trait `Step`:
              char
-             i128
+             isize
+             i8
              i16
              i32
              i64
-             i8
-             isize
-             u128
+             i128
+             usize
            and 5 others
    = note: required for `std::ops::Range<bool>` to implement `Iterator`
    = note: required for `std::ops::Range<bool>` to implement `IntoIterator`
diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs
index 2f1cffa2fa9..7ee31d85c2b 100644
--- a/tests/ui/recursion/issue-95134.rs
+++ b/tests/ui/recursion/issue-95134.rs
@@ -3,6 +3,7 @@
 // compile-flags: -Copt-level=0
 // dont-check-failure-status
 // dont-check-compiler-stderr
+// ignore-compare-mode-next-solver (hangs)
 
 pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
     if n > 15 {
diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr
index 313b3e30dd9..30f5f059526 100644
--- a/tests/ui/resolve/issue-2356.stderr
+++ b/tests/ui/resolve/issue-2356.stderr
@@ -1,18 +1,3 @@
-error[E0425]: cannot find function `default` in this scope
-  --> $DIR/issue-2356.rs:31:5
-   |
-LL |     default();
-   |     ^^^^^^^
-   |
-help: you might have meant to call the associated function
-   |
-LL |     Self::default();
-   |     ~~~~~~~~~~~~~
-help: consider importing this function
-   |
-LL + use std::default::default;
-   |
-
 error[E0425]: cannot find value `whiskers` in this scope
   --> $DIR/issue-2356.rs:39:5
    |
@@ -64,6 +49,12 @@ error[E0425]: cannot find function `clone` in this scope
 LL |     clone();
    |     ^^^^^ help: you might have meant to call the method: `self.clone`
 
+error[E0425]: cannot find function `default` in this scope
+  --> $DIR/issue-2356.rs:31:5
+   |
+LL |     default();
+   |     ^^^^^^^ help: you might have meant to call the associated function: `Self::default`
+
 error[E0425]: cannot find function `shave` in this scope
   --> $DIR/issue-2356.rs:41:5
    |
diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr
index b44df962a9b..b6052a209bf 100644
--- a/tests/ui/span/multiline-span-simple.stderr
+++ b/tests/ui/span/multiline-span-simple.stderr
@@ -6,10 +6,10 @@ LL |     foo(1 as u32 +
    |
    = help: the trait `Add<()>` is not implemented for `u32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <u32 as Add>
+             <u32 as Add<&u32>>
              <&'a u32 as Add<u32>>
              <&u32 as Add<&u32>>
-             <u32 as Add<&u32>>
-             <u32 as Add>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
index e74c2c4214f..6465eeb8bc6 100644
--- a/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
+++ b/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
@@ -16,8 +16,8 @@ LL | fn bar() -> impl Bar {
    |             ^^^^^^^^ the trait `Bar` is not implemented for `()`
    |
    = help: the following other types implement trait `Bar`:
-             Qux
              i32
+             Qux
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/into-str.stderr b/tests/ui/suggestions/into-str.stderr
index a56a2a188cb..7e24150e7f4 100644
--- a/tests/ui/suggestions/into-str.stderr
+++ b/tests/ui/suggestions/into-str.stderr
@@ -8,12 +8,12 @@ LL |     foo(String::new());
    |
    = note: to coerce a `String` into a `&str`, use `&*` as a prefix
    = help: the following other types implement trait `From<T>`:
-             <String as From<&String>>
-             <String as From<&mut str>>
-             <String as From<&str>>
+             <String as From<char>>
              <String as From<Box<str>>>
              <String as From<Cow<'a, str>>>
-             <String as From<char>>
+             <String as From<&str>>
+             <String as From<&mut str>>
+             <String as From<&String>>
    = note: required for `String` to implement `Into<&str>`
 note: required by a bound in `foo`
   --> $DIR/into-str.rs:1:31
diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
index ea57992b483..004f1c1622b 100644
--- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -5,14 +5,14 @@ LL |     let _: &[i8] = data.into();
    |                         ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
    |
    = help: the following other types implement trait `From<T>`:
-             <&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>>
-             <[T; 10] as From<(T, T, T, T, T, T, T, T, T, T)>>
-             <[T; 11] as From<(T, T, T, T, T, T, T, T, T, T, T)>>
-             <[T; 12] as From<(T, T, T, T, T, T, T, T, T, T, T, T)>>
+             <[bool; LANES] as From<Mask<T, LANES>>>
+             <[T; N] as From<Simd<T, N>>>
              <[T; 1] as From<(T,)>>
              <[T; 2] as From<(T, T)>>
              <[T; 3] as From<(T, T, T)>>
              <[T; 4] as From<(T, T, T, T)>>
+             <[T; 5] as From<(T, T, T, T, T)>>
+             <[T; 6] as From<(T, T, T, T, T, T)>>
            and 7 others
    = note: required for `&[u8]` to implement `Into<&[i8]>`
 
diff --git a/tests/ui/thir-print/thir-flat-const-variant.rs b/tests/ui/thir-print/thir-flat-const-variant.rs
new file mode 100644
index 00000000000..2cd87a5cbb2
--- /dev/null
+++ b/tests/ui/thir-print/thir-flat-const-variant.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z unpretty=thir-flat
+// check-pass
+
+// Previously, the constants with `Self::Bar(())` would be `Call`s instead of
+// `Adt`s in THIR.
+
+pub enum Foo {
+    Bar(()),
+}
+
+impl Foo {
+    const BAR1: Foo = Foo::Bar(());
+    const BAR2: Foo = Self::Bar(());
+    const BAR3: Self = Foo::Bar(());
+    const BAR4: Self = Self::Bar(());
+}
+
+fn main() {}
diff --git a/tests/ui/thir-print/thir-flat-const-variant.stdout b/tests/ui/thir-print/thir-flat-const-variant.stdout
new file mode 100644
index 00000000000..1b76f07c318
--- /dev/null
+++ b/tests/ui/thir-print/thir-flat-const-variant.stdout
@@ -0,0 +1,399 @@
+DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1):
+Thir {
+    body_type: Const(
+        Foo,
+    ),
+    arms: [],
+    blocks: [],
+    exprs: [
+        Expr {
+            kind: Tuple {
+                fields: [],
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(7),
+                lint_level: Explicit(
+                    HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7),
+                ),
+                value: e0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:12:32: 12:34 (#0),
+        },
+        Expr {
+            kind: Adt(
+                AdtExpr {
+                    adt_def: Foo,
+                    variant_index: 0,
+                    substs: [],
+                    user_ty: None,
+                    fields: [
+                        FieldExpr {
+                            name: 0,
+                            expr: e1,
+                        },
+                    ],
+                    base: None,
+                },
+            ),
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(3),
+                lint_level: Explicit(
+                    HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3),
+                ),
+                value: e2,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Destruction(3),
+                lint_level: Inherited,
+                value: e3,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:12:23: 12:35 (#0),
+        },
+    ],
+    stmts: [],
+    params: [],
+}
+
+DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2):
+Thir {
+    body_type: Const(
+        Foo,
+    ),
+    arms: [],
+    blocks: [],
+    exprs: [
+        Expr {
+            kind: Tuple {
+                fields: [],
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(8),
+                lint_level: Explicit(
+                    HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8),
+                ),
+                value: e0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:13:33: 13:35 (#0),
+        },
+        Expr {
+            kind: Adt(
+                AdtExpr {
+                    adt_def: Foo,
+                    variant_index: 0,
+                    substs: [],
+                    user_ty: None,
+                    fields: [
+                        FieldExpr {
+                            name: 0,
+                            expr: e1,
+                        },
+                    ],
+                    base: None,
+                },
+            ),
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(3),
+                lint_level: Explicit(
+                    HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3),
+                ),
+                value: e2,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Destruction(3),
+                lint_level: Inherited,
+                value: e3,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:13:23: 13:36 (#0),
+        },
+    ],
+    stmts: [],
+    params: [],
+}
+
+DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3):
+Thir {
+    body_type: Const(
+        Foo,
+    ),
+    arms: [],
+    blocks: [],
+    exprs: [
+        Expr {
+            kind: Tuple {
+                fields: [],
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(7),
+                lint_level: Explicit(
+                    HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7),
+                ),
+                value: e0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:14:33: 14:35 (#0),
+        },
+        Expr {
+            kind: Adt(
+                AdtExpr {
+                    adt_def: Foo,
+                    variant_index: 0,
+                    substs: [],
+                    user_ty: None,
+                    fields: [
+                        FieldExpr {
+                            name: 0,
+                            expr: e1,
+                        },
+                    ],
+                    base: None,
+                },
+            ),
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(3),
+                lint_level: Explicit(
+                    HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3),
+                ),
+                value: e2,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Destruction(3),
+                lint_level: Inherited,
+                value: e3,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:14:24: 14:36 (#0),
+        },
+    ],
+    stmts: [],
+    params: [],
+}
+
+DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4):
+Thir {
+    body_type: Const(
+        Foo,
+    ),
+    arms: [],
+    blocks: [],
+    exprs: [
+        Expr {
+            kind: Tuple {
+                fields: [],
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(8),
+                lint_level: Explicit(
+                    HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8),
+                ),
+                value: e0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:15:34: 15:36 (#0),
+        },
+        Expr {
+            kind: Adt(
+                AdtExpr {
+                    adt_def: Foo,
+                    variant_index: 0,
+                    substs: [],
+                    user_ty: None,
+                    fields: [
+                        FieldExpr {
+                            name: 0,
+                            expr: e1,
+                        },
+                    ],
+                    base: None,
+                },
+            ),
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(3),
+                lint_level: Explicit(
+                    HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3),
+                ),
+                value: e2,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Destruction(3),
+                lint_level: Inherited,
+                value: e3,
+            },
+            ty: Foo,
+            temp_lifetime: Some(
+                Node(3),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:15:24: 15:37 (#0),
+        },
+    ],
+    stmts: [],
+    params: [],
+}
+
+DefId(0:12 ~ thir_flat_const_variant[1f54]::main):
+Thir {
+    body_type: Fn(
+        fn(),
+    ),
+    arms: [],
+    blocks: [
+        Block {
+            targeted_by_break: false,
+            region_scope: Node(1),
+            opt_destruction_scope: None,
+            span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
+            stmts: [],
+            expr: None,
+            safety_mode: Safe,
+        },
+    ],
+    exprs: [
+        Expr {
+            kind: Block {
+                block: b0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Node(2),
+                lint_level: Explicit(
+                    HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2),
+                ),
+                value: e0,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
+        },
+        Expr {
+            kind: Scope {
+                region_scope: Destruction(2),
+                lint_level: Inherited,
+                value: e1,
+            },
+            ty: (),
+            temp_lifetime: Some(
+                Node(2),
+            ),
+            span: $DIR/thir-flat-const-variant.rs:18:11: 18:13 (#0),
+        },
+    ],
+    stmts: [],
+    params: [],
+}
+
diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
index ce9ab2d811a..b1c683e4729 100644
--- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
+++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
@@ -6,13 +6,13 @@ LL |     s.strip_suffix(b'\n').unwrap_or(s)
    |
    = help: the trait `FnMut<(char,)>` is not implemented for `u8`
    = help: the following other types implement trait `Pattern<'a>`:
+             char
+             [char; N]
              &'b String
              &'b [char; N]
              &'b [char]
-             &'b str
              &'c &'b str
-             [char; N]
-             char
+             &'b str
    = note: required for `u8` to implement `Pattern<'_>`
 
 error: aborting due to previous error
diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.rs b/tests/ui/traits/new-solver/slice-match-byte-lit.rs
index 5f9c0df6450..4f848062595 100644
--- a/tests/ui/traits/new-solver/slice-match-byte-lit.rs
+++ b/tests/ui/traits/new-solver/slice-match-byte-lit.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Ztrait-solver=next
-// known-bug: rust-lang/trait-system-refactor-initiative#38
+// check-pass
 
 fn test(s: &[u8]) {
     match &s[0..3] {
diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.stderr b/tests/ui/traits/new-solver/slice-match-byte-lit.stderr
deleted file mode 100644
index cd48a6d1843..00000000000
--- a/tests/ui/traits/new-solver/slice-match-byte-lit.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0271]: type mismatch resolving `[u8; 3] <: <[u8] as Index<Range<usize>>>::Output`
-  --> $DIR/slice-match-byte-lit.rs:6:9
-   |
-LL |     match &s[0..3] {
-   |           -------- this expression has type `&<[u8] as Index<std::ops::Range<usize>>>::Output`
-LL |         b"uwu" => {}
-   |         ^^^^^^ types differ
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
index a49630adb95..7eb392faa66 100644
--- a/tests/ui/try-trait/bad-interconversion.stderr
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -8,8 +8,8 @@ LL |     Ok(Err(123_i32)?)
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
-             <u8 as From<NonZeroU8>>
              <u8 as From<bool>>
+             <u8 as From<NonZeroU8>>
    = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
 
 error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
@@ -22,8 +22,8 @@ LL |     Some(3)?;
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`
    = help: the following other types implement trait `FromResidual<R>`:
-             <Result<T, F> as FromResidual<Result<Infallible, E>>>
              <Result<T, F> as FromResidual<Yeet<E>>>
+             <Result<T, F> as FromResidual<Result<Infallible, E>>>
 
 error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
   --> $DIR/bad-interconversion.rs:17:31
@@ -35,8 +35,8 @@ LL |     Ok(ControlFlow::Break(123)?)
    |
    = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
    = help: the following other types implement trait `FromResidual<R>`:
-             <Result<T, F> as FromResidual<Result<Infallible, E>>>
              <Result<T, F> as FromResidual<Yeet<E>>>
+             <Result<T, F> as FromResidual<Result<Infallible, E>>>
 
 error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
   --> $DIR/bad-interconversion.rs:22:22
diff --git a/tests/ui/try-trait/option-to-result.stderr b/tests/ui/try-trait/option-to-result.stderr
index fabc1ff2c76..1c4d718f1ee 100644
--- a/tests/ui/try-trait/option-to-result.stderr
+++ b/tests/ui/try-trait/option-to-result.stderr
@@ -9,8 +9,8 @@ LL |     a?;
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
    = help: the following other types implement trait `FromResidual<R>`:
-             <Result<T, F> as FromResidual<Result<Infallible, E>>>
              <Result<T, F> as FromResidual<Yeet<E>>>
+             <Result<T, F> as FromResidual<Result<Infallible, E>>>
 
 error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
   --> $DIR/option-to-result.rs:11:6
diff --git a/tests/ui/try-trait/try-on-option.stderr b/tests/ui/try-trait/try-on-option.stderr
index fad6a1fe823..eeb0439df29 100644
--- a/tests/ui/try-trait/try-on-option.stderr
+++ b/tests/ui/try-trait/try-on-option.stderr
@@ -9,8 +9,8 @@ LL |     x?;
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>`
    = help: the following other types implement trait `FromResidual<R>`:
-             <Result<T, F> as FromResidual<Result<Infallible, E>>>
              <Result<T, F> as FromResidual<Yeet<E>>>
+             <Result<T, F> as FromResidual<Result<Infallible, E>>>
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
   --> $DIR/try-on-option.rs:11:6
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr
index f4d96038d91..dccf84362f0 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr
@@ -8,8 +8,8 @@ LL |     ()
    |     -- return type was inferred to be `()` here
    |
    = help: the following other types implement trait `Foo<A>`:
-             <() as Foo<()>>
              <() as Foo<u32>>
+             <() as Foo<()>>
 
 error: aborting due to previous error
 
diff --git a/tests/ui/type/type-check-defaults.stderr b/tests/ui/type/type-check-defaults.stderr
index 9ba63ffe9c9..10d600cbfcc 100644
--- a/tests/ui/type/type-check-defaults.stderr
+++ b/tests/ui/type/type-check-defaults.stderr
@@ -66,10 +66,10 @@ LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
    |
    = help: the trait `Add<u8>` is not implemented for `i32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <i32 as Add>
+             <i32 as Add<&i32>>
              <&'a i32 as Add<i32>>
              <&i32 as Add<&i32>>
-             <i32 as Add<&i32>>
-             <i32 as Add>
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/typeck/issue-81293.stderr b/tests/ui/typeck/issue-81293.stderr
index 6976be71135..292c63070ae 100644
--- a/tests/ui/typeck/issue-81293.stderr
+++ b/tests/ui/typeck/issue-81293.stderr
@@ -21,10 +21,10 @@ LL |     a = c + b * 5;
    |
    = help: the trait `Add<u16>` is not implemented for `usize`
    = help: the following other types implement trait `Add<Rhs>`:
+             <usize as Add>
+             <usize as Add<&usize>>
              <&'a usize as Add<usize>>
              <&usize as Add<&usize>>
-             <usize as Add<&usize>>
-             <usize as Add>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/typeck/issue-90101.stderr b/tests/ui/typeck/issue-90101.stderr
index d2729d85354..484089f9e87 100644
--- a/tests/ui/typeck/issue-90101.stderr
+++ b/tests/ui/typeck/issue-90101.stderr
@@ -7,11 +7,11 @@ LL |     func(Path::new("hello").to_path_buf().to_string_lossy(), "world")
    |     required by a bound introduced by this call
    |
    = help: the following other types implement trait `From<T>`:
-             <PathBuf as From<&T>>
              <PathBuf as From<Box<Path>>>
              <PathBuf as From<Cow<'a, Path>>>
              <PathBuf as From<OsString>>
              <PathBuf as From<String>>
+             <PathBuf as From<&T>>
    = note: required for `Cow<'_, str>` to implement `Into<PathBuf>`
 note: required by a bound in `func`
   --> $DIR/issue-90101.rs:3:20
diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index 96ac4321689..85adf775139 100644
--- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -8,10 +8,10 @@ LL |     <i32 as Add<u32>>::add(1, 2);
    |
    = help: the trait `Add<u32>` is not implemented for `i32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <i32 as Add>
+             <i32 as Add<&i32>>
              <&'a i32 as Add<i32>>
              <&i32 as Add<&i32>>
-             <i32 as Add<&i32>>
-             <i32 as Add>
 
 error[E0308]: mismatched types
   --> $DIR/ufcs-qpath-self-mismatch.rs:7:28
@@ -65,10 +65,10 @@ LL |     <i32 as Add<u32>>::add(1, 2);
    |
    = help: the trait `Add<u32>` is not implemented for `i32`
    = help: the following other types implement trait `Add<Rhs>`:
+             <i32 as Add>
+             <i32 as Add<&i32>>
              <&'a i32 as Add<i32>>
              <&i32 as Add<&i32>>
-             <i32 as Add<&i32>>
-             <i32 as Add>
 
 error: aborting due to 4 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 4bab8facc85..e6c593204ca 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -20,6 +20,7 @@ allow-unauthenticated = [
     "regression-*",
     "perf-*",
     "AsyncAwait-OnDeck",
+    "needs-triage",
 ]
 
 [glacier]
@@ -254,6 +255,9 @@ trigger_files = [
 [autolabel."S-waiting-on-review"]
 new_pr = true
 
+[autolabel."needs-triage"]
+new_issue = true
+
 [autolabel."WG-trait-system-refactor"]
 trigger_files = [
     "compiler/rustc_trait_selection/src/solve",