about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md15
-rw-r--r--compiler/rustc_borrowck/src/polonius/dump.rs110
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs7
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/int.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs61
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs35
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs77
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs17
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs7
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs45
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs53
-rw-r--r--compiler/rustc_const_eval/src/interpret/traits.rs3
-rw-r--r--compiler/rustc_const_eval/src/lib.rs9
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/collect/dump.rs82
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs94
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs13
-rw-r--r--compiler/rustc_infer/src/infer/at.rs24
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs91
-rw-r--r--compiler/rustc_lint/src/multiple_supertrait_upcastable.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp217
-rw-r--r--compiler/rustc_middle/src/middle/resolve_bound_vars.rs15
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs22
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/query/keys.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs47
-rw-r--r--compiler/rustc_middle/src/ty/consts/valtree.rs61
-rw-r--r--compiler/rustc_middle/src/ty/context.rs26
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs7
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs52
-rw-r--r--compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs18
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs17
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs3
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs6
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs22
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs10
-rw-r--r--compiler/rustc_session/src/code_stats.rs60
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs9
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs23
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs7
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs11
-rw-r--r--compiler/rustc_target/src/asm/mod.rs13
-rw-r--r--compiler/rustc_target/src/spec/json.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/messages.ftl2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs175
-rw-r--r--compiler/rustc_transmute/src/lib.rs8
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs6
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs19
-rw-r--r--compiler/rustc_type_ir/src/const_kind.rs4
-rw-r--r--compiler/rustc_type_ir/src/fast_reject.rs4
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs5
-rw-r--r--compiler/rustc_type_ir/src/interner.rs3
-rw-r--r--compiler/rustc_type_ir/src/relate.rs4
-rw-r--r--library/core/src/hint.rs4
-rw-r--r--library/core/src/intrinsics/mod.rs1
-rw-r--r--library/core/src/mem/maybe_uninit.rs5
-rw-r--r--library/core/src/num/f128.rs6
-rw-r--r--library/core/src/num/f16.rs6
-rw-r--r--library/core/src/num/f32.rs6
-rw-r--r--library/core/src/num/f64.rs6
-rw-r--r--library/core/src/prelude/common.rs3
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/std/src/fs.rs57
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs50
-rw-r--r--library/std/src/sys/path/mod.rs8
-rw-r--r--library/std/src/sys/path/uefi.rs105
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs3
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs28
-rw-r--r--src/ci/github-actions/jobs.yml6
-rw-r--r--src/doc/rustc-dev-guide/src/building/new-target.md5
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-debugging.md2
-rw-r--r--src/doc/rustc/src/target-tier-policy.md11
-rw-r--r--src/doc/rustdoc/src/unstable-features.md64
-rw-r--r--src/librustdoc/clean/utils.rs6
-rw-r--r--src/librustdoc/config.rs60
-rw-r--r--src/librustdoc/doctest.rs51
-rw-r--r--src/librustdoc/doctest/extracted.rs141
-rw-r--r--src/librustdoc/lib.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs5
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs2
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.rs52
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.stdout2
-rw-r--r--src/tools/opt-dist/src/main.rs12
-rw-r--r--tests/codegen/addr-of-mutate.rs6
-rw-r--r--tests/codegen/asm/bpf-clobbers.rs31
-rw-r--r--tests/codegen/cast-target-abi.rs2
-rw-r--r--tests/codegen/function-arguments.rs4
-rw-r--r--tests/codegen/i128-x86-align.rs21
-rw-r--r--tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs4
-rw-r--r--tests/codegen/packed.rs4
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64d-abi.rs2
-rw-r--r--tests/crashes/131102.rs4
-rw-r--r--tests/run-make/target-specs/require-explicit-cpu.json11
-rw-r--r--tests/run-make/target-specs/rmake.rs13
-rw-r--r--tests/rustdoc-ui/coverage/html.stderr2
-rw-r--r--tests/rustdoc-ui/doctest-output.rs1
-rw-r--r--tests/rustdoc-ui/doctest-output.stderr2
-rw-r--r--tests/rustdoc-ui/extract-doctests.rs15
-rw-r--r--tests/rustdoc-ui/extract-doctests.stdout1
-rw-r--r--tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs (renamed from tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs)0
-rw-r--r--tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs (renamed from tests/rustdoc/intra-doc/issue-104145.rs)3
-rw-r--r--tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs (renamed from tests/rustdoc/intra-doc/issue-103463.rs)3
-rw-r--r--tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr2
-rw-r--r--tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr2
-rw-r--r--tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs (renamed from tests/rustdoc/inline_cross/issue-28480.rs)5
-rw-r--r--tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs (renamed from tests/rustdoc/inline_cross/issue-31948-1.rs)13
-rw-r--r--tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs (renamed from tests/rustdoc/inline_cross/issue-31948-2.rs)13
-rw-r--r--tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs (renamed from tests/rustdoc/inline_cross/issue-31948.rs)17
-rw-r--r--tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs (renamed from tests/rustdoc/inline_cross/issue-32881.rs)5
-rw-r--r--tests/rustdoc/inline_cross/impl-ref-33113.rs (renamed from tests/rustdoc/inline_cross/issue-33113.rs)5
-rw-r--r--tests/rustdoc/inline_cross/rustc-private-76736-1.rs (renamed from tests/rustdoc/inline_cross/issue-76736-1.rs)2
-rw-r--r--tests/rustdoc/inline_cross/rustc-private-76736-2.rs (renamed from tests/rustdoc/inline_cross/issue-76736-2.rs)2
-rw-r--r--tests/rustdoc/inline_cross/rustc-private-76736-3.rs (renamed from tests/rustdoc/inline_cross/issue-76736-3.rs)2
-rw-r--r--tests/rustdoc/inline_cross/rustc-private-76736-4.rs (renamed from tests/rustdoc/inline_cross/issue-76736-4.rs)2
-rw-r--r--tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html (renamed from tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html)0
-rw-r--r--tests/rustdoc/inline_cross/self-sized-bounds-24183.rs (renamed from tests/rustdoc/inline_cross/issue-24183.rs)1
-rw-r--r--tests/rustdoc/inline_local/doc-no-inline-32343.rs (renamed from tests/rustdoc/inline_local/issue-32343.rs)13
-rw-r--r--tests/rustdoc/inline_local/pub-re-export-28537.rs (renamed from tests/rustdoc/inline_local/issue-28537.rs)7
-rw-r--r--tests/rustdoc/intra-doc/enum-self-82209.rs (renamed from tests/rustdoc/intra-doc/issue-82209.rs)2
-rw-r--r--tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs (renamed from tests/rustdoc/intra-doc/issue-108459.rs)11
-rw-r--r--tests/rustdoc/intra-doc/same-name-different-crates-66159.rs (renamed from tests/rustdoc/intra-doc/issue-66159.rs)5
-rw-r--r--tests/ui/associated-consts/associated-const-in-trait.stderr4
-rw-r--r--tests/ui/associated-item/issue-48027.stderr2
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.stderr2
-rw-r--r--tests/ui/async-await/in-trait/dyn-compatibility.stderr2
-rw-r--r--tests/ui/async-await/inference_var_self_argument.stderr2
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr2
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-102768.stderr2
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.rs11
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.stderr43
-rw-r--r--tests/ui/consts/const-slice-array-deref.rs9
-rw-r--r--tests/ui/consts/const-slice-array-deref.stderr33
-rw-r--r--tests/ui/consts/large_const_alloc.rs2
-rw-r--r--tests/ui/consts/large_const_alloc.stderr4
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs2
-rw-r--r--tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr2
-rw-r--r--tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr2
-rw-r--r--tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr6
-rw-r--r--tests/ui/dyn-compatibility/associated-consts.curr.stderr4
-rw-r--r--tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr2
-rw-r--r--tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr4
-rw-r--r--tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr2
-rw-r--r--tests/ui/dyn-compatibility/bounds.stderr2
-rw-r--r--tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr2
-rw-r--r--tests/ui/dyn-compatibility/generics.curr.stderr10
-rw-r--r--tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr4
-rw-r--r--tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr4
-rw-r--r--tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr6
-rw-r--r--tests/ui/dyn-compatibility/mentions-Self.curr.stderr8
-rw-r--r--tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr4
-rw-r--r--tests/ui/dyn-compatibility/missing-assoc-type.stderr2
-rw-r--r--tests/ui/dyn-compatibility/no-static.curr.stderr6
-rw-r--r--tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/dyn-compatibility/sized-2.curr.stderr4
-rw-r--r--tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/dyn-compatibility/sized.curr.stderr4
-rw-r--r--tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr2
-rw-r--r--tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr2
-rw-r--r--tests/ui/dyn-compatibility/taint-const-eval.curr.stderr6
-rw-r--r--tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr6
-rw-r--r--tests/ui/error-codes/E0038.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr10
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr2
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path.stderr6
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr4
-rw-r--r--tests/ui/generic-associated-types/issue-67510-pass.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-67510.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-71176.stderr6
-rw-r--r--tests/ui/generic-associated-types/issue-76535.stderr4
-rw-r--r--tests/ui/generic-associated-types/issue-78671.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-79422.stderr4
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait2.rs3
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait2.stderr2
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.stderr2
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr2
-rw-r--r--tests/ui/generic-associated-types/trait-objects.stderr6
-rw-r--r--tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr4
-rw-r--r--tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr6
-rw-r--r--tests/ui/impl-trait/in-trait/dyn-compatibility.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr2
-rw-r--r--tests/ui/issues/issue-18959.stderr10
-rw-r--r--tests/ui/issues/issue-19380.stderr6
-rw-r--r--tests/ui/issues/issue-26056.stderr2
-rw-r--r--tests/ui/issues/issue-50781.stderr6
-rw-r--r--tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr4
-rw-r--r--tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/resolve/issue-3907-2.stderr2
-rw-r--r--tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr4
-rw-r--r--tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr2
-rw-r--r--tests/ui/statics/unsizing-wfcheck-issue-127299.stderr6
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr4
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr4
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr4
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr2
-rw-r--r--tests/ui/suggestions/issue-116434-2015.stderr4
-rw-r--r--tests/ui/suggestions/issue-98500.stderr2
-rw-r--r--tests/ui/traits/alias/generic-default-in-dyn.stderr4
-rw-r--r--tests/ui/traits/alias/object-fail.stderr2
-rw-r--r--tests/ui/traits/alias/self-in-const-generics.stderr2
-rw-r--r--tests/ui/traits/alias/self-in-generics.stderr2
-rw-r--r--tests/ui/traits/issue-20692.stderr4
-rw-r--r--tests/ui/traits/issue-28576.stderr2
-rw-r--r--tests/ui/traits/issue-38404.stderr6
-rw-r--r--tests/ui/traits/issue-38604.stderr4
-rw-r--r--tests/ui/traits/issue-72410.stderr2
-rw-r--r--tests/ui/traits/item-privacy.stderr2
-rw-r--r--tests/ui/traits/missing-for-type-in-impl.e2015.stderr2
-rw-r--r--tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr6
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs (renamed from tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs)0
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr (renamed from tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr)0
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs (renamed from tests/ui/type-alias-impl-trait/non-lifetime-binder.rs)0
-rw-r--r--tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr (renamed from tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr)0
-rw-r--r--tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr4
-rw-r--r--tests/ui/traits/object/macro-matcher.stderr2
-rw-r--r--tests/ui/traits/object/print_vtable_sizes.rs62
-rw-r--r--tests/ui/traits/object/print_vtable_sizes.stdout11
-rw-r--r--tests/ui/traits/object/safety.stderr4
-rw-r--r--tests/ui/traits/sized-coniductive.rs14
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs23
-rw-r--r--tests/ui/traits/solver-cycles/129541-recursive-struct.rs5
-rw-r--r--tests/ui/traits/test-2.stderr6
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs27
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr26
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs26
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout1
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs37
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr26
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs34
-rw-r--r--tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout1
-rw-r--r--tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs30
-rw-r--r--tests/ui/traits/vtable/multiple-markers.rs33
-rw-r--r--tests/ui/traits/vtable/multiple-markers.stderr32
-rw-r--r--tests/ui/traits/vtable/vtable-diamond.rs31
-rw-r--r--tests/ui/traits/vtable/vtable-diamond.stderr45
-rw-r--r--tests/ui/traits/vtable/vtable-dyn-incompatible.rs7
-rw-r--r--tests/ui/traits/vtable/vtable-dyn-incompatible.stderr16
-rw-r--r--tests/ui/traits/vtable/vtable-multi-level.rs99
-rw-r--r--tests/ui/traits/vtable/vtable-multi-level.stderr197
-rw-r--r--tests/ui/traits/vtable/vtable-multiple.rs22
-rw-r--r--tests/ui/traits/vtable/vtable-multiple.stderr33
-rw-r--r--tests/ui/traits/vtable/vtable-vacant.rs15
-rw-r--r--tests/ui/traits/vtable/vtable-vacant.stderr22
-rw-r--r--tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr2
-rw-r--r--tests/ui/wf/issue-87495.stderr2
-rw-r--r--tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr6
-rw-r--r--tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr6
-rw-r--r--tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr4
-rw-r--r--tests/ui/wf/wf-dyn-incompatible.stderr2
-rw-r--r--tests/ui/wf/wf-fn-where-clause.stderr2
-rw-r--r--tests/ui/wf/wf-trait-default-fn-ret.rs3
-rw-r--r--tests/ui/wf/wf-trait-default-fn-ret.stderr4
304 files changed, 2643 insertions, 1550 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 2da6ed3f100..e0175db7ec8 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,18 @@
+Version 1.84.1 (2025-01-30)
+==========================
+
+<a id="1.84.1"></a>
+
+- [Fix ICE 132920 in duplicate-crate diagnostics.](https://github.com/rust-lang/rust/pull/133304/)
+- [Fix errors for overlapping impls in incremental rebuilds.](https://github.com/rust-lang/rust/pull/133828/)
+- [Fix slow compilation related to the next-generation trait solver.](https://github.com/rust-lang/rust/pull/135618/)
+- [Fix debuginfo when LLVM's location discriminator value limit is exceeded.](https://github.com/rust-lang/rust/pull/135643/)
+- Fixes for building Rust from source:
+  - [Only try to distribute `llvm-objcopy` if llvm tools are enabled.](https://github.com/rust-lang/rust/pull/134240/)
+  - [Add Profile Override for Non-Git Sources.](https://github.com/rust-lang/rust/pull/135433/)
+  - [Resolve symlinks of LLVM tool binaries before copying them.](https://github.com/rust-lang/rust/pull/135585/)
+  - [Make it possible to use ci-rustc on tarball sources.](https://github.com/rust-lang/rust/pull/135722/)
+
 Version 1.84.0 (2025-01-09)
 ==========================
 
diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs
index f71e6f3e6f3..6d32ee17f4c 100644
--- a/compiler/rustc_borrowck/src/polonius/dump.rs
+++ b/compiler/rustc_borrowck/src/polonius/dump.rs
@@ -1,17 +1,19 @@
 use std::io;
 
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_index::IndexVec;
 use rustc_middle::mir::pretty::{
     PassWhere, PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer,
 };
-use rustc_middle::mir::{Body, ClosureRegionRequirements};
+use rustc_middle::mir::{Body, ClosureRegionRequirements, Location};
 use rustc_middle::ty::{RegionVid, TyCtxt};
+use rustc_mir_dataflow::points::PointIndex;
 use rustc_session::config::MirIncludeSpans;
 
 use crate::borrow_set::BorrowSet;
 use crate::constraints::OutlivesConstraint;
 use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
+use crate::region_infer::values::LivenessValues;
 use crate::type_check::Locations;
 use crate::{BorrowckInferCtxt, RegionInferenceContext};
 
@@ -80,14 +82,27 @@ fn emit_polonius_dump<'tcx>(
         body,
         regioncx,
         borrow_set,
-        localized_outlives_constraints,
+        &localized_outlives_constraints,
         closure_region_requirements,
         out,
     )?;
     writeln!(out, "</code></pre>")?;
     writeln!(out, "</div>")?;
 
-    // Section 2: mermaid visualization of the CFG.
+    // Section 2: mermaid visualization of the polonius constraint graph.
+    writeln!(out, "<div>")?;
+    writeln!(out, "Polonius constraint graph")?;
+    writeln!(out, "<pre class='mermaid'>")?;
+    let edge_count = emit_mermaid_constraint_graph(
+        borrow_set,
+        regioncx.liveness_constraints(),
+        &localized_outlives_constraints,
+        out,
+    )?;
+    writeln!(out, "</pre>")?;
+    writeln!(out, "</div>")?;
+
+    // Section 3: mermaid visualization of the CFG.
     writeln!(out, "<div>")?;
     writeln!(out, "Control-flow graph")?;
     writeln!(out, "<pre class='mermaid'>")?;
@@ -95,7 +110,7 @@ fn emit_polonius_dump<'tcx>(
     writeln!(out, "</pre>")?;
     writeln!(out, "</div>")?;
 
-    // Section 3: mermaid visualization of the NLL region graph.
+    // Section 4: mermaid visualization of the NLL region graph.
     writeln!(out, "<div>")?;
     writeln!(out, "NLL regions")?;
     writeln!(out, "<pre class='mermaid'>")?;
@@ -103,7 +118,7 @@ fn emit_polonius_dump<'tcx>(
     writeln!(out, "</pre>")?;
     writeln!(out, "</div>")?;
 
-    // Section 4: mermaid visualization of the NLL SCC graph.
+    // Section 5: mermaid visualization of the NLL SCC graph.
     writeln!(out, "<div>")?;
     writeln!(out, "NLL SCCs")?;
     writeln!(out, "<pre class='mermaid'>")?;
@@ -117,7 +132,11 @@ fn emit_polonius_dump<'tcx>(
         "<script src='https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js'></script>"
     )?;
     writeln!(out, "<script>")?;
-    writeln!(out, "mermaid.initialize({{ startOnLoad: false, maxEdges: 100 }});")?;
+    writeln!(
+        out,
+        "mermaid.initialize({{ startOnLoad: false, maxEdges: {} }});",
+        edge_count.max(100),
+    )?;
     writeln!(out, "mermaid.run({{ querySelector: '.mermaid' }})")?;
     writeln!(out, "</script>")?;
     writeln!(out, "</body>")?;
@@ -132,7 +151,7 @@ fn emit_html_mir<'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
-    localized_outlives_constraints: LocalizedOutlivesConstraintSet,
+    localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
     closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
     out: &mut dyn io::Write,
 ) -> io::Result<()> {
@@ -160,7 +179,7 @@ fn emit_html_mir<'tcx>(
                 regioncx,
                 closure_region_requirements,
                 borrow_set,
-                &localized_outlives_constraints,
+                localized_outlives_constraints,
                 pass_where,
                 out,
             )
@@ -392,3 +411,76 @@ fn emit_mermaid_nll_sccs<'tcx>(
 
     Ok(())
 }
+
+/// Emits a mermaid flowchart of the polonius localized outlives constraints, with subgraphs per
+/// region, and loan introductions.
+fn emit_mermaid_constraint_graph<'tcx>(
+    borrow_set: &BorrowSet<'tcx>,
+    liveness: &LivenessValues,
+    localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
+    out: &mut dyn io::Write,
+) -> io::Result<usize> {
+    let location_name = |location: Location| {
+        // A MIR location looks like `bb5[2]`. As that is not a syntactically valid mermaid node id,
+        // transform it into `BB5_2`.
+        format!("BB{}_{}", location.block.index(), location.statement_index)
+    };
+    let region_name = |region: RegionVid| format!("'{}", region.index());
+    let node_name = |region: RegionVid, point: PointIndex| {
+        let location = liveness.location_from_point(point);
+        format!("{}_{}", region_name(region), location_name(location))
+    };
+
+    // The mermaid chart type: a top-down flowchart, which supports subgraphs.
+    writeln!(out, "flowchart TD")?;
+
+    // The loans subgraph: a node per loan.
+    writeln!(out, "    subgraph \"Loans\"")?;
+    for loan_idx in 0..borrow_set.len() {
+        writeln!(out, "        L{loan_idx}")?;
+    }
+    writeln!(out, "    end\n")?;
+
+    // And an edge from that loan node to where it enters the constraint graph.
+    for (loan_idx, loan) in borrow_set.iter_enumerated() {
+        writeln!(
+            out,
+            "    L{} --> {}_{}",
+            loan_idx.index(),
+            region_name(loan.region),
+            location_name(loan.reserve_location),
+        )?;
+    }
+    writeln!(out, "")?;
+
+    // The regions subgraphs containing the region/point nodes.
+    let mut points_per_region: FxIndexMap<RegionVid, FxIndexSet<PointIndex>> =
+        FxIndexMap::default();
+    for constraint in &localized_outlives_constraints.outlives {
+        points_per_region.entry(constraint.source).or_default().insert(constraint.from);
+        points_per_region.entry(constraint.target).or_default().insert(constraint.to);
+    }
+    for (region, points) in points_per_region {
+        writeln!(out, "    subgraph \"{}\"", region_name(region))?;
+        for point in points {
+            writeln!(out, "        {}", node_name(region, point))?;
+        }
+        writeln!(out, "    end\n")?;
+    }
+
+    // The constraint graph edges.
+    for constraint in &localized_outlives_constraints.outlives {
+        // FIXME: add killed loans and constraint kind as edge labels.
+        writeln!(
+            out,
+            "    {} --> {}",
+            node_name(constraint.source, constraint.from),
+            node_name(constraint.target, constraint.to),
+        )?;
+    }
+
+    // Return the number of edges: this is the biggest graph in the dump and its edge count will be
+    // mermaid's max edge count to support.
+    let edge_count = borrow_set.len() + localized_outlives_constraints.outlives.len();
+    Ok(edge_count)
+}
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index 3e7b81a96b6..425b2adf32a 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -6,7 +6,7 @@ use cranelift_module::*;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint};
-use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt};
+use rustc_middle::ty::{ExistentialTraitRef, ScalarInt};
 
 use crate::prelude::*;
 
@@ -167,7 +167,9 @@ pub(crate) fn codegen_const_value<'tcx>(
                             &mut fx.constants_cx,
                             fx.module,
                             ty,
-                            dyn_ty.principal(),
+                            dyn_ty.principal().map(|principal| {
+                                fx.tcx.instantiate_bound_regions_with_erased(principal)
+                            }),
                         );
                         let local_data_id =
                             fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
@@ -243,7 +245,7 @@ pub(crate) fn data_id_for_vtable<'tcx>(
     cx: &mut ConstantCx,
     module: &mut dyn Module,
     ty: Ty<'tcx>,
-    trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
+    trait_ref: Option<ExistentialTraitRef<'tcx>>,
 ) -> DataId {
     let alloc_id = tcx.vtable_allocation((ty, trait_ref));
     data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
@@ -460,9 +462,15 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                 GlobalAlloc::Memory(target_alloc) => {
                     data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability)
                 }
-                GlobalAlloc::VTable(ty, dyn_ty) => {
-                    data_id_for_vtable(tcx, cx, module, ty, dyn_ty.principal())
-                }
+                GlobalAlloc::VTable(ty, dyn_ty) => data_id_for_vtable(
+                    tcx,
+                    cx,
+                    module,
+                    ty,
+                    dyn_ty
+                        .principal()
+                        .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
+                ),
                 GlobalAlloc::Static(def_id) => {
                     if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
                     {
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 6d71b8e8aba..d682efd19aa 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -129,12 +129,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 return;
             }
 
-            let idx = generic_args[2]
-                .expect_const()
-                .try_to_valtree()
-                .expect("expected monomorphic const in codegen")
-                .0
-                .unwrap_branch();
+            let idx = generic_args[2].expect_const().to_value().valtree.unwrap_branch();
 
             assert_eq!(x.layout(), y.layout());
             let layout = x.layout();
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 2843e5bbdfb..f8bbb214920 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -61,7 +61,12 @@ pub(crate) fn unsized_info<'tcx>(
                 old_info
             }
         }
-        (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()),
+        (_, ty::Dynamic(data, ..)) => crate::vtable::get_vtable(
+            fx,
+            source,
+            data.principal()
+                .map(|principal| fx.tcx.instantiate_bound_regions_with_erased(principal)),
+        ),
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index 82b6178be9d..a460023b59c 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -90,7 +90,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
 pub(crate) fn get_vtable<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     ty: Ty<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
 ) -> Value {
     let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref);
     let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index bd5d6ba387c..20a3482aaa2 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -234,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                     GlobalAlloc::VTable(ty, dyn_ty) => {
                         let alloc = self
                             .tcx
-                            .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
+                            .global_alloc(self.tcx.vtable_allocation((
+                                ty,
+                                dyn_ty.principal().map(|principal| {
+                                    self.tcx.instantiate_bound_regions_with_erased(principal)
+                                }),
+                            )))
                             .unwrap_memory();
                         let init = const_alloc_to_gcc(self, alloc);
                         self.static_addr_of(init, alloc.inner().align, None)
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 30732c74eb3..570ef938dc4 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
     LayoutOfHelpers,
 };
-use rustc_middle::ty::{self, Instance, PolyExistentialTraitRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::source_map::respan;
 use rustc_span::{DUMMY_SP, Span};
@@ -90,7 +90,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
     pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
     /// Cache generated vtables
     pub vtables:
-        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
+        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
 
     // TODO(antoyo): improve the SSA API to not require those.
     /// Mapping from function pointer type to indexes of on stack parameters.
@@ -401,7 +401,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
 impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn vtables(
         &self,
-    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
+    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
         &self.vtables
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index 4b84b1dbfd3..86d3de225f7 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::{self, Body, SourceScope};
-use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
+use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
 use rustc_session::config::DebugInfo;
 use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol};
 use rustc_target::abi::Size;
@@ -214,7 +214,7 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn create_vtable_debuginfo(
         &self,
         _ty: Ty<'tcx>,
-        _trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+        _trait_ref: Option<ExistentialTraitRef<'tcx>>,
         _vtable: Self::Value,
     ) {
         // TODO(antoyo)
diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs
index bfe73c38435..58a26801b67 100644
--- a/compiler/rustc_codegen_gcc/tests/run/int.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/int.rs
@@ -3,8 +3,6 @@
 // Run-time:
 //   status: 0
 
-#![feature(const_black_box)]
-
 /*
  * Code
  */
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index d2de62b17f0..2d007416263 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1325,7 +1325,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
 impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
     fn get_static(&mut self, def_id: DefId) -> &'ll Value {
         // Forward to the `get_static` method of `CodegenCx`
-        self.cx().get_static(def_id)
+        let s = self.cx().get_static(def_id);
+        // Cast to default address space if globals are in a different addrspace
+        self.cx().const_pointercast(s, self.type_ptr())
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index b4e9b9f44f4..8c94a46ebf3 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -225,6 +225,8 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                     llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
                 }
                 llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
+                // Cast to default address space if globals are in a different addrspace
+                let g = self.const_pointercast(g, self.type_ptr());
                 (s.to_owned(), g)
             })
             .1;
@@ -289,7 +291,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                             let alloc = alloc.inner();
                             let value = match alloc.mutability {
                                 Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
-                                _ => self.static_addr_of(init, alloc.align, None),
+                                _ => self.static_addr_of_impl(init, alloc.align, None),
                             };
                             if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty()
                             {
@@ -312,10 +314,15 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                     GlobalAlloc::VTable(ty, dyn_ty) => {
                         let alloc = self
                             .tcx
-                            .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
+                            .global_alloc(self.tcx.vtable_allocation((
+                                ty,
+                                dyn_ty.principal().map(|principal| {
+                                    self.tcx.instantiate_bound_regions_with_erased(principal)
+                                }),
+                            )))
                             .unwrap_memory();
                         let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
-                        let value = self.static_addr_of(init, alloc.inner().align, None);
+                        let value = self.static_addr_of_impl(init, alloc.inner().align, None);
                         (value, AddressSpace::DATA)
                     }
                     GlobalAlloc::Static(def_id) => {
@@ -327,7 +334,8 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                 let llval = unsafe {
                     llvm::LLVMConstInBoundsGEP2(
                         self.type_i8(),
-                        self.const_bitcast(base_addr, self.type_ptr_ext(base_addr_space)),
+                        // Cast to the required address space if necessary
+                        self.const_pointercast(base_addr, self.type_ptr_ext(base_addr_space)),
                         &self.const_usize(offset.bytes()),
                         1,
                     )
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index c7114480d8b..771ebf2057f 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -210,6 +210,14 @@ impl<'ll> CodegenCx<'ll, '_> {
         unsafe { llvm::LLVMConstBitCast(val, ty) }
     }
 
+    pub(crate) fn const_pointercast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
+        unsafe { llvm::LLVMConstPointerCast(val, ty) }
+    }
+
+    /// Create a global variable.
+    ///
+    /// The returned global variable is a pointer in the default address space for globals.
+    /// Fails if a symbol with the given name already exists.
     pub(crate) fn static_addr_of_mut(
         &self,
         cv: &'ll Value,
@@ -233,6 +241,34 @@ impl<'ll> CodegenCx<'ll, '_> {
         gv
     }
 
+    /// Create a global constant.
+    ///
+    /// The returned global variable is a pointer in the default address space for globals.
+    pub(crate) fn static_addr_of_impl(
+        &self,
+        cv: &'ll Value,
+        align: Align,
+        kind: Option<&str>,
+    ) -> &'ll Value {
+        if let Some(&gv) = self.const_globals.borrow().get(&cv) {
+            unsafe {
+                // Upgrade the alignment in cases where the same constant is used with different
+                // alignment requirements
+                let llalign = align.bytes() as u32;
+                if llalign > llvm::LLVMGetAlignment(gv) {
+                    llvm::LLVMSetAlignment(gv, llalign);
+                }
+            }
+            return gv;
+        }
+        let gv = self.static_addr_of_mut(cv, align, kind);
+        unsafe {
+            llvm::LLVMSetGlobalConstant(gv, True);
+        }
+        self.const_globals.borrow_mut().insert(cv, gv);
+        gv
+    }
+
     #[instrument(level = "debug", skip(self))]
     pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value {
         let instance = Instance::mono(self.tcx, def_id);
@@ -505,24 +541,15 @@ impl<'ll> CodegenCx<'ll, '_> {
 }
 
 impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
+    /// Get a pointer to a global variable.
+    ///
+    /// The pointer will always be in the default address space. If global variables default to a
+    /// different address space, an addrspacecast is inserted.
     fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value {
-        if let Some(&gv) = self.const_globals.borrow().get(&cv) {
-            unsafe {
-                // Upgrade the alignment in cases where the same constant is used with different
-                // alignment requirements
-                let llalign = align.bytes() as u32;
-                if llalign > llvm::LLVMGetAlignment(gv) {
-                    llvm::LLVMSetAlignment(gv, llalign);
-                }
-            }
-            return gv;
-        }
-        let gv = self.static_addr_of_mut(cv, align, kind);
-        unsafe {
-            llvm::LLVMSetGlobalConstant(gv, True);
-        }
-        self.const_globals.borrow_mut().insert(cv, gv);
-        gv
+        let gv = self.static_addr_of_impl(cv, align, kind);
+        // static_addr_of_impl returns the bare global variable, which might not be in the default
+        // address space. Cast to the default address space if necessary.
+        self.const_pointercast(gv, self.type_ptr())
     }
 
     fn codegen_static(&self, def_id: DefId) {
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 79381f35a3c..ba4fd75fb94 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -77,8 +77,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
     /// Cache instances of monomorphic and polymorphic items
     pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
     /// Cache generated vtables
-    pub vtables:
-        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
+    pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>,
     /// Cache of constant strings,
     pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>,
 
@@ -663,15 +662,14 @@ impl<'ll> SimpleCx<'ll> {
 impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn vtables(
         &self,
-    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>
-    {
+    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> {
         &self.vtables
     }
 
     fn apply_vcall_visibility_metadata(
         &self,
         ty: Ty<'tcx>,
-        poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+        poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
         vtable: &'ll Value,
     ) {
         apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 2a1a12f3ce5..3a0c7f007bd 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{
-    self, AdtKind, CoroutineArgsExt, Instance, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
+    self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
 };
 use rustc_session::config::{self, DebugInfo, Lto};
 use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
@@ -1399,7 +1399,7 @@ pub(crate) fn build_global_var_di_node<'ll>(
 fn build_vtable_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     ty: Ty<'tcx>,
-    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
 ) -> &'ll DIType {
     let tcx = cx.tcx;
 
@@ -1487,10 +1487,30 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
     .di_node
 }
 
+/// Get the global variable for the vtable.
+///
+/// When using global variables, we may have created an addrspacecast to get a pointer to the
+/// default address space if global variables are created in a different address space.
+/// For modifying the vtable, we need the real global variable. This function accepts either a
+/// global variable (which is simply returned), or an addrspacecast constant expression.
+/// If the given value is an addrspacecast, the cast is removed and the global variable behind
+/// the cast is returned.
+fn find_vtable_behind_cast<'ll>(vtable: &'ll Value) -> &'ll Value {
+    // The vtable is a global variable, which may be behind an addrspacecast.
+    unsafe {
+        if let Some(c) = llvm::LLVMIsAConstantExpr(vtable) {
+            if llvm::LLVMGetConstOpcode(c) == llvm::Opcode::AddrSpaceCast {
+                return llvm::LLVMGetOperand(c, 0).unwrap();
+            }
+        }
+    }
+    vtable
+}
+
 pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     ty: Ty<'tcx>,
-    trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+    trait_ref: Option<ExistentialTraitRef<'tcx>>,
     vtable: &'ll Value,
 ) {
     // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
@@ -1507,9 +1527,11 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
 
     let Some(trait_ref) = trait_ref else { return };
 
+    // Unwrap potential addrspacecast
+    let vtable = find_vtable_behind_cast(vtable);
     let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
     let trait_ref_self = cx.tcx.erase_regions(trait_ref_self);
-    let trait_def_id = trait_ref_self.def_id();
+    let trait_def_id = trait_ref_self.def_id;
     let trait_vis = cx.tcx.visibility(trait_def_id);
 
     let cgus = cx.sess().codegen_units().as_usize();
@@ -1568,7 +1590,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
 pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     ty: Ty<'tcx>,
-    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
     vtable: &'ll Value,
 ) {
     if cx.dbg_cx.is_none() {
@@ -1580,6 +1602,9 @@ pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
         return;
     }
 
+    // Unwrap potential addrspacecast
+    let vtable = find_vtable_behind_cast(vtable);
+
     // When full debuginfo is enabled, we want to try and prevent vtables from being
     // merged. Otherwise debuggers will have a hard time mapping from dyn pointer
     // to concrete type.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
index a37e719d43f..af1d503ad6a 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_macros::HashStable;
 use rustc_middle::bug;
-use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt};
 
 use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
 use crate::common::{AsCCharPtr, CodegenCx};
@@ -44,7 +44,7 @@ pub(super) enum UniqueTypeId<'tcx> {
     /// The ID for the additional wrapper struct type describing an enum variant in CPP-like mode.
     VariantStructTypeCppLikeWrapper(Ty<'tcx>, VariantIdx, private::HiddenZst),
     /// The ID of the artificial type we create for VTables.
-    VTableTy(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>, private::HiddenZst),
+    VTableTy(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>, private::HiddenZst),
 }
 
 impl<'tcx> UniqueTypeId<'tcx> {
@@ -88,7 +88,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
     pub(crate) fn for_vtable_ty(
         tcx: TyCtxt<'tcx>,
         self_type: Ty<'tcx>,
-        implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
+        implemented_trait: Option<ExistentialTraitRef<'tcx>>,
     ) -> Self {
         assert_eq!(
             self_type,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 5089560784a..b1ce52667bd 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -588,7 +588,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn create_vtable_debuginfo(
         &self,
         ty: Ty<'tcx>,
-        trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+        trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
         vtable: Self::Value,
     ) {
         metadata::create_vtable_di_node(self, ty, trait_ref, vtable)
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index eab4a9f30c9..43d6ccfcb4a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1329,7 +1329,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     }
 
     if name == sym::simd_shuffle_generic {
-        let idx = fn_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
+        let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch();
         let n = idx.len() as u64;
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 009d15a932f..cc7c5231aca 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -661,6 +661,79 @@ pub enum MemoryEffects {
     InaccessibleMemOnly,
 }
 
+/// LLVMOpcode
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(C)]
+pub enum Opcode {
+    Ret = 1,
+    Br = 2,
+    Switch = 3,
+    IndirectBr = 4,
+    Invoke = 5,
+    Unreachable = 7,
+    CallBr = 67,
+    FNeg = 66,
+    Add = 8,
+    FAdd = 9,
+    Sub = 10,
+    FSub = 11,
+    Mul = 12,
+    FMul = 13,
+    UDiv = 14,
+    SDiv = 15,
+    FDiv = 16,
+    URem = 17,
+    SRem = 18,
+    FRem = 19,
+    Shl = 20,
+    LShr = 21,
+    AShr = 22,
+    And = 23,
+    Or = 24,
+    Xor = 25,
+    Alloca = 26,
+    Load = 27,
+    Store = 28,
+    GetElementPtr = 29,
+    Trunc = 30,
+    ZExt = 31,
+    SExt = 32,
+    FPToUI = 33,
+    FPToSI = 34,
+    UIToFP = 35,
+    SIToFP = 36,
+    FPTrunc = 37,
+    FPExt = 38,
+    PtrToInt = 39,
+    IntToPtr = 40,
+    BitCast = 41,
+    AddrSpaceCast = 60,
+    ICmp = 42,
+    FCmp = 43,
+    PHI = 44,
+    Call = 45,
+    Select = 46,
+    UserOp1 = 47,
+    UserOp2 = 48,
+    VAArg = 49,
+    ExtractElement = 50,
+    InsertElement = 51,
+    ShuffleVector = 52,
+    ExtractValue = 53,
+    InsertValue = 54,
+    Freeze = 68,
+    Fence = 55,
+    AtomicCmpXchg = 56,
+    AtomicRMW = 57,
+    Resume = 58,
+    LandingPad = 59,
+    CleanupRet = 61,
+    CatchRet = 62,
+    CatchPad = 63,
+    CleanupPad = 64,
+    CatchSwitch = 65,
+}
+
 unsafe extern "C" {
     type Opaque;
 }
@@ -991,7 +1064,10 @@ unsafe extern "C" {
     pub fn LLVMConstPtrToInt<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
     pub fn LLVMConstIntToPtr<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
     pub fn LLVMConstBitCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
+    pub fn LLVMConstPointerCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
     pub fn LLVMGetAggregateElement(ConstantVal: &Value, Idx: c_uint) -> Option<&Value>;
+    pub fn LLVMGetConstOpcode(ConstantVal: &Value) -> Opcode;
+    pub fn LLVMIsAConstantExpr(Val: &Value) -> Option<&Value>;
 
     // Operations on global variables, functions, and aliases (globals)
     pub fn LLVMIsDeclaration(Global: &Value) -> Bool;
@@ -1048,6 +1124,7 @@ unsafe extern "C" {
     // Operations on instructions
     pub fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>;
     pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock;
+    pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>;
 
     // Operations on call sites
     pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index de37de09f5a..186b8171dd8 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -30,6 +30,8 @@ codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
 
 codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error}
 
+codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C target-cpu`
+
 codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
 
 codegen_ssa_dlltool_fail_import_library =
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index e438bd70c51..ee98c8c4861 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -25,7 +25,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
 use rustc_span::{DUMMY_SP, Symbol, sym};
-use rustc_trait_selection::infer::at::ToTrace;
 use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
 use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
 use tracing::{debug, info};
@@ -129,14 +128,9 @@ pub fn validate_trivial_unsize<'tcx>(
                     BoundRegionConversionTime::HigherRankedType,
                     hr_source_principal,
                 );
-                let Ok(()) = ocx.eq_trace(
+                let Ok(()) = ocx.eq(
                     &ObligationCause::dummy(),
                     param_env,
-                    ToTrace::to_trace(
-                        &ObligationCause::dummy(),
-                        hr_target_principal,
-                        hr_source_principal,
-                    ),
                     target_principal,
                     source_principal,
                 ) else {
@@ -211,7 +205,12 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 old_info
             }
         }
-        (_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()),
+        (_, ty::Dynamic(data, _, _)) => meth::get_vtable(
+            cx,
+            source,
+            data.principal()
+                .map(|principal| bx.tcx().instantiate_bound_regions_with_erased(principal)),
+        ),
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
     }
 }
@@ -615,6 +614,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         return ongoing_codegen;
     }
 
+    if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() {
+        // The target has no default cpu, but none is set explicitly
+        tcx.dcx().emit_fatal(errors::CpuRequired);
+    }
+
     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
 
     // Run the monomorphization collector and partition the collected items into
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 869798d8be1..05175371591 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -507,7 +507,7 @@ pub enum VTableNameKind {
 pub fn compute_debuginfo_vtable_name<'tcx>(
     tcx: TyCtxt<'tcx>,
     t: Ty<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
     kind: VTableNameKind,
 ) -> String {
     let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
@@ -530,8 +530,8 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
     }
 
     if let Some(trait_ref) = trait_ref {
-        let trait_ref = tcx
-            .normalize_erasing_late_bound_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
+        let trait_ref =
+            tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref);
         push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
         visited.clear();
         push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
@@ -673,25 +673,23 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
         ty::ConstKind::Param(param) => {
             write!(output, "{}", param.name)
         }
-        ty::ConstKind::Value(ty, valtree) => {
-            match ty.kind() {
+        ty::ConstKind::Value(cv) => {
+            match cv.ty.kind() {
                 ty::Int(ity) => {
-                    // FIXME: directly extract the bits from a valtree instead of evaluating an
-                    // already evaluated `Const` in order to get the bits.
-                    let bits = ct
+                    let bits = cv
                         .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
                         .expect("expected monomorphic const in codegen");
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
                     write!(output, "{val}")
                 }
                 ty::Uint(_) => {
-                    let val = ct
+                    let val = cv
                         .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
                         .expect("expected monomorphic const in codegen");
                     write!(output, "{val}")
                 }
                 ty::Bool => {
-                    let val = ct.try_to_bool().expect("expected monomorphic const in codegen");
+                    let val = cv.try_to_bool().expect("expected monomorphic const in codegen");
                     write!(output, "{val}")
                 }
                 _ => {
@@ -703,9 +701,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
                     // avoiding collisions and will make the emitted type names shorter.
                     let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
                         let mut hasher = StableHasher::new();
-                        hcx.while_hashing_spans(false, |hcx| {
-                            (ty, valtree).hash_stable(hcx, &mut hasher)
-                        });
+                        hcx.while_hashing_spans(false, |hcx| cv.hash_stable(hcx, &mut hasher));
                         hasher.finish::<Hash64>()
                     });
 
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 5e684632fb2..f3afb37a9ef 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -524,6 +524,10 @@ pub(crate) struct CheckInstalledVisualStudio;
 pub(crate) struct InsufficientVSCodeProduct;
 
 #[derive(Diagnostic)]
+#[diag(codegen_ssa_cpu_required)]
+pub(crate) struct CpuRequired;
+
+#[derive(Diagnostic)]
 #[diag(codegen_ssa_processing_dymutil_failed)]
 #[note]
 pub(crate) struct ProcessingDymutilFailed {
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 64cd4c38937..399c592432a 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -1,5 +1,5 @@
 use rustc_middle::bug;
-use rustc_middle::ty::{self, GenericArgKind, Ty};
+use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt};
 use rustc_session::config::Lto;
 use rustc_symbol_mangling::typeid_for_trait_ref;
 use rustc_target::callconv::FnAbi;
@@ -72,12 +72,19 @@ impl<'a, 'tcx> VirtualIndex {
 
 /// This takes a valid `self` receiver type and extracts the principal trait
 /// ref of the type. Return `None` if there is no principal trait.
-fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
+fn dyn_trait_in_self<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>,
+) -> Option<ty::ExistentialTraitRef<'tcx>> {
     for arg in ty.peel_refs().walk() {
         if let GenericArgKind::Type(ty) = arg.unpack()
             && let ty::Dynamic(data, _, _) = ty.kind()
         {
-            return data.principal();
+            // FIXME(arbitrary_self_types): This is likely broken for receivers which
+            // have a "non-self" trait objects as a generic argument.
+            return data
+                .principal()
+                .map(|principal| tcx.instantiate_bound_regions_with_erased(principal));
         }
     }
 
@@ -96,7 +103,7 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
 pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     cx: &Cx,
     ty: Ty<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
 ) -> Cx::Value {
     let tcx = cx.tcx();
 
@@ -131,7 +138,7 @@ pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
         && bx.cx().sess().lto() == Lto::Fat
     {
-        if let Some(trait_ref) = dyn_trait_in_self(ty) {
+        if let Some(trait_ref) = dyn_trait_in_self(bx.tcx(), ty) {
             let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap();
             let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
             return func;
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 7676e1e171a..eafc551501c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -43,7 +43,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Const::Ty(_, c) => match c.kind() {
                 // A constant that came from a const generic but was then used as an argument to
                 // old-style simd_shuffle (passing as argument instead of as a generic param).
-                rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)),
+                rustc_type_ir::ConstKind::Value(cv) => return Ok(Ok(cv.valtree)),
                 other => span_bug!(constant.span, "{other:#?}"),
             },
             // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index fe135e911fb..30d77c206a5 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -2,7 +2,7 @@ use std::ops::Range;
 
 use rustc_abi::Size;
 use rustc_middle::mir;
-use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
+use rustc_middle::ty::{ExistentialTraitRef, Instance, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::callconv::FnAbi;
 
@@ -13,7 +13,7 @@ pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
     fn create_vtable_debuginfo(
         &self,
         ty: Ty<'tcx>,
-        trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+        trait_ref: Option<ExistentialTraitRef<'tcx>>,
         vtable: Self::Value,
     );
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index 5b33fd7ab10..4004947b464 100644
--- a/compiler/rustc_codegen_ssa/src/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
@@ -10,11 +10,11 @@ use super::BackendTypes;
 pub trait MiscCodegenMethods<'tcx>: BackendTypes {
     fn vtables(
         &self,
-    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
+    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), Self::Value>>;
     fn apply_vcall_visibility_metadata(
         &self,
         _ty: Ty<'tcx>,
-        _poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+        _poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
         _vtable: Self::Value,
     ) {
     }
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 16ead1b9785..4834fd3d34c 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -634,7 +634,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, place) => {
                 // These are only inserted for slice length, so the place must already be indirect.
                 // This implies we do not have to worry about whether the borrow escapes.
-                assert!(place.is_indirect(), "fake borrows are always indirect");
+                if !place.is_indirect() {
+                    self.tcx.dcx().span_delayed_bug(
+                        self.body.source_info(location).span,
+                        "fake borrows are always indirect",
+                    );
+                }
             }
 
             Rvalue::Cast(
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index e244b50a4b5..5d368b600a0 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -345,7 +345,7 @@ where
         Const::Ty(_, ct)
             if matches!(
                 ct.kind(),
-                ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _)
+                ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_)
             ) =>
         {
             None
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 4ff8aa9a3b4..4d625f76aba 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -272,7 +272,8 @@ pub(crate) fn eval_to_valtree<'tcx>(
 
 /// Converts a `ValTree` to a `ConstValue`, which is needed after mir
 /// construction has finished.
-// FIXME Merge `valtree_to_const_value` and `valtree_into_mplace` into one function
+// FIXME(valtrees): Merge `valtree_to_const_value` and `valtree_into_mplace` into one function
+// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
 #[instrument(skip(tcx), level = "debug", ret)]
 pub fn valtree_to_const_value<'tcx>(
     tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index e6a34193c9d..e2e6e16d8a7 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -5,6 +5,7 @@ use std::borrow::Cow;
 
 use either::{Left, Right};
 use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx};
+use rustc_hir::def_id::DefId;
 use rustc_middle::ty::layout::{FnAbiOf, IntegerExt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef};
 use rustc_middle::{bug, mir, span_bug};
@@ -693,25 +694,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 trace!("Virtual call dispatches to {fn_inst:#?}");
                 // We can also do the lookup based on `def_id` and `dyn_ty`, and check that that
                 // produces the same result.
-                if cfg!(debug_assertions) {
-                    let tcx = *self.tcx;
-
-                    let trait_def_id = tcx.trait_of_item(def_id).unwrap();
-                    let virtual_trait_ref =
-                        ty::TraitRef::from_method(tcx, trait_def_id, instance.args);
-                    let existential_trait_ref =
-                        ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
-                    let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
-
-                    let concrete_method = Instance::expect_resolve_for_vtable(
-                        tcx,
-                        self.typing_env,
-                        def_id,
-                        instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
-                        self.cur_span(),
-                    );
-                    assert_eq!(fn_inst, concrete_method);
-                }
+                self.assert_virtual_instance_matches_concrete(dyn_ty, def_id, instance, fn_inst);
 
                 // Adjust receiver argument. Layout can be any (thin) ptr.
                 let receiver_ty = Ty::new_mut_ptr(self.tcx.tcx, dyn_ty);
@@ -744,6 +727,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         }
     }
 
+    fn assert_virtual_instance_matches_concrete(
+        &self,
+        dyn_ty: Ty<'tcx>,
+        def_id: DefId,
+        virtual_instance: ty::Instance<'tcx>,
+        concrete_instance: ty::Instance<'tcx>,
+    ) {
+        let tcx = *self.tcx;
+
+        let trait_def_id = tcx.trait_of_item(def_id).unwrap();
+        let virtual_trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, virtual_instance.args);
+        let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
+        let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);
+
+        let concrete_method = Instance::expect_resolve_for_vtable(
+            tcx,
+            self.typing_env,
+            def_id,
+            virtual_instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
+            self.cur_span(),
+        );
+        assert_eq!(concrete_instance, concrete_method);
+    }
+
     /// Initiate a tail call to this function -- popping the current stack frame, pushing the new
     /// stack frame and initializing the arguments.
     pub(super) fn init_fn_tail_call(
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index ef3e96784ce..e110c155da0 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -414,36 +414,33 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
                 // Sanity-check that `supertrait_vtable_slot` in this type's vtable indeed produces
                 // our destination trait.
-                if cfg!(debug_assertions) {
-                    let vptr_entry_idx =
-                        self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty));
-                    let vtable_entries = self.vtable_entries(data_a.principal(), ty);
-                    if let Some(entry_idx) = vptr_entry_idx {
-                        let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) =
-                            vtable_entries.get(entry_idx)
-                        else {
-                            span_bug!(
-                                self.cur_span(),
-                                "invalid vtable entry index in {} -> {} upcast",
-                                src_pointee_ty,
-                                dest_pointee_ty
-                            );
-                        };
-                        let erased_trait_ref = upcast_trait_ref
-                            .map_bound(|r| ty::ExistentialTraitRef::erase_self_ty(*self.tcx, r));
-                        assert!(
-                            data_b
-                                .principal()
-                                .is_some_and(|b| self.eq_in_param_env(erased_trait_ref, b))
+                let vptr_entry_idx =
+                    self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty));
+                let vtable_entries = self.vtable_entries(data_a.principal(), ty);
+                if let Some(entry_idx) = vptr_entry_idx {
+                    let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) =
+                        vtable_entries.get(entry_idx)
+                    else {
+                        span_bug!(
+                            self.cur_span(),
+                            "invalid vtable entry index in {} -> {} upcast",
+                            src_pointee_ty,
+                            dest_pointee_ty
                         );
-                    } else {
-                        // In this case codegen would keep using the old vtable. We don't want to do
-                        // that as it has the wrong trait. The reason codegen can do this is that
-                        // one vtable is a prefix of the other, so we double-check that.
-                        let vtable_entries_b = self.vtable_entries(data_b.principal(), ty);
-                        assert!(&vtable_entries[..vtable_entries_b.len()] == vtable_entries_b);
                     };
-                }
+                    let erased_trait_ref =
+                        ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref);
+                    assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env(
+                        erased_trait_ref,
+                        self.tcx.instantiate_bound_regions_with_erased(b)
+                    )));
+                } else {
+                    // In this case codegen would keep using the old vtable. We don't want to do
+                    // that as it has the wrong trait. The reason codegen can do this is that
+                    // one vtable is a prefix of the other, so we double-check that.
+                    let vtable_entries_b = self.vtable_entries(data_b.principal(), ty);
+                    assert!(&vtable_entries[..vtable_entries_b.len()] == vtable_entries_b);
+                };
 
                 // Get the destination trait vtable and return that.
                 let new_vptr = self.get_vtable_ptr(ty, data_b)?;
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index af8d618b6b5..4cfaacebfcd 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -54,7 +54,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ) -> &'tcx [VtblEntry<'tcx>] {
         if let Some(trait_) = trait_ {
             let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty);
-            let trait_ref = self.tcx.erase_regions(trait_ref);
+            let trait_ref =
+                self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
             self.tcx.vtable_entries(trait_ref)
         } else {
             TyCtxt::COMMON_VTABLE_ENTRIES
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index b5adf06b300..ecf9745b779 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -46,8 +46,13 @@ pub fn provide(providers: &mut Providers) {
     };
     providers.hooks.try_destructure_mir_constant_for_user_output =
         const_eval::try_destructure_mir_constant_for_user_output;
-    providers.valtree_to_const_val = |tcx, (ty, valtree)| {
-        const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), ty, valtree)
+    providers.valtree_to_const_val = |tcx, cv| {
+        const_eval::valtree_to_const_value(
+            tcx,
+            ty::TypingEnv::fully_monomorphized(),
+            cv.ty,
+            cv.valtree,
+        )
     };
     providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
         util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 17433eed9e7..684fc5e37e0 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1136,7 +1136,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     rustc_attr!(
         TEST, rustc_dump_vtable, Normal, template!(Word),
-        WarnFollowing, EncodeCrossCrate::Yes
+        WarnFollowing, EncodeCrossCrate::No
     ),
     rustc_attr!(
         TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 4e5f0a3186a..07ba6033a9f 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -199,10 +199,9 @@ fn check_object_overlap<'tcx>(
 
         for component_def_id in component_def_ids {
             if !tcx.is_dyn_compatible(component_def_id) {
-                // FIXME(dyn_compat_renaming): Rename test and update comment.
                 // Without the 'dyn_compatible_for_dispatch' feature this is an error
                 // which will be reported by wfcheck. Ignore it here.
-                // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
+                // This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
                 // With the feature enabled, the trait is not implemented automatically,
                 // so this is valid.
             } else {
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
index f1022d95753..4a508fc0cf6 100644
--- a/compiler/rustc_hir_analysis/src/collect/dump.rs
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -1,7 +1,8 @@
+use rustc_hir as hir;
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::intravisit;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::sym;
 
 pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
@@ -87,3 +88,82 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
         }
     }
 }
+
+pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
+    for id in tcx.hir().items() {
+        let def_id = id.owner_id.def_id;
+
+        let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else {
+            continue;
+        };
+
+        let vtable_entries = match tcx.hir().item(id).kind {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
+                let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity();
+                if trait_ref.has_non_region_param() {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to non-generic impl",
+                    );
+                    continue;
+                }
+                if !tcx.is_dyn_compatible(trait_ref.def_id) {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to dyn-compatible trait",
+                    );
+                    continue;
+                }
+                let Ok(trait_ref) = tcx
+                    .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref)
+                else {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` applied to impl header that cannot be normalized",
+                    );
+                    continue;
+                };
+                tcx.vtable_entries(trait_ref)
+            }
+            hir::ItemKind::TyAlias(_, _) => {
+                let ty = tcx.type_of(def_id).instantiate_identity();
+                if ty.has_non_region_param() {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` must be applied to non-generic type",
+                    );
+                    continue;
+                }
+                let Ok(ty) =
+                    tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
+                else {
+                    tcx.dcx().span_err(
+                        attr.span,
+                        "`rustc_dump_vtable` applied to type alias that cannot be normalized",
+                    );
+                    continue;
+                };
+                let ty::Dynamic(data, _, _) = *ty.kind() else {
+                    tcx.dcx().span_err(attr.span, "`rustc_dump_vtable` to type alias of dyn type");
+                    continue;
+                };
+                if let Some(principal) = data.principal() {
+                    tcx.vtable_entries(
+                        tcx.instantiate_bound_regions_with_erased(principal).with_self_ty(tcx, ty),
+                    )
+                } else {
+                    TyCtxt::COMMON_VTABLE_ENTRIES
+                }
+            }
+            _ => {
+                tcx.dcx().span_err(
+                    attr.span,
+                    "`rustc_dump_vtable` only applies to impl, or type alias of dyn type",
+                );
+                continue;
+            }
+        };
+
+        tcx.dcx().span_err(tcx.def_span(def_id), format!("vtable entries: {vtable_entries:#?}"));
+    }
+}
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 72baf5c4b58..d67b9d33596 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -12,13 +12,11 @@ use std::ops::ControlFlow;
 
 use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_data_structures::sorted_map::SortedMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
 use rustc_hir::{
-    self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, ItemLocalMap,
-    LifetimeName, Node,
+    self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeName, Node,
 };
 use rustc_macros::extension;
 use rustc_middle::hir::nested_filter;
@@ -26,7 +24,7 @@ use rustc_middle::middle::resolve_bound_vars::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_middle::{bug, span_bug};
-use rustc_span::def_id::{DefId, LocalDefId, LocalDefIdMap};
+use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::{Ident, Span, sym};
 use tracing::{debug, debug_span, instrument};
 
@@ -62,33 +60,9 @@ impl ResolvedArg {
     }
 }
 
-/// Maps the id of each bound variable reference to the variable decl
-/// that it corresponds to.
-///
-/// FIXME. This struct gets converted to a `ResolveBoundVars` for
-/// actual use. It has the same data, but indexed by `LocalDefId`. This
-/// is silly.
-#[derive(Debug, Default)]
-struct NamedVarMap {
-    // maps from every use of a named (not anonymous) bound var to a
-    // `ResolvedArg` describing how that variable is bound
-    defs: ItemLocalMap<ResolvedArg>,
-
-    // Maps relevant hir items to the bound vars on them. These include:
-    // - function defs
-    // - function pointers
-    // - closures
-    // - trait refs
-    // - bound types (like `T` in `for<'a> T<'a>: Foo`)
-    late_bound_vars: ItemLocalMap<Vec<ty::BoundVariableKind>>,
-
-    // List captured variables for each opaque type.
-    opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>,
-}
-
 struct BoundVarContext<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    map: &'a mut NamedVarMap,
+    rbv: &'a mut ResolveBoundVars,
     scope: ScopeRef<'a>,
 }
 
@@ -267,19 +241,12 @@ pub(crate) fn provide(providers: &mut Providers) {
 
 /// Computes the `ResolveBoundVars` map that contains data for an entire `Item`.
 /// You should not read the result of this query directly, but rather use
-/// `named_variable_map`, `is_late_bound_map`, etc.
+/// `named_variable_map`, `late_bound_vars_map`, etc.
 #[instrument(level = "debug", skip(tcx))]
 fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars {
-    let mut named_variable_map = NamedVarMap {
-        defs: Default::default(),
-        late_bound_vars: Default::default(),
-        opaque_captured_lifetimes: Default::default(),
-    };
-    let mut visitor = BoundVarContext {
-        tcx,
-        map: &mut named_variable_map,
-        scope: &Scope::Root { opt_parent_item: None },
-    };
+    let mut rbv = ResolveBoundVars::default();
+    let mut visitor =
+        BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } };
     match tcx.hir_owner_node(local_def_id) {
         hir::OwnerNode::Item(item) => visitor.visit_item(item),
         hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
@@ -299,19 +266,10 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
         hir::OwnerNode::Synthetic => unreachable!(),
     }
 
-    let defs = named_variable_map.defs.into_sorted_stable_ord();
-    let late_bound_vars = named_variable_map.late_bound_vars.into_sorted_stable_ord();
-    let opaque_captured_lifetimes = named_variable_map.opaque_captured_lifetimes;
-    let rl = ResolveBoundVars {
-        defs: SortedMap::from_presorted_elements(defs),
-        late_bound_vars: SortedMap::from_presorted_elements(late_bound_vars),
-        opaque_captured_lifetimes,
-    };
-
-    debug!(?rl.defs);
-    debug!(?rl.late_bound_vars);
-    debug!(?rl.opaque_captured_lifetimes);
-    rl
+    debug!(?rbv.defs);
+    debug!(?rbv.late_bound_vars);
+    debug!(?rbv.opaque_captured_lifetimes);
+    rbv
 }
 
 fn late_arg_as_bound_arg<'tcx>(
@@ -404,7 +362,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 Scope::Binder { hir_id, .. } => {
                     // Nested poly trait refs have the binders concatenated
                     let mut full_binders =
-                        self.map.late_bound_vars.entry(hir_id.local_id).or_default().clone();
+                        self.rbv.late_bound_vars.get_mut_or_insert_default(hir_id.local_id).clone();
                     full_binders.extend(supertrait_bound_vars);
                     break (full_binders, BinderScopeType::Concatenating);
                 }
@@ -646,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
         let captures = captures.into_inner().into_iter().collect();
         debug!(?captures);
-        self.map.opaque_captured_lifetimes.insert(opaque.def_id, captures);
+        self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures);
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -848,7 +806,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             hir::TyKind::Ref(lifetime_ref, ref mt) => {
                 self.visit_lifetime(lifetime_ref);
                 let scope = Scope::ObjectLifetimeDefault {
-                    lifetime: self.map.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
+                    lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).cloned(),
                     s: self.scope,
                 };
                 self.with(scope, |this| this.visit_ty_unambig(mt.ty));
@@ -966,7 +924,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             let bound_vars: Vec<_> =
                 self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect();
             let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
-            self.map.late_bound_vars.insert(hir_id.local_id, bound_vars);
+            self.rbv.late_bound_vars.insert(hir_id.local_id, bound_vars);
         }
         self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
         intravisit::walk_fn_kind(self, fk);
@@ -1140,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     where
         F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
     {
-        let BoundVarContext { tcx, map, .. } = self;
-        let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
+        let BoundVarContext { tcx, rbv, .. } = self;
+        let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope };
         let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
         {
             let _enter = span.enter();
@@ -1150,10 +1108,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     }
 
     fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) {
-        if let Some(old) = self.map.late_bound_vars.insert(hir_id.local_id, binder) {
+        if let Some(old) = self.rbv.late_bound_vars.insert(hir_id.local_id, binder) {
             bug!(
                 "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}",
-                self.map.late_bound_vars[&hir_id.local_id]
+                self.rbv.late_bound_vars[&hir_id.local_id]
             )
         }
     }
@@ -1597,9 +1555,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         kind.descr(param_def_id.to_def_id())
                     ),
                 };
-                self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
+                self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
             } else {
-                self.map.defs.insert(hir_id.local_id, def);
+                self.rbv.defs.insert(hir_id.local_id, def);
             }
             return;
         }
@@ -1632,7 +1590,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
                         }
                     });
-                    self.map.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
+                    self.rbv.defs.insert(hir_id.local_id, ResolvedArg::Error(guar));
                     return;
                 }
                 Scope::Root { .. } => break,
@@ -1725,7 +1683,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 }
             };
 
-            let map = &self.map;
+            let rbv = &self.rbv;
             let generics = self.tcx.generics_of(def_id);
 
             // `type_def_id` points to an item, so there is nothing to inherit generics from.
@@ -1744,7 +1702,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // This index can be used with `generic_args` since `parent_count == 0`.
                     let index = generics.param_def_id_to_index[&param_def_id] as usize;
                     generic_args.args.get(index).and_then(|arg| match arg {
-                        GenericArg::Lifetime(lt) => map.defs.get(&lt.hir_id.local_id).copied(),
+                        GenericArg::Lifetime(lt) => rbv.defs.get(&lt.hir_id.local_id).copied(),
                         _ => None,
                     })
                 }
@@ -2042,7 +2000,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: ResolvedArg) {
         debug!(span = ?lifetime_ref.ident.span);
-        self.map.defs.insert(lifetime_ref.hir_id.local_id, def);
+        self.rbv.defs.insert(lifetime_ref.hir_id.local_id, def);
     }
 
     // When we have a return type notation type in a where clause, like
@@ -2197,7 +2155,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         // See where these vars are used in `HirTyLowerer::lower_ty_maybe_return_type_notation`.
         // And this is exercised in:
         // `tests/ui/associated-type-bounds/return-type-notation/higher-ranked-bound-works.rs`.
-        let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
+        let existing_bound_vars = self.rbv.late_bound_vars.get_mut(&hir_id.local_id).unwrap();
         let existing_bound_vars_saved = existing_bound_vars.clone();
         existing_bound_vars.extend(bound_vars);
         self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index bc7d4365eee..03dd0cccf75 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -152,11 +152,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     });
 
     if tcx.features().rustc_attrs() {
-        tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
-        tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
-        collect::dump::opaque_hidden_types(tcx);
-        collect::dump::predicates_and_item_bounds(tcx);
-        collect::dump::def_parents(tcx);
+        tcx.sess.time("dumping_rustc_attr_data", || {
+            outlives::dump::inferred_outlives(tcx);
+            variance::dump::variances(tcx);
+            collect::dump::opaque_hidden_types(tcx);
+            collect::dump::predicates_and_item_bounds(tcx);
+            collect::dump::def_parents(tcx);
+            collect::dump::vtables(tcx);
+        });
     }
 
     // Make sure we evaluate all static and (non-associated) const items, even if unused.
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 12e2bbc968f..ad15b764bcc 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -402,6 +402,18 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
     }
 }
 
+impl<'tcx> ToTrace<'tcx> for ty::ExistentialTraitRef<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
+        TypeTrace {
+            cause: cause.clone(),
+            values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(
+                ty::Binder::dummy(a),
+                ty::Binder::dummy(b),
+            )),
+        }
+    }
+}
+
 impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
     fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
         TypeTrace {
@@ -410,3 +422,15 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
         }
     }
 }
+
+impl<'tcx> ToTrace<'tcx> for ty::ExistentialProjection<'tcx> {
+    fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
+        TypeTrace {
+            cause: cause.clone(),
+            values: ValuePairs::ExistentialProjection(ExpectedFound::new(
+                ty::Binder::dummy(a),
+                ty::Binder::dummy(b),
+            )),
+        }
+    }
+}
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 28eac5b7496..74c8b463fc8 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -170,7 +170,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
             }
 
             ty::ConstKind::Param(_)
-            | ty::ConstKind::Value(_, _)
+            | ty::ConstKind::Value(_)
             | ty::ConstKind::Unevaluated(..)
             | ty::ConstKind::Expr(..)
             | ty::ConstKind::Error(_) => ct.super_fold_with(self),
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 283ebdfa236..515c9c34098 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1055,7 +1055,7 @@ impl<'tcx> InferCtxt<'tcx> {
             | ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Placeholder(_)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Value(_, _)
+            | ty::ConstKind::Value(_)
             | ty::ConstKind::Error(_)
             | ty::ConstKind::Expr(_) => ct,
         }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 241bc35857a..0b91c023cfc 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -26,7 +26,6 @@ use rustc_parse::{
 };
 use rustc_passes::{abi_test, input_stats, layout_test};
 use rustc_resolve::Resolver;
-use rustc_session::code_stats::VTableSizeInfo;
 use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::output::{collect_crate_types, filename_for_input, find_crate_name};
@@ -989,90 +988,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
         // we will fail to emit overlap diagnostics. Thus we invoke it here unconditionally.
         let _ = tcx.all_diagnostic_items(());
     });
-
-    if sess.opts.unstable_opts.print_vtable_sizes {
-        let traits = tcx.traits(LOCAL_CRATE);
-
-        for &tr in traits {
-            if !tcx.is_dyn_compatible(tr) {
-                continue;
-            }
-
-            let name = ty::print::with_no_trimmed_paths!(tcx.def_path_str(tr));
-
-            let mut first_dsa = true;
-
-            // Number of vtable entries, if we didn't have upcasting
-            let mut entries_ignoring_upcasting = 0;
-            // Number of vtable entries needed solely for upcasting
-            let mut entries_for_upcasting = 0;
-
-            let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, tr));
-
-            // A slightly edited version of the code in
-            // `rustc_trait_selection::traits::vtable::vtable_entries`, that works without self
-            // type and just counts number of entries.
-            //
-            // Note that this is technically wrong, for traits which have associated types in
-            // supertraits:
-            //
-            //   trait A: AsRef<Self::T> + AsRef<()> { type T; }
-            //
-            // Without self type we can't normalize `Self::T`, so we can't know if `AsRef<Self::T>`
-            // and `AsRef<()>` are the same trait, thus we assume that those are different, and
-            // potentially over-estimate how many vtable entries there are.
-            //
-            // Similarly this is wrong for traits that have methods with possibly-impossible bounds.
-            // For example:
-            //
-            //   trait B<T> { fn f(&self) where T: Copy; }
-            //
-            // Here `dyn B<u8>` will have 4 entries, while `dyn B<String>` will only have 3.
-            // However, since we don't know `T`, we can't know if `T: Copy` holds or not,
-            // thus we lean on the bigger side and say it has 4 entries.
-            traits::vtable::prepare_vtable_segments(tcx, trait_ref, |segment| {
-                match segment {
-                    traits::vtable::VtblSegment::MetadataDSA => {
-                        // If this is the first dsa, it would be included either way,
-                        // otherwise it's needed for upcasting
-                        if std::mem::take(&mut first_dsa) {
-                            entries_ignoring_upcasting += 3;
-                        } else {
-                            entries_for_upcasting += 3;
-                        }
-                    }
-
-                    traits::vtable::VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
-                        // Lookup the shape of vtable for the trait.
-                        let own_existential_entries =
-                            tcx.own_existential_vtable_entries(trait_ref.def_id());
-
-                        // The original code here ignores the method if its predicates are
-                        // impossible. We can't really do that as, for example, all not trivial
-                        // bounds on generic parameters are impossible (since we don't know the
-                        // parameters...), see the comment above.
-                        entries_ignoring_upcasting += own_existential_entries.len();
-
-                        if emit_vptr {
-                            entries_for_upcasting += 1;
-                        }
-                    }
-                }
-
-                std::ops::ControlFlow::Continue::<std::convert::Infallible>(())
-            });
-
-            sess.code_stats.record_vtable_size(tr, &name, VTableSizeInfo {
-                trait_name: name.clone(),
-                entries: entries_ignoring_upcasting + entries_for_upcasting,
-                entries_ignoring_upcasting,
-                entries_for_upcasting,
-                upcasting_cost_percent: entries_for_upcasting as f64
-                    / entries_ignoring_upcasting as f64
-                    * 100.,
-            })
-        }
-    }
 }
 
 /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
@@ -1153,12 +1068,6 @@ pub(crate) fn start_codegen<'tcx>(
         tcx.sess.code_stats.print_type_sizes();
     }
 
-    if tcx.sess.opts.unstable_opts.print_vtable_sizes {
-        let crate_name = tcx.crate_name(LOCAL_CRATE);
-
-        tcx.sess.code_stats.print_vtable_sizes(crate_name);
-    }
-
     codegen
 }
 
diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
index 9fde35f82d8..35db8632625 100644
--- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
+++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
@@ -37,7 +37,7 @@ declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTAB
 impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
         let def_id = item.owner_id.to_def_id();
-        // NOTE(nbdd0121): use `object_safety_violations` instead of `is_dyn_compatible` because
+        // NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because
         // the latter will report `where_clause_object_safety` lint.
         if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind
             && cx.tcx.is_dyn_compatible(def_id)
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 35186778671..b0c6fa42190 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -319,7 +319,11 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
   case LLVMRustAttributeKind::NoAlias:
     return Attribute::NoAlias;
   case LLVMRustAttributeKind::NoCapture:
+#if LLVM_VERSION_GE(21, 0)
+    report_fatal_error("NoCapture doesn't exist in LLVM 21");
+#else
     return Attribute::NoCapture;
+#endif
   case LLVMRustAttributeKind::NoCfCheck:
     return Attribute::NoCfCheck;
   case LLVMRustAttributeKind::NoInline:
@@ -431,6 +435,12 @@ extern "C" void LLVMRustEraseInstFromParent(LLVMValueRef Instr) {
 
 extern "C" LLVMAttributeRef
 LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) {
+#if LLVM_VERSION_GE(21, 0)
+  // LLVM 21 replaced the NoCapture attribute with Captures(none).
+  if (RustAttr == LLVMRustAttributeKind::NoCapture) {
+    return wrap(Attribute::getWithCaptureInfo(*unwrap(C), CaptureInfo::none()));
+  }
+#endif
   return wrap(Attribute::get(*unwrap(C), fromRust(RustAttr)));
 }
 
@@ -667,8 +677,6 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
       unwrap<FunctionType>(Ty), StringRef(Constraints, ConstraintsLen)));
 }
 
-typedef DIBuilder *LLVMRustDIBuilderRef;
-
 template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
   return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
 }
@@ -677,12 +685,6 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
 #define DIArray DINodeArray
 #define unwrapDI unwrapDIPtr
 
-// FIXME(Zalathar): This is a temporary typedef to avoid churning dozens of
-// bindings that are going to be deleted and replaced with their LLVM-C
-// equivalents, as part of #134009. After that happens, the remaining bindings
-// can be adjusted to use `LLVMDIFlags` instead of relying on this typedef.
-typedef LLVMDIFlags LLVMRustDIFlags;
-
 // Statically assert that `LLVMDIFlags` (C) and `DIFlags` (C++) have the same
 // layout, at least for the flags we know about. This isn't guaranteed, but is
 // likely to remain true, and as long as it is true it makes conversions easy.
@@ -994,34 +996,34 @@ extern "C" void LLVMRustGlobalAddMetadata(LLVMValueRef Global, unsigned Kind,
   unwrap<GlobalObject>(Global)->addMetadata(Kind, *unwrap<MDNode>(MD));
 }
 
-extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
-  return new DIBuilder(*unwrap(M));
+extern "C" LLVMDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
+  return wrap(new DIBuilder(*unwrap(M)));
 }
 
-extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
-  delete Builder;
+extern "C" void LLVMRustDIBuilderDispose(LLVMDIBuilderRef Builder) {
+  delete unwrap(Builder);
 }
 
-extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
-  Builder->finalize();
+extern "C" void LLVMRustDIBuilderFinalize(LLVMDIBuilderRef Builder) {
+  unwrap(Builder)->finalize();
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
-    LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
+    LLVMDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
     const char *Producer, size_t ProducerLen, bool isOptimized,
     const char *Flags, unsigned RuntimeVer, const char *SplitName,
     size_t SplitNameLen, LLVMRustDebugEmissionKind Kind, uint64_t DWOId,
     bool SplitDebugInlining, LLVMRustDebugNameTableKind TableKind) {
   auto *File = unwrapDI<DIFile>(FileRef);
 
-  return wrap(Builder->createCompileUnit(
+  return wrap(unwrap(Builder)->createCompileUnit(
       Lang, File, StringRef(Producer, ProducerLen), isOptimized, Flags,
       RuntimeVer, StringRef(SplitName, SplitNameLen), fromRust(Kind), DWOId,
       SplitDebugInlining, false, fromRust(TableKind)));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
+LLVMRustDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
                             size_t FilenameLen, const char *Directory,
                             size_t DirectoryLen, LLVMRustChecksumKind CSKind,
                             const char *Checksum, size_t ChecksumLen,
@@ -1034,29 +1036,29 @@ LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
   std::optional<StringRef> oSource{};
   if (Source)
     oSource = StringRef(Source, SourceLen);
-  return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
-                                  StringRef(Directory, DirectoryLen), CSInfo,
-                                  oSource));
+  return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),
+                                          StringRef(Directory, DirectoryLen),
+                                          CSInfo, oSource));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
+LLVMRustDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
                                       LLVMMetadataRef ParameterTypes) {
-  return wrap(Builder->createSubroutineType(
+  return wrap(unwrap(Builder)->createSubroutineType(
       DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
-    unsigned ScopeLine, LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags,
+    unsigned ScopeLine, LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags,
     LLVMValueRef MaybeFn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) {
   DITemplateParameterArray TParams =
       DITemplateParameterArray(unwrap<MDTuple>(TParam));
   DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
   DINode::DIFlags llvmFlags = fromRust(Flags);
-  DISubprogram *Sub = Builder->createFunction(
+  DISubprogram *Sub = unwrap(Builder)->createFunction(
       unwrapDI<DIScope>(Scope), StringRef(Name, NameLen),
       StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo,
       unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags, llvmSPFlags,
@@ -1067,15 +1069,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
-    LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) {
+    LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) {
   DITemplateParameterArray TParams =
       DITemplateParameterArray(unwrap<MDTuple>(TParam));
   DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
   DINode::DIFlags llvmFlags = fromRust(Flags);
-  DISubprogram *Sub = Builder->createMethod(
+  DISubprogram *Sub = unwrap(Builder)->createMethod(
       unwrapDI<DIScope>(Scope), StringRef(Name, NameLen),
       StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File), LineNo,
       unwrapDI<DISubroutineType>(Ty), 0, 0,
@@ -1085,39 +1087,39 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod(
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
+LLVMRustDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,
                                  size_t NameLen, uint64_t SizeInBits,
                                  unsigned Encoding) {
-  return wrap(
-      Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
+  return wrap(unwrap(Builder)->createBasicType(StringRef(Name, NameLen),
+                                               SizeInBits, Encoding));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateTypedef(LLVMRustDIBuilderRef Builder,
-                               LLVMMetadataRef Type, const char *Name,
-                               size_t NameLen, LLVMMetadataRef File,
-                               unsigned LineNo, LLVMMetadataRef Scope) {
-  return wrap(Builder->createTypedef(
+LLVMRustDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type,
+                               const char *Name, size_t NameLen,
+                               LLVMMetadataRef File, unsigned LineNo,
+                               LLVMMetadataRef Scope) {
+  return wrap(unwrap(Builder)->createTypedef(
       unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
       LineNo, unwrapDIPtr<DIScope>(Scope)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
-    uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
-    const char *Name, size_t NameLen) {
-  return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
-                                         SizeInBits, AlignInBits, AddressSpace,
-                                         StringRef(Name, NameLen)));
+    LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits,
+    uint32_t AlignInBits, unsigned AddressSpace, const char *Name,
+    size_t NameLen) {
+  return wrap(unwrap(Builder)->createPointerType(
+      unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace,
+      StringRef(Name, NameLen)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
-    uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags,
+    uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,
     LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements, unsigned RunTimeLang,
     LLVMMetadataRef VTableHolder, const char *UniqueId, size_t UniqueIdLen) {
-  return wrap(Builder->createStructType(
+  return wrap(unwrap(Builder)->createStructType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits,
       fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
@@ -1126,12 +1128,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
-    uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags,
+    uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,
     LLVMMetadataRef Discriminator, LLVMMetadataRef Elements,
     const char *UniqueId, size_t UniqueIdLen) {
-  return wrap(Builder->createVariantPart(
+  return wrap(unwrap(Builder)->createVariantPart(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits,
       fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
@@ -1140,36 +1142,36 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
-    uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
+    uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,
     LLVMMetadataRef Ty) {
-  return wrap(Builder->createMemberType(
+  return wrap(unwrap(Builder)->createMemberType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, OffsetInBits,
       fromRust(Flags), unwrapDI<DIType>(Ty)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
     uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
-    LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
+    LLVMDIFlags Flags, LLVMMetadataRef Ty) {
   llvm::ConstantInt *D = nullptr;
   if (Discriminant) {
     D = unwrap<llvm::ConstantInt>(Discriminant);
   }
-  return wrap(Builder->createVariantMemberType(
+  return wrap(unwrap(Builder)->createVariantMemberType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, D,
       fromRust(Flags), unwrapDI<DIType>(Ty)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
-    LLVMRustDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) {
-  return wrap(Builder->createStaticMemberType(
+    LLVMDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) {
+  return wrap(unwrap(Builder)->createStaticMemberType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), fromRust(Flags),
       unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits));
@@ -1183,21 +1185,21 @@ LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder,
+LLVMRustDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Builder,
                                     LLVMMetadataRef Scope, LLVMMetadataRef File,
                                     unsigned Line, unsigned Col) {
-  return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
-                                          unwrapDI<DIFile>(File), Line, Col));
+  return wrap(unwrap(Builder)->createLexicalBlock(
+      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Col));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) {
-  return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
-                                              unwrapDI<DIFile>(File)));
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) {
+  return wrap(unwrap(Builder)->createLexicalBlockFile(
+      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
     size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
     bool IsLocalToUnit, LLVMValueRef V, LLVMMetadataRef Decl = nullptr,
@@ -1206,16 +1208,16 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
 
   llvm::DIExpression *InitExpr = nullptr;
   if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
-    InitExpr = Builder->createConstantValueExpression(
+    InitExpr = unwrap(Builder)->createConstantValueExpression(
         IntVal->getValue().getSExtValue());
   } else if (llvm::ConstantFP *FPVal =
                  llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
-    InitExpr = Builder->createConstantValueExpression(
+    InitExpr = unwrap(Builder)->createConstantValueExpression(
         FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
   }
 
   llvm::DIGlobalVariableExpression *VarExpr =
-      Builder->createGlobalVariableExpression(
+      unwrap(Builder)->createGlobalVariableExpression(
           unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
           StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File),
           LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
@@ -1228,17 +1230,17 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
-    LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
+    LLVMDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
     const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
-    LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
-    unsigned ArgNo, uint32_t AlignInBits) {
+    LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMDIFlags Flags, unsigned ArgNo,
+    uint32_t AlignInBits) {
   if (Tag == 0x100) { // DW_TAG_auto_variable
-    return wrap(Builder->createAutoVariable(
+    return wrap(unwrap(Builder)->createAutoVariable(
         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
         unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve,
         fromRust(Flags), AlignInBits));
   } else {
-    return wrap(Builder->createParameterVariable(
+    return wrap(unwrap(Builder)->createParameterVariable(
         unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
         unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), AlwaysPreserve,
         fromRust(Flags)));
@@ -1246,53 +1248,56 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
+LLVMRustDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size,
                                  uint32_t AlignInBits, LLVMMetadataRef Ty,
                                  LLVMMetadataRef Subscripts) {
-  return wrap(
-      Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
-                               DINodeArray(unwrapDI<MDTuple>(Subscripts))));
+  return wrap(unwrap(Builder)->createArrayType(
+      Size, AlignInBits, unwrapDI<DIType>(Ty),
+      DINodeArray(unwrapDI<MDTuple>(Subscripts))));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
+LLVMRustDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, int64_t Lo,
                                      int64_t Count) {
-  return wrap(Builder->getOrCreateSubrange(Lo, Count));
+  return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
+LLVMRustDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder,
                                   LLVMMetadataRef *Ptr, unsigned Count) {
   Metadata **DataValue = unwrap(Ptr);
-  return wrap(
-      Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
+  return wrap(unwrap(Builder)
+                  ->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count))
+                  .get());
 }
 
-extern "C" void LLVMRustDIBuilderInsertDeclareAtEnd(
-    LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
-    uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
-    LLVMBasicBlockRef InsertAtEnd) {
-  Builder->insertDeclare(unwrap(V), unwrap<DILocalVariable>(VarInfo),
-                         Builder->createExpression(
-                             llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
-                         DebugLoc(cast<MDNode>(unwrap(DL))),
-                         unwrap(InsertAtEnd));
+extern "C" void
+LLVMRustDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V,
+                                    LLVMMetadataRef VarInfo, uint64_t *AddrOps,
+                                    unsigned AddrOpsCount, LLVMMetadataRef DL,
+                                    LLVMBasicBlockRef InsertAtEnd) {
+  unwrap(Builder)->insertDeclare(
+      unwrap(V), unwrap<DILocalVariable>(VarInfo),
+      unwrap(Builder)->createExpression(
+          llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
+      DebugLoc(cast<MDNode>(unwrap(DL))), unwrap(InsertAtEnd));
 }
 
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
-    LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
-    const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) {
-  return wrap(Builder->createEnumerator(
+extern "C" LLVMMetadataRef
+LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name,
+                                  size_t NameLen, const uint64_t Value[2],
+                                  unsigned SizeInBits, bool IsUnsigned) {
+  return wrap(unwrap(Builder)->createEnumerator(
       StringRef(Name, NameLen),
       APSInt(APInt(SizeInBits, ArrayRef<uint64_t>(Value, 2)), IsUnsigned)));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
     uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef Elements,
     LLVMMetadataRef ClassTy, bool IsScoped) {
-  return wrap(Builder->createEnumerationType(
+  return wrap(unwrap(Builder)->createEnumerationType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits,
       DINodeArray(unwrapDI<MDTuple>(Elements)), unwrapDI<DIType>(ClassTy),
@@ -1300,12 +1305,12 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
-    uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags,
+    uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,
     LLVMMetadataRef Elements, unsigned RunTimeLang, const char *UniqueId,
     size_t UniqueIdLen) {
-  return wrap(Builder->createUnionType(
+  return wrap(unwrap(Builder)->createUnionType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits,
       fromRust(Flags), DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
@@ -1313,28 +1318,28 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, LLVMMetadataRef Ty) {
   bool IsDefault = false; // FIXME: should we ever set this true?
-  return wrap(Builder->createTemplateTypeParameter(
+  return wrap(unwrap(Builder)->createTemplateTypeParameter(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIType>(Ty), IsDefault));
 }
 
 extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
+LLVMRustDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder,
                                  LLVMMetadataRef Scope, const char *Name,
                                  size_t NameLen, bool ExportSymbols) {
-  return wrap(Builder->createNameSpace(
+  return wrap(unwrap(Builder)->createNameSpace(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols));
 }
 
 extern "C" void LLVMRustDICompositeTypeReplaceArrays(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef CompositeTy,
+    LLVMDIBuilderRef Builder, LLVMMetadataRef CompositeTy,
     LLVMMetadataRef Elements, LLVMMetadataRef Params) {
   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
-  Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
-                         DINodeArray(unwrap<MDTuple>(Params)));
+  unwrap(Builder)->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
+                                 DINodeArray(unwrap<MDTuple>(Params)));
 }
 
 extern "C" LLVMMetadataRef
diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
index 111ac990bc7..51a079e8bc1 100644
--- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
+++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
@@ -45,15 +45,22 @@ pub enum ObjectLifetimeDefault {
     Param(DefId),
 }
 
-/// Maps the id of each lifetime reference to the lifetime decl
+/// Maps the id of each bound variable reference to the variable decl
 /// that it corresponds to.
-#[derive(HashStable, Debug)]
+#[derive(Debug, Default, HashStable)]
 pub struct ResolveBoundVars {
-    /// Maps from every use of a named (not anonymous) lifetime to a
-    /// `Region` describing how that region is bound
+    // Maps from every use of a named (not anonymous) bound var to a
+    // `ResolvedArg` describing how that variable is bound.
     pub defs: SortedMap<ItemLocalId, ResolvedArg>,
 
+    // Maps relevant hir items to the bound vars on them. These include:
+    // - function defs
+    // - function pointers
+    // - closures
+    // - trait refs
+    // - bound types (like `T` in `for<'a> T<'a>: Foo`)
     pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>>,
 
+    // List captured variables for each opaque type.
     pub opaque_captured_lifetimes: LocalDefIdMap<Vec<(ResolvedArg, LocalDefId)>>,
 }
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 66d97fda433..923160cc0cc 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -250,7 +250,7 @@ impl<'tcx> Const<'tcx> {
                     // Dont use the outer ty as on invalid code we can wind up with them not being the same.
                     // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
                     // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
-                    ty::ConstKind::Value(ty, _) => ty,
+                    ty::ConstKind::Value(cv) => cv.ty,
                     _ => *ty,
                 }
             }
@@ -264,7 +264,7 @@ impl<'tcx> Const<'tcx> {
     pub fn is_required_const(&self) -> bool {
         match self {
             Const::Ty(_, c) => match c.kind() {
-                ty::ConstKind::Value(_, _) => false, // already a value, cannot error
+                ty::ConstKind::Value(_) => false, // already a value, cannot error
                 _ => true,
             },
             Const::Val(..) => false, // already a value, cannot error
@@ -276,11 +276,11 @@ impl<'tcx> Const<'tcx> {
     pub fn try_to_scalar(self) -> Option<Scalar> {
         match self {
             Const::Ty(_, c) => match c.kind() {
-                ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
+                ty::ConstKind::Value(cv) if cv.ty.is_primitive() => {
                     // A valtree of a type where leaves directly represent the scalar const value.
                     // Just checking whether it is a leaf is insufficient as e.g. references are leafs
                     // but the leaf value is the value they point to, not the reference itself!
-                    Some(valtree.unwrap_leaf().into())
+                    Some(cv.valtree.unwrap_leaf().into())
                 }
                 _ => None,
             },
@@ -295,9 +295,7 @@ impl<'tcx> Const<'tcx> {
         match self {
             Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
             Const::Ty(_, c) => match c.kind() {
-                ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
-                    Some(valtree.unwrap_leaf())
-                }
+                ty::ConstKind::Value(cv) if cv.ty.is_primitive() => Some(cv.valtree.unwrap_leaf()),
                 _ => None,
             },
             _ => None,
@@ -328,7 +326,7 @@ impl<'tcx> Const<'tcx> {
                 }
 
                 match c.kind() {
-                    ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
+                    ConstKind::Value(cv) => Ok(tcx.valtree_to_const_val(cv)),
                     ConstKind::Expr(_) => {
                         bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
                     }
@@ -353,13 +351,13 @@ impl<'tcx> Const<'tcx> {
         typing_env: ty::TypingEnv<'tcx>,
     ) -> Option<Scalar> {
         if let Const::Ty(_, c) = self
-            && let ty::ConstKind::Value(ty, val) = c.kind()
-            && ty.is_primitive()
+            && let ty::ConstKind::Value(cv) = c.kind()
+            && cv.ty.is_primitive()
         {
             // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
             // are valtree leaves, and *not* on references. (References should return the
             // pointer here, which valtrees don't represent.)
-            Some(val.unwrap_leaf().into())
+            Some(cv.valtree.unwrap_leaf().into())
         } else {
             self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar()
         }
@@ -473,7 +471,7 @@ impl<'tcx> Const<'tcx> {
                 // A valtree may be a reference. Valtree references correspond to a
                 // different allocation each time they are evaluated. Valtrees for primitive
                 // types are fine though.
-                ty::ConstKind::Value(ty, _) => ty.is_primitive(),
+                ty::ConstKind::Value(cv) => cv.ty.is_primitive(),
                 ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false,
                 // This can happen if evaluation of a constant failed. The result does not matter
                 // much since compilation is doomed.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 3b4fba97e60..a318bacb866 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1441,7 +1441,9 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                     ty::ConstKind::Unevaluated(uv) => {
                         format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
                     }
-                    ty::ConstKind::Value(_, val) => format!("ty::Valtree({})", fmt_valtree(&val)),
+                    ty::ConstKind::Value(cv) => {
+                        format!("ty::Valtree({})", fmt_valtree(&cv.valtree))
+                    }
                     // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
                     ty::ConstKind::Error(_) => "Error".to_string(),
                     // These variants shouldn't exist in the MIR.
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index e243425c0b7..949d8303385 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -95,7 +95,7 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
     }
 }
 
-impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) {
+impl<'tcx> Key for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
     type Cache<V> = DefaultCache<Self, V>;
 
     fn default_span(&self, _: TyCtxt<'_>) -> Span {
@@ -550,7 +550,7 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
     }
 }
 
-impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
+impl<'tcx> Key for ty::Value<'tcx> {
     type Cache<V> = DefaultCache<Self, V>;
 
     fn default_span(&self, _: TyCtxt<'_>) -> Span {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d83bc19a6a2..41e9858030c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1256,9 +1256,9 @@ rustc_queries! {
         desc { "evaluating type-level constant" }
     }
 
-    /// Converts a type level constant value into `ConstValue`
-    query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> mir::ConstValue<'tcx> {
-        desc { "converting type-level constant value to mir constant value"}
+    /// Converts a type-level constant value into a MIR constant value.
+    query valtree_to_const_val(key: ty::Value<'tcx>) -> mir::ConstValue<'tcx> {
+        desc { "converting type-level constant value to MIR constant value"}
     }
 
     /// Destructures array, ADT or tuple constants into the constants
@@ -1437,9 +1437,9 @@ rustc_queries! {
         desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) }
     }
 
-    query vtable_entries(key: ty::PolyTraitRef<'tcx>)
+    query vtable_entries(key: ty::TraitRef<'tcx>)
                         -> &'tcx [ty::VtblEntry<'tcx>] {
-        desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
+        desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) }
     }
 
     query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize {
@@ -1451,7 +1451,7 @@ rustc_queries! {
             key.1, key.0 }
     }
 
-    query vtable_allocation(key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
+    query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
         desc { |tcx| "vtable const allocation for <{} as {}>",
             key.0,
             key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or("_".to_owned())
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 31055276422..d77fb1cc91e 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -5,7 +5,6 @@ use rustc_error_messages::MultiSpan;
 use rustc_macros::HashStable;
 use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
 
-use crate::mir::interpret::Scalar;
 use crate::ty::{self, Ty, TyCtxt};
 
 mod int;
@@ -110,8 +109,8 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[inline]
-    pub fn new_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Value(ty, val))
+    pub fn new_value(tcx: TyCtxt<'tcx>, valtree: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Value(ty::Value { ty, valtree }))
     }
 
     #[inline]
@@ -214,47 +213,31 @@ impl<'tcx> Const<'tcx> {
         Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize)
     }
 
-    /// Panics if self.kind != ty::ConstKind::Value
-    pub fn to_valtree(self) -> (ty::ValTree<'tcx>, Ty<'tcx>) {
+    /// Panics if `self.kind != ty::ConstKind::Value`.
+    pub fn to_value(self) -> ty::Value<'tcx> {
         match self.kind() {
-            ty::ConstKind::Value(ty, valtree) => (valtree, ty),
+            ty::ConstKind::Value(cv) => cv,
             _ => bug!("expected ConstKind::Value, got {:?}", self.kind()),
         }
     }
 
-    /// Attempts to convert to a `ValTree`
-    pub fn try_to_valtree(self) -> Option<(ty::ValTree<'tcx>, Ty<'tcx>)> {
+    /// Attempts to convert to a value.
+    ///
+    /// Note that this does not evaluate the constant.
+    pub fn try_to_value(self) -> Option<ty::Value<'tcx>> {
         match self.kind() {
-            ty::ConstKind::Value(ty, valtree) => Some((valtree, ty)),
+            ty::ConstKind::Value(cv) => Some(cv),
             _ => None,
         }
     }
 
-    #[inline]
-    pub fn try_to_scalar(self) -> Option<(Scalar, Ty<'tcx>)> {
-        let (valtree, ty) = self.try_to_valtree()?;
-        Some((valtree.try_to_scalar()?, ty))
-    }
-
-    pub fn try_to_bool(self) -> Option<bool> {
-        self.try_to_valtree()?.0.try_to_scalar_int()?.try_to_bool().ok()
-    }
-
+    /// Convenience method to extract the value of a usize constant,
+    /// useful to get the length of an array type.
+    ///
+    /// Note that this does not evaluate the constant.
     #[inline]
     pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
-        self.try_to_valtree()?.0.try_to_target_usize(tcx)
-    }
-
-    /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of
-    /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
-    /// contains const generic parameters or pointers).
-    #[inline]
-    pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
-        let (scalar, ty) = self.try_to_scalar()?;
-        let scalar = scalar.try_to_scalar_int().ok()?;
-        let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty);
-        let size = tcx.layout_of(input).ok()?.size;
-        Some(scalar.to_bits(size))
+        self.try_to_value()?.try_to_target_usize(tcx)
     }
 
     pub fn is_ct_infer(self) -> bool {
diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs
index 9f9bf41c335..d914b7576dc 100644
--- a/compiler/rustc_middle/src/ty/consts/valtree.rs
+++ b/compiler/rustc_middle/src/ty/consts/valtree.rs
@@ -1,11 +1,9 @@
-use rustc_macros::{HashStable, TyDecodable, TyEncodable};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 
 use super::ScalarInt;
 use crate::mir::interpret::Scalar;
 use crate::ty::{self, Ty, TyCtxt};
 
-#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq)]
-#[derive(HashStable)]
 /// This datastructure is used to represent the value of constants used in the type system.
 ///
 /// We explicitly choose a different datastructure from the way values are processed within
@@ -18,6 +16,8 @@ use crate::ty::{self, Ty, TyCtxt};
 ///
 /// `ValTree` does not have this problem with representation, as it only contains integers or
 /// lists of (nested) `ValTree`.
+#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
+#[derive(HashStable, TyEncodable, TyDecodable)]
 pub enum ValTree<'tcx> {
     /// integers, `bool`, `char` are represented as scalars.
     /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
@@ -79,10 +79,6 @@ impl<'tcx> ValTree<'tcx> {
         }
     }
 
-    pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
-        self.try_to_scalar_int().map(|s| s.to_target_usize(tcx))
-    }
-
     /// Get the values inside the ValTree as a slice of bytes. This only works for
     /// constants with types &str, &[u8], or [u8; _].
     pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> {
@@ -107,3 +103,54 @@ impl<'tcx> ValTree<'tcx> {
         )
     }
 }
+
+/// A type-level constant value.
+///
+/// Represents a typed, fully evaluated constant.
+#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
+#[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
+pub struct Value<'tcx> {
+    pub ty: Ty<'tcx>,
+    pub valtree: ValTree<'tcx>,
+}
+
+impl<'tcx> Value<'tcx> {
+    /// Attempts to extract the raw bits from the constant.
+    ///
+    /// Fails if the value can't be represented as bits (e.g. because it is a reference
+    /// or an aggregate).
+    #[inline]
+    pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
+        let (ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Float(_)) = self.ty.kind() else {
+            return None;
+        };
+        let scalar = self.valtree.try_to_scalar_int()?;
+        let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty);
+        let size = tcx.layout_of(input).ok()?.size;
+        Some(scalar.to_bits(size))
+    }
+
+    pub fn try_to_bool(self) -> Option<bool> {
+        if !self.ty.is_bool() {
+            return None;
+        }
+        self.valtree.try_to_scalar_int()?.try_to_bool().ok()
+    }
+
+    pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
+        if !self.ty.is_usize() {
+            return None;
+        }
+        self.valtree.try_to_scalar_int().map(|s| s.to_target_usize(tcx))
+    }
+}
+
+impl<'tcx> rustc_type_ir::inherent::ValueConst<TyCtxt<'tcx>> for Value<'tcx> {
+    fn ty(self) -> Ty<'tcx> {
+        self.ty
+    }
+
+    fn valtree(self) -> ValTree<'tcx> {
+        self.valtree
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 0c22c056dab..69f6fc0ad8a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -142,10 +142,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
 
     type ParamConst = ty::ParamConst;
     type BoundConst = ty::BoundVar;
-    type ValueConst = ty::ValTree<'tcx>;
+    type ValueConst = ty::Value<'tcx>;
     type ExprConst = ty::Expr<'tcx>;
-    type Region = Region<'tcx>;
+    type ValTree = ty::ValTree<'tcx>;
 
+    type Region = Region<'tcx>;
     type EarlyParamRegion = ty::EarlyParamRegion;
     type LateParamRegion = ty::LateParamRegion;
     type BoundRegion = ty::BoundRegion;
@@ -1118,15 +1119,18 @@ impl<'tcx> CommonConsts<'tcx> {
         };
 
         CommonConsts {
-            unit: mk_const(ty::ConstKind::Value(types.unit, ty::ValTree::zst())),
-            true_: mk_const(ty::ConstKind::Value(
-                types.bool,
-                ty::ValTree::Leaf(ty::ScalarInt::TRUE),
-            )),
-            false_: mk_const(ty::ConstKind::Value(
-                types.bool,
-                ty::ValTree::Leaf(ty::ScalarInt::FALSE),
-            )),
+            unit: mk_const(ty::ConstKind::Value(ty::Value {
+                ty: types.unit,
+                valtree: ty::ValTree::zst(),
+            })),
+            true_: mk_const(ty::ConstKind::Value(ty::Value {
+                ty: types.bool,
+                valtree: ty::ValTree::Leaf(ty::ScalarInt::TRUE),
+            })),
+            false_: mk_const(ty::ConstKind::Value(ty::Value {
+                ty: types.bool,
+                valtree: ty::ValTree::Leaf(ty::ScalarInt::FALSE),
+            })),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 0af57f636aa..ec0498b168c 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -381,7 +381,7 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
-            ty::ConstKind::Value(ty, _) => self.add_ty(ty),
+            ty::ConstKind::Value(cv) => self.add_ty(cv.ty),
             ty::ConstKind::Expr(e) => self.add_args(e.args()),
             ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index b212992bd2d..3ced64b5b80 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -858,7 +858,12 @@ where
                     }
 
                     let mk_dyn_vtable = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
-                        let min_count = ty::vtable_min_entries(tcx, principal);
+                        let min_count = ty::vtable_min_entries(
+                            tcx,
+                            principal.map(|principal| {
+                                tcx.instantiate_bound_regions_with_erased(principal)
+                            }),
+                        );
                         Ty::new_imm_ref(
                             tcx,
                             tcx.lifetimes.re_static,
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 8cd632790a8..88eea6101b5 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -60,7 +60,7 @@ pub use self::closure::{
     place_to_string_for_capture,
 };
 pub use self::consts::{
-    Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
+    Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, Value,
 };
 pub use self::context::{
     CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 027a4315b4b..018fcc66aee 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1484,8 +1484,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 _ => write!(self, "_")?,
             },
             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
-            ty::ConstKind::Value(ty, value) => {
-                return self.pretty_print_const_valtree(value, ty, print_ty);
+            ty::ConstKind::Value(cv) => {
+                return self.pretty_print_const_valtree(cv.valtree, cv.ty, print_ty);
             }
 
             ty::ConstKind::Bound(debruijn, bound_var) => {
@@ -1637,33 +1637,32 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         match ty.kind() {
             // Byte strings (&[u8; N])
             ty::Ref(_, inner, _) => {
-                if let ty::Array(elem, len) = inner.kind() {
-                    if let ty::Uint(ty::UintTy::U8) = elem.kind() {
-                        if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() {
-                            match self.tcx().try_get_global_alloc(prov.alloc_id()) {
-                                Some(GlobalAlloc::Memory(alloc)) => {
-                                    let len = int.to_bits(self.tcx().data_layout.pointer_size);
-                                    let range =
-                                        AllocRange { start: offset, size: Size::from_bytes(len) };
-                                    if let Ok(byte_str) =
-                                        alloc.inner().get_bytes_strip_provenance(&self.tcx(), range)
-                                    {
-                                        p!(pretty_print_byte_str(byte_str))
-                                    } else {
-                                        p!("<too short allocation>")
-                                    }
-                                }
-                                // FIXME: for statics, vtables, and functions, we could in principle print more detail.
-                                Some(GlobalAlloc::Static(def_id)) => {
-                                    p!(write("<static({:?})>", def_id))
-                                }
-                                Some(GlobalAlloc::Function { .. }) => p!("<function>"),
-                                Some(GlobalAlloc::VTable(..)) => p!("<vtable>"),
-                                None => p!("<dangling pointer>"),
+                if let ty::Array(elem, len) = inner.kind()
+                    && let ty::Uint(ty::UintTy::U8) = elem.kind()
+                    && let ty::ConstKind::Value(cv) = len.kind()
+                    && let ty::ValTree::Leaf(int) = cv.valtree
+                {
+                    match self.tcx().try_get_global_alloc(prov.alloc_id()) {
+                        Some(GlobalAlloc::Memory(alloc)) => {
+                            let len = int.to_bits(self.tcx().data_layout.pointer_size);
+                            let range = AllocRange { start: offset, size: Size::from_bytes(len) };
+                            if let Ok(byte_str) =
+                                alloc.inner().get_bytes_strip_provenance(&self.tcx(), range)
+                            {
+                                p!(pretty_print_byte_str(byte_str))
+                            } else {
+                                p!("<too short allocation>")
                             }
-                            return Ok(());
                         }
+                        // FIXME: for statics, vtables, and functions, we could in principle print more detail.
+                        Some(GlobalAlloc::Static(def_id)) => {
+                            p!(write("<static({:?})>", def_id))
+                        }
+                        Some(GlobalAlloc::Function { .. }) => p!("<function>"),
+                        Some(GlobalAlloc::VTable(..)) => p!("<vtable>"),
+                        None => p!("<dangling pointer>"),
                     }
+                    return Ok(());
                 }
             }
             ty::FnPtr(..) => {
@@ -1786,6 +1785,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         Ok(())
     }
 
+    // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
     fn pretty_print_const_valtree(
         &mut self,
         valtree: ty::ValTree<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs
index cbc02097d82..568e504b940 100644
--- a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs
+++ b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs
@@ -4,7 +4,7 @@ use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt};
 
 impl<'tcx> TyCtxt<'tcx> {
     /// Given a `def_id` of a trait or impl method, compute whether that method needs to
-    /// have an RPITIT shim applied to it for it to be object safe. If so, return the
+    /// have an RPITIT shim applied to it for it to be dyn compatible. If so, return the
     /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT.
     ///
     /// NOTE that these args are not, in general, the same as than the RPITIT's args. They
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 68cb56f3583..9e9de4fb064 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -162,16 +162,15 @@ impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
 impl<'tcx> fmt::Debug for ty::Const<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // If this is a value, we spend some effort to make it look nice.
-        if let ConstKind::Value(_, _) = self.kind() {
+        if let ConstKind::Value(_) = self.kind() {
             return ty::tls::with(move |tcx| {
-                // Somehow trying to lift the valtree results in lifetime errors, so we lift the
-                // entire constant.
+                // ValTrees aren't interned, so we lift the entire constant.
                 let lifted = tcx.lift(*self).unwrap();
-                let ConstKind::Value(ty, valtree) = lifted.kind() else {
+                let ConstKind::Value(cv) = lifted.kind() else {
                     bug!("we checked that this is a valtree")
                 };
                 let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.pretty_print_const_valtree(valtree, ty, /*print_ty*/ true)?;
+                cx.pretty_print_const_valtree(cv.valtree, cv.ty, /*print_ty*/ true)?;
                 f.write_str(&cx.into_buffer())
             });
         }
@@ -589,9 +588,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
             }
             ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
             ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
-            ConstKind::Value(t, v) => {
-                ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?)
-            }
+            ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
             ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
             ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
         };
@@ -610,10 +607,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
             }
             ConstKind::Placeholder(p) => p.visit_with(visitor),
             ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
-            ConstKind::Value(t, v) => {
-                try_visit!(t.visit_with(visitor));
-                v.visit_with(visitor)
-            }
+            ConstKind::Value(v) => v.visit_with(visitor),
             ConstKind::Error(e) => e.visit_with(visitor),
             ConstKind::Expr(e) => e.visit_with(visitor),
         }
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index 455bd16ff8c..6c9e0e7c0eb 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -7,7 +7,7 @@ use rustc_type_ir::elaborate;
 use crate::mir::interpret::{
     AllocId, AllocInit, Allocation, CTFE_ALLOC_SALT, Pointer, Scalar, alloc_range,
 };
-use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
+use crate::ty::{self, Instance, TraitRef, Ty, TyCtxt};
 
 #[derive(Clone, Copy, PartialEq, HashStable)]
 pub enum VtblEntry<'tcx> {
@@ -22,7 +22,7 @@ pub enum VtblEntry<'tcx> {
     /// dispatchable associated function
     Method(Instance<'tcx>),
     /// pointer to a separate supertrait vtable, can be used by trait upcasting coercion
-    TraitVPtr(PolyTraitRef<'tcx>),
+    TraitVPtr(TraitRef<'tcx>),
 }
 
 impl<'tcx> fmt::Debug for VtblEntry<'tcx> {
@@ -59,7 +59,7 @@ pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2;
 // function is an accurate approximation. We verify this when actually computing the vtable below.
 pub(crate) fn vtable_min_entries<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
 ) -> usize {
     let mut count = TyCtxt::COMMON_VTABLE_ENTRIES.len();
     let Some(trait_ref) = trait_ref else {
@@ -67,7 +67,7 @@ pub(crate) fn vtable_min_entries<'tcx>(
     };
 
     // This includes self in supertraits.
-    for def_id in elaborate::supertrait_def_ids(tcx, trait_ref.def_id()) {
+    for def_id in elaborate::supertrait_def_ids(tcx, trait_ref.def_id) {
         count += tcx.own_existential_vtable_entries(def_id).len();
     }
 
@@ -83,7 +83,7 @@ pub(crate) fn vtable_min_entries<'tcx>(
 /// initial contents.)
 pub(super) fn vtable_allocation_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
-    key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
+    key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>),
 ) -> AllocId {
     let (ty, poly_trait_ref) = key;
 
@@ -118,7 +118,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
 
     for (idx, entry) in vtable_entries.iter().enumerate() {
         let idx: u64 = u64::try_from(idx).unwrap();
-        let scalar = match entry {
+        let scalar = match *entry {
             VtblEntry::MetadataDropInPlace => {
                 if ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) {
                     let instance = ty::Instance::resolve_drop_in_place(tcx, ty);
@@ -134,13 +134,12 @@ pub(super) fn vtable_allocation_provider<'tcx>(
             VtblEntry::Vacant => continue,
             VtblEntry::Method(instance) => {
                 // Prepare the fn ptr we write into the vtable.
-                let fn_alloc_id = tcx.reserve_and_set_fn_alloc(*instance, CTFE_ALLOC_SALT);
+                let fn_alloc_id = tcx.reserve_and_set_fn_alloc(instance, CTFE_ALLOC_SALT);
                 let fn_ptr = Pointer::from(fn_alloc_id);
                 Scalar::from_pointer(fn_ptr, &tcx)
             }
             VtblEntry::TraitVPtr(trait_ref) => {
-                let super_trait_ref = trait_ref
-                    .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
+                let super_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref);
                 let supertrait_alloc_id = tcx.vtable_allocation((ty, Some(super_trait_ref)));
                 let vptr = Pointer::from(supertrait_alloc_id);
                 Scalar::from_pointer(vptr, &tcx)
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 2dcba8c2f82..3e8a3d1a289 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -206,7 +206,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
             | ty::ConstKind::Bound(..)
             | ty::ConstKind::Error(_) => {}
 
-            ty::ConstKind::Value(ty, _) => stack.push(ty.into()),
+            ty::ConstKind::Value(cv) => stack.push(cv.ty.into()),
 
             ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
             ty::ConstKind::Unevaluated(ct) => {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 3853b95f78b..cc6d69710e4 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -46,7 +46,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         match c.kind() {
             ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
-            ty::ConstKind::Value(_, val) => convert.valtree_to_pat(val, ty),
+            ty::ConstKind::Value(cv) => convert.valtree_to_pat(cv.valtree, cv.ty),
             _ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c),
         }
     }
@@ -214,6 +214,7 @@ impl<'tcx> ConstToPat<'tcx> {
     }
 
     // Recursive helper for `to_pat`; invoke that (instead of calling this directly).
+    // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
     #[instrument(skip(self), level = "debug")]
     fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
         let span = self.span;
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index d53848f7461..150594ab94d 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1138,11 +1138,12 @@ fn create_mono_items_for_vtable_methods<'tcx>(
         bug!("create_mono_items_for_vtable_methods: {trait_ty:?} not a trait type");
     };
     if let Some(principal) = trait_ty.principal() {
-        let poly_trait_ref = principal.with_self_ty(tcx, impl_ty);
-        assert!(!poly_trait_ref.has_escaping_bound_vars());
+        let trait_ref =
+            tcx.instantiate_bound_regions_with_erased(principal.with_self_ty(tcx, impl_ty));
+        assert!(!trait_ref.has_escaping_bound_vars());
 
         // Walk all methods of the trait, including those of its supertraits
-        let entries = tcx.vtable_entries(poly_trait_ref);
+        let entries = tcx.vtable_entries(trait_ref);
         debug!(?entries);
         let methods = entries
             .iter()
@@ -1197,7 +1198,12 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
             }
         }
         GlobalAlloc::VTable(ty, dyn_ty) => {
-            let alloc_id = tcx.vtable_allocation((ty, dyn_ty.principal()));
+            let alloc_id = tcx.vtable_allocation((
+                ty,
+                dyn_ty
+                    .principal()
+                    .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
+            ));
             collect_alloc(tcx, alloc_id, output)
         }
     }
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 62a7c84bc28..7eeed721d5a 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -522,7 +522,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
             // FIXME: See comment above -- we could fold the region separately or something.
             ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Value(_, _)
+            | ty::ConstKind::Value(_)
             | ty::ConstKind::Error(_)
             | ty::ConstKind::Expr(_) => return c.super_fold_with(self),
         };
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 8d1194ee539..1fa35b60304 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -160,9 +160,7 @@ where
             ty::ConstKind::Infer(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
             }
-            ty::ConstKind::Placeholder(_)
-            | ty::ConstKind::Value(_, _)
-            | ty::ConstKind::Error(_) => {
+            ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
             // We can freely ICE here as:
@@ -199,7 +197,7 @@ where
                 unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`")
             }
             ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct),
-            ty::ConstKind::Value(ty, _) => ty,
+            ty::ConstKind::Value(cv) => cv.ty(),
             ty::ConstKind::Placeholder(placeholder) => {
                 self.cx().find_const_ty_from_env(goal.param_env, placeholder)
             }
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index 09648e28df4..5f0c1afdf64 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -103,7 +103,7 @@ fn encode_args<'tcx>(
 /// <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling.literal>).
 fn encode_const<'tcx>(
     tcx: TyCtxt<'tcx>,
-    c: Const<'tcx>,
+    ct: Const<'tcx>,
     ct_ty: Ty<'tcx>,
     dict: &mut FxHashMap<DictKey<'tcx>, usize>,
     options: EncodeTyOptions,
@@ -111,7 +111,7 @@ fn encode_const<'tcx>(
     // L<element-type>[n][<element-value>]E as literal argument
     let mut s = String::from('L');
 
-    match c.kind() {
+    match ct.kind() {
         // Const parameters
         ty::ConstKind::Param(..) => {
             // L<element-type>E as literal argument
@@ -121,18 +121,18 @@ fn encode_const<'tcx>(
         }
 
         // Literal arguments
-        ty::ConstKind::Value(ct_ty, ..) => {
+        ty::ConstKind::Value(cv) => {
             // L<element-type>[n]<element-value>E as literal argument
 
             // Element type
-            s.push_str(&encode_ty(tcx, ct_ty, dict, options));
+            s.push_str(&encode_ty(tcx, cv.ty, dict, options));
 
             // The only allowed types of const values are bool, u8, u16, u32,
             // u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The
             // bool value false is encoded as 0 and true as 1.
-            match ct_ty.kind() {
+            match cv.ty.kind() {
                 ty::Int(ity) => {
-                    let bits = c
+                    let bits = cv
                         .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
                         .expect("expected monomorphic const in cfi");
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
@@ -142,30 +142,30 @@ fn encode_const<'tcx>(
                     let _ = write!(s, "{val}");
                 }
                 ty::Uint(_) => {
-                    let val = c
+                    let val = cv
                         .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized())
                         .expect("expected monomorphic const in cfi");
                     let _ = write!(s, "{val}");
                 }
                 ty::Bool => {
-                    let val = c.try_to_bool().expect("expected monomorphic const in cfi");
+                    let val = cv.try_to_bool().expect("expected monomorphic const in cfi");
                     let _ = write!(s, "{val}");
                 }
                 _ => {
-                    bug!("encode_const: unexpected type `{:?}`", ct_ty);
+                    bug!("encode_const: unexpected type `{:?}`", cv.ty);
                 }
             }
         }
 
         _ => {
-            bug!("encode_const: unexpected kind `{:?}`", c.kind());
+            bug!("encode_const: unexpected kind `{:?}`", ct.kind());
         }
     }
 
     // Close the "L..E" pair
     s.push('E');
 
-    compress(dict, DictKey::Const(c), &mut s);
+    compress(dict, DictKey::Const(ct), &mut s);
 
     s
 }
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 9c6186d6882..b711c238d59 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -51,8 +51,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
     // Transforms a ty:Ty for being encoded and used in the substitution dictionary.
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         match t.kind() {
-            ty::Array(..)
-            | ty::Closure(..)
+            ty::Closure(..)
             | ty::Coroutine(..)
             | ty::CoroutineClosure(..)
             | ty::CoroutineWitness(..)
@@ -67,6 +66,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
             | ty::Tuple(..)
             | ty::UnsafeBinder(_) => t.super_fold_with(self),
 
+            // Don't transform the type of the array length and keep it as `usize`.
+            // This is required for `try_to_target_usize` to work correctly.
+            &ty::Array(inner, len) => {
+                let inner = self.fold_ty(inner);
+                Ty::new_array_with_const_len(self.tcx, inner, len)
+            }
+
             ty::Bool => {
                 if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
                     // Note: on all platforms that Rust's currently supports, its size and alignment
diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index f3c21992784..b4597ae2515 100644
--- a/compiler/rustc_session/src/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
@@ -1,10 +1,9 @@
 use std::cmp;
 
 use rustc_abi::{Align, Size};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lock;
 use rustc_span::Symbol;
-use rustc_span::def_id::DefId;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct VariantInfo {
@@ -71,29 +70,9 @@ pub struct TypeSizeInfo {
     pub variants: Vec<VariantInfo>,
 }
 
-pub struct VTableSizeInfo {
-    pub trait_name: String,
-
-    /// Number of entries in a vtable with the current algorithm
-    /// (i.e. with upcasting).
-    pub entries: usize,
-
-    /// Number of entries in a vtable, as-if we did not have trait upcasting.
-    pub entries_ignoring_upcasting: usize,
-
-    /// Number of entries in a vtable needed solely for upcasting
-    /// (i.e. `entries - entries_ignoring_upcasting`).
-    pub entries_for_upcasting: usize,
-
-    /// Cost of having upcasting in % relative to the number of entries without
-    /// upcasting (i.e. `entries_for_upcasting / entries_ignoring_upcasting * 100%`).
-    pub upcasting_cost_percent: f64,
-}
-
 #[derive(Default)]
 pub struct CodeStats {
     type_sizes: Lock<FxHashSet<TypeSizeInfo>>,
-    vtable_sizes: Lock<FxHashMap<DefId, VTableSizeInfo>>,
 }
 
 impl CodeStats {
@@ -127,14 +106,6 @@ impl CodeStats {
         self.type_sizes.borrow_mut().insert(info);
     }
 
-    pub fn record_vtable_size(&self, trait_did: DefId, trait_name: &str, info: VTableSizeInfo) {
-        let prev = self.vtable_sizes.lock().insert(trait_did, info);
-        assert!(
-            prev.is_none(),
-            "size of vtable for `{trait_name}` ({trait_did:?}) is already recorded"
-        );
-    }
-
     pub fn print_type_sizes(&self) {
         let type_sizes = self.type_sizes.borrow();
         // We will soon sort, so the initial order does not matter.
@@ -238,33 +209,4 @@ impl CodeStats {
             }
         }
     }
-
-    pub fn print_vtable_sizes(&self, crate_name: Symbol) {
-        // We will soon sort, so the initial order does not matter.
-        #[allow(rustc::potential_query_instability)]
-        let mut infos =
-            std::mem::take(&mut *self.vtable_sizes.lock()).into_values().collect::<Vec<_>>();
-
-        // Primary sort: cost % in reverse order (from largest to smallest)
-        // Secondary sort: trait_name
-        infos.sort_by(|a, b| {
-            a.upcasting_cost_percent
-                .total_cmp(&b.upcasting_cost_percent)
-                .reverse()
-                .then_with(|| a.trait_name.cmp(&b.trait_name))
-        });
-
-        for VTableSizeInfo {
-            trait_name,
-            entries,
-            entries_ignoring_upcasting,
-            entries_for_upcasting,
-            upcasting_cost_percent,
-        } in infos
-        {
-            println!(
-                r#"print-vtable-sizes {{ "crate_name": "{crate_name}", "trait_name": "{trait_name}", "entries": "{entries}", "entries_ignoring_upcasting": "{entries_ignoring_upcasting}", "entries_for_upcasting": "{entries_for_upcasting}", "upcasting_cost_percent": "{upcasting_cost_percent}" }}"#
-            );
-        }
-    }
 }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index c7af40a8ad4..e3236350cad 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2034,8 +2034,6 @@ options! {
          Note that this overwrites the effect `-Clink-dead-code` has on collection!"),
     print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
         "print layout information for each type encountered (default: no)"),
-    print_vtable_sizes: bool = (false, parse_bool, [UNTRACKED],
-        "print size comparison between old and new vtable layouts (default: no)"),
     proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
          "show backtraces for panics during proc-macro execution (default: no)"),
     proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread,
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 31c7e6c3eb4..cdc56782a26 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -450,8 +450,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let tcx = tables.tcx;
         let ty = ty::Ty::new_static_str(tcx);
         let bytes = value.as_bytes();
-        let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes);
-        let val = tcx.valtree_to_const_val((ty, val_tree));
+        let valtree = ty::ValTree::from_raw_bytes(tcx, bytes);
+        let cv = ty::Value { ty, valtree };
+        let val = tcx.valtree_to_const_val(cv);
         mir::Const::from_value(val, ty).stable(&mut tables)
     }
 
@@ -746,7 +747,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let tcx = tables.tcx;
         let alloc_id = tables.tcx.vtable_allocation((
             ty.internal(&mut *tables, tcx),
-            trait_ref.internal(&mut *tables, tcx),
+            trait_ref
+                .internal(&mut *tables, tcx)
+                .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
         ));
         Some(alloc_id.stable(&mut *tables))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index ff452eea23d..a2d95f0f693 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -418,23 +418,16 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
     type T = stable_mir::ty::TyConst;
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
-        let kind = match self.kind() {
-            ty::ConstKind::Value(ty, val) => {
-                let val = match val {
-                    ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
-                    ty::ValTree::Branch(branch) => {
-                        ty::ValTree::Branch(tables.tcx.lift(branch).unwrap())
-                    }
-                };
-
-                let ty = tables.tcx.lift(ty).unwrap();
-                let const_val = tables.tcx.valtree_to_const_val((ty, val));
+        let ct = tables.tcx.lift(*self).unwrap();
+        let kind = match ct.kind() {
+            ty::ConstKind::Value(cv) => {
+                let const_val = tables.tcx.valtree_to_const_val(cv);
                 if matches!(const_val, mir::ConstValue::ZeroSized) {
-                    stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables))
+                    stable_mir::ty::TyConstKind::ZSTValue(cv.ty.stable(tables))
                 } else {
                     stable_mir::ty::TyConstKind::Value(
-                        ty.stable(tables),
-                        alloc::new_allocation(ty, const_val, tables),
+                        cv.ty.stable(tables),
+                        alloc::new_allocation(cv.ty, const_val, tables),
                     )
                 }
             }
@@ -449,7 +442,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
             ty::ConstKind::Placeholder(_) => unimplemented!(),
             ty::ConstKind::Expr(_) => unimplemented!(),
         };
-        let id = tables.intern_ty_const(tables.tcx.lift(*self).unwrap());
+        let id = tables.intern_ty_const(ct);
         stable_mir::ty::TyConst::new(kind, id)
     }
 }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 879f3fac21f..8ae35572d01 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -274,14 +274,15 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
     fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
         // only print integers
         match ct.kind() {
-            ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) if ty.is_integral() => {
+            ty::ConstKind::Value(cv) if cv.ty.is_integral() => {
                 // The `pretty_print_const` formatting depends on -Zverbose-internals
                 // flag, so we cannot reuse it here.
-                let signed = matches!(ty.kind(), ty::Int(_));
+                let scalar = cv.valtree.unwrap_leaf();
+                let signed = matches!(cv.ty.kind(), ty::Int(_));
                 write!(
                     self,
                     "{:#?}",
-                    ty::ConstInt::new(scalar, signed, ty.is_ptr_sized_integral())
+                    ty::ConstInt::new(scalar, signed, cv.ty.is_ptr_sized_integral())
                 )?;
             }
             _ => self.write_str("_")?,
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 5c5ab435dbd..4312c82815c 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -151,7 +151,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
 
 pub fn typeid_for_trait_ref<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyExistentialTraitRef<'tcx>,
+    trait_ref: ty::ExistentialTraitRef<'tcx>,
 ) -> String {
     v0::mangle_typeid_for_trait_ref(tcx, trait_ref)
 }
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 4ddf530a00d..7b040a8b2c4 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -72,7 +72,7 @@ pub(super) fn mangle<'tcx>(
 
 pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyExistentialTraitRef<'tcx>,
+    trait_ref: ty::ExistentialTraitRef<'tcx>,
 ) -> String {
     // FIXME(flip1995): See comment in `mangle_typeid_for_fnabi`.
     let mut cx = SymbolMangler {
@@ -84,7 +84,7 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
         binders: vec![],
         out: String::new(),
     };
-    cx.print_def_path(trait_ref.def_id(), &[]).unwrap();
+    cx.print_def_path(trait_ref.def_id, &[]).unwrap();
     std::mem::take(&mut cx.out)
 }
 
@@ -590,8 +590,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
 
     fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
         // We only mangle a typed value if the const can be evaluated.
-        let (ct_ty, valtree) = match ct.kind() {
-            ty::ConstKind::Value(ty, val) => (ty, val),
+        let cv = match ct.kind() {
+            ty::ConstKind::Value(cv) => cv,
 
             // Should only be encountered within the identity-substituted
             // impl header of an item nested within an impl item.
@@ -619,13 +619,14 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             return Ok(());
         }
 
+        let ty::Value { ty: ct_ty, valtree } = cv;
         let start = self.out.len();
 
         match ct_ty.kind() {
             ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
                 ct_ty.print(self)?;
 
-                let mut bits = ct
+                let mut bits = cv
                     .try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized())
                     .expect("expected const to be monomorphic");
 
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 1292f46f0c9..f17452b3ba0 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -934,6 +934,7 @@ pub enum InlineAsmClobberAbi {
     LoongArch,
     PowerPC,
     S390x,
+    Bpf,
     Msp430,
 }
 
@@ -1003,6 +1004,10 @@ impl InlineAsmClobberAbi {
                 "C" | "system" => Ok(InlineAsmClobberAbi::S390x),
                 _ => Err(&["C", "system"]),
             },
+            InlineAsmArch::Bpf => match name {
+                "C" | "system" => Ok(InlineAsmClobberAbi::Bpf),
+                _ => Err(&["C", "system"]),
+            },
             InlineAsmArch::Msp430 => match name {
                 "C" | "system" => Ok(InlineAsmClobberAbi::Msp430),
                 _ => Err(&["C", "system"]),
@@ -1278,6 +1283,14 @@ impl InlineAsmClobberAbi {
                     a8, a9, a10, a11, a12, a13, a14, a15,
                 }
             },
+            InlineAsmClobberAbi::Bpf => clobbered_regs! {
+                Bpf BpfInlineAsmReg {
+                    // Refs: Section 1.1 "Registers and calling convention" in BPF ABI Recommended Conventions and Guidelines v1.0
+                    // https://www.kernel.org/doc/html/latest/bpf/standardization/abi.html#registers-and-calling-convention
+
+                    r0, r1, r2, r3, r4, r5,
+                }
+            },
             InlineAsmClobberAbi::Msp430 => clobbered_regs! {
                 Msp430 Msp430InlineAsmReg {
                     r11, r12, r13, r14, r15,
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 9cdc0801b1f..015ea97f2ac 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -546,6 +546,7 @@ impl Target {
         key!(link_env_remove, list);
         key!(asm_args, list);
         key!(cpu);
+        key!(need_explicit_cpu, bool);
         key!(features);
         key!(dynamic_linking, bool);
         key!(direct_access_external_data, Option<bool>);
@@ -720,6 +721,7 @@ impl ToJson for Target {
         target_option_val!(link_env_remove);
         target_option_val!(asm_args);
         target_option_val!(cpu);
+        target_option_val!(need_explicit_cpu);
         target_option_val!(features);
         target_option_val!(dynamic_linking);
         target_option_val!(direct_access_external_data);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index bcd2aff54bb..3fc7a07fb91 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2254,6 +2254,9 @@ pub struct TargetOptions {
     /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults
     /// to "generic".
     pub cpu: StaticCow<str>,
+    /// Whether a cpu needs to be explicitly set.
+    /// Set to true if there is no default cpu. Defaults to false.
+    pub need_explicit_cpu: bool,
     /// Default target features to pass to LLVM. These features overwrite
     /// `-Ctarget-cpu` but can be overwritten with `-Ctarget-features`.
     /// Corresponds to `llc -mattr=$features`.
@@ -2686,6 +2689,7 @@ impl Default for TargetOptions {
             link_script: None,
             asm_args: cvs![],
             cpu: "generic".into(),
+            need_explicit_cpu: false,
             features: "".into(),
             direct_access_external_data: None,
             dynamic_linking: false,
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 7c72318b4d7..055a3edcc32 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -148,8 +148,6 @@ trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement
 trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
 trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement
 
-trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
-
 trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
     .label = empty on-clause here
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 9eacd377361..117b6a76425 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -2023,14 +2023,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             _ => None,
         };
         if let Some(tykind) = tykind
-            && let hir::TyKind::Array(_, length) = tykind
-            && let Some((scalar, ty)) = sz.found.try_to_scalar()
-            && ty == self.tcx.types.usize
+            && let hir::TyKind::Array(_, length_arg) = tykind
+            && let Some(length_val) = sz.found.try_to_target_usize(self.tcx)
         {
-            let span = length.span();
             Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength {
-                span,
-                length: scalar.to_target_usize(&self.tcx).unwrap(),
+                span: length_arg.span(),
+                length: length_val,
             })
         } else {
             None
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index 8111983c539..b4e5cc6185c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -482,11 +482,10 @@ pub fn report_dyn_incompatibility<'tcx>(
     for (span, msg) in iter::zip(multi_span, messages) {
         note_span.push_span_label(span, msg);
     }
-    // FIXME(dyn_compat_renaming): Update the URL.
     err.span_note(
         note_span,
         "for a trait to be dyn compatible it needs to allow building a vtable\n\
-        for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
+        for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>",
     );
 
     // Only provide the help if its a local trait, otherwise it's not actionable.
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index c8672b9dbd2..c5ab8a71c78 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -12,7 +12,7 @@ use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty};
 use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath};
-use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt};
+use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, Region, Ty, TyCtxt};
 use rustc_span::{BytePos, Ident, Span, Symbol, kw};
 
 use crate::error_reporting::infer::ObligationCauseAsDiagArg;
@@ -23,15 +23,6 @@ use crate::fluent_generated as fluent;
 pub mod note_and_explain;
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_dump_vtable_entries)]
-pub struct DumpVTableEntries<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub trait_ref: PolyTraitRef<'a>,
-    pub entries: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(trait_selection_unable_to_construct_constant_value)]
 pub struct UnableToConstructConstantValue<'a> {
     #[primary_span]
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 2b7da4bc5ff..c8ae977b5ad 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -264,7 +264,7 @@ fn fulfillment_error_for_no_solution<'tcx>(
                     infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
                 }
                 ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env),
-                ty::ConstKind::Value(ty, _) => ty,
+                ty::ConstKind::Value(cv) => cv.ty,
                 kind => span_bug!(
                     obligation.cause.span,
                     "ConstArgHasWrongType failed but we don't know how to compute type for {kind:?}"
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 446f9eaa348..bdee6ca2afe 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -35,7 +35,7 @@ pub fn is_const_evaluatable<'tcx>(
         ty::ConstKind::Param(_)
         | ty::ConstKind::Bound(_, _)
         | ty::ConstKind::Placeholder(_)
-        | ty::ConstKind::Value(_, _)
+        | ty::ConstKind::Value(_)
         | ty::ConstKind::Error(_) => return Ok(()),
         ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
     };
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 66491d9abe1..baa94ead9d4 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -64,7 +64,7 @@ fn is_dyn_compatible(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
 }
 
 /// We say a method is *vtable safe* if it can be invoked on a trait
-/// object. Note that object-safe traits can have some
+/// object. Note that dyn-compatible traits can have some
 /// non-vtable-safe methods, so long as they require `Self: Sized` or
 /// otherwise ensure that they cannot be used when `Self = Trait`.
 pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool {
@@ -421,7 +421,7 @@ fn virtual_call_violations_for_method<'tcx>(
     let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));
 
     // Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
-    // However, this is already considered object-safe. We allow it as a special case here.
+    // However, this is already considered dyn compatible. We allow it as a special case here.
     // FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
     // `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
     if receiver_ty != tcx.types.self_param {
@@ -631,7 +631,7 @@ fn object_ty_for_trait<'tcx>(
 /// - `self: Pin<Box<Self>>` requires `Pin<Box<Self>>: DispatchFromDyn<Pin<Box<dyn Trait>>>`.
 ///
 /// The only case where the receiver is not dispatchable, but is still a valid receiver
-/// type (just not object-safe), is when there is more than one level of pointer indirection.
+/// type (just not dyn compatible), is when there is more than one level of pointer indirection.
 /// E.g., `self: &&Self`, `self: &Rc<Self>`, `self: Box<Box<Self>>`. In these cases, there
 /// is no way, or at least no inexpensive way, to coerce the receiver from the version where
 /// `Self = dyn Trait` to the version where `Self = T`, where `T` is the unknown erased type
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 7529ee128f5..f2d2dd2f3ce 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -479,7 +479,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         ty::ConstKind::Error(_) => {
                             return ProcessResult::Changed(PendingPredicateObligations::new());
                         }
-                        ty::ConstKind::Value(ty, _) => ty,
+                        ty::ConstKind::Value(cv) => cv.ty,
                         ty::ConstKind::Unevaluated(uv) => {
                             infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 6b6e0b32385..99ce1fd9fb4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -962,7 +962,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             return Ok(EvaluatedToAmbig);
                         }
                         ty::ConstKind::Error(_) => return Ok(EvaluatedToOk),
-                        ty::ConstKind::Value(ty, _) => ty,
+                        ty::ConstKind::Value(cv) => cv.ty,
                         ty::ConstKind::Unevaluated(uv) => {
                             self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args)
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index c9fb2a757e1..d30363ec158 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -25,7 +25,7 @@ use tracing::debug;
 /// trait Bar {}
 /// trait Foo = Bar + Bar;
 ///
-/// let not_object_safe: dyn Foo; // bad, two `Bar` principals.
+/// let dyn_incompatible: dyn Foo; // bad, two `Bar` principals.
 /// ```
 pub fn expand_trait_aliases<'tcx>(
     tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index b5bc8364c7b..000e6a765d3 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -2,26 +2,22 @@ use std::fmt::Debug;
 use std::ops::ControlFlow;
 
 use rustc_hir::def_id::DefId;
-use rustc_infer::infer::at::ToTrace;
-use rustc_infer::infer::{BoundRegionConversionTime, TyCtxtInferExt};
-use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::util::PredicateSet;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
     self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Upcast, VtblEntry,
 };
-use rustc_span::{DUMMY_SP, Span, sym};
+use rustc_span::DUMMY_SP;
 use smallvec::{SmallVec, smallvec};
 use tracing::debug;
 
-use crate::errors::DumpVTableEntries;
-use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method};
+use crate::traits::{impossible_predicates, is_vtable_safe_method};
 
 #[derive(Clone, Debug)]
 pub enum VtblSegment<'tcx> {
     MetadataDSA,
-    TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool },
+    TraitOwnEntries { trait_ref: ty::TraitRef<'tcx>, emit_vptr: bool },
 }
 
 /// Prepare the segments for a vtable
@@ -29,7 +25,7 @@ pub enum VtblSegment<'tcx> {
 // about our `Self` type here.
 pub fn prepare_vtable_segments<'tcx, T>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
     segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>,
 ) -> Option<T> {
     prepare_vtable_segments_inner(tcx, trait_ref, segment_visitor).break_value()
@@ -39,7 +35,7 @@ pub fn prepare_vtable_segments<'tcx, T>(
 /// such that we can use `?` in the body.
 fn prepare_vtable_segments_inner<'tcx, T>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
     mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>,
 ) -> ControlFlow<T> {
     // The following constraints holds for the final arrangement.
@@ -92,7 +88,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
     let mut emit_vptr_on_new_entry = false;
     let mut visited = PredicateSet::new(tcx);
     let predicate = trait_ref.upcast(tcx);
-    let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> =
+    let mut stack: SmallVec<[(ty::TraitRef<'tcx>, _, _); 5]> =
         smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))];
     visited.insert(predicate);
 
@@ -125,10 +121,18 @@ fn prepare_vtable_segments_inner<'tcx, T>(
             let &(inner_most_trait_ref, _, _) = stack.last().unwrap();
 
             let mut direct_super_traits_iter = tcx
-                .explicit_super_predicates_of(inner_most_trait_ref.def_id())
+                .explicit_super_predicates_of(inner_most_trait_ref.def_id)
                 .iter_identity_copied()
                 .filter_map(move |(pred, _)| {
-                    pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause()
+                    pred.instantiate_supertrait(tcx, ty::Binder::dummy(inner_most_trait_ref))
+                        .as_trait_clause()
+                })
+                .map(move |pred| {
+                    tcx.normalize_erasing_late_bound_regions(
+                        ty::TypingEnv::fully_monomorphized(),
+                        pred,
+                    )
+                    .trait_ref
                 });
 
             // Find an unvisited supertrait
@@ -136,16 +140,11 @@ fn prepare_vtable_segments_inner<'tcx, T>(
                 .find(|&super_trait| visited.insert(super_trait.upcast(tcx)))
             {
                 // Push it to the stack for the next iteration of 'diving_in to pick up
-                Some(unvisited_super_trait) => {
-                    // We're throwing away potential constness of super traits here.
-                    // FIXME: handle ~const super traits
-                    let next_super_trait = unvisited_super_trait.map_bound(|t| t.trait_ref);
-                    stack.push((
-                        next_super_trait,
-                        emit_vptr_on_new_entry,
-                        maybe_iter(Some(direct_super_traits_iter)),
-                    ))
-                }
+                Some(next_super_trait) => stack.push((
+                    next_super_trait,
+                    emit_vptr_on_new_entry,
+                    maybe_iter(Some(direct_super_traits_iter)),
+                )),
 
                 // There are no more unvisited direct super traits, dive-in finished
                 None => break 'diving_in,
@@ -154,8 +153,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
 
         // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
         while let Some((inner_most_trait_ref, emit_vptr, mut siblings)) = stack.pop() {
-            let has_entries =
-                has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id());
+            let has_entries = has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id);
 
             segment_visitor(VtblSegment::TraitOwnEntries {
                 trait_ref: inner_most_trait_ref,
@@ -169,11 +167,6 @@ fn prepare_vtable_segments_inner<'tcx, T>(
             if let Some(next_inner_most_trait_ref) =
                 siblings.find(|&sibling| visited.insert(sibling.upcast(tcx)))
             {
-                // We're throwing away potential constness of super traits here.
-                // FIXME: handle ~const super traits
-                let next_inner_most_trait_ref =
-                    next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
-
                 stack.push((next_inner_most_trait_ref, emit_vptr_on_new_entry, siblings));
 
                 // just pushed a new trait onto the stack, so we need to go through its super traits
@@ -192,15 +185,6 @@ fn maybe_iter<I: Iterator>(i: Option<I>) -> impl Iterator<Item = I::Item> {
     i.into_iter().flatten()
 }
 
-fn dump_vtable_entries<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    sp: Span,
-    trait_ref: ty::PolyTraitRef<'tcx>,
-    entries: &[VtblEntry<'tcx>],
-) {
-    tcx.dcx().emit_err(DumpVTableEntries { span: sp, trait_ref, entries: format!("{entries:#?}") });
-}
-
 fn has_own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
     own_existential_vtable_entries_iter(tcx, trait_def_id).next().is_some()
 }
@@ -239,8 +223,15 @@ fn own_existential_vtable_entries_iter(
 /// that come from `trait_ref`, including its supertraits.
 fn vtable_entries<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::PolyTraitRef<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
 ) -> &'tcx [VtblEntry<'tcx>] {
+    debug_assert!(!trait_ref.has_non_region_infer() && !trait_ref.has_non_region_param());
+    debug_assert_eq!(
+        tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref),
+        trait_ref,
+        "vtable trait ref should be normalized"
+    );
+
     debug!("vtable_entries({:?})", trait_ref);
 
     let mut entries = vec![];
@@ -251,33 +242,26 @@ fn vtable_entries<'tcx>(
                 entries.extend(TyCtxt::COMMON_VTABLE_ENTRIES);
             }
             VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
-                let existential_trait_ref = trait_ref
-                    .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
+                let existential_trait_ref = ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref);
 
                 // Lookup the shape of vtable for the trait.
                 let own_existential_entries =
-                    tcx.own_existential_vtable_entries(existential_trait_ref.def_id());
+                    tcx.own_existential_vtable_entries(existential_trait_ref.def_id);
 
                 let own_entries = own_existential_entries.iter().copied().map(|def_id| {
                     debug!("vtable_entries: trait_method={:?}", def_id);
 
                     // The method may have some early-bound lifetimes; add regions for those.
-                    let args = trait_ref.map_bound(|trait_ref| {
+                    // FIXME: Is this normalize needed?
+                    let args = tcx.normalize_erasing_regions(
+                        ty::TypingEnv::fully_monomorphized(),
                         GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
                             GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
                             GenericParamDefKind::Type { .. }
                             | GenericParamDefKind::Const { .. } => {
                                 trait_ref.args[param.index as usize]
                             }
-                        })
-                    });
-
-                    // The trait type may have higher-ranked lifetimes in it;
-                    // erase them if they appear, so that we get the type
-                    // at some particular call site.
-                    let args = tcx.normalize_erasing_late_bound_regions(
-                        ty::TypingEnv::fully_monomorphized(),
-                        args,
+                        }),
                     );
 
                     // It's possible that the method relies on where-clauses that
@@ -317,11 +301,6 @@ fn vtable_entries<'tcx>(
 
     let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback);
 
-    if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) {
-        let sp = tcx.def_span(trait_ref.def_id());
-        dump_vtable_entries(tcx, sp, trait_ref, &entries);
-    }
-
     tcx.arena.alloc_from_iter(entries)
 }
 
@@ -329,14 +308,20 @@ fn vtable_entries<'tcx>(
 // for `Supertrait`'s methods in the vtable of `Subtrait`.
 pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRef<'tcx>) -> usize {
     debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param());
+    debug_assert_eq!(
+        tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key),
+        key,
+        "vtable trait ref should be normalized"
+    );
 
     let ty::Dynamic(source, _, _) = *key.self_ty().kind() else {
         bug!();
     };
-    let source_principal =
-        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let source_principal = tcx.instantiate_bound_regions_with_erased(
+        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
+    );
 
-    let target_principal = ty::Binder::dummy(ty::ExistentialTraitRef::erase_self_ty(tcx, key));
+    let target_principal = ty::ExistentialTraitRef::erase_self_ty(tcx, key);
 
     let vtable_segment_callback = {
         let mut vptr_offset = 0;
@@ -346,17 +331,14 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
                     vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
                 }
                 VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
-                    if trait_refs_are_compatible(
-                        tcx,
-                        vtable_principal
-                            .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
-                        target_principal,
-                    ) {
+                    if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal)
+                        == target_principal
+                    {
                         return ControlFlow::Break(vptr_offset);
                     }
 
                     vptr_offset +=
-                        tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
+                        tcx.own_existential_vtable_entries(vtable_principal.def_id).len();
 
                     if emit_vptr {
                         vptr_offset += 1;
@@ -382,20 +364,27 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
     ),
 ) -> Option<usize> {
     debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param());
+    debug_assert_eq!(
+        tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key),
+        key,
+        "upcasting trait refs should be normalized"
+    );
+
     let (source, target) = key;
 
     // If the target principal is `None`, we can just return `None`.
     let ty::Dynamic(target, _, _) = *target.kind() else {
         bug!();
     };
-    let target_principal = target.principal()?;
+    let target_principal = tcx.instantiate_bound_regions_with_erased(target.principal()?);
 
     // Given that we have a target principal, it is a bug for there not to be a source principal.
     let ty::Dynamic(source, _, _) = *source.kind() else {
         bug!();
     };
-    let source_principal =
-        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let source_principal = tcx.instantiate_bound_regions_with_erased(
+        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
+    );
 
     let vtable_segment_callback = {
         let mut vptr_offset = 0;
@@ -406,13 +395,10 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
                 }
                 VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
                     vptr_offset +=
-                        tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
-                    if trait_refs_are_compatible(
-                        tcx,
-                        vtable_principal
-                            .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
-                        target_principal,
-                    ) {
+                        tcx.own_existential_vtable_entries(vtable_principal.def_id).len();
+                    if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal)
+                        == target_principal
+                    {
                         if emit_vptr {
                             return ControlFlow::Break(Some(vptr_offset));
                         } else {
@@ -432,41 +418,6 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
     prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap()
 }
 
-fn trait_refs_are_compatible<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    hr_vtable_principal: ty::PolyExistentialTraitRef<'tcx>,
-    hr_target_principal: ty::PolyExistentialTraitRef<'tcx>,
-) -> bool {
-    if hr_vtable_principal.def_id() != hr_target_principal.def_id() {
-        return false;
-    }
-
-    let (infcx, param_env) =
-        tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized());
-    let ocx = ObligationCtxt::new(&infcx);
-    let hr_source_principal =
-        ocx.normalize(&ObligationCause::dummy(), param_env, hr_vtable_principal);
-    let hr_target_principal =
-        ocx.normalize(&ObligationCause::dummy(), param_env, hr_target_principal);
-    infcx.enter_forall(hr_target_principal, |target_principal| {
-        let source_principal = infcx.instantiate_binder_with_fresh_vars(
-            DUMMY_SP,
-            BoundRegionConversionTime::HigherRankedType,
-            hr_source_principal,
-        );
-        let Ok(()) = ocx.eq_trace(
-            &ObligationCause::dummy(),
-            param_env,
-            ToTrace::to_trace(&ObligationCause::dummy(), hr_target_principal, hr_source_principal),
-            target_principal,
-            source_principal,
-        ) else {
-            return false;
-        };
-        ocx.select_all_or_error().is_empty()
-    })
-}
-
 pub(super) fn provide(providers: &mut Providers) {
     *providers = Providers {
         own_existential_vtable_entries,
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index ad86813c87e..a50cc8f5932 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -128,16 +128,16 @@ mod rustc {
         pub fn from_const<'tcx>(
             tcx: TyCtxt<'tcx>,
             param_env: ParamEnv<'tcx>,
-            c: Const<'tcx>,
+            ct: Const<'tcx>,
         ) -> Option<Self> {
             use rustc_middle::ty::ScalarInt;
             use rustc_span::sym;
 
-            let Some((cv, ty)) = c.try_to_valtree() else {
+            let Some(cv) = ct.try_to_value() else {
                 return None;
             };
 
-            let adt_def = ty.ty_adt_def()?;
+            let adt_def = cv.ty.ty_adt_def()?;
 
             assert_eq!(
                 tcx.require_lang_item(LangItem::TransmuteOpts, None),
@@ -147,7 +147,7 @@ mod rustc {
             );
 
             let variant = adt_def.non_enum_variant();
-            let fields = match cv {
+            let fields = match cv.valtree {
                 ValTree::Branch(branch) => branch,
                 _ => {
                     return Some(Self {
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 51a7c976f60..931c36137ee 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -22,16 +22,16 @@ fn destructure_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     const_: ty::Const<'tcx>,
 ) -> ty::DestructuredConst<'tcx> {
-    let ty::ConstKind::Value(ct_ty, valtree) = const_.kind() else {
+    let ty::ConstKind::Value(cv) = const_.kind() else {
         bug!("cannot destructure constant {:?}", const_)
     };
 
-    let branches = match valtree {
+    let branches = match cv.valtree {
         ty::ValTree::Branch(b) => b,
         _ => bug!("cannot destructure constant {:?}", const_),
     };
 
-    let (fields, variant) = match ct_ty.kind() {
+    let (fields, variant) = match cv.ty.kind() {
         ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
             // construct the consts for the elements of the array/slice
             let field_consts = branches
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index a04c7536118..2f258b23f2d 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -144,13 +144,13 @@ fn univariant_uninterned<'tcx>(
     cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err))
 }
 
-fn validate_const_with_value<'tcx>(
+fn extract_const_value<'tcx>(
     const_: ty::Const<'tcx>,
     ty: Ty<'tcx>,
     cx: &LayoutCx<'tcx>,
-) -> Result<ty::Const<'tcx>, &'tcx LayoutError<'tcx>> {
+) -> Result<ty::Value<'tcx>, &'tcx LayoutError<'tcx>> {
     match const_.kind() {
-        ty::ConstKind::Value(..) => Ok(const_),
+        ty::ConstKind::Value(cv) => Ok(cv),
         ty::ConstKind::Error(guar) => {
             return Err(error(cx, LayoutError::ReferencesError(guar)));
         }
@@ -209,13 +209,12 @@ fn layout_of_uncached<'tcx>(
                         &mut layout.backend_repr
                     {
                         if let Some(start) = start {
-                            scalar.valid_range_mut().start =
-                                validate_const_with_value(start, ty, cx)?
-                                    .try_to_bits(tcx, cx.typing_env)
-                                    .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
+                            scalar.valid_range_mut().start = extract_const_value(start, ty, cx)?
+                                .try_to_bits(tcx, cx.typing_env)
+                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                         }
                         if let Some(end) = end {
-                            let mut end = validate_const_with_value(end, ty, cx)?
+                            let mut end = extract_const_value(end, ty, cx)?
                                 .try_to_bits(tcx, cx.typing_env)
                                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                             if !include_end {
@@ -348,9 +347,7 @@ fn layout_of_uncached<'tcx>(
 
         // Arrays and slices.
         ty::Array(element, count) => {
-            let count = validate_const_with_value(count, ty, cx)?
-                .to_valtree()
-                .0
+            let count = extract_const_value(count, ty, cx)?
                 .try_to_target_usize(tcx)
                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index 03dfe547ced..aafc0907ae1 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -31,7 +31,7 @@ pub enum ConstKind<I: Interner> {
     Unevaluated(ty::UnevaluatedConst<I>),
 
     /// Used to hold computed value.
-    Value(I::Ty, I::ValueConst),
+    Value(I::ValueConst),
 
     /// A placeholder for a const which could not be computed; this is
     /// propagated to avoid useless error messages.
@@ -52,7 +52,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
             Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var),
             Placeholder(placeholder) => write!(f, "{placeholder:?}"),
             Unevaluated(uv) => write!(f, "{uv:?}"),
-            Value(ty, valtree) => write!(f, "({valtree:?}: {ty:?})"),
+            Value(val) => write!(f, "{val:?}"),
             Error(_) => write!(f, "{{const error}}"),
             Expr(expr) => write!(f, "{expr:?}"),
         }
diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs
index 9b3ff14d507..9955e92b55a 100644
--- a/compiler/rustc_type_ir/src/fast_reject.rs
+++ b/compiler/rustc_type_ir/src/fast_reject.rs
@@ -483,8 +483,8 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
         };
 
         match lhs.kind() {
-            ty::ConstKind::Value(_, lhs_val) => match rhs.kind() {
-                ty::ConstKind::Value(_, rhs_val) => lhs_val == rhs_val,
+            ty::ConstKind::Value(lhs_val) => match rhs.kind() {
+                ty::ConstKind::Value(rhs_val) => lhs_val.valtree() == rhs_val.valtree(),
                 _ => false,
             },
 
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 872cf668018..4e6d645e6fa 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -286,6 +286,11 @@ pub trait Const<I: Interner<Const = Self>>:
     }
 }
 
+pub trait ValueConst<I: Interner<ValueConst = Self>>: Copy + Debug + Hash + Eq {
+    fn ty(self) -> I::Ty;
+    fn valtree(self) -> I::ValTree;
+}
+
 pub trait ExprConst<I: Interner<ExprConst = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
     fn args(self) -> I::GenericArgs;
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 0c3b0758f0f..a6c72da0c56 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -112,8 +112,9 @@ pub trait Interner:
     type PlaceholderConst: PlaceholderLike;
     type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
     type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
-    type ValueConst: Copy + Debug + Hash + Eq;
+    type ValueConst: ValueConst<Self>;
     type ExprConst: ExprConst<Self>;
+    type ValTree: Copy + Debug + Hash + Eq;
 
     // Kinds of regions
     type Region: Region<Self>;
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index e628b66d2f0..5b696ee5ed4 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -606,7 +606,9 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
             true
         }
         (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
-        (ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val,
+        (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
+            a_val.valtree() == b_val.valtree()
+        }
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
         // and is the better alternative to waiting until `generic_const_exprs` can
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 80f6e32b6b2..e5c1a64c12e 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -468,9 +468,11 @@ pub fn spin_loop() {
 /// // No assumptions can be made about either operand, so the multiplication is not optimized out.
 /// let y = black_box(5) * black_box(10);
 /// ```
+///
+/// During constant evaluation, `black_box` is treated as a no-op.
 #[inline]
 #[stable(feature = "bench_black_box", since = "1.66.0")]
-#[rustc_const_unstable(feature = "const_black_box", issue = "none")]
+#[rustc_const_stable(feature = "const_black_box", since = "CURRENT_RUSTC_VERSION")]
 pub const fn black_box<T>(dummy: T) -> T {
     crate::intrinsics::black_box(dummy)
 }
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 41b2ffad668..c0d435f99c0 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -3725,6 +3725,7 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u
 #[rustc_nounwind]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
+#[rustc_intrinsic_const_stable_indirect]
 pub const fn black_box<T>(_dummy: T) -> T {
     unimplemented!()
 }
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index ac5307a671d..0d8c3ef906b 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -276,10 +276,9 @@ impl<T: Copy> Clone for MaybeUninit<T> {
 impl<T> fmt::Debug for MaybeUninit<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>").
-        // This needs to be adjusted if `MaybeUninit` moves modules.
         let full_name = type_name::<Self>();
-        let short_name = full_name.split_once("mem::maybe_uninit::").unwrap().1;
-        f.pad(short_name)
+        let prefix_len = full_name.find("MaybeUninit").unwrap();
+        f.pad(&full_name[prefix_len..])
     }
 }
 
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 8fb1588e60b..5e45974b3d4 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -670,7 +670,8 @@ impl f128 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f128)]
@@ -696,7 +697,8 @@ impl f128 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f128)]
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 8c2af74b8f8..e3176cd1688 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -662,7 +662,8 @@ impl f16 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f16)]
@@ -687,7 +688,8 @@ impl f16 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// #![feature(f16)]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 817bedbd44f..4d42997369f 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -874,7 +874,8 @@ impl f32 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0f32;
@@ -895,7 +896,8 @@ impl f32 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0f32;
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 1b0651a0def..907971d303f 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -892,7 +892,8 @@ impl f64 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmax.
+    /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0_f64;
@@ -913,7 +914,8 @@ impl f64 {
     /// If one of the arguments is NaN, then the other argument is returned.
     /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
     /// this function handles all NaNs the same way and avoids minNum's problems with associativity.
-    /// This also matches the behavior of libm’s fmin.
+    /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal
+    /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically.
     ///
     /// ```
     /// let x = 1.0_f64;
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index e38ef1e147c..8b116cecb52 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -12,6 +12,9 @@ pub use crate::marker::{Copy, Send, Sized, Sync, Unpin};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
+#[stable(feature = "async_closure", since = "1.85.0")]
+#[doc(no_inline)]
+pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
 
 // Re-exported functions
 #[stable(feature = "core_prelude", since = "1.4.0")]
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 0607d508a48..7fe72862608 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -14,7 +14,6 @@
 #![feature(bstr)]
 #![feature(cell_update)]
 #![feature(clone_to_uninit)]
-#![feature(const_black_box)]
 #![feature(const_eval_select)]
 #![feature(const_swap_nonoverlapping)]
 #![feature(const_trait_impl)]
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 1f8aac48a9a..a5b0111adfb 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -629,9 +629,9 @@ impl File {
     /// This acquires an exclusive advisory lock; no other file handle to this file may acquire
     /// another lock.
     ///
-    /// If this file handle, or a clone of it, already holds an advisory lock the exact behavior is
-    /// unspecified and platform dependent, including the possibility that it will deadlock.
-    /// However, if this method returns, then an exclusive lock is held.
+    /// If this file handle/descriptor, or a clone of it, already holds an advisory lock the exact
+    /// behavior is unspecified and platform dependent, including the possibility that it will
+    /// deadlock. However, if this method returns, then an exclusive lock is held.
     ///
     /// If the file not open for writing, it is unspecified whether this function returns an error.
     ///
@@ -639,6 +639,9 @@ impl File {
     /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
     /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
     ///
+    /// The lock will be released when this file (along with any other file descriptors/handles
+    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
+    ///
     /// # Platform-specific behavior
     ///
     /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,
@@ -671,19 +674,22 @@ impl File {
         self.inner.lock()
     }
 
-    /// Acquire a shared advisory lock on the file. Blocks until the lock can be acquired.
+    /// Acquire a shared (non-exclusive) advisory lock on the file. Blocks until the lock can be acquired.
     ///
     /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but
-    /// none may hold an exclusive lock.
+    /// none may hold an exclusive lock at the same time.
     ///
-    /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
-    /// unspecified and platform dependent, including the possibility that it will deadlock.
-    /// However, if this method returns, then a shared lock is held.
+    /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact
+    /// behavior is unspecified and platform dependent, including the possibility that it will
+    /// deadlock. However, if this method returns, then a shared lock is held.
     ///
     /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`],
     /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
     /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
     ///
+    /// The lock will be released when this file (along with any other file descriptors/handles
+    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
+    ///
     /// # Platform-specific behavior
     ///
     /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,
@@ -716,14 +722,18 @@ impl File {
         self.inner.lock_shared()
     }
 
-    /// Acquire an exclusive advisory lock on the file. Returns `Ok(false)` if the file is locked.
+    /// Try to acquire an exclusive advisory lock on the file.
+    ///
+    /// Returns `Ok(false)` if a different lock is already held on this file (via another
+    /// handle/descriptor).
     ///
     /// This acquires an exclusive advisory lock; no other file handle to this file may acquire
     /// another lock.
     ///
-    /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
-    /// unspecified and platform dependent, including the possibility that it will deadlock.
-    /// However, if this method returns, then an exclusive lock is held.
+    /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact
+    /// behavior is unspecified and platform dependent, including the possibility that it will
+    /// deadlock. However, if this method returns `Ok(true)`, then it has acquired an exclusive
+    /// lock.
     ///
     /// If the file not open for writing, it is unspecified whether this function returns an error.
     ///
@@ -731,6 +741,9 @@ impl File {
     /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
     /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
     ///
+    /// The lock will be released when this file (along with any other file descriptors/handles
+    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
+    ///
     /// # Platform-specific behavior
     ///
     /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and
@@ -764,20 +777,25 @@ impl File {
         self.inner.try_lock()
     }
 
-    /// Acquire a shared advisory lock on the file.
-    /// Returns `Ok(false)` if the file is exclusively locked.
+    /// Try to acquire a shared (non-exclusive) advisory lock on the file.
+    ///
+    /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another
+    /// handle/descriptor).
     ///
     /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but
-    /// none may hold an exclusive lock.
+    /// none may hold an exclusive lock at the same time.
     ///
     /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
     /// unspecified and platform dependent, including the possibility that it will deadlock.
-    /// However, if this method returns, then a shared lock is held.
+    /// However, if this method returns `Ok(true)`, then it has acquired a shared lock.
     ///
     /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`],
     /// [`try_lock`], and [`unlock`]. Its interactions with other methods, such as [`read`]
     /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
     ///
+    /// The lock will be released when this file (along with any other file descriptors/handles
+    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
+    ///
     /// # Platform-specific behavior
     ///
     /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and
@@ -813,7 +831,12 @@ impl File {
 
     /// Release all locks on the file.
     ///
-    /// All remaining locks are released when the file handle, and all clones of it, are dropped.
+    /// All locks are released when the file (along with any other file descriptors/handles
+    /// duplicated or inherited from it) is closed. This method allows releasing locks without
+    /// closing the file.
+    ///
+    /// If no lock is currently held via this file descriptor/handle, this method may return an
+    /// error, or may return successfully without taking any action.
     ///
     /// # Platform-specific behavior
     ///
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 7504a0f7ad7..dccc137d6f5 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -14,10 +14,12 @@ use r_efi::protocols::{device_path, device_path_to_text, shell};
 
 use crate::ffi::{OsStr, OsString};
 use crate::io::{self, const_error};
+use crate::marker::PhantomData;
 use crate::mem::{MaybeUninit, size_of};
 use crate::os::uefi::env::boot_services;
 use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
 use crate::os::uefi::{self};
+use crate::path::Path;
 use crate::ptr::NonNull;
 use crate::slice;
 use crate::sync::atomic::{AtomicPtr, Ordering};
@@ -278,6 +280,10 @@ impl OwnedDevicePath {
     pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
         self.0.as_ptr()
     }
+
+    pub(crate) const fn borrow<'a>(&'a self) -> BorrowedDevicePath<'a> {
+        BorrowedDevicePath::new(self.0)
+    }
 }
 
 impl Drop for OwnedDevicePath {
@@ -293,13 +299,37 @@ impl Drop for OwnedDevicePath {
 
 impl crate::fmt::Debug for OwnedDevicePath {
     fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
-        match device_path_to_text(self.0) {
+        match self.borrow().to_text() {
             Ok(p) => p.fmt(f),
             Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(),
         }
     }
 }
 
+pub(crate) struct BorrowedDevicePath<'a> {
+    protocol: NonNull<r_efi::protocols::device_path::Protocol>,
+    phantom: PhantomData<&'a r_efi::protocols::device_path::Protocol>,
+}
+
+impl<'a> BorrowedDevicePath<'a> {
+    pub(crate) const fn new(protocol: NonNull<r_efi::protocols::device_path::Protocol>) -> Self {
+        Self { protocol, phantom: PhantomData }
+    }
+
+    pub(crate) fn to_text(&self) -> io::Result<OsString> {
+        device_path_to_text(self.protocol)
+    }
+}
+
+impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> {
+    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
+        match self.to_text() {
+            Ok(p) => p.fmt(f),
+            Err(_) => f.debug_struct("BorrowedDevicePath").finish_non_exhaustive(),
+        }
+    }
+}
+
 pub(crate) struct OwnedProtocol<T> {
     guid: r_efi::efi::Guid,
     handle: NonNull<crate::ffi::c_void>,
@@ -452,3 +482,21 @@ pub(crate) fn open_shell() -> Option<NonNull<shell::Protocol>> {
 
     None
 }
+
+/// Get device path protocol associated with shell mapping.
+///
+/// returns None in case no such mapping is exists
+pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result<BorrowedDevicePath<'static>> {
+    let shell =
+        open_shell().ok_or(io::const_error!(io::ErrorKind::NotFound, "UEFI Shell not found"))?;
+    let mut path = os_string_to_raw(map.as_os_str())
+        .ok_or(io::const_error!(io::ErrorKind::InvalidFilename, "Invalid UEFI shell mapping"))?;
+
+    // The Device Path Protocol pointer returned by UEFI shell is owned by the shell and is not
+    // freed throughout it's lifetime. So it has a 'static lifetime.
+    let protocol = unsafe { ((*shell.as_ptr()).get_device_path_from_map)(path.as_mut_ptr()) };
+    let protocol = NonNull::new(protocol)
+        .ok_or(io::const_error!(io::ErrorKind::NotFound, "UEFI Shell mapping not found"))?;
+
+    Ok(BorrowedDevicePath::new(protocol))
+}
diff --git a/library/std/src/sys/path/mod.rs b/library/std/src/sys/path/mod.rs
index 24a94ec7828..1fa4e80d678 100644
--- a/library/std/src/sys/path/mod.rs
+++ b/library/std/src/sys/path/mod.rs
@@ -5,12 +5,12 @@ cfg_if::cfg_if! {
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use sgx::*;
-    } else if #[cfg(any(
-        target_os = "uefi",
-        target_os = "solid_asp3",
-    ))] {
+    } else if #[cfg(target_os = "solid_asp3")] {
         mod unsupported_backslash;
         pub use unsupported_backslash::*;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+        pub use uefi::*;
     } else {
         mod unix;
         pub use unix::*;
diff --git a/library/std/src/sys/path/uefi.rs b/library/std/src/sys/path/uefi.rs
new file mode 100644
index 00000000000..a3f4a3bfe1b
--- /dev/null
+++ b/library/std/src/sys/path/uefi.rs
@@ -0,0 +1,105 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+use crate::ffi::OsStr;
+use crate::io;
+use crate::path::{Path, PathBuf, Prefix};
+use crate::sys::{helpers, unsupported_err};
+
+const FORWARD_SLASH: u8 = b'/';
+const COLON: u8 = b':';
+
+#[inline]
+pub fn is_sep_byte(b: u8) -> bool {
+    b == b'\\'
+}
+
+#[inline]
+pub fn is_verbatim_sep(b: u8) -> bool {
+    b == b'\\'
+}
+
+pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
+    None
+}
+
+pub const MAIN_SEP_STR: &str = "\\";
+pub const MAIN_SEP: char = '\\';
+
+/// UEFI paths can be of 4 types:
+///
+/// 1. Absolute Shell Path: Uses shell mappings (eg: `FS0:`). Does not exist if UEFI shell not present.
+///    It can be identified with `:`.
+///    Eg: FS0:\abc\run.efi
+///
+/// 2. Absolute Device Path: this is what we want
+///    It can be identified with `/`.
+///    Eg: PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi
+///
+/// 3: Relative root: path relative to the current volume.
+///    It will start with `\`.
+///    Eg: \abc\run.efi
+///
+/// 4: Relative
+///    Eg: run.efi
+///
+/// The algorithm is mostly taken from edk2 UEFI shell implementation and is
+/// somewhat simple. Check for the path type in order.
+///
+/// The volume mapping in Absolute Shell Path (not the rest of the path) can be converted to Device
+/// Path Protocol using `EFI_SHELL->GetDevicePathFromMap`. The rest of the path (Relative root
+/// path), can just be appended to the remaining path.
+///
+/// For Relative root, we get the current volume (either in Shell Mapping, or Device Path Protocol
+/// form) and join it with the relative root path. We then recurse the function to resolve the Shell
+/// Mapping if present.
+///
+/// For Relative paths, we use the current working directory to construct
+/// the new path and recurse the function to resolve the Shell mapping if present.
+///
+/// Finally, at the end, we get the 2nd form, i.e. Absolute Device Path, which can be used in the
+/// normal UEFI APIs such as file, process, etc.
+/// Eg: PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi
+pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
+    // Absolute Shell Path
+    if path.as_os_str().as_encoded_bytes().contains(&COLON) {
+        let mut path_components = path.components();
+        // Since path is not empty, it has at least one Component
+        let prefix = path_components.next().unwrap();
+
+        let dev_path = helpers::get_device_path_from_map(prefix.as_ref())?;
+        let mut dev_path_text = dev_path.to_text().map_err(|_| unsupported_err())?;
+
+        // UEFI Shell does not seem to end device path with `/`
+        if *dev_path_text.as_encoded_bytes().last().unwrap() != FORWARD_SLASH {
+            dev_path_text.push("/");
+        }
+
+        let mut ans = PathBuf::from(dev_path_text);
+        ans.push(path_components);
+
+        return Ok(ans);
+    }
+
+    // Absolute Device Path
+    if path.as_os_str().as_encoded_bytes().contains(&FORWARD_SLASH) {
+        return Ok(path.to_path_buf());
+    }
+
+    // cur_dir() always returns something
+    let cur_dir = crate::env::current_dir().unwrap();
+    let mut path_components = path.components();
+
+    // Relative Root
+    if path_components.next().unwrap() == crate::path::Component::RootDir {
+        let mut ans = PathBuf::new();
+        ans.push(cur_dir.components().next().unwrap());
+        ans.push(path_components);
+        return absolute(&ans);
+    }
+
+    absolute(&cur_dir.join(path))
+}
+
+pub(crate) fn is_absolute(path: &Path) -> bool {
+    let temp = path.as_os_str().as_encoded_bytes();
+    temp.contains(&COLON) || temp.contains(&FORWARD_SLASH)
+}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 5e250d18ce6..825e5452f0e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -86,6 +86,7 @@ impl Step for CrateBootstrap {
             SourceType::InTree,
             &[],
         );
+
         let crate_name = path.rsplit_once('/').unwrap().1;
         run_cargo_test(cargo, &[], &[], crate_name, crate_name, bootstrap_host, builder);
     }
@@ -3106,6 +3107,8 @@ impl Step for Bootstrap {
             &[],
         );
 
+        cargo.release_build(false);
+
         cargo
             .rustflag("-Cdebuginfo=2")
             .env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 1b413dcb07e..f6a03a386d1 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -88,12 +88,14 @@ impl HostFlags {
 #[derive(Debug)]
 pub struct Cargo {
     command: BootstrapCommand,
+    args: Vec<OsString>,
     compiler: Compiler,
     target: TargetSelection,
     rustflags: Rustflags,
     rustdocflags: Rustflags,
     hostflags: HostFlags,
     allow_features: String,
+    release_build: bool,
 }
 
 impl Cargo {
@@ -121,6 +123,10 @@ impl Cargo {
         cargo
     }
 
+    pub fn release_build(&mut self, release_build: bool) {
+        self.release_build = release_build;
+    }
+
     pub fn compiler(&self) -> Compiler {
         self.compiler
     }
@@ -153,7 +159,7 @@ impl Cargo {
     }
 
     pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Cargo {
-        self.command.arg(arg.as_ref());
+        self.args.push(arg.as_ref().into());
         self
     }
 
@@ -342,6 +348,12 @@ impl Cargo {
 
 impl From<Cargo> for BootstrapCommand {
     fn from(mut cargo: Cargo) -> BootstrapCommand {
+        if cargo.release_build {
+            cargo.args.insert(0, "--release".into());
+        }
+
+        cargo.command.args(cargo.args);
+
         let rustflags = &cargo.rustflags.0;
         if !rustflags.is_empty() {
             cargo.command.env("RUSTFLAGS", rustflags);
@@ -360,6 +372,7 @@ impl From<Cargo> for BootstrapCommand {
         if !cargo.allow_features.is_empty() {
             cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features);
         }
+
         cargo.command
     }
 }
@@ -429,13 +442,6 @@ impl Builder<'_> {
             assert_eq!(target, compiler.host);
         }
 
-        if self.config.rust_optimize.is_release() &&
-        // cargo bench/install do not accept `--release` and miri doesn't want it
-        !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest)
-        {
-            cargo.arg("--release");
-        }
-
         // Remove make-related flags to ensure Cargo can correctly set things up
         cargo.env_remove("MAKEFLAGS");
         cargo.env_remove("MFLAGS");
@@ -1218,14 +1224,20 @@ impl Builder<'_> {
             rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions");
         }
 
+        let release_build = self.config.rust_optimize.is_release() &&
+            // cargo bench/install do not accept `--release` and miri doesn't want it
+            !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest);
+
         Cargo {
             command: cargo,
+            args: vec![],
             compiler,
             target,
             rustflags,
             rustdocflags,
             hostflags,
             allow_features,
+            release_build,
         }
     }
 }
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index c6bc19f9e6c..9af88709625 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -43,6 +43,10 @@ runners:
     os: windows-2022-8core-32gb
     <<: *base-job
 
+  - &job-windows-25-8c
+    os: windows-2025-8core-32gb
+    <<: *base-job
+
   - &job-aarch64-linux
     # Free some disk space to avoid running out of space during the build.
     free_disk: true
@@ -524,7 +528,7 @@ auto:
       # We are intentionally allowing an old toolchain on this builder (and that's
       # incompatible with LLVM downloads today).
       NO_DOWNLOAD_CI_LLVM: 1
-    <<: *job-windows-8c
+    <<: *job-windows-25-8c
 
   # x86_64-mingw is split into two jobs to run tests in parallel.
   - name: x86_64-mingw-1
diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
index 1d9fa1b52d5..cd215277e69 100644
--- a/src/doc/rustc-dev-guide/src/building/new-target.md
+++ b/src/doc/rustc-dev-guide/src/building/new-target.md
@@ -4,8 +4,13 @@ These are a set of steps to add support for a new target. There are
 numerous end states and paths to get there, so not all sections may be
 relevant to your desired goal.
 
+See also the associated documentation in the
+[target tier policy][target_tier_policy_add].
+
 <!-- toc -->
 
+[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
+
 ## Specifying a new LLVM
 
 For very new targets, you may need to use a different fork of LLVM
diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md
index a2a6c8085df..e2097b26e5c 100644
--- a/src/doc/rustc-dev-guide/src/compiler-debugging.md
+++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md
@@ -275,7 +275,7 @@ Here are some notable ones:
 | `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. |
 | `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. |
 | `rustc_dump_predicates` | Dumps the [`predicates_of`] an item. |
-| `rustc_dump_vtable` |  |
+| `rustc_dump_vtable` | Dumps the vtable layout of an impl, or a type alias of a dyn type. |
 | `rustc_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. |
 | `rustc_layout` | [See this section](#debugging-type-layouts). |
 | `rustc_object_lifetime_default` | Dumps the [object lifetime defaults] of an item. |
diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md
index bdcf2c0b07e..a0acfdf0e4a 100644
--- a/src/doc/rustc/src/target-tier-policy.md
+++ b/src/doc/rustc/src/target-tier-policy.md
@@ -122,12 +122,23 @@ To propose addition of a new target, open a pull request on [`rust-lang/rust`]:
   r? compiler
   ```
 
+See also the documentation in the `rustc-dev-guide` on [adding a new target to
+`rustc`][rustc_dev_guide_add_target].
+
+Note that adding a new target that wants to support `std` would transitively
+require `cc` and `libc` support. However, these would like to know about the
+target from `rustc` as well. To break this cycle, you are strongly encouraged
+to add a _minimal_ `#![no_core]` target spec first to teach `rustc` about the
+target's existence, and add `std` support as a follow-up once you've added
+support for the target in `cc` and `libc`.
+
 [tier3example]: https://github.com/rust-lang/rust/pull/94872
 [platform_template]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/TEMPLATE.md
 [summary]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/SUMMARY.md
 [platformsupport]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support.md
 [rust_compiler_team]: https://www.rust-lang.org/governance/teams/compiler
 [`rust-lang/rust`]: https://github.com/rust-lang/rust
+[rustc_dev_guide_add_target]: https://rustc-dev-guide.rust-lang.org/building/new-target.html
 
 ## Tier 3 target policy
 
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index d1d42e47322..7eb1b8df233 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -524,6 +524,8 @@ use `-o -`.
 
 ## `-w`/`--output-format`: output format
 
+### json
+
 `--output-format json` emits documentation in the experimental
 [JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect,
 and is also accepted on stable toolchains.
@@ -542,6 +544,68 @@ It can also be used with `--show-coverage`. Take a look at its
 [documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more
 information.
 
+### doctest
+
+`--output-format doctest` emits JSON on stdout which gives you information about doctests in the
+provided crate.
+
+Tracking issue: [#134529](https://github.com/rust-lang/rust/issues/134529)
+
+You can use this option like this:
+
+```bash
+rustdoc -Zunstable-options --output-format=doctest src/lib.rs
+```
+
+For this rust code:
+
+```rust
+/// ```
+/// let x = 12;
+/// ```
+pub trait Trait {}
+```
+
+The generated output (formatted) will look like this:
+
+```json
+{
+  "format_version": 1,
+  "doctests": [
+    {
+      "file": "foo.rs",
+      "line": 1,
+      "doctest_attributes": {
+        "original": "",
+        "should_panic": false,
+        "no_run": false,
+        "ignore": "None",
+        "rust": true,
+        "test_harness": false,
+        "compile_fail": false,
+        "standalone_crate": false,
+        "error_codes": [],
+        "edition": null,
+        "added_css_classes": [],
+        "unknown": []
+      },
+      "original_code": "let x = 12;",
+      "doctest_code": "#![allow(unused)]\nfn main() {\nlet x = 12;\n}",
+      "name": "foo.rs - Trait (line 1)"
+    }
+  ]
+}
+```
+
+ * `format_version` gives you the current version of the generated JSON. If we change the output in any way, the number will increase.
+ * `doctests` contains the list of doctests present in the crate.
+   * `file` is the file path where the doctest is located.
+   * `line` is the line where the doctest starts (so where the \`\`\` is located in the current code).
+   * `doctest_attributes` contains computed information about the attributes used on the doctests. For more information about doctest attributes, take a look [here](write-documentation/documentation-tests.html#attributes).
+   * `original_code` is the code as written in the source code before rustdoc modifies it.
+   * `doctest_code` is the code modified by rustdoc that will be run. If there is a fatal syntax error, this field will not be present.
+   * `name` is the name generated by rustdoc which represents this doctest.
+
 ## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests
 
  * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245)
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 77040aeb94d..0b4fd9c2258 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -344,10 +344,8 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
             s
         }
         // array lengths are obviously usize
-        ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar))
-            if *ty.kind() == ty::Uint(ty::UintTy::Usize) =>
-        {
-            scalar.to_string()
+        ty::ConstKind::Value(cv) if *cv.ty.kind() == ty::Uint(ty::UintTy::Usize) => {
+            cv.valtree.unwrap_leaf().to_string()
         }
         _ => n.to_string(),
     }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 80bc6cebd2a..cfba7895208 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -33,6 +33,7 @@ pub(crate) enum OutputFormat {
     Json,
     #[default]
     Html,
+    Doctest,
 }
 
 impl OutputFormat {
@@ -48,6 +49,7 @@ impl TryFrom<&str> for OutputFormat {
         match value {
             "json" => Ok(OutputFormat::Json),
             "html" => Ok(OutputFormat::Html),
+            "doctest" => Ok(OutputFormat::Doctest),
             _ => Err(format!("unknown output format `{value}`")),
         }
     }
@@ -445,14 +447,42 @@ impl Options {
             }
         }
 
+        let show_coverage = matches.opt_present("show-coverage");
+        let output_format_s = matches.opt_str("output-format");
+        let output_format = match output_format_s {
+            Some(ref s) => match OutputFormat::try_from(s.as_str()) {
+                Ok(out_fmt) => out_fmt,
+                Err(e) => dcx.fatal(e),
+            },
+            None => OutputFormat::default(),
+        };
+
         // check for `--output-format=json`
-        if !matches!(matches.opt_str("output-format").as_deref(), None | Some("html"))
-            && !matches.opt_present("show-coverage")
-            && !nightly_options::is_unstable_enabled(matches)
-        {
-            dcx.fatal(
-                "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
-            );
+        match (
+            output_format_s.as_ref().map(|_| output_format),
+            show_coverage,
+            nightly_options::is_unstable_enabled(matches),
+        ) {
+            (None | Some(OutputFormat::Json), true, _) => {}
+            (_, true, _) => {
+                dcx.fatal(format!(
+                    "`--output-format={}` is not supported for the `--show-coverage` option",
+                    output_format_s.unwrap_or_default(),
+                ));
+            }
+            // If `-Zunstable-options` is used, nothing to check after this point.
+            (_, false, true) => {}
+            (None | Some(OutputFormat::Html), false, _) => {}
+            (Some(OutputFormat::Json), false, false) => {
+                dcx.fatal(
+                    "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
+                );
+            }
+            (Some(OutputFormat::Doctest), false, false) => {
+                dcx.fatal(
+                    "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/134529)",
+                );
+            }
         }
 
         let to_check = matches.opt_strs("check-theme");
@@ -704,8 +734,6 @@ impl Options {
             })
             .collect();
 
-        let show_coverage = matches.opt_present("show-coverage");
-
         let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
             Ok(types) => types,
             Err(e) => {
@@ -713,20 +741,6 @@ impl Options {
             }
         };
 
-        let output_format = match matches.opt_str("output-format") {
-            Some(s) => match OutputFormat::try_from(s.as_str()) {
-                Ok(out_fmt) => {
-                    if !out_fmt.is_json() && show_coverage {
-                        dcx.fatal(
-                            "html output format isn't supported for the --show-coverage option",
-                        );
-                    }
-                    out_fmt
-                }
-                Err(e) => dcx.fatal(e),
-            },
-            None => OutputFormat::default(),
-        };
         let crate_name = matches.opt_str("crate-name");
         let bin_crate = crate_types.contains(&CrateType::Executable);
         let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 8c3e28ecec3..8b522e614b8 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1,3 +1,4 @@
+mod extracted;
 mod make;
 mod markdown;
 mod runner;
@@ -30,7 +31,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir};
 use tracing::debug;
 
 use self::rust::HirCollector;
-use crate::config::Options as RustdocOptions;
+use crate::config::{Options as RustdocOptions, OutputFormat};
 use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine};
 use crate::lint::init_lints;
 
@@ -209,15 +210,8 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
     let args_path = temp_dir.path().join("rustdoc-cfgs");
     crate::wrap_return(dcx, generate_args_file(&args_path, &options));
 
-    let CreateRunnableDocTests {
-        standalone_tests,
-        mergeable_tests,
-        rustdoc_options,
-        opts,
-        unused_extern_reports,
-        compiling_test_count,
-        ..
-    } = interface::run_compiler(config, |compiler| {
+    let extract_doctests = options.output_format == OutputFormat::Doctest;
+    let result = interface::run_compiler(config, |compiler| {
         let krate = rustc_interface::passes::parse(&compiler.sess);
 
         let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
@@ -226,22 +220,53 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
             let opts = scrape_test_config(crate_name, crate_attrs, args_path);
             let enable_per_target_ignores = options.enable_per_target_ignores;
 
-            let mut collector = CreateRunnableDocTests::new(options, opts);
             let hir_collector = HirCollector::new(
                 ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()),
                 enable_per_target_ignores,
                 tcx,
             );
             let tests = hir_collector.collect_crate();
-            tests.into_iter().for_each(|t| collector.add_test(t));
+            if extract_doctests {
+                let mut collector = extracted::ExtractedDocTests::new();
+                tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options));
+
+                let stdout = std::io::stdout();
+                let mut stdout = stdout.lock();
+                if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) {
+                    eprintln!();
+                    Err(format!("Failed to generate JSON output for doctests: {error:?}"))
+                } else {
+                    Ok(None)
+                }
+            } else {
+                let mut collector = CreateRunnableDocTests::new(options, opts);
+                tests.into_iter().for_each(|t| collector.add_test(t));
 
-            collector
+                Ok(Some(collector))
+            }
         });
         compiler.sess.dcx().abort_if_errors();
 
         collector
     });
 
+    let CreateRunnableDocTests {
+        standalone_tests,
+        mergeable_tests,
+        rustdoc_options,
+        opts,
+        unused_extern_reports,
+        compiling_test_count,
+        ..
+    } = match result {
+        Ok(Some(collector)) => collector,
+        Ok(None) => return,
+        Err(error) => {
+            eprintln!("{error}");
+            std::process::exit(1);
+        }
+    };
+
     run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests);
 
     let compiling_test_count = compiling_test_count.load(Ordering::SeqCst);
diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs
new file mode 100644
index 00000000000..03c8814a4c9
--- /dev/null
+++ b/src/librustdoc/doctest/extracted.rs
@@ -0,0 +1,141 @@
+//! Rustdoc's doctest extraction.
+//!
+//! This module contains the logic to extract doctests and output a JSON containing this
+//! information.
+
+use serde::Serialize;
+
+use super::{DocTestBuilder, ScrapedDocTest};
+use crate::config::Options as RustdocOptions;
+use crate::html::markdown;
+
+/// The version of JSON output that this code generates.
+///
+/// This integer is incremented with every breaking change to the API,
+/// and is returned along with the JSON blob into the `format_version` root field.
+/// Consuming code should assert that this value matches the format version(s) that it supports.
+const FORMAT_VERSION: u32 = 1;
+
+#[derive(Serialize)]
+pub(crate) struct ExtractedDocTests {
+    format_version: u32,
+    doctests: Vec<ExtractedDocTest>,
+}
+
+impl ExtractedDocTests {
+    pub(crate) fn new() -> Self {
+        Self { format_version: FORMAT_VERSION, doctests: Vec::new() }
+    }
+
+    pub(crate) fn add_test(
+        &mut self,
+        scraped_test: ScrapedDocTest,
+        opts: &super::GlobalTestOptions,
+        options: &RustdocOptions,
+    ) {
+        let edition = scraped_test.edition(&options);
+
+        let ScrapedDocTest { filename, line, langstr, text, name } = scraped_test;
+
+        let doctest = DocTestBuilder::new(
+            &text,
+            Some(&opts.crate_name),
+            edition,
+            false,
+            None,
+            Some(&langstr),
+        );
+        let (full_test_code, size) = doctest.generate_unique_doctest(
+            &text,
+            langstr.test_harness,
+            &opts,
+            Some(&opts.crate_name),
+        );
+        self.doctests.push(ExtractedDocTest {
+            file: filename.prefer_remapped_unconditionaly().to_string(),
+            line,
+            doctest_attributes: langstr.into(),
+            doctest_code: if size != 0 { Some(full_test_code) } else { None },
+            original_code: text,
+            name,
+        });
+    }
+}
+
+#[derive(Serialize)]
+pub(crate) struct ExtractedDocTest {
+    file: String,
+    line: usize,
+    doctest_attributes: LangString,
+    original_code: String,
+    /// `None` if the code syntax is invalid.
+    doctest_code: Option<String>,
+    name: String,
+}
+
+#[derive(Serialize)]
+pub(crate) enum Ignore {
+    All,
+    None,
+    Some(Vec<String>),
+}
+
+impl From<markdown::Ignore> for Ignore {
+    fn from(original: markdown::Ignore) -> Self {
+        match original {
+            markdown::Ignore::All => Self::All,
+            markdown::Ignore::None => Self::None,
+            markdown::Ignore::Some(values) => Self::Some(values),
+        }
+    }
+}
+
+#[derive(Serialize)]
+struct LangString {
+    pub(crate) original: String,
+    pub(crate) should_panic: bool,
+    pub(crate) no_run: bool,
+    pub(crate) ignore: Ignore,
+    pub(crate) rust: bool,
+    pub(crate) test_harness: bool,
+    pub(crate) compile_fail: bool,
+    pub(crate) standalone_crate: bool,
+    pub(crate) error_codes: Vec<String>,
+    pub(crate) edition: Option<String>,
+    pub(crate) added_css_classes: Vec<String>,
+    pub(crate) unknown: Vec<String>,
+}
+
+impl From<markdown::LangString> for LangString {
+    fn from(original: markdown::LangString) -> Self {
+        let markdown::LangString {
+            original,
+            should_panic,
+            no_run,
+            ignore,
+            rust,
+            test_harness,
+            compile_fail,
+            standalone_crate,
+            error_codes,
+            edition,
+            added_classes,
+            unknown,
+        } = original;
+
+        Self {
+            original,
+            should_panic,
+            no_run,
+            ignore: ignore.into(),
+            rust,
+            test_harness,
+            compile_fail,
+            standalone_crate,
+            error_codes,
+            edition: edition.map(|edition| edition.to_string()),
+            added_css_classes: added_classes,
+            unknown,
+        }
+    }
+}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bb954a31891..44adf92ff0e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -814,7 +814,12 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
         }
     };
 
-    match (options.should_test, config::markdown_input(&input)) {
+    let output_format = options.output_format;
+
+    match (
+        options.should_test || output_format == config::OutputFormat::Doctest,
+        config::markdown_input(&input),
+    ) {
         (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
         (true, None) => return doctest::run(dcx, input, options),
         (false, Some(md_input)) => {
@@ -849,7 +854,6 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
     // plug/cleaning passes.
     let crate_version = options.crate_version.clone();
 
-    let output_format = options.output_format;
     let scrape_examples_options = options.scrape_examples_options.clone();
     let bin_crate = options.bin_crate;
 
@@ -899,6 +903,8 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
                 config::OutputFormat::Json => sess.time("render_json", || {
                     run_renderer::<json::JsonRenderer<'_>>(krate, render_opts, cache, tcx)
                 }),
+                // Already handled above with doctest runners.
+                config::OutputFormat::Doctest => unreachable!(),
             }
         })
     })
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 623b6b4fcc1..cabf10b7e0e 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -56,9 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && !item.span.from_expansion()
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx
-                .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_valtree()
-            && let element_count = element_count.to_target_usize(cx.tcx)
+            && let Some(element_count) = cx.tcx
+                .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
         {
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
index 46d7df6995a..6f5c5d6b3ea 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -8,7 +8,7 @@ use clippy_utils::source::snippet;
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self, ConstKind};
+use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
 
@@ -81,8 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
             && let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind
             && !self.is_from_vec_macro(cx, expr.span)
             && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
-            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
-            && let element_count = element_count.to_target_usize(cx.tcx)
+            && let Some(element_count) = cst.try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| {
                 matches!(
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index 54bdd3f02c2..63a61dcd148 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -640,7 +640,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let (dest, dest_len) = this.project_to_simd(dest)?;
 
                 let index =
-                    generic_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch();
+                    generic_args[2].expect_const().to_value().valtree.unwrap_branch();
                 let index_len = index.len();
 
                 assert_eq!(left_len, right_len);
diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs
index 61410f7c4e0..f100c4d6a86 100644
--- a/src/tools/miri/tests/pass/dyn-upcast.rs
+++ b/src/tools/miri/tests/pass/dyn-upcast.rs
@@ -10,6 +10,8 @@ fn main() {
     replace_vptr();
     vtable_nop_cast();
     drop_principal();
+    modulo_binder();
+    modulo_assoc();
 }
 
 fn vtable_nop_cast() {
@@ -482,3 +484,53 @@ fn drop_principal() {
     println!("before");
     drop(y);
 }
+
+// Test for <https://github.com/rust-lang/rust/issues/135316>.
+fn modulo_binder() {
+    trait Supertrait<T> {
+        fn _print_numbers(&self, mem: &[usize; 100]) {
+            println!("{mem:?}");
+        }
+    }
+    impl<T> Supertrait<T> for () {}
+
+    trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
+        fn say_hello(&self, _: &usize) {
+            println!("Hello!");
+        }
+    }
+    impl<T, U> Trait<T, U> for () {}
+
+    (&() as &'static dyn for<'a> Trait<&'static (), &'a ()>
+        as &'static dyn Trait<&'static (), &'static ()>)
+        .say_hello(&0);
+}
+
+// Test for <https://github.com/rust-lang/rust/issues/135315>.
+fn modulo_assoc() {
+    trait Supertrait<T> {
+        fn _print_numbers(&self, mem: &[usize; 100]) {
+            println!("{mem:?}");
+        }
+    }
+    impl<T> Supertrait<T> for () {}
+
+    trait Identity {
+        type Selff;
+    }
+    impl<Selff> Identity for Selff {
+        type Selff = Selff;
+    }
+
+    trait Middle<T>: Supertrait<()> + Supertrait<T> {
+        fn say_hello(&self, _: &usize) {
+            println!("Hello!");
+        }
+    }
+    impl<T> Middle<T> for () {}
+
+    trait Trait: Middle<<() as Identity>::Selff> {}
+    impl Trait for () {}
+
+    (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
+}
diff --git a/src/tools/miri/tests/pass/dyn-upcast.stdout b/src/tools/miri/tests/pass/dyn-upcast.stdout
index edd99a114a1..379600db3d9 100644
--- a/src/tools/miri/tests/pass/dyn-upcast.stdout
+++ b/src/tools/miri/tests/pass/dyn-upcast.stdout
@@ -2,3 +2,5 @@ before
 goodbye
 before
 goodbye
+Hello!
+Hello!
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 04de3493ea2..565721a9093 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -148,16 +148,6 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
 
             let is_aarch64 = target_triple.starts_with("aarch64");
 
-            let skip_tests = if is_aarch64 {
-                vec![
-                    // Those tests fail only inside of Docker on aarch64, as of December 2024
-                    "tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs".to_string(),
-                    "tests/ui/consts/large_const_alloc.rs".to_string(),
-                ]
-            } else {
-                vec![]
-            };
-
             let checkout_dir = Utf8PathBuf::from("/checkout");
             let env = EnvironmentBuilder::default()
                 .host_tuple(target_triple)
@@ -169,7 +159,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .shared_llvm(true)
                 // FIXME: Enable bolt for aarch64 once it's fixed upstream. Broken as of December 2024.
                 .use_bolt(!is_aarch64)
-                .skipped_tests(skip_tests)
+                .skipped_tests(vec![])
                 .build()?;
 
             (env, shared.build_args)
diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs
index f10f01274b1..14bc4b8ab28 100644
--- a/tests/codegen/addr-of-mutate.rs
+++ b/tests/codegen/addr-of-mutate.rs
@@ -5,7 +5,7 @@
 // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
 // See <https://github.com/rust-lang/rust/issues/111502>.
 
-// CHECK: i8 @foo(ptr noalias nocapture noundef align 1 dereferenceable(128) %x)
+// CHECK: i8 @foo(ptr noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
 #[no_mangle]
 pub fn foo(x: [u8; 128]) -> u8 {
     let ptr = core::ptr::addr_of!(x).cast_mut();
@@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 {
     x[0]
 }
 
-// CHECK: i1 @second(ptr noalias nocapture noundef align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @second(ptr noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
@@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
 }
 
 // If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
-// CHECK: i1 @third(ptr noalias nocapture noundef readonly align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @third(ptr noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();
diff --git a/tests/codegen/asm/bpf-clobbers.rs b/tests/codegen/asm/bpf-clobbers.rs
new file mode 100644
index 00000000000..1117549b1ec
--- /dev/null
+++ b/tests/codegen/asm/bpf-clobbers.rs
@@ -0,0 +1,31 @@
+//@ add-core-stubs
+//@ compile-flags: --target bpfel-unknown-none
+//@ needs-llvm-components: bpf
+
+#![crate_type = "rlib"]
+#![feature(no_core, asm_experimental_arch)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+// CHECK-LABEL: @flags_clobber
+// CHECK: call void asm sideeffect "", ""()
+#[no_mangle]
+pub unsafe fn flags_clobber() {
+    asm!("", options(nostack, nomem));
+}
+
+// CHECK-LABEL: @no_clobber
+// CHECK: call void asm sideeffect "", ""()
+#[no_mangle]
+pub unsafe fn no_clobber() {
+    asm!("", options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @clobber_abi
+// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5}"()
+#[no_mangle]
+pub unsafe fn clobber_abi() {
+    asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
+}
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
index db76aae3dd0..b3a35cbf3b1 100644
--- a/tests/codegen/cast-target-abi.rs
+++ b/tests/codegen/cast-target-abi.rs
@@ -392,7 +392,7 @@ pub fn call_fiveu16s() {
 }
 
 // CHECK-LABEL: @return_fiveu16s
-// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]])
+// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] {{.*}}dereferenceable(10) [[RET_PTR:%.+]])
 #[no_mangle]
 pub fn return_fiveu16s() -> FiveU16s {
     // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index 503799d3ed2..1a211dfe096 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -135,7 +135,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {}
 #[no_mangle]
 pub fn notunpin_borrow(_: &NotUnpin) {}
 
-// CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1)
+// CHECK: @indirect_struct(ptr noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {}
 
@@ -198,7 +198,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
     x
 }
 
-// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([32 x i8]) align 4 dereferenceable(32){{( %_0)?}})
+// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(none\))?}} dereferenceable(32){{( %_0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
     S { _field: [0, 0, 0, 0, 0, 0, 0, 0] }
diff --git a/tests/codegen/i128-x86-align.rs b/tests/codegen/i128-x86-align.rs
index 6b1da445c40..ac101b72513 100644
--- a/tests/codegen/i128-x86-align.rs
+++ b/tests/codegen/i128-x86-align.rs
@@ -19,8 +19,10 @@ pub struct ScalarPair {
 #[no_mangle]
 pub fn load(x: &ScalarPair) -> ScalarPair {
     // CHECK-LABEL: @load(
-    // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0,
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: sret([32 x i8]) align 16
+    // CHECK-SAME: dereferenceable(32) %_0,
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[A:%.*]] = load i32, ptr %x, align 16
     // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16
     // CHECK-NEXT: [[B:%.*]] = load i128, ptr [[GEP]], align 16
@@ -34,7 +36,8 @@ pub fn load(x: &ScalarPair) -> ScalarPair {
 #[no_mangle]
 pub fn store(x: &mut ScalarPair) {
     // CHECK-LABEL: @store(
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      store i32 1, ptr %x, align 16
     // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16
     // CHECK-NEXT: store i128 2, ptr [[GEP]], align 16
@@ -55,8 +58,10 @@ pub fn alloca() {
 #[no_mangle]
 pub fn load_volatile(x: &ScalarPair) -> ScalarPair {
     // CHECK-LABEL: @load_volatile(
-    // CHECK-SAME: sret([32 x i8]) align 16 dereferenceable(32) %_0,
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: sret([32 x i8]) align 16
+    // CHECK-SAME: dereferenceable(32) %_0,
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[LOAD:%.*]] = load volatile %ScalarPair, ptr %x, align 16
     // CHECK-NEXT: store %ScalarPair [[LOAD]], ptr %_0, align 16
     // CHECK-NEXT: ret void
@@ -66,7 +71,8 @@ pub fn load_volatile(x: &ScalarPair) -> ScalarPair {
 #[no_mangle]
 pub fn transmute(x: ScalarPair) -> (std::mem::MaybeUninit<i128>, i128) {
     // CHECK-LABEL: @transmute(
-    // CHECK-SAME:  sret([32 x i8]) align 16 dereferenceable(32) %_0,
+    // CHECK-SAME:  sret([32 x i8]) align 16
+    // CHECK-SAME:  dereferenceable(32) %_0,
     // CHECK-SAME:  i32 noundef %x.0, i128 noundef %x.1
     // CHECK:       store i32 %x.0, ptr %_0, align 16
     // CHECK-NEXT:  [[GEP:%.*]] = getelementptr inbounds i8, ptr %_0, i64 16
@@ -86,7 +92,8 @@ pub struct Struct {
 #[no_mangle]
 pub fn store_struct(x: &mut Struct) {
     // CHECK-LABEL: @store_struct(
-    // CHECK-SAME: align 16 dereferenceable(32) %x
+    // CHECK-SAME: align 16
+    // CHECK-SAME: dereferenceable(32) %x
     // CHECK:      [[TMP:%.*]] = alloca [32 x i8], align 16
     // CHECK:      store i32 1, ptr [[TMP]], align 16
     // CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4
diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
index cba1a980caa..b147d01b38e 100644
--- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
+++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
@@ -259,11 +259,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef align 8 dereferenceable(24) %a)
+// CHECK: define void @f_int_double_int_s_arg(ptr noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias nocapture noundef{{( writable)?}} sret([24 x i8]) align 8 dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(none\))?}} dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs
index 790d618b2ea..66df978d48c 100644
--- a/tests/codegen/packed.rs
+++ b/tests/codegen/packed.rs
@@ -52,7 +52,7 @@ pub struct BigPacked2 {
 #[no_mangle]
 pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
     // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8]
-    // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
+    // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
     // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
@@ -64,7 +64,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 #[no_mangle]
 pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
     // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8]
-    // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
+    // CHECK: call void %{{.*}}(ptr{{( captures(none))?}} noalias{{( nocapture)?}} noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
     // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
diff --git a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
index bcd9b0eae71..c14d5c01450 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
@@ -263,7 +263,7 @@ pub struct IntDoubleInt {
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 {{.*}}dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/crashes/131102.rs b/tests/crashes/131102.rs
deleted file mode 100644
index 12b35f8d1b2..00000000000
--- a/tests/crashes/131102.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #131102
-pub struct Blorb<const N: u16>([String; N]);
-pub struct Wrap(Blorb<0>);
-pub const fn i(_: Wrap) {}
diff --git a/tests/run-make/target-specs/require-explicit-cpu.json b/tests/run-make/target-specs/require-explicit-cpu.json
new file mode 100644
index 00000000000..5cbb9573b3f
--- /dev/null
+++ b/tests/run-make/target-specs/require-explicit-cpu.json
@@ -0,0 +1,11 @@
+{
+    "data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
+    "linker-flavor": "gcc",
+    "llvm-target": "i686-unknown-linux-gnu",
+    "target-endian": "little",
+    "target-pointer-width": "32",
+    "target-c-int-width": "32",
+    "arch": "x86",
+    "os": "linux",
+    "need-explicit-cpu": true
+}
diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs
index 79c888ab340..f36a5784c89 100644
--- a/tests/run-make/target-specs/rmake.rs
+++ b/tests/run-make/target-specs/rmake.rs
@@ -63,4 +63,17 @@ fn main() {
         .crate_type("lib")
         .run_fail()
         .assert_stderr_contains("data-layout for target");
+    rustc()
+        .input("foo.rs")
+        .target("require-explicit-cpu")
+        .crate_type("lib")
+        .run_fail()
+        .assert_stderr_contains("target requires explicitly specifying a cpu");
+    rustc()
+        .input("foo.rs")
+        .target("require-explicit-cpu")
+        .crate_type("lib")
+        .arg("-Ctarget-cpu=generic")
+        .run();
+    rustc().target("require-explicit-cpu").arg("--print=target-cpus").run();
 }
diff --git a/tests/rustdoc-ui/coverage/html.stderr b/tests/rustdoc-ui/coverage/html.stderr
index adca375d4bc..764179820c5 100644
--- a/tests/rustdoc-ui/coverage/html.stderr
+++ b/tests/rustdoc-ui/coverage/html.stderr
@@ -1,2 +1,2 @@
-error: html output format isn't supported for the --show-coverage option
+error: `--output-format=html` is not supported for the `--show-coverage` option
 
diff --git a/tests/rustdoc-ui/doctest-output.rs b/tests/rustdoc-ui/doctest-output.rs
new file mode 100644
index 00000000000..720f2952980
--- /dev/null
+++ b/tests/rustdoc-ui/doctest-output.rs
@@ -0,0 +1 @@
+//@ compile-flags:-Z unstable-options --show-coverage --output-format=doctest
diff --git a/tests/rustdoc-ui/doctest-output.stderr b/tests/rustdoc-ui/doctest-output.stderr
new file mode 100644
index 00000000000..20c618dc61b
--- /dev/null
+++ b/tests/rustdoc-ui/doctest-output.stderr
@@ -0,0 +1,2 @@
+error: `--output-format=doctest` is not supported for the `--show-coverage` option
+
diff --git a/tests/rustdoc-ui/extract-doctests.rs b/tests/rustdoc-ui/extract-doctests.rs
new file mode 100644
index 00000000000..06bd35969d0
--- /dev/null
+++ b/tests/rustdoc-ui/extract-doctests.rs
@@ -0,0 +1,15 @@
+// Test to ensure that it generates expected output for `--output-format=doctest` command-line
+// flag.
+
+//@ compile-flags:-Z unstable-options --output-format=doctest
+//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR"
+//@ check-pass
+
+//! ```ignore (checking attributes)
+//! let x = 12;
+//! let y = 14;
+//! ```
+//!
+//! ```edition2018,compile_fail
+//! let
+//! ```
diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout
new file mode 100644
index 00000000000..fa8604cae94
--- /dev/null
+++ b/tests/rustdoc-ui/extract-doctests.stdout
@@ -0,0 +1 @@
+{"format_version":1,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":"#![allow(unused)]\nfn main() {\nlet\n}","name":"$DIR/extract-doctests.rs - (line 13)"}]}
\ No newline at end of file
diff --git a/tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs
index 2b8fdec1f12..2b8fdec1f12 100644
--- a/tests/rustdoc/intra-doc/auxiliary/issue-103463-aux.rs
+++ b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs
diff --git a/tests/rustdoc/intra-doc/issue-104145.rs b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs
index 5690803af5a..0e403b21c8a 100644
--- a/tests/rustdoc/intra-doc/issue-104145.rs
+++ b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/104145
+//@ check-pass
+
 // Doc links in `Trait`'s methods are resolved because it has a local impl.
 
 //@ aux-build:issue-103463-aux.rs
diff --git a/tests/rustdoc/intra-doc/issue-103463.rs b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs
index 9b5cb67fd32..10894282e55 100644
--- a/tests/rustdoc/intra-doc/issue-103463.rs
+++ b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/103463
+//@ check-pass
+
 // The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved.
 
 //@ aux-build:issue-103463-aux.rs
diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
index 180ba63927b..2c25589a553 100644
--- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
+++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
@@ -99,7 +99,7 @@ LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
    |                    ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/invalid_const_in_lifetime_position.rs:2:10
    |
 LL | trait X {
diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
index 72d1a52f710..1e52b699820 100644
--- a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
+++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr
@@ -301,7 +301,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/ice-generic-type-alias-105742.rs:15:17
    |
 LL |    pub trait SVec: Index<
diff --git a/tests/rustdoc/inline_cross/issue-28480.rs b/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs
index 004510fd922..e1ca7403c03 100644
--- a/tests/rustdoc/inline_cross/issue-28480.rs
+++ b/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/28480
+#![crate_name="foobar"]
+
 //@ aux-build:rustdoc-hidden-sig.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
@@ -7,7 +10,7 @@
 //@ has -  '//a' 'u8'
 extern crate rustdoc_hidden_sig;
 
-//@ has issue_28480/struct.Bar.html
+//@ has foobar/struct.Bar.html
 //@ !has -  '//a/@title' 'Hidden'
 //@ has -  '//a' 'u8'
 pub use rustdoc_hidden_sig::Bar;
diff --git a/tests/rustdoc/inline_cross/issue-31948-1.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs
index e59da87c29d..baab1da9547 100644
--- a/tests/rustdoc/inline_cross/issue-31948-1.rs
+++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs
@@ -1,27 +1,30 @@
+// https://github.com/rust-lang/rust/issues/31948
+#![crate_name="foobar"]
+
 //@ aux-build:rustdoc-nonreachable-impls.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
 
 extern crate rustdoc_nonreachable_impls;
 
-//@ has issue_31948_1/struct.Wobble.html
+//@ has foobar/struct.Wobble.html
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
 //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
 pub use rustdoc_nonreachable_impls::hidden::Wobble;
 
-//@ has issue_31948_1/trait.Bark.html
+//@ has foobar/trait.Bark.html
 //@ has - '//h3[@class="code-header"]' 'for Foo'
 //@ has - '//h3[@class="code-header"]' 'for Wobble'
 //@ !has - '//h3[@class="code-header"]' 'for Wibble'
 pub use rustdoc_nonreachable_impls::Bark;
 
-//@ has issue_31948_1/trait.Woof.html
+//@ has foobar/trait.Woof.html
 //@ has - '//h3[@class="code-header"]' 'for Foo'
 //@ has - '//h3[@class="code-header"]' 'for Wobble'
 //@ !has - '//h3[@class="code-header"]' 'for Wibble'
 pub use rustdoc_nonreachable_impls::Woof;
 
-//@ !has issue_31948_1/trait.Bar.html
-//@ !has issue_31948_1/trait.Qux.html
+//@ !has foobar/trait.Bar.html
+//@ !has foobar/trait.Qux.html
diff --git a/tests/rustdoc/inline_cross/issue-31948-2.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs
index 34b57052883..40e9108ec62 100644
--- a/tests/rustdoc/inline_cross/issue-31948-2.rs
+++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs
@@ -1,21 +1,24 @@
+// https://github.com/rust-lang/rust/issues/31948
+#![crate_name="foobar"]
+
 //@ aux-build:rustdoc-nonreachable-impls.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
 
 extern crate rustdoc_nonreachable_impls;
 
-//@ has issue_31948_2/struct.Wobble.html
+//@ has foobar/struct.Wobble.html
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
 //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 pub use rustdoc_nonreachable_impls::hidden::Wobble;
 
-//@ has issue_31948_2/trait.Qux.html
+//@ has foobar/trait.Qux.html
 //@ has - '//h3[@class="code-header"]' 'for Foo'
 //@ has - '//h3[@class="code-header"]' 'for Wobble'
 pub use rustdoc_nonreachable_impls::hidden::Qux;
 
-//@ !has issue_31948_2/trait.Bar.html
-//@ !has issue_31948_2/trait.Woof.html
-//@ !has issue_31948_2/trait.Bark.html
+//@ !has foobar/trait.Bar.html
+//@ !has foobar/trait.Woof.html
+//@ !has foobar/trait.Bark.html
diff --git a/tests/rustdoc/inline_cross/issue-31948.rs b/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs
index 7a43fc7b279..ab0048513c7 100644
--- a/tests/rustdoc/inline_cross/issue-31948.rs
+++ b/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs
@@ -1,29 +1,32 @@
+// https://github.com/rust-lang/rust/issues/31948
+#![crate_name="foobar"]
+
 //@ aux-build:rustdoc-nonreachable-impls.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
 
 extern crate rustdoc_nonreachable_impls;
 
-//@ has issue_31948/struct.Foo.html
+//@ has foobar/struct.Foo.html
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
 //@ has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
 //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 //@ !has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
 pub use rustdoc_nonreachable_impls::Foo;
 
-//@ has issue_31948/trait.Bark.html
+//@ has foobar/trait.Bark.html
 //@ has - '//h3[@class="code-header"]' 'for Foo'
 //@ !has - '//h3[@class="code-header"]' 'for Wibble'
 //@ !has - '//h3[@class="code-header"]' 'for Wobble'
 pub use rustdoc_nonreachable_impls::Bark;
 
-//@ has issue_31948/trait.Woof.html
+//@ has foobar/trait.Woof.html
 //@ has - '//h3[@class="code-header"]' 'for Foo'
 //@ !has - '//h3[@class="code-header"]' 'for Wibble'
 //@ !has - '//h3[@class="code-header"]' 'for Wobble'
 pub use rustdoc_nonreachable_impls::Woof;
 
-//@ !has issue_31948/trait.Bar.html
-//@ !has issue_31948/trait.Qux.html
-//@ !has issue_31948/struct.Wibble.html
-//@ !has issue_31948/struct.Wobble.html
+//@ !has foobar/trait.Bar.html
+//@ !has foobar/trait.Qux.html
+//@ !has foobar/struct.Wibble.html
+//@ !has foobar/struct.Wobble.html
diff --git a/tests/rustdoc/inline_cross/issue-32881.rs b/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs
index d4ebf10a1ca..f7dc7414455 100644
--- a/tests/rustdoc/inline_cross/issue-32881.rs
+++ b/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs
@@ -1,10 +1,13 @@
+// https://github.com/rust-lang/rust/issues/32881
+#![crate_name="foobar"]
+
 //@ aux-build:rustdoc-trait-object-impl.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
 
 extern crate rustdoc_trait_object_impl;
 
-//@ has issue_32881/trait.Bar.html
+//@ has foobar/trait.Bar.html
 //@ has - '//h3[@class="code-header"]' "impl<'a> dyn Bar"
 //@ has - '//h3[@class="code-header"]' "impl<'a> Debug for dyn Bar"
 
diff --git a/tests/rustdoc/inline_cross/issue-33113.rs b/tests/rustdoc/inline_cross/impl-ref-33113.rs
index 05e87d962cb..9ac4f02e00c 100644
--- a/tests/rustdoc/inline_cross/issue-33113.rs
+++ b/tests/rustdoc/inline_cross/impl-ref-33113.rs
@@ -1,10 +1,13 @@
+// https://github.com/rust-lang/rust/issues/33113
+#![crate_name="foobar"]
+
 //@ aux-build:issue-33113.rs
 //@ build-aux-docs
 //@ ignore-cross-compile
 
 extern crate bar;
 
-//@ has issue_33113/trait.Bar.html
+//@ has foobar/trait.Bar.html
 //@ has - '//h3[@class="code-header"]' "for &'a char"
 //@ has - '//h3[@class="code-header"]' "for Foo"
 pub use bar::Bar;
diff --git a/tests/rustdoc/inline_cross/issue-76736-1.rs b/tests/rustdoc/inline_cross/rustc-private-76736-1.rs
index fe52702fd6f..3ffa5e6cc06 100644
--- a/tests/rustdoc/inline_cross/issue-76736-1.rs
+++ b/tests/rustdoc/inline_cross/rustc-private-76736-1.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/76736
+
 //@ aux-build:issue-76736-1.rs
 //@ aux-build:issue-76736-2.rs
 
diff --git a/tests/rustdoc/inline_cross/issue-76736-2.rs b/tests/rustdoc/inline_cross/rustc-private-76736-2.rs
index df376ebe9a1..843b2941602 100644
--- a/tests/rustdoc/inline_cross/issue-76736-2.rs
+++ b/tests/rustdoc/inline_cross/rustc-private-76736-2.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/76736
+
 //@ aux-build:issue-76736-1.rs
 //@ aux-build:issue-76736-2.rs
 
diff --git a/tests/rustdoc/inline_cross/issue-76736-3.rs b/tests/rustdoc/inline_cross/rustc-private-76736-3.rs
index 1bed4621c04..f9b46caa02f 100644
--- a/tests/rustdoc/inline_cross/issue-76736-3.rs
+++ b/tests/rustdoc/inline_cross/rustc-private-76736-3.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/76736
+
 //@ compile-flags: -Zforce-unstable-if-unmarked
 //@ aux-build:issue-76736-1.rs
 //@ aux-build:issue-76736-2.rs
diff --git a/tests/rustdoc/inline_cross/issue-76736-4.rs b/tests/rustdoc/inline_cross/rustc-private-76736-4.rs
index 487e9030108..511464f2c49 100644
--- a/tests/rustdoc/inline_cross/issue-76736-4.rs
+++ b/tests/rustdoc/inline_cross/rustc-private-76736-4.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/76736
+
 //@ aux-build:issue-76736-1.rs
 //@ aux-build:issue-76736-2.rs
 
diff --git a/tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html
index f3c1c045202..f3c1c045202 100644
--- a/tests/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html
+++ b/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html
diff --git a/tests/rustdoc/inline_cross/issue-24183.rs b/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs
index 8299eecc575..909005532f5 100644
--- a/tests/rustdoc/inline_cross/issue-24183.rs
+++ b/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/24183
 #![crate_type = "lib"]
 #![crate_name = "usr"]
 
diff --git a/tests/rustdoc/inline_local/issue-32343.rs b/tests/rustdoc/inline_local/doc-no-inline-32343.rs
index 2ec123fdc5c..ed11614a500 100644
--- a/tests/rustdoc/inline_local/issue-32343.rs
+++ b/tests/rustdoc/inline_local/doc-no-inline-32343.rs
@@ -1,12 +1,15 @@
-//@ !has issue_32343/struct.Foo.html
-//@ has issue_32343/index.html
+// https://github.com/rust-lang/rust/issues/32343
+#![crate_name="foobar"]
+
+//@ !has foobar/struct.Foo.html
+//@ has foobar/index.html
 //@ has - '//code' 'pub use foo::Foo'
 //@ !has - '//code/a' 'Foo'
 #[doc(no_inline)]
 pub use foo::Foo;
 
-//@ !has issue_32343/struct.Bar.html
-//@ has issue_32343/index.html
+//@ !has foobar/struct.Bar.html
+//@ has foobar/index.html
 //@ has - '//code' 'pub use foo::Bar'
 //@ has - '//code/a' 'Bar'
 #[doc(no_inline)]
@@ -18,6 +21,6 @@ mod foo {
 }
 
 pub mod bar {
-    //@ has issue_32343/bar/struct.Bar.html
+    //@ has foobar/bar/struct.Bar.html
     pub use ::foo::Bar;
 }
diff --git a/tests/rustdoc/inline_local/issue-28537.rs b/tests/rustdoc/inline_local/pub-re-export-28537.rs
index d5ba94d2e6c..0e9836c7cee 100644
--- a/tests/rustdoc/inline_local/issue-28537.rs
+++ b/tests/rustdoc/inline_local/pub-re-export-28537.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/28537
+#![crate_name="foo"]
+
 #[doc(hidden)]
 pub mod foo {
     pub struct Foo;
@@ -10,8 +13,8 @@ mod bar {
     }
 }
 
-//@ has issue_28537/struct.Foo.html
+//@ has foo/struct.Foo.html
 pub use foo::Foo;
 
-//@ has issue_28537/struct.Bar.html
+//@ has foo/struct.Bar.html
 pub use self::bar::Bar;
diff --git a/tests/rustdoc/intra-doc/issue-82209.rs b/tests/rustdoc/intra-doc/enum-self-82209.rs
index 46d028e535c..615115a5f8b 100644
--- a/tests/rustdoc/intra-doc/issue-82209.rs
+++ b/tests/rustdoc/intra-doc/enum-self-82209.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/82209
+
 #![crate_name = "foo"]
 #![deny(rustdoc::broken_intra_doc_links)]
 pub enum Foo {
diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs
index 18424c069d3..0b339eaf6b2 100644
--- a/tests/rustdoc/intra-doc/issue-108459.rs
+++ b/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/pull/108459
+#![crate_name="foobar"]
+
 #![deny(rustdoc::broken_intra_doc_links)]
 #![allow(rustdoc::redundant_explicit_links)]
 
@@ -13,13 +16,13 @@ pub struct MyStruct1;
 // the same target but different text
 
 /// See also [crate::char] and [mod@char] and [prim@char]
-//@ has issue_108459/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char'
+//@ has foobar/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char'
 //@ has - '//*[@href="char/index.html"]' 'char'
 //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
 pub struct MyStruct2;
 
 /// See also [mod@char] and [prim@char] and [crate::char]
-//@ has issue_108459/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char'
+//@ has foobar/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char'
 //@ has - '//*[@href="char/index.html"]' 'char'
 //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
 pub struct MyStruct3;
@@ -28,11 +31,11 @@ pub struct MyStruct3;
 // different targets
 
 /// See also [char][mod@char] and [char][prim@char]
-//@ has issue_108459/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char'
+//@ has foobar/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char'
 //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
 pub struct MyStruct4;
 
 /// See also [char][prim@char] and [char][crate::char]
-//@ has issue_108459/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char'
+//@ has foobar/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char'
 //@ has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
 pub struct MyStruct5;
diff --git a/tests/rustdoc/intra-doc/issue-66159.rs b/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs
index 5d50f63f299..7e3ace9355a 100644
--- a/tests/rustdoc/intra-doc/issue-66159.rs
+++ b/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/66159
+#![crate_name="foobar"]
+
 //@ aux-crate:priv:pub_struct=pub-struct.rs
 //@ compile-flags:-Z unstable-options
 
@@ -6,5 +9,5 @@
 // Since we don't generate the docs for the auxiliary files, we can't actually
 // verify that the struct is linked correctly.
 
-//@ has issue_66159/index.html
+//@ has foobar/index.html
 //! [pub_struct::SomeStruct]
diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr
index 107ceeaf113..5aaa6f6be05 100644
--- a/tests/ui/associated-consts/associated-const-in-trait.stderr
+++ b/tests/ui/associated-consts/associated-const-in-trait.stderr
@@ -5,7 +5,7 @@ LL | impl dyn Trait {
    |      ^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/associated-const-in-trait.rs:4:11
    |
 LL | trait Trait {
@@ -21,7 +21,7 @@ LL |     const fn n() -> usize { Self::N }
    |                             ^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/associated-const-in-trait.rs:4:11
    |
 LL | trait Trait {
diff --git a/tests/ui/associated-item/issue-48027.stderr b/tests/ui/associated-item/issue-48027.stderr
index 1baaefd7720..513961e2bd0 100644
--- a/tests/ui/associated-item/issue-48027.stderr
+++ b/tests/ui/associated-item/issue-48027.stderr
@@ -5,7 +5,7 @@ LL | impl dyn Bar {}
    |      ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-48027.rs:2:11
    |
 LL | trait Bar {
diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr
index f9d2a669477..7d5b37bdbe7 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.stderr
+++ b/tests/ui/async-await/async-fn/dyn-pos.stderr
@@ -5,7 +5,7 @@ LL | fn foo(x: &dyn AsyncFn()) {}
    |                ^^^^^^^^^ `AsyncFnMut` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
    |
    = note: the trait is not dyn compatible because it contains the generic associated type `CallRefFuture`
diff --git a/tests/ui/async-await/in-trait/dyn-compatibility.stderr b/tests/ui/async-await/in-trait/dyn-compatibility.stderr
index c6c406902f6..553bcbf89d5 100644
--- a/tests/ui/async-await/in-trait/dyn-compatibility.stderr
+++ b/tests/ui/async-await/in-trait/dyn-compatibility.stderr
@@ -5,7 +5,7 @@ LL |     let x: &dyn Foo = todo!();
    |            ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility.rs:5:14
    |
 LL | trait Foo {
diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr
index a674fc0f3a5..1fccc32470f 100644
--- a/tests/ui/async-await/inference_var_self_argument.stderr
+++ b/tests/ui/async-await/inference_var_self_argument.stderr
@@ -14,7 +14,7 @@ LL |     async fn foo(self: &dyn Foo) {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/inference_var_self_argument.rs:5:14
    |
 LL | trait Foo {
diff --git a/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr b/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr
index 20257bbaf28..033bfee226f 100644
--- a/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr
+++ b/tests/ui/coherence/coherence-impl-trait-for-trait-dyn-compatible.stderr
@@ -5,7 +5,7 @@ LL | impl DynIncompatible for dyn DynIncompatible { }
    |                          ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/coherence-impl-trait-for-trait-dyn-compatible.rs:6:45
    |
 LL | trait DynIncompatible { fn eq(&self, other: Self); }
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
index cd7f3a3c21d..6fa9b591ad2 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr
@@ -5,7 +5,7 @@ LL | fn foo(a: &dyn ConstParamTy_) {}
    |                ^^^^^^^^^^^^^ `ConstParamTy_` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: the trait is not dyn compatible because it uses `Self` as a type parameter
@@ -21,7 +21,7 @@ LL | fn bar(a: &dyn UnsizedConstParamTy) {}
    |                ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: the trait is not dyn compatible because it uses `Self` as a type parameter
diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr
index 763bc626c9d..8bc6ef093d0 100644
--- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-ret.stderr
@@ -5,7 +5,7 @@ LL | fn use_dyn(v: &dyn Foo) {
    |                ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility-err-ret.rs:8:8
    |
 LL | trait Foo {
@@ -24,7 +24,7 @@ LL |     v.test();
    |     ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility-err-ret.rs:8:8
    |
 LL | trait Foo {
diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr
index 56678e4e9af..f5eaaa37916 100644
--- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-err-where-bounds.stderr
@@ -5,7 +5,7 @@ LL | fn use_dyn(v: &dyn Foo) {
    |                ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility-err-where-bounds.rs:8:8
    |
 LL | trait Foo {
@@ -22,7 +22,7 @@ LL |     v.test();
    |     ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility-err-where-bounds.rs:8:8
    |
 LL | trait Foo {
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
index bd1811bd2cc..57b61006631 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
@@ -99,7 +99,7 @@ LL |     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
    |                        ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-102768.rs:5:10
    |
 LL | trait X {
diff --git a/tests/ui/consts/bad-array-size-in-type-err.rs b/tests/ui/consts/bad-array-size-in-type-err.rs
index cb02ad3205d..0490a9d3620 100644
--- a/tests/ui/consts/bad-array-size-in-type-err.rs
+++ b/tests/ui/consts/bad-array-size-in-type-err.rs
@@ -8,3 +8,14 @@ fn main() {
     //~^ ERROR mismatched types
     //~| ERROR the constant `2` is not of type `usize`
 }
+
+fn iter(val: BadArraySize::<2>) {
+    for _ in val.arr {}
+    //~^ ERROR the constant `2` is not of type `usize`
+    //~| ERROR `[i32; 2]` is not an iterator
+}
+
+// issue #131102
+pub struct Blorb<const N: u16>([String; N]); //~ ERROR the constant `N` is not of type `usize`
+pub struct Wrap(Blorb<0>);
+pub const fn i(_: Wrap) {} //~ ERROR destructor of `Wrap` cannot be evaluated at compile-time
diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr
index c3ff216432e..84e16f8d931 100644
--- a/tests/ui/consts/bad-array-size-in-type-err.stderr
+++ b/tests/ui/consts/bad-array-size-in-type-err.stderr
@@ -6,6 +6,14 @@ LL |     arr: [i32; N],
    |
    = note: the length of array `[i32; N]` must be type `usize`
 
+error: the constant `N` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:19:32
+   |
+LL | pub struct Blorb<const N: u16>([String; N]);
+   |                                ^^^^^^^^^^^ expected `usize`, found `u16`
+   |
+   = note: the length of array `[String; N]` must be type `usize`
+
 error[E0308]: mismatched types
   --> $DIR/bad-array-size-in-type-err.rs:7:38
    |
@@ -20,6 +28,37 @@ LL |     let _ = BadArraySize::<2> { arr: [0, 0, 0] };
    |
    = note: the length of array `[i32; 2]` must be type `usize`
 
-error: aborting due to 3 previous errors
+error: the constant `2` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:13:14
+   |
+LL |     for _ in val.arr {}
+   |              ^^^^^^^ expected `usize`, found `u8`
+   |
+   = note: the length of array `[i32; 2]` must be type `usize`
+
+error[E0277]: `[i32; 2]` is not an iterator
+  --> $DIR/bad-array-size-in-type-err.rs:13:14
+   |
+LL |     for _ in val.arr {}
+   |              ^^^^^^^ `[i32; 2]` is not an iterator; try calling `.into_iter()` or `.iter()`
+   |
+   = help: the trait `IntoIterator` is not implemented for `[i32; 2]`
+   = help: the following other types implement trait `IntoIterator`:
+             &[T; N]
+             &[T]
+             &mut [T; N]
+             &mut [T]
+             [T; N]
+
+error[E0493]: destructor of `Wrap` cannot be evaluated at compile-time
+  --> $DIR/bad-array-size-in-type-err.rs:21:16
+   |
+LL | pub const fn i(_: Wrap) {}
+   |                ^         - value is dropped here
+   |                |
+   |                the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0493.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const-slice-array-deref.rs b/tests/ui/consts/const-slice-array-deref.rs
new file mode 100644
index 00000000000..9d84ed4bdb0
--- /dev/null
+++ b/tests/ui/consts/const-slice-array-deref.rs
@@ -0,0 +1,9 @@
+const ONE: [u16] = [1];
+//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
+//~| ERROR the size for values of type `[u16]` cannot be known at compilation time
+//~| ERROR mismatched types
+
+const TWO: &'static u16 = &ONE[0];
+//~^ ERROR cannot move a value of type `[u16]`
+
+fn main() {}
diff --git a/tests/ui/consts/const-slice-array-deref.stderr b/tests/ui/consts/const-slice-array-deref.stderr
new file mode 100644
index 00000000000..6e69744144e
--- /dev/null
+++ b/tests/ui/consts/const-slice-array-deref.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the size for values of type `[u16]` cannot be known at compilation time
+  --> $DIR/const-slice-array-deref.rs:1:12
+   |
+LL | const ONE: [u16] = [1];
+   |            ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u16]`
+
+error[E0308]: mismatched types
+  --> $DIR/const-slice-array-deref.rs:1:20
+   |
+LL | const ONE: [u16] = [1];
+   |                    ^^^ expected `[u16]`, found `[u16; 1]`
+
+error[E0277]: the size for values of type `[u16]` cannot be known at compilation time
+  --> $DIR/const-slice-array-deref.rs:1:20
+   |
+LL | const ONE: [u16] = [1];
+   |                    ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u16]`
+   = note: constant expressions must have a statically known size
+
+error[E0161]: cannot move a value of type `[u16]`
+  --> $DIR/const-slice-array-deref.rs:6:28
+   |
+LL | const TWO: &'static u16 = &ONE[0];
+   |                            ^^^ the size of `[u16]` cannot be statically determined
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0161, E0277, E0308.
+For more information about an error, try `rustc --explain E0161`.
diff --git a/tests/ui/consts/large_const_alloc.rs b/tests/ui/consts/large_const_alloc.rs
index 61a22216ae5..14edc1bb696 100644
--- a/tests/ui/consts/large_const_alloc.rs
+++ b/tests/ui/consts/large_const_alloc.rs
@@ -1,5 +1,7 @@
 //@ only-64bit
 // on 32bit and 16bit platforms it is plausible that the maximum allocation size will succeed
+// FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger
+//@ ignore-aarch64-unknown-linux-gnu
 
 const FOO: () = {
     // 128 TiB, unlikely anyone has that much RAM
diff --git a/tests/ui/consts/large_const_alloc.stderr b/tests/ui/consts/large_const_alloc.stderr
index 25d660f1217..fa7d5977a95 100644
--- a/tests/ui/consts/large_const_alloc.stderr
+++ b/tests/ui/consts/large_const_alloc.stderr
@@ -1,11 +1,11 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/large_const_alloc.rs:6:13
+  --> $DIR/large_const_alloc.rs:8:13
    |
 LL |     let x = [0_u8; (1 << 47) - 1];
    |             ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/large_const_alloc.rs:11:13
+  --> $DIR/large_const_alloc.rs:13:13
    |
 LL |     let x = [0_u8; (1 << 47) - 1];
    |             ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
index b923a768cbf..53618e2e86a 100644
--- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs
@@ -3,6 +3,8 @@
 
 // Needs the max type size to be much bigger than the RAM people typically have.
 //@ only-64bit
+// FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger
+//@ ignore-aarch64-unknown-linux-gnu
 
 pub struct Data([u8; (1 << 47) - 1]);
 const _: &'static Data = &Data([0; (1 << 47) - 1]);
diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
index f5d767efceb..aac805dbd8c 100644
--- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
+++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:32
+  --> $DIR/promoted_running_out_of_memory_issue-130687.rs:10:32
    |
 LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
    |                                ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
diff --git a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
index 7994ddf11c3..4fee6cc9a22 100644
--- a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
+++ b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
@@ -28,7 +28,7 @@ LL |     let _: &Copy + 'static;
    |
    = note: the trait is not dyn compatible because it requires `Self: Sized`
    = note: for a trait to be dyn compatible it needs to allow building a vtable
-           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr
index f241333f2a7..a384697ee08 100644
--- a/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr
+++ b/tests/ui/dyn-compatibility/almost-supertrait-associated-type.stderr
@@ -5,7 +5,7 @@ LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ {
    |                    ^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/almost-supertrait-associated-type.rs:33:34
    |
 LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
@@ -22,7 +22,7 @@ LL |     (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
    |                           ^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/almost-supertrait-associated-type.rs:33:34
    |
 LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
@@ -39,7 +39,7 @@ LL |     (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
    |      ^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/almost-supertrait-associated-type.rs:33:34
    |
 LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
diff --git a/tests/ui/dyn-compatibility/associated-consts.curr.stderr b/tests/ui/dyn-compatibility/associated-consts.curr.stderr
index 45d4f795542..de243938123 100644
--- a/tests/ui/dyn-compatibility/associated-consts.curr.stderr
+++ b/tests/ui/dyn-compatibility/associated-consts.curr.stderr
@@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                               ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/associated-consts.rs:9:11
    |
 LL | trait Bar {
@@ -21,7 +21,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/associated-consts.rs:9:11
    |
 LL | trait Bar {
diff --git a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr
index 4c8c82196ed..704d833f00b 100644
--- a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/associated-consts.rs:9:11
    |
 LL | trait Bar {
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
index ff5e9fdb6b3..b811ef40c26 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
@@ -34,7 +34,7 @@ LL | fn id<F>(f: Copy) -> usize {
    |
    = note: the trait is not dyn compatible because it requires `Self: Sized`
    = note: for a trait to be dyn compatible it needs to allow building a vtable
-           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 
 error[E0618]: expected function, found `(dyn Copy + 'static)`
   --> $DIR/avoid-ice-on-warning-2.rs:12:5
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
index 92a2d340115..d8935be5609 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
@@ -72,7 +72,7 @@ LL | trait B { fn f(a: A) -> A; }
    |                   ^ `A` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/avoid-ice-on-warning-3.rs:14:14
    |
 LL | trait A { fn g(b: B) -> B; }
@@ -109,7 +109,7 @@ LL | trait A { fn g(b: B) -> B; }
    |                   ^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/avoid-ice-on-warning-3.rs:4:14
    |
 LL | trait B { fn f(a: A) -> A; }
diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
index e3ec5b9c3c8..7be6cb0d03b 100644
--- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
+++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
@@ -23,7 +23,7 @@ LL | fn ord_prefer_dot(s: String) -> Ord {
    |                                 ^^^ `Ord` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: the trait is not dyn compatible because it uses `Self` as a type parameter
diff --git a/tests/ui/dyn-compatibility/bounds.stderr b/tests/ui/dyn-compatibility/bounds.stderr
index d45e66b1d5e..5473af388c0 100644
--- a/tests/ui/dyn-compatibility/bounds.stderr
+++ b/tests/ui/dyn-compatibility/bounds.stderr
@@ -5,7 +5,7 @@ LL | fn f() -> Box<dyn X<U = u32>> {
    |               ^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/bounds.rs:4:13
    |
 LL | trait X {
diff --git a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr
index 04dc0b1d6f4..cfebd5d6947 100644
--- a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr
+++ b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr
@@ -5,7 +5,7 @@ LL | fn take_dyn(_: &dyn Child) {}
    |                     ^^^^^ `Super` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-incompatible-supertrait.rs:10:10
    |
 LL | trait Super {
diff --git a/tests/ui/dyn-compatibility/generics.curr.stderr b/tests/ui/dyn-compatibility/generics.curr.stderr
index 1607954ab70..d29d02b2ff3 100644
--- a/tests/ui/dyn-compatibility/generics.curr.stderr
+++ b/tests/ui/dyn-compatibility/generics.curr.stderr
@@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                               ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
@@ -21,7 +21,7 @@ LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
    |                                        ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
@@ -37,7 +37,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
@@ -54,7 +54,7 @@ LL |     t as &dyn Bar
    |          ^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
@@ -70,7 +70,7 @@ LL |     t as &dyn Bar
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
diff --git a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr
index 7f31b29b39c..b3565a766fe 100644
--- a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
@@ -22,7 +22,7 @@ LL |     t as &dyn Bar
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generics.rs:10:8
    |
 LL | trait Bar {
diff --git a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
index 1ed78e1e659..bb3f7899bf1 100644
--- a/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
+++ b/tests/ui/dyn-compatibility/mention-correct-dyn-incompatible-trait.stderr
@@ -5,7 +5,7 @@ LL |     let test: &mut dyn Bar = &mut thing;
    |               ^^^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8
    |
 LL |     fn foo<T>(&self, val: T);
@@ -23,7 +23,7 @@ LL |     let test: &mut dyn Bar = &mut thing;
    |                              ^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8
    |
 LL |     fn foo<T>(&self, val: T);
diff --git a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
index eba2c15dd74..cf3a7b23084 100644
--- a/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
+++ b/tests/ui/dyn-compatibility/mentions-Self-in-super-predicates.stderr
@@ -5,7 +5,7 @@ LL |     elements: Vec<Box<dyn Expr + 'x>>,
    |                           ^^^^ `Expr` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self-in-super-predicates.rs:5:21
    |
 LL | trait Expr: Debug + PartialEq {
@@ -20,7 +20,7 @@ LL |     let a: Box<dyn Expr> = Box::new(SExpr::new());
    |                    ^^^^ `Expr` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self-in-super-predicates.rs:5:21
    |
 LL | trait Expr: Debug + PartialEq {
@@ -35,7 +35,7 @@ LL |     let b: Box<dyn Expr> = Box::new(SExpr::new());
    |                    ^^^^ `Expr` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self-in-super-predicates.rs:5:21
    |
 LL | trait Expr: Debug + PartialEq {
diff --git a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr
index 90db86ffef9..2d3fe5ce636 100644
--- a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr
+++ b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr
@@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                               ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:11:22
    |
 LL | trait Bar {
@@ -21,7 +21,7 @@ LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    |                               ^^^^^^^ `Baz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:15:22
    |
 LL | trait Baz {
@@ -37,7 +37,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:11:22
    |
 LL | trait Bar {
@@ -54,7 +54,7 @@ LL |     t
    |     ^ `Baz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:15:22
    |
 LL | trait Baz {
diff --git a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr
index 4a50d3f07e4..91c26a86025 100644
--- a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:11:22
    |
 LL | trait Bar {
@@ -22,7 +22,7 @@ LL |     t
    |     ^ `Baz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/mentions-Self.rs:15:22
    |
 LL | trait Baz {
diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.stderr b/tests/ui/dyn-compatibility/missing-assoc-type.stderr
index 3f550494b33..5a7560682f2 100644
--- a/tests/ui/dyn-compatibility/missing-assoc-type.stderr
+++ b/tests/ui/dyn-compatibility/missing-assoc-type.stderr
@@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Foo) {}
    |                ^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/missing-assoc-type.rs:2:10
    |
 LL | trait Foo {
diff --git a/tests/ui/dyn-compatibility/no-static.curr.stderr b/tests/ui/dyn-compatibility/no-static.curr.stderr
index 867c485053d..bf9b48e7a43 100644
--- a/tests/ui/dyn-compatibility/no-static.curr.stderr
+++ b/tests/ui/dyn-compatibility/no-static.curr.stderr
@@ -5,7 +5,7 @@ LL | fn diverges() -> Box<dyn Foo> {
    |                      ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/no-static.rs:9:8
    |
 LL | trait Foo {
@@ -29,7 +29,7 @@ LL |     let b: Box<dyn Foo> = Box::new(Bar);
    |            ^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/no-static.rs:9:8
    |
 LL | trait Foo {
@@ -53,7 +53,7 @@ LL |     let b: Box<dyn Foo> = Box::new(Bar);
    |                           ^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/no-static.rs:9:8
    |
 LL | trait Foo {
diff --git a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr
index 65608a9cca7..d5ad4510334 100644
--- a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     let b: Box<dyn Foo> = Box::new(Bar);
    |                           ^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/no-static.rs:9:8
    |
 LL | trait Foo {
diff --git a/tests/ui/dyn-compatibility/sized-2.curr.stderr b/tests/ui/dyn-compatibility/sized-2.curr.stderr
index c8fd1056237..2d262072d5d 100644
--- a/tests/ui/dyn-compatibility/sized-2.curr.stderr
+++ b/tests/ui/dyn-compatibility/sized-2.curr.stderr
@@ -5,7 +5,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    |                               ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized-2.rs:9:18
    |
 LL | trait Bar
@@ -20,7 +20,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized-2.rs:9:18
    |
 LL | trait Bar
diff --git a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr
index 477dacdf5a1..1fbc10c0c3f 100644
--- a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized-2.rs:9:18
    |
 LL | trait Bar
diff --git a/tests/ui/dyn-compatibility/sized.curr.stderr b/tests/ui/dyn-compatibility/sized.curr.stderr
index d86ea9197b9..a197d967005 100644
--- a/tests/ui/dyn-compatibility/sized.curr.stderr
+++ b/tests/ui/dyn-compatibility/sized.curr.stderr
@@ -5,7 +5,7 @@ LL | fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
    |                                ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized.rs:8:12
    |
 LL | trait Bar: Sized {
@@ -20,7 +20,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized.rs:8:12
    |
 LL | trait Bar: Sized {
diff --git a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr
index b763173594b..350c8992c6f 100644
--- a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL |     t
    |     ^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/sized.rs:8:12
    |
 LL | trait Bar: Sized {
diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr
index f5dea256469..8e139ee6b48 100644
--- a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr
+++ b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr
@@ -27,7 +27,7 @@ LL |     fn c(&self) -> dyn SuperTrait<T>;
    |                    ^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/supertrait-mentions-GAT.rs:4:10
    |
 LL |     type Gat<'a>
diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
index f9ef0c9b2e0..a763649e9c6 100644
--- a/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
+++ b/tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
@@ -25,7 +25,7 @@ LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    |                                   ^^^ `Baz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/supertrait-mentions-Self.rs:8:13
    |
 LL | trait Baz : Bar<Self> {
diff --git a/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr
index 8442314835e..7e80a1d2e42 100644
--- a/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr
+++ b/tests/ui/dyn-compatibility/taint-const-eval.curr.stderr
@@ -5,7 +5,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc";
    |               ^^^^^^^^^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/taint-const-eval.rs:8:8
    |
 LL | trait Qux {
@@ -28,7 +28,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc";
    |                                 ^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/taint-const-eval.rs:8:8
    |
 LL | trait Qux {
@@ -52,7 +52,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc";
    |               ^^^^^^^^^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/taint-const-eval.rs:8:8
    |
 LL | trait Qux {
diff --git a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr
index 1c51df8501f..0bc7d0b14d3 100644
--- a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL | static FOO: &(dyn Qux + Sync) = "desc";
    |                                 ^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/taint-const-eval.rs:8:8
    |
 LL | trait Qux {
diff --git a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr
index 45a924008c7..1299167159e 100644
--- a/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr
+++ b/tests/ui/dyn-compatibility/undispatchable-receiver-and-wc-references-Self.stderr
@@ -8,7 +8,7 @@ LL | fn fetcher() -> Box<dyn Fetcher> {
    |                     ^^^^^^^^^^^ `Fetcher` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22
    |
 LL | pub trait Fetcher: Send + Sync {
@@ -26,7 +26,7 @@ LL |     let fetcher = fetcher();
    |                   ^^^^^^^^^ `Fetcher` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22
    |
 LL | pub trait Fetcher: Send + Sync {
@@ -44,7 +44,7 @@ LL |     let _ = fetcher.get();
    |             ^^^^^^^^^^^^^ `Fetcher` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/undispatchable-receiver-and-wc-references-Self.rs:11:22
    |
 LL | pub trait Fetcher: Send + Sync {
diff --git a/tests/ui/error-codes/E0038.stderr b/tests/ui/error-codes/E0038.stderr
index 59e9f504d17..63a5249a386 100644
--- a/tests/ui/error-codes/E0038.stderr
+++ b/tests/ui/error-codes/E0038.stderr
@@ -5,7 +5,7 @@ LL | fn call_foo(x: Box<dyn Trait>) {
    |                    ^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/E0038.rs:2:22
    |
 LL | trait Trait {
@@ -21,7 +21,7 @@ LL |     let y = x.foo();
    |             ^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/E0038.rs:2:22
    |
 LL | trait Trait {
diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
index b4de6b66469..ab8c092a826 100644
--- a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
+++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
@@ -5,7 +5,7 @@ LL | async fn takes_dyn_trait(x: &dyn Foo) {
    |                              ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
    |
 LL | trait Foo {
@@ -21,7 +21,7 @@ LL |     x.bar().await;
    |       ^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
    |
 LL | trait Foo {
@@ -37,7 +37,7 @@ LL |     x.bar().await;
    |     ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:4:14
    |
 LL | trait Foo {
diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
index f8fc086c441..6634ce12118 100644
--- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
+++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr
@@ -8,7 +8,7 @@ LL |     Ptr(Box::new(4)) as Ptr<dyn Trait>;
    |                         ^^^^^^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18
    |
 LL | trait Trait {
@@ -27,7 +27,7 @@ LL |     Ptr(Box::new(4)) as Ptr<dyn Trait>;
    |     ^^^^^^^^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18
    |
 LL | trait Trait {
diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr
index 10540f0219d..2c3edd6e6a5 100644
--- a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr
@@ -5,7 +5,7 @@ LL | fn takes_dyn_incompatible_ref<T>(obj: &dyn DynIncompatible1) {
    |                                        ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25
    |
 LL | trait DynIncompatible1: Sized {}
@@ -20,7 +20,7 @@ LL | fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 {
    |                                              ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible2` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:7:8
    |
 LL | trait DynIncompatible2 {
@@ -43,7 +43,7 @@ LL | fn takes_dyn_incompatible_box(obj: Box<dyn DynIncompatible3>) {
    |                                        ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible3` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:11:8
    |
 LL | trait DynIncompatible3 {
@@ -59,7 +59,7 @@ LL | fn return_dyn_incompatible_rc() -> std::rc::Rc<dyn DynIncompatible4> {
    |                                                ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible4` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:15:22
    |
 LL | trait DynIncompatible4 {
@@ -75,7 +75,7 @@ LL | impl Trait for dyn DynIncompatible1 {}
    |                ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25
    |
 LL | trait DynIncompatible1: Sized {}
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
index 4c5a47e73c6..c9b46de5c33 100644
--- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
+++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
@@ -43,7 +43,7 @@ LL |   fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:2:8
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.stderr
index df79556c825..e57f6b48401 100644
--- a/tests/ui/generic-associated-types/gat-in-trait-path.stderr
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.stderr
@@ -5,7 +5,7 @@ LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-in-trait-path.rs:6:10
    |
 LL | trait Foo {
@@ -21,7 +21,7 @@ LL |   f(Box::new(foo));
    |     ^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-in-trait-path.rs:6:10
    |
 LL | trait Foo {
@@ -37,7 +37,7 @@ LL |   f(Box::new(foo));
    |     ^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-in-trait-path.rs:6:10
    |
 LL | trait Foo {
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index 499ce8e4a32..52fed354edf 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -130,7 +130,7 @@ LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
    |                     ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
    |
 LL | trait X {
@@ -196,7 +196,7 @@ LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
    |                     ^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/issue-67510-pass.stderr b/tests/ui/generic-associated-types/issue-67510-pass.stderr
index f6846f833fe..4b56c4ef35f 100644
--- a/tests/ui/generic-associated-types/issue-67510-pass.stderr
+++ b/tests/ui/generic-associated-types/issue-67510-pass.stderr
@@ -5,7 +5,7 @@ LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
    |                       ^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-67510-pass.rs:4:10
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/issue-67510.stderr b/tests/ui/generic-associated-types/issue-67510.stderr
index e8555a7aa1f..f5c494788ea 100644
--- a/tests/ui/generic-associated-types/issue-67510.stderr
+++ b/tests/ui/generic-associated-types/issue-67510.stderr
@@ -36,7 +36,7 @@ LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
    |             ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-67510.rs:2:10
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr
index a78151384d4..56439f6dfea 100644
--- a/tests/ui/generic-associated-types/issue-71176.stderr
+++ b/tests/ui/generic-associated-types/issue-71176.stderr
@@ -55,7 +55,7 @@ LL |   inner: Box<dyn Provider<A = B>>,
    |              ^^^^^^^^^^^^^^^^^^^ `Provider` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-71176.rs:2:10
    |
 LL | trait Provider {
@@ -72,7 +72,7 @@ LL |         inner: Box::new(()),
    |                ^^^^^^^^^^^^ `Provider` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-71176.rs:2:10
    |
 LL | trait Provider {
@@ -89,7 +89,7 @@ LL |         inner: Box::new(()),
    |                ^^^^^^^^^^^^ `Provider` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-71176.rs:2:10
    |
 LL | trait Provider {
diff --git a/tests/ui/generic-associated-types/issue-76535.stderr b/tests/ui/generic-associated-types/issue-76535.stderr
index 6b7c3bfe731..b828234afa1 100644
--- a/tests/ui/generic-associated-types/issue-76535.stderr
+++ b/tests/ui/generic-associated-types/issue-76535.stderr
@@ -21,7 +21,7 @@ LL |     let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruc
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-76535.rs:4:10
    |
 LL | pub trait SuperTrait {
@@ -39,7 +39,7 @@ LL |     let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruc
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-76535.rs:4:10
    |
 LL | pub trait SuperTrait {
diff --git a/tests/ui/generic-associated-types/issue-78671.stderr b/tests/ui/generic-associated-types/issue-78671.stderr
index c85e97067cb..c6da137672d 100644
--- a/tests/ui/generic-associated-types/issue-78671.stderr
+++ b/tests/ui/generic-associated-types/issue-78671.stderr
@@ -21,7 +21,7 @@ LL |     Box::new(Family) as &dyn CollectionFamily<Member=usize>
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-78671.rs:2:10
    |
 LL | trait CollectionFamily {
diff --git a/tests/ui/generic-associated-types/issue-79422.stderr b/tests/ui/generic-associated-types/issue-79422.stderr
index a81217e96c3..6311e4de272 100644
--- a/tests/ui/generic-associated-types/issue-79422.stderr
+++ b/tests/ui/generic-associated-types/issue-79422.stderr
@@ -21,7 +21,7 @@ LL |         as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-79422.rs:18:10
    |
 LL | trait MapLike<K, V> {
@@ -37,7 +37,7 @@ LL |     let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-79422.rs:18:10
    |
 LL | trait MapLike<K, V> {
diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs
index ef54a89aaae..3f7a9ff63c3 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.rs
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs
@@ -3,8 +3,6 @@
 //! Unfortunately we don't even reach opaque type collection, as we ICE in typeck before that.
 //! See #109281 for the original report.
 //@ edition:2018
-//@ error-pattern: expected generic lifetime parameter, found `'a`
-
 #![feature(type_alias_impl_trait)]
 
 use std::future::Future;
@@ -24,6 +22,7 @@ impl<'x, T: 'x> Trait<'x> for (T,) {
 impl Foo<'_> {
     fn make_fut(&self) -> Box<dyn for<'a> Trait<'a, Thing = Fut<'a>>> {
         Box::new((async { () },))
+        //~^ ERROR expected generic lifetime parameter, found `'a`
     }
 }
 
diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
index be6f4272ce1..aa427d42649 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.stderr
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/issue-90014-tait2.rs:26:9
+  --> $DIR/issue-90014-tait2.rs:24:9
    |
 LL | type Fut<'a> = impl Future<Output = ()>;
    |          -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
index 6b8df5cc12f..7b6888817f4 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -55,7 +55,7 @@ LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/missing_lifetime_args.rs:2:10
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
index 5c9e9dbe3d7..45bca1a7628 100644
--- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -99,7 +99,7 @@ LL |   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
    |                       ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/trait-path-type-error-once-implemented.rs:2:10
    |
 LL | trait X {
diff --git a/tests/ui/generic-associated-types/trait-objects.stderr b/tests/ui/generic-associated-types/trait-objects.stderr
index 56a1cb1906f..7d95718ec87 100644
--- a/tests/ui/generic-associated-types/trait-objects.stderr
+++ b/tests/ui/generic-associated-types/trait-objects.stderr
@@ -5,7 +5,7 @@ LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> u
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/trait-objects.rs:2:10
    |
 LL | trait StreamingIterator {
@@ -21,7 +21,7 @@ LL |     x.size_hint().0
    |       ^^^^^^^^^ `StreamingIterator` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/trait-objects.rs:2:10
    |
 LL | trait StreamingIterator {
@@ -37,7 +37,7 @@ LL |     x.size_hint().0
    |     ^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/trait-objects.rs:2:10
    |
 LL | trait StreamingIterator {
diff --git a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr
index fc3d9c2171d..183ee678d7a 100644
--- a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr
@@ -5,7 +5,7 @@ LL |     let x: &dyn Foo = &();
    |                       ^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/span-bug-issue-121597.rs:4:12
    |
 LL | trait Foo: for<T> Bar<T> {}
@@ -21,7 +21,7 @@ LL |     let x: &dyn Foo = &();
    |            ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/span-bug-issue-121597.rs:4:12
    |
 LL | trait Foo: for<T> Bar<T> {}
diff --git a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
index 4abd7bcf31c..2869702d7fc 100644
--- a/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
+++ b/tests/ui/impl-trait/dyn-incompatible-trait-in-return-position-dyn-trait.stderr
@@ -5,7 +5,7 @@ LL | fn car() -> dyn DynIncompatible {
    |             ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
    |
 LL | trait DynIncompatible {
@@ -33,7 +33,7 @@ LL | fn cat() -> Box<dyn DynIncompatible> {
    |                 ^^^^^^^^^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
    |
 LL | trait DynIncompatible {
@@ -78,7 +78,7 @@ LL |         return Box::new(A);
    |                ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
    |
 LL | trait DynIncompatible {
@@ -107,7 +107,7 @@ LL |     Box::new(B)
    |     ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
    |
 LL | trait DynIncompatible {
diff --git a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr
index 44ca09150fe..61fe9432a1e 100644
--- a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr
+++ b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-dyn-compatibility-check.stderr
@@ -15,7 +15,7 @@ LL |         MyTrait::foo(&self)
    |         ^^^^^^^^^^^^ `MyTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22
    |
 LL | trait MyTrait {
@@ -40,7 +40,7 @@ LL | impl dyn MyTrait {
    |      ^^^^^^^^^^^ `MyTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22
    |
 LL | trait MyTrait {
@@ -57,7 +57,7 @@ LL |     fn other(&self) -> impl Marker {
    |               ^^^^ `MyTrait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/cycle-effective-visibilities-during-dyn-compatibility-check.rs:5:22
    |
 LL | trait MyTrait {
diff --git a/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr b/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr
index 87a5480b1e3..840c27e183f 100644
--- a/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr
+++ b/tests/ui/impl-trait/in-trait/dyn-compatibility.stderr
@@ -5,7 +5,7 @@ LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |                                 ^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility.rs:4:22
    |
 LL | trait Foo {
@@ -22,7 +22,7 @@ LL |     let s = i.baz();
    |               ^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility.rs:4:22
    |
 LL | trait Foo {
@@ -39,7 +39,7 @@ LL |     let s = i.baz();
    |             ^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility.rs:4:22
    |
 LL | trait Foo {
@@ -56,7 +56,7 @@ LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |             ^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-compatibility.rs:4:22
    |
 LL | trait Foo {
diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr
index 07d09468b04..29235ca78a5 100644
--- a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr
+++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr
@@ -5,7 +5,7 @@ LL |     let _: &dyn rpitit::Foo = todo!();
    |            ^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/auxiliary/rpitit.rs:4:21
    |
 LL |     fn bar(self) -> impl Deref<Target = impl Sized>;
diff --git a/tests/ui/issues/issue-18959.stderr b/tests/ui/issues/issue-18959.stderr
index 49d501c397f..c37c4177bfc 100644
--- a/tests/ui/issues/issue-18959.stderr
+++ b/tests/ui/issues/issue-18959.stderr
@@ -5,7 +5,7 @@ LL | fn foo(b: &dyn Bar) {
    |            ^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-18959.rs:1:20
    |
 LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
@@ -21,7 +21,7 @@ LL |     b.foo(&0)
    |     ^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-18959.rs:1:20
    |
 LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
@@ -37,7 +37,7 @@ LL |     let test: &dyn Bar = &mut thing;
    |               ^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-18959.rs:1:20
    |
 LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
@@ -53,7 +53,7 @@ LL |     let test: &dyn Bar = &mut thing;
    |                          ^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-18959.rs:1:20
    |
 LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
@@ -70,7 +70,7 @@ LL |     foo(test);
    |         ^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-18959.rs:1:20
    |
 LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
diff --git a/tests/ui/issues/issue-19380.stderr b/tests/ui/issues/issue-19380.stderr
index 7d4812c3693..f8509891d3a 100644
--- a/tests/ui/issues/issue-19380.stderr
+++ b/tests/ui/issues/issue-19380.stderr
@@ -5,7 +5,7 @@ LL |   foos: &'static [&'static (dyn Qiz + 'static)]
    |                             ^^^^^^^^^^^^^^^^^ `Qiz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-19380.rs:2:6
    |
 LL | trait Qiz {
@@ -29,7 +29,7 @@ LL | const BAR : Bar = Bar { foos: &[&FOO]};
    |                                 ^^^^ `Qiz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-19380.rs:2:6
    |
 LL | trait Qiz {
@@ -54,7 +54,7 @@ LL | const BAR : Bar = Bar { foos: &[&FOO]};
    |                               ^^^^^^^ `Qiz` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-19380.rs:2:6
    |
 LL | trait Qiz {
diff --git a/tests/ui/issues/issue-26056.stderr b/tests/ui/issues/issue-26056.stderr
index d1cdf43351e..c2168af9496 100644
--- a/tests/ui/issues/issue-26056.stderr
+++ b/tests/ui/issues/issue-26056.stderr
@@ -5,7 +5,7 @@ LL |         as &dyn Map<Key=u32,MapValue=u32>;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-26056.rs:9:12
    |
 LL | trait Map: MapLookup<<Self as Map>::Key> {
diff --git a/tests/ui/issues/issue-50781.stderr b/tests/ui/issues/issue-50781.stderr
index 293e9839944..88b83a83e0c 100644
--- a/tests/ui/issues/issue-50781.stderr
+++ b/tests/ui/issues/issue-50781.stderr
@@ -5,7 +5,7 @@ LL | impl Trait for dyn X {}
    |                ^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-50781.rs:4:8
    |
 LL | trait X {
@@ -22,7 +22,7 @@ LL |     <dyn X as X>::foo(&());
    |                       ^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-50781.rs:4:8
    |
 LL | trait X {
@@ -40,7 +40,7 @@ LL |     <dyn X as X>::foo(&());
    |      ^^^^^ `X` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-50781.rs:4:8
    |
 LL | trait X {
diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index 83446fc9ec0..95048c4454b 100644
--- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
+++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -26,7 +26,7 @@ LL |     let z = &x as &dyn Foo;
    |                   ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/kindck-inherited-copy-bound.rs:10:13
    |
 LL | trait Foo : Copy {
@@ -41,7 +41,7 @@ LL |     let z = &x as &dyn Foo;
    |             ^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/kindck-inherited-copy-bound.rs:10:13
    |
 LL | trait Foo : Copy {
diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr
index 271e5afb9e7..296f011193e 100644
--- a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr
@@ -26,7 +26,7 @@ LL |     let z = &x as &dyn Foo;
    |             ^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/kindck-inherited-copy-bound.rs:10:13
    |
 LL | trait Foo : Copy {
diff --git a/tests/ui/resolve/issue-3907-2.stderr b/tests/ui/resolve/issue-3907-2.stderr
index 4ab72a42eb8..40cdfb7a302 100644
--- a/tests/ui/resolve/issue-3907-2.stderr
+++ b/tests/ui/resolve/issue-3907-2.stderr
@@ -5,7 +5,7 @@ LL | fn bar(_x: Foo) {}
    |            ^^^ `issue_3907::Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/auxiliary/issue-3907.rs:2:8
    |
 LL |     fn bar();
diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr
index 3e018995ba5..8382b4867e2 100644
--- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr
+++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.curr.stderr
@@ -8,7 +8,7 @@ LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18
    |
 LL | trait Foo {
@@ -27,7 +27,7 @@ LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |             ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18
    |
 LL | trait Foo {
diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr
index 12c93d58537..d324f4641cf 100644
--- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr
+++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr
@@ -8,7 +8,7 @@ LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |             ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18
    |
 LL | trait Foo {
diff --git a/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr
index 08c744979f5..28427161e87 100644
--- a/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr
+++ b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr
@@ -5,7 +5,7 @@ LL |     pub desc: &'static dyn Qux,
    |                        ^^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8
    |
 LL | trait Qux {
@@ -44,7 +44,7 @@ LL | static FOO: &Lint = &Lint { desc: "desc" };
    |                                   ^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8
    |
 LL | trait Qux {
@@ -68,7 +68,7 @@ LL | static FOO: &Lint = &Lint { desc: "desc" };
    |                                   ^^^^^^ `Qux` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/unsizing-wfcheck-issue-127299.rs:4:8
    |
 LL | trait Qux {
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
index cb0e7fce910..ae009d26029 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-references-self.stderr
@@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Trait) {}
    |            ^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-references-self.rs:2:22
    |
 LL | trait Trait {
@@ -25,7 +25,7 @@ LL | fn foo(x: &dyn Other) {}
    |            ^^^^^^^^^ `Other` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-references-self.rs:11:14
    |
 LL | trait Other: Sized {}
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr
index 2efcad1e7bd..742011ad0c0 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self-2021.stderr
@@ -18,7 +18,7 @@ LL |     fn f(a: dyn A) -> dyn A;
    |             ^^^^^ `A` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:3:10
    |
 LL | trait A: Sized {
@@ -46,7 +46,7 @@ LL |     fn f(a: dyn B) -> dyn B;
    |             ^^^^^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:9:8
    |
 LL | trait B {
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr
index ecb3ee9185f..843c139851d 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-self.stderr
@@ -18,7 +18,7 @@ LL |     fn f(a: A) -> A;
    |             ^ `A` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-should-use-self.rs:2:10
    |
 LL | trait A: Sized {
@@ -46,7 +46,7 @@ LL |     fn f(a: B) -> B;
    |             ^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-should-use-self.rs:8:8
    |
 LL | trait B {
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
index 696840d3ba4..e2250807603 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
@@ -5,7 +5,7 @@ LL | fn bar(x: &dyn Trait) {}
    |            ^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/dyn-incompatible-trait-should-use-where-sized.rs:5:8
    |
 LL | trait Trait {
diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr
index 508c3ec5e4f..e7b8cd2f101 100644
--- a/tests/ui/suggestions/issue-116434-2015.stderr
+++ b/tests/ui/suggestions/issue-116434-2015.stderr
@@ -47,7 +47,7 @@ LL |     fn foo() -> Clone;
    |
    = note: the trait is not dyn compatible because it requires `Self: Sized`
    = note: for a trait to be dyn compatible it needs to allow building a vtable
-           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 help: there is an associated type with the same name
    |
 LL |     fn foo() -> Self::Clone;
@@ -74,7 +74,7 @@ LL |     fn handle() -> DbHandle;
    |                    ^^^^^^^^ `DbHandle` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-116434-2015.rs:14:17
    |
 LL | trait DbHandle: Sized {}
diff --git a/tests/ui/suggestions/issue-98500.stderr b/tests/ui/suggestions/issue-98500.stderr
index 97b712acfcb..ec984c0d60e 100644
--- a/tests/ui/suggestions/issue-98500.stderr
+++ b/tests/ui/suggestions/issue-98500.stderr
@@ -5,7 +5,7 @@ LL | struct S(Box<dyn B>);
    |              ^^^^^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/auxiliary/dyn-incompatible.rs:4:8
    |
 LL |     fn f();
diff --git a/tests/ui/traits/alias/generic-default-in-dyn.stderr b/tests/ui/traits/alias/generic-default-in-dyn.stderr
index 1ab9e6d5c5c..c6f8ab4137b 100644
--- a/tests/ui/traits/alias/generic-default-in-dyn.stderr
+++ b/tests/ui/traits/alias/generic-default-in-dyn.stderr
@@ -15,7 +15,7 @@ LL | struct Foo<T>(dyn SendEqAlias<T>);
    |                   ^^^^^^^^^^^^^^ `SendEqAlias` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generic-default-in-dyn.rs:1:24
    |
 LL | trait SendEqAlias<T> = PartialEq;
@@ -30,7 +30,7 @@ LL | struct Bar<T>(dyn SendEqAlias<T>, T);
    |                   ^^^^^^^^^^^^^^ `SendEqAlias` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/generic-default-in-dyn.rs:1:24
    |
 LL | trait SendEqAlias<T> = PartialEq;
diff --git a/tests/ui/traits/alias/object-fail.stderr b/tests/ui/traits/alias/object-fail.stderr
index 52ce79a4597..d60d8843407 100644
--- a/tests/ui/traits/alias/object-fail.stderr
+++ b/tests/ui/traits/alias/object-fail.stderr
@@ -5,7 +5,7 @@ LL |     let _: &dyn EqAlias = &123;
    |                 ^^^^^^^ `EqAlias` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: ...because it uses `Self` as a type parameter
diff --git a/tests/ui/traits/alias/self-in-const-generics.stderr b/tests/ui/traits/alias/self-in-const-generics.stderr
index 3c799492591..b5538cb6e2f 100644
--- a/tests/ui/traits/alias/self-in-const-generics.stderr
+++ b/tests/ui/traits/alias/self-in-const-generics.stderr
@@ -5,7 +5,7 @@ LL | fn foo(x: &dyn BB) {}
    |                ^^ `BB` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/self-in-const-generics.rs:7:12
    |
 LL | trait BB = Bar<{ 2 + 1 }>;
diff --git a/tests/ui/traits/alias/self-in-generics.stderr b/tests/ui/traits/alias/self-in-generics.stderr
index 5639b2b44a1..afe4dff45ed 100644
--- a/tests/ui/traits/alias/self-in-generics.stderr
+++ b/tests/ui/traits/alias/self-in-generics.stderr
@@ -5,7 +5,7 @@ LL | pub fn f(_f: &dyn SelfInput) {}
    |                   ^^^^^^^^^ `SelfInput` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/self-in-generics.rs:6:23
    |
 LL | pub trait SelfInput = Fn(&mut Self);
diff --git a/tests/ui/traits/issue-20692.stderr b/tests/ui/traits/issue-20692.stderr
index 50ea7cde961..32e29de49a1 100644
--- a/tests/ui/traits/issue-20692.stderr
+++ b/tests/ui/traits/issue-20692.stderr
@@ -5,7 +5,7 @@ LL |     &dyn Array;
    |     ^^^^^^^^^^ `Array` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-20692.rs:1:14
    |
 LL | trait Array: Sized + Copy {}
@@ -21,7 +21,7 @@ LL |     let _ = x
    |             ^ `Array` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-20692.rs:1:14
    |
 LL | trait Array: Sized + Copy {}
diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr
index ba113d573d6..ba61ce98554 100644
--- a/tests/ui/traits/issue-28576.stderr
+++ b/tests/ui/traits/issue-28576.stderr
@@ -27,7 +27,7 @@ LL | |               <Assoc=()>
    | |________________________^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-28576.rs:5:16
    |
 LL | pub trait Bar: Foo<Assoc=()> {
diff --git a/tests/ui/traits/issue-38404.stderr b/tests/ui/traits/issue-38404.stderr
index f9e592255dd..63269d3379e 100644
--- a/tests/ui/traits/issue-38404.stderr
+++ b/tests/ui/traits/issue-38404.stderr
@@ -5,7 +5,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {}
    |                   ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-38404.rs:1:13
    |
 LL | trait A<T>: std::ops::Add<Self> + Sized {}
@@ -20,7 +20,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {}
    |                   ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-38404.rs:1:13
    |
 LL | trait A<T>: std::ops::Add<Self> + Sized {}
@@ -36,7 +36,7 @@ LL | trait C<T>: A<dyn B<T, Output = usize>> {}
    |                   ^^^^^^^^^^^^^^^^^^^^ `B` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-38404.rs:1:13
    |
 LL | trait A<T>: std::ops::Add<Self> + Sized {}
diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr
index 94f9c1540ad..e6a6b44e730 100644
--- a/tests/ui/traits/issue-38604.stderr
+++ b/tests/ui/traits/issue-38604.stderr
@@ -5,7 +5,7 @@ LL |     let _f: Box<dyn Foo> =
    |             ^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-38604.rs:2:22
    |
 LL | trait Foo where u32: Q<Self> {
@@ -21,7 +21,7 @@ LL |         Box::new(());
    |         ^^^^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-38604.rs:2:22
    |
 LL | trait Foo where u32: Q<Self> {
diff --git a/tests/ui/traits/issue-72410.stderr b/tests/ui/traits/issue-72410.stderr
index 002345bff84..c9e133437dd 100644
--- a/tests/ui/traits/issue-72410.stderr
+++ b/tests/ui/traits/issue-72410.stderr
@@ -5,7 +5,7 @@ LL |     where for<'a> &'a mut [dyn Bar]: ;
    |                   ^^^^^^^^^^^^^^^^^ `Bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-72410.rs:13:8
    |
 LL | pub trait Bar {
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr
index c97158a5b76..58c558d6685 100644
--- a/tests/ui/traits/item-privacy.stderr
+++ b/tests/ui/traits/item-privacy.stderr
@@ -143,7 +143,7 @@ LL |     <dyn C>::A;
    |      ^^^^^ `assoc_const::C` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/item-privacy.rs:25:15
    |
 LL |         const A: u8 = 0;
diff --git a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
index 682d18842b8..c8a1329e3d0 100644
--- a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
+++ b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
@@ -41,7 +41,7 @@ LL | impl Foo<i64> {
    |      ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/missing-for-type-in-impl.rs:4:8
    |
 LL | trait Foo<T> {
diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr
index 8448890c084..43b69d0b50e 100644
--- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr
+++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr
@@ -14,7 +14,7 @@ LL |     let x: &dyn Foo = &();
    |                       ^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/supertrait-dyn-compatibility.rs:4:12
    |
 LL | trait Foo: for<T> Bar<T> {}
@@ -31,7 +31,7 @@ LL |     let x: &dyn Foo = &();
    |            ^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/supertrait-dyn-compatibility.rs:4:12
    |
 LL | trait Foo: for<T> Bar<T> {}
@@ -47,7 +47,7 @@ LL |     needs_bar(x);
    |     ^^^^^^^^^ `Foo` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/supertrait-dyn-compatibility.rs:4:12
    |
 LL | trait Foo: for<T> Bar<T> {}
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
index 2a301788525..2a301788525 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
+++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
index 38dcdbd0af2..38dcdbd0af2 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
+++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs
index 23f3666618b..23f3666618b 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.rs
+++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.rs
diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr
index 3c352c9889c..3c352c9889c 100644
--- a/tests/ui/type-alias-impl-trait/non-lifetime-binder.stderr
+++ b/tests/ui/traits/non_lifetime_binders/type-alias-impl-trait/non-lifetime-binder.stderr
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
index ae3762704c6..b4bbd65b2f4 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
@@ -20,7 +20,7 @@ LL |     let b: &dyn FromResidual = &();
    |                                ^^^ `FromResidual` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8
    |
 LL | trait FromResidual<R = <Self as Try>::Residual> {
@@ -44,7 +44,7 @@ LL |     let b: &dyn FromResidual = &();
    |            ^^^^^^^^^^^^^^^^^ `FromResidual` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8
    |
 LL | trait FromResidual<R = <Self as Try>::Residual> {
diff --git a/tests/ui/traits/object/macro-matcher.stderr b/tests/ui/traits/object/macro-matcher.stderr
index ab0fc213c9f..3c668ce99c7 100644
--- a/tests/ui/traits/object/macro-matcher.stderr
+++ b/tests/ui/traits/object/macro-matcher.stderr
@@ -12,7 +12,7 @@ LL |     m!(dyn Copy + Send + 'static);
    |
    = note: the trait is not dyn compatible because it requires `Self: Sized`
    = note: for a trait to be dyn compatible it needs to allow building a vtable
-           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/traits/object/print_vtable_sizes.rs b/tests/ui/traits/object/print_vtable_sizes.rs
deleted file mode 100644
index 2b1745da5f3..00000000000
--- a/tests/ui/traits/object/print_vtable_sizes.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-//@ check-pass
-//@ compile-flags: -Z print-vtable-sizes
-#![crate_type = "lib"]
-
-trait A<T: help::V>: AsRef<[T::V]> + AsMut<[T::V]> {}
-
-trait B<T>: AsRef<T> + AsRef<T> + AsRef<T> + AsRef<T> {}
-
-trait C {
-    fn x() {} // not dyn-compatible, shouldn't be reported
-}
-
-// This does not have any upcasting cost,
-// because both `Send` and `Sync` are traits
-// with no methods
-trait D: Send + Sync + help::MarkerWithSuper {}
-
-// This can't have no cost without reordering,
-// because `Super::f`.
-trait E: help::MarkerWithSuper + Send + Sync {}
-
-trait F {
-    fn a(&self);
-    fn b(&self);
-    fn c(&self);
-
-    fn d() -> Self
-    where
-        Self: Sized;
-}
-
-trait G: AsRef<u8> + AsRef<u16> + help::MarkerWithSuper {
-    fn a(&self);
-    fn b(&self);
-    fn c(&self);
-    fn d(&self);
-    fn e(&self);
-
-    fn f() -> Self
-    where
-        Self: Sized;
-}
-
-// Traits with the same name
-const _: () = {
-    trait S {}
-};
-const _: () = {
-    trait S {}
-};
-
-mod help {
-    pub trait V {
-        type V;
-    }
-
-    pub trait MarkerWithSuper: Super {}
-
-    pub trait Super {
-        fn f(&self);
-    }
-}
diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout
deleted file mode 100644
index 4daf4769576..00000000000
--- a/tests/ui/traits/object/print_vtable_sizes.stdout
+++ /dev/null
@@ -1,11 +0,0 @@
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "G", "entries": "13", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "2", "upcasting_cost_percent": "18.181818181818183" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "E", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::MarkerWithSuper", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::Super", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::V", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
diff --git a/tests/ui/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr
index eab59f39c28..593e42619f4 100644
--- a/tests/ui/traits/object/safety.stderr
+++ b/tests/ui/traits/object/safety.stderr
@@ -5,7 +5,7 @@ LL |     let _: &dyn Tr = &St;
    |                      ^^^ `Tr` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/safety.rs:4:8
    |
 LL | trait Tr {
@@ -30,7 +30,7 @@ LL |     let _: &dyn Tr = &St;
    |            ^^^^^^^ `Tr` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/safety.rs:4:8
    |
 LL | trait Tr {
diff --git a/tests/ui/traits/sized-coniductive.rs b/tests/ui/traits/sized-coniductive.rs
deleted file mode 100644
index 5f63b166f98..00000000000
--- a/tests/ui/traits/sized-coniductive.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ check-pass
-// https://github.com/rust-lang/rust/issues/129541
-
-#[derive(Clone)]
-struct Test {
-    field: std::borrow::Cow<'static, [Self]>,
-}
-
-#[derive(Clone)]
-struct Hello {
-    a: <[Hello] as std::borrow::ToOwned>::Owned,
-}
-
-fn main(){}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
deleted file mode 100644
index defb39aae06..00000000000
--- a/tests/ui/traits/solver-cycles/129541-recursive-struct-and-array-impl.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Regression test for #129541
-
-//@ check-pass
-
-trait Bound {}
-trait Normalize {
-    type Assoc;
-}
-
-impl<T: Bound> Normalize for T {
-    type Assoc = T;
-}
-
-impl<T: Bound> Normalize for [T] {
-    type Assoc = T;
-}
-
-impl Bound for Hello {}
-struct Hello {
-    a: <[Hello] as Normalize>::Assoc,
-}
-
-fn main() {}
diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
index d4339dd54d6..4fbcbefec91 100644
--- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
+++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs
@@ -1,5 +1,6 @@
 // Regression test for #129541
 
+//@ revisions: unique multiple
 //@ check-pass
 
 trait Bound {}
@@ -7,6 +8,10 @@ trait Normalize {
     type Assoc;
 }
 
+#[cfg(multiple)]
+impl<T: Bound> Normalize for T {
+    type Assoc = T;
+}
 impl<T: Bound> Normalize for [T] {
     type Assoc = T;
 }
diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr
index 8915e490b4d..6a6cb503aa4 100644
--- a/tests/ui/traits/test-2.stderr
+++ b/tests/ui/traits/test-2.stderr
@@ -33,7 +33,7 @@ LL |     (Box::new(10) as Box<dyn bar>).dup();
    |                      ^^^^^^^^^^^^ `bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/test-2.rs:4:30
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
@@ -56,7 +56,7 @@ LL |     (Box::new(10) as Box<dyn bar>).dup();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/test-2.rs:4:30
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
@@ -79,7 +79,7 @@ LL |     (Box::new(10) as Box<dyn bar>).dup();
    |      ^^^^^^^^^^^^ `bar` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/test-2.rs:4:30
    |
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs
new file mode 100644
index 00000000000..796ddec46ac
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.rs
@@ -0,0 +1,27 @@
+#![feature(rustc_attrs)]
+
+// Test for <https://github.com/rust-lang/rust/issues/135316>.
+
+trait Supertrait<T> {
+    fn _print_numbers(&self, mem: &[usize; 100]) {
+    }
+}
+impl<T> Supertrait<T> for () {}
+
+trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
+    fn say_hello(&self, _: &usize) {
+    }
+}
+impl<T, U> Trait<T, U> for () {}
+
+// We should observe compatibility between these two vtables.
+
+#[rustc_dump_vtable]
+type First = dyn for<'a> Trait<&'static (), &'a ()>;
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
+type Second = dyn Trait<&'static (), &'static ()>;
+//~^ ERROR vtable entries
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr
new file mode 100644
index 00000000000..24fa1650ca1
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder-vtable.stderr
@@ -0,0 +1,26 @@
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<dyn for<'a> Trait<&(), &'a ()> as Supertrait<&()>>::_print_numbers - shim(reify)),
+           Method(<dyn for<'a> Trait<&(), &'a ()> as Trait<&(), &()>>::say_hello - shim(reify)),
+       ]
+  --> $DIR/multiple-supertraits-modulo-binder-vtable.rs:20:1
+   |
+LL | type First = dyn for<'a> Trait<&'static (), &'a ()>;
+   | ^^^^^^^^^^
+
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<dyn Trait<&(), &()> as Supertrait<&()>>::_print_numbers - shim(reify)),
+           Method(<dyn Trait<&(), &()> as Trait<&(), &()>>::say_hello - shim(reify)),
+       ]
+  --> $DIR/multiple-supertraits-modulo-binder-vtable.rs:24:1
+   |
+LL | type Second = dyn Trait<&'static (), &'static ()>;
+   | ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs
new file mode 100644
index 00000000000..510a1471af2
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.rs
@@ -0,0 +1,26 @@
+//@ run-pass
+//@ check-run-results
+
+// Test for <https://github.com/rust-lang/rust/issues/135316>.
+
+#![feature(trait_upcasting)]
+
+trait Supertrait<T> {
+    fn _print_numbers(&self, mem: &[usize; 100]) {
+        println!("{mem:?}");
+    }
+}
+impl<T> Supertrait<T> for () {}
+
+trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
+    fn say_hello(&self, _: &usize) {
+        println!("Hello!");
+    }
+}
+impl<T, U> Trait<T, U> for () {}
+
+fn main() {
+    (&() as &'static dyn for<'a> Trait<&'static (), &'a ()>
+        as &'static dyn Trait<&'static (), &'static ()>)
+        .say_hello(&0);
+}
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout
new file mode 100644
index 00000000000..10ddd6d257e
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-binder.run.stdout
@@ -0,0 +1 @@
+Hello!
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs
new file mode 100644
index 00000000000..69a71859a5c
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.rs
@@ -0,0 +1,37 @@
+#![feature(rustc_attrs)]
+#![feature(trait_upcasting)]
+
+// Test for <https://github.com/rust-lang/rust/issues/135315>.
+
+trait Supertrait<T> {
+    fn _print_numbers(&self, mem: &[usize; 100]) {
+        println!("{mem:?}");
+    }
+}
+impl<T> Supertrait<T> for () {}
+
+trait Identity {
+    type Selff;
+}
+impl<Selff> Identity for Selff {
+    type Selff = Selff;
+}
+
+trait Middle<T>: Supertrait<()> + Supertrait<T> {
+    fn say_hello(&self, _: &usize) {
+        println!("Hello!");
+    }
+}
+impl<T> Middle<T> for () {}
+
+trait Trait: Middle<<() as Identity>::Selff> {}
+
+#[rustc_dump_vtable]
+impl Trait for () {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
+type Virtual = dyn Middle<()>;
+//~^ ERROR vtable entries
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr
new file mode 100644
index 00000000000..757e2dc6939
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization-vtable.stderr
@@ -0,0 +1,26 @@
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<() as Supertrait<()>>::_print_numbers),
+           Method(<() as Middle<()>>::say_hello),
+       ]
+  --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:30:1
+   |
+LL | impl Trait for () {}
+   | ^^^^^^^^^^^^^^^^^
+
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<dyn Middle<()> as Supertrait<()>>::_print_numbers - shim(reify)),
+           Method(<dyn Middle<()> as Middle<()>>::say_hello - shim(reify)),
+       ]
+  --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:34:1
+   |
+LL | type Virtual = dyn Middle<()>;
+   | ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs
new file mode 100644
index 00000000000..c744e6e64f5
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.rs
@@ -0,0 +1,34 @@
+//@ run-pass
+//@ check-run-results
+
+#![feature(trait_upcasting)]
+
+// Test for <https://github.com/rust-lang/rust/issues/135315>.
+
+trait Supertrait<T> {
+    fn _print_numbers(&self, mem: &[usize; 100]) {
+        println!("{mem:?}");
+    }
+}
+impl<T> Supertrait<T> for () {}
+
+trait Identity {
+    type Selff;
+}
+impl<Selff> Identity for Selff {
+    type Selff = Selff;
+}
+
+trait Middle<T>: Supertrait<()> + Supertrait<T> {
+    fn say_hello(&self, _: &usize) {
+        println!("Hello!");
+    }
+}
+impl<T> Middle<T> for () {}
+
+trait Trait: Middle<<() as Identity>::Selff> {}
+impl Trait for () {}
+
+fn main() {
+    (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
+}
diff --git a/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout
new file mode 100644
index 00000000000..10ddd6d257e
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/multiple-supertraits-modulo-normalization.run.stdout
@@ -0,0 +1 @@
+Hello!
diff --git a/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs
new file mode 100644
index 00000000000..6cd74b6c7f7
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/supertraits-modulo-inner-binder.rs
@@ -0,0 +1,30 @@
+//@ run-pass
+
+#![feature(trait_upcasting)]
+
+trait Super<U> {
+    fn call(&self)
+    where
+        U: HigherRanked,
+    {
+    }
+}
+
+impl<T> Super<T> for () {}
+
+trait HigherRanked {}
+impl HigherRanked for for<'a> fn(&'a ()) {}
+
+trait Unimplemented {}
+impl<T: Unimplemented> HigherRanked for T {}
+
+trait Sub: Super<fn(&'static ())> + Super<for<'a> fn(&'a ())> {}
+impl Sub for () {}
+
+fn main() {
+    let a: &dyn Sub = &();
+    // `Super<fn(&'static ())>` and `Super<for<'a> fn(&'a ())>` have different
+    // vtables and we need to upcast to the latter!
+    let b: &dyn Super<for<'a> fn(&'a ())> = a;
+    b.call();
+}
diff --git a/tests/ui/traits/vtable/multiple-markers.rs b/tests/ui/traits/vtable/multiple-markers.rs
index 8a9e7a006cf..8eba5135582 100644
--- a/tests/ui/traits/vtable/multiple-markers.rs
+++ b/tests/ui/traits/vtable/multiple-markers.rs
@@ -2,8 +2,7 @@
 //
 // This test makes sure that multiple marker (method-less) traits can reuse the
 // same pointer for upcasting.
-//
-//@ build-fail
+
 #![crate_type = "lib"]
 #![feature(rustc_attrs)]
 
@@ -17,17 +16,13 @@ trait T {
     fn method(&self) {}
 }
 
-#[rustc_dump_vtable]
-trait A: M0 + M1 + M2 + T {} //~ error: vtable entries for `<S as A>`:
+trait A: M0 + M1 + M2 + T {}
 
-#[rustc_dump_vtable]
-trait B: M0 + M1 + T + M2 {} //~ error: vtable entries for `<S as B>`:
+trait B: M0 + M1 + T + M2 {}
 
-#[rustc_dump_vtable]
-trait C: M0 + T + M1 + M2 {} //~ error: vtable entries for `<S as C>`:
+trait C: M0 + T + M1 + M2 {}
 
-#[rustc_dump_vtable]
-trait D: T + M0 + M1 + M2 {} //~ error: vtable entries for `<S as D>`:
+trait D: T + M0 + M1 + M2 {}
 
 struct S;
 
@@ -35,13 +30,21 @@ impl M0 for S {}
 impl M1 for S {}
 impl M2 for S {}
 impl T for S {}
+
+#[rustc_dump_vtable]
 impl A for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl B for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl C for S {}
-impl D for S {}
+//~^ ERROR vtable entries
 
-pub fn require_vtables() {
-    fn require_vtables(_: &dyn A, _: &dyn B, _: &dyn C, _: &dyn D) {}
+#[rustc_dump_vtable]
+impl D for S {}
+//~^ ERROR vtable entries
 
-    require_vtables(&S, &S, &S, &S)
-}
+fn main() {}
diff --git a/tests/ui/traits/vtable/multiple-markers.stderr b/tests/ui/traits/vtable/multiple-markers.stderr
index 36ac8b24eb5..35dd3c2516d 100644
--- a/tests/ui/traits/vtable/multiple-markers.stderr
+++ b/tests/ui/traits/vtable/multiple-markers.stderr
@@ -1,46 +1,46 @@
-error: vtable entries for `<S as A>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
        ]
-  --> $DIR/multiple-markers.rs:21:1
+  --> $DIR/multiple-markers.rs:35:1
    |
-LL | trait A: M0 + M1 + M2 + T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl A for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as B>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
        ]
-  --> $DIR/multiple-markers.rs:24:1
+  --> $DIR/multiple-markers.rs:39:1
    |
-LL | trait B: M0 + M1 + T + M2 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl B for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as C>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
        ]
-  --> $DIR/multiple-markers.rs:27:1
+  --> $DIR/multiple-markers.rs:43:1
    |
-LL | trait C: M0 + T + M1 + M2 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl C for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as D>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
        ]
-  --> $DIR/multiple-markers.rs:30:1
+  --> $DIR/multiple-markers.rs:47:1
    |
-LL | trait D: T + M0 + M1 + M2 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl D for S {}
+   | ^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/vtable/vtable-diamond.rs b/tests/ui/traits/vtable/vtable-diamond.rs
index 2cfa86c526d..56053f6d026 100644
--- a/tests/ui/traits/vtable/vtable-diamond.rs
+++ b/tests/ui/traits/vtable/vtable-diamond.rs
@@ -1,44 +1,37 @@
-//@ build-fail
 #![feature(rustc_attrs)]
 
-#[rustc_dump_vtable]
 trait A {
     fn foo_a(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait B: A {
     fn foo_b(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait C: A {
-    //~^ error vtable
     fn foo_c(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait D: B + C {
-    //~^ error vtable
     fn foo_d(&self) {}
 }
 
 struct S;
 
+#[rustc_dump_vtable]
 impl A for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl B for S {}
-impl C for S {}
-impl D for S {}
+//~^ ERROR vtable entries
 
-fn foo(d: &dyn D) {
-    d.foo_d();
-}
+#[rustc_dump_vtable]
+impl C for S {}
+//~^ ERROR vtable entries
 
-fn bar(d: &dyn C) {
-    d.foo_c();
-}
+#[rustc_dump_vtable]
+impl D for S {}
+//~^ ERROR vtable entries
 
-fn main() {
-    foo(&S);
-    bar(&S);
-}
+fn main() {}
diff --git a/tests/ui/traits/vtable/vtable-diamond.stderr b/tests/ui/traits/vtable/vtable-diamond.stderr
index f3718c5d852..4644bf339b1 100644
--- a/tests/ui/traits/vtable/vtable-diamond.stderr
+++ b/tests/ui/traits/vtable/vtable-diamond.stderr
@@ -1,29 +1,52 @@
-error: vtable entries for `<S as D>`: [
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<S as A>::foo_a),
+       ]
+  --> $DIR/vtable-diamond.rs:22:1
+   |
+LL | impl A for S {}
+   | ^^^^^^^^^^^^
+
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as A>::foo_a),
            Method(<S as B>::foo_b),
+       ]
+  --> $DIR/vtable-diamond.rs:26:1
+   |
+LL | impl B for S {}
+   | ^^^^^^^^^^^^
+
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<S as A>::foo_a),
            Method(<S as C>::foo_c),
-           TraitVPtr(<S as C>),
-           Method(<S as D>::foo_d),
        ]
-  --> $DIR/vtable-diamond.rs:21:1
+  --> $DIR/vtable-diamond.rs:30:1
    |
-LL | trait D: B + C {
-   | ^^^^^^^^^^^^^^
+LL | impl C for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as C>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as A>::foo_a),
+           Method(<S as B>::foo_b),
            Method(<S as C>::foo_c),
+           TraitVPtr(<S as C>),
+           Method(<S as D>::foo_d),
        ]
-  --> $DIR/vtable-diamond.rs:15:1
+  --> $DIR/vtable-diamond.rs:34:1
    |
-LL | trait C: A {
-   | ^^^^^^^^^^
+LL | impl D for S {}
+   | ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/vtable/vtable-dyn-incompatible.rs b/tests/ui/traits/vtable/vtable-dyn-incompatible.rs
index 64a8138bdcf..fb19dec4ace 100644
--- a/tests/ui/traits/vtable/vtable-dyn-incompatible.rs
+++ b/tests/ui/traits/vtable/vtable-dyn-incompatible.rs
@@ -1,15 +1,16 @@
-//@ build-fail
 #![feature(rustc_attrs)]
 
 // Ensure that dyn-incompatible methods in Iterator does not generate
 // vtable entries.
 
-#[rustc_dump_vtable]
 trait A: Iterator {}
-//~^ error vtable
 
 impl<T> A for T where T: Iterator {}
 
+#[rustc_dump_vtable]
+type Test = dyn A<Item=u8>;
+//~^ error vtable
+
 fn foo(_a: &mut dyn A<Item=u8>) {
 }
 
diff --git a/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr b/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr
index e442c3eac00..c80a763998b 100644
--- a/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr
+++ b/tests/ui/traits/vtable/vtable-dyn-incompatible.stderr
@@ -1,16 +1,16 @@
-error: vtable entries for `<std::vec::IntoIter<u8> as A>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
-           Method(<std::vec::IntoIter<u8> as Iterator>::next),
-           Method(<std::vec::IntoIter<u8> as Iterator>::size_hint),
-           Method(<std::vec::IntoIter<u8> as Iterator>::advance_by),
-           Method(<std::vec::IntoIter<u8> as Iterator>::nth),
+           Method(<dyn A<Item = u8> as Iterator>::next - shim(reify)),
+           Method(<dyn A<Item = u8> as Iterator>::size_hint - shim(reify)),
+           Method(<dyn A<Item = u8> as Iterator>::advance_by - shim(reify)),
+           Method(<dyn A<Item = u8> as Iterator>::nth - shim(reify)),
        ]
-  --> $DIR/vtable-dyn-incompatible.rs:8:1
+  --> $DIR/vtable-dyn-incompatible.rs:11:1
    |
-LL | trait A: Iterator {}
-   | ^^^^^^^^^^^^^^^^^
+LL | type Test = dyn A<Item=u8>;
+   | ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/vtable/vtable-multi-level.rs b/tests/ui/traits/vtable/vtable-multi-level.rs
index bedbf84d303..67bac49f9f6 100644
--- a/tests/ui/traits/vtable/vtable-multi-level.rs
+++ b/tests/ui/traits/vtable/vtable-multi-level.rs
@@ -1,4 +1,3 @@
-//@ build-fail
 #![feature(rustc_attrs)]
 
 //   O --> G --> C --> A
@@ -10,134 +9,126 @@
 //           |-> M --> K
 //                 \-> L
 
-#[rustc_dump_vtable]
 trait A {
-    //~^ error vtable
     fn foo_a(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait B {
-    //~^ error vtable
     fn foo_b(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait C: A + B {
-    //~^ error vtable
     fn foo_c(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait D {
-    //~^ error vtable
     fn foo_d(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait E {
-    //~^ error vtable
     fn foo_e(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait F: D + E {
-    //~^ error vtable
     fn foo_f(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait G: C + F {
     fn foo_g(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait H {
-    //~^ error vtable
     fn foo_h(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait I {
-    //~^ error vtable
     fn foo_i(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait J: H + I {
-    //~^ error vtable
     fn foo_j(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait K {
-    //~^ error vtable
     fn foo_k(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait L {
-    //~^ error vtable
     fn foo_l(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait M: K + L {
-    //~^ error vtable
     fn foo_m(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait N: J + M {
-    //~^ error vtable
     fn foo_n(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait O: G + N {
-    //~^ error vtable
     fn foo_o(&self) {}
 }
 
 struct S;
 
+#[rustc_dump_vtable]
 impl A for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl B for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl C for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl D for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl E for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl F for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl G for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl H for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl I for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl J for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl K for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl L for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl M for S {}
+//~^ ERROR vtable entries
+
+#[rustc_dump_vtable]
 impl N for S {}
-impl O for S {}
+//~^ ERROR vtable entries
 
-macro_rules! monomorphize_vtable {
-    ($trait:ident) => {{
-        fn foo(_ : &dyn $trait) {}
-        foo(&S);
-    }}
-}
+#[rustc_dump_vtable]
+impl O for S {}
+//~^ ERROR vtable entries
 
-fn main() {
-    monomorphize_vtable!(O);
-
-    monomorphize_vtable!(A);
-    monomorphize_vtable!(B);
-    monomorphize_vtable!(C);
-    monomorphize_vtable!(D);
-    monomorphize_vtable!(E);
-    monomorphize_vtable!(F);
-    monomorphize_vtable!(H);
-    monomorphize_vtable!(I);
-    monomorphize_vtable!(J);
-    monomorphize_vtable!(K);
-    monomorphize_vtable!(L);
-    monomorphize_vtable!(M);
-    monomorphize_vtable!(N);
-}
+fn main() {}
diff --git a/tests/ui/traits/vtable/vtable-multi-level.stderr b/tests/ui/traits/vtable/vtable-multi-level.stderr
index c4389e23fc1..961900aa3d2 100644
--- a/tests/ui/traits/vtable/vtable-multi-level.stderr
+++ b/tests/ui/traits/vtable/vtable-multi-level.stderr
@@ -1,134 +1,119 @@
-error: vtable entries for `<S as O>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as A>::foo_a),
-           Method(<S as B>::foo_b),
-           TraitVPtr(<S as B>),
-           Method(<S as C>::foo_c),
-           Method(<S as D>::foo_d),
-           TraitVPtr(<S as D>),
-           Method(<S as E>::foo_e),
-           TraitVPtr(<S as E>),
-           Method(<S as F>::foo_f),
-           TraitVPtr(<S as F>),
-           Method(<S as G>::foo_g),
-           Method(<S as H>::foo_h),
-           TraitVPtr(<S as H>),
-           Method(<S as I>::foo_i),
-           TraitVPtr(<S as I>),
-           Method(<S as J>::foo_j),
-           TraitVPtr(<S as J>),
-           Method(<S as K>::foo_k),
-           TraitVPtr(<S as K>),
-           Method(<S as L>::foo_l),
-           TraitVPtr(<S as L>),
-           Method(<S as M>::foo_m),
-           TraitVPtr(<S as M>),
-           Method(<S as N>::foo_n),
-           TraitVPtr(<S as N>),
-           Method(<S as O>::foo_o),
        ]
-  --> $DIR/vtable-multi-level.rs:97:1
+  --> $DIR/vtable-multi-level.rs:75:1
    |
-LL | trait O: G + N {
-   | ^^^^^^^^^^^^^^
+LL | impl A for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as A>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
-           Method(<S as A>::foo_a),
+           Method(<S as B>::foo_b),
        ]
-  --> $DIR/vtable-multi-level.rs:14:1
+  --> $DIR/vtable-multi-level.rs:79:1
    |
-LL | trait A {
-   | ^^^^^^^
+LL | impl B for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as B>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
+           Method(<S as A>::foo_a),
            Method(<S as B>::foo_b),
+           TraitVPtr(<S as B>),
+           Method(<S as C>::foo_c),
        ]
-  --> $DIR/vtable-multi-level.rs:20:1
+  --> $DIR/vtable-multi-level.rs:83:1
    |
-LL | trait B {
-   | ^^^^^^^
+LL | impl C for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as C>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
-           Method(<S as A>::foo_a),
-           Method(<S as B>::foo_b),
-           TraitVPtr(<S as B>),
-           Method(<S as C>::foo_c),
+           Method(<S as D>::foo_d),
        ]
-  --> $DIR/vtable-multi-level.rs:26:1
+  --> $DIR/vtable-multi-level.rs:87:1
    |
-LL | trait C: A + B {
-   | ^^^^^^^^^^^^^^
+LL | impl D for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as D>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
-           Method(<S as D>::foo_d),
+           Method(<S as E>::foo_e),
        ]
-  --> $DIR/vtable-multi-level.rs:32:1
+  --> $DIR/vtable-multi-level.rs:91:1
    |
-LL | trait D {
-   | ^^^^^^^
+LL | impl E for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as E>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
+           Method(<S as D>::foo_d),
            Method(<S as E>::foo_e),
+           TraitVPtr(<S as E>),
+           Method(<S as F>::foo_f),
        ]
-  --> $DIR/vtable-multi-level.rs:38:1
+  --> $DIR/vtable-multi-level.rs:95:1
    |
-LL | trait E {
-   | ^^^^^^^
+LL | impl F for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as F>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
+           Method(<S as A>::foo_a),
+           Method(<S as B>::foo_b),
+           TraitVPtr(<S as B>),
+           Method(<S as C>::foo_c),
            Method(<S as D>::foo_d),
+           TraitVPtr(<S as D>),
            Method(<S as E>::foo_e),
            TraitVPtr(<S as E>),
            Method(<S as F>::foo_f),
+           TraitVPtr(<S as F>),
+           Method(<S as G>::foo_g),
        ]
-  --> $DIR/vtable-multi-level.rs:44:1
+  --> $DIR/vtable-multi-level.rs:99:1
    |
-LL | trait F: D + E {
-   | ^^^^^^^^^^^^^^
+LL | impl G for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as H>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as H>::foo_h),
        ]
-  --> $DIR/vtable-multi-level.rs:55:1
+  --> $DIR/vtable-multi-level.rs:103:1
    |
-LL | trait H {
-   | ^^^^^^^
+LL | impl H for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as I>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as I>::foo_i),
        ]
-  --> $DIR/vtable-multi-level.rs:61:1
+  --> $DIR/vtable-multi-level.rs:107:1
    |
-LL | trait I {
-   | ^^^^^^^
+LL | impl I for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as J>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
@@ -137,34 +122,34 @@ error: vtable entries for `<S as J>`: [
            TraitVPtr(<S as I>),
            Method(<S as J>::foo_j),
        ]
-  --> $DIR/vtable-multi-level.rs:67:1
+  --> $DIR/vtable-multi-level.rs:111:1
    |
-LL | trait J: H + I {
-   | ^^^^^^^^^^^^^^
+LL | impl J for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as K>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as K>::foo_k),
        ]
-  --> $DIR/vtable-multi-level.rs:73:1
+  --> $DIR/vtable-multi-level.rs:115:1
    |
-LL | trait K {
-   | ^^^^^^^
+LL | impl K for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as L>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as L>::foo_l),
        ]
-  --> $DIR/vtable-multi-level.rs:79:1
+  --> $DIR/vtable-multi-level.rs:119:1
    |
-LL | trait L {
-   | ^^^^^^^
+LL | impl L for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as M>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
@@ -173,12 +158,12 @@ error: vtable entries for `<S as M>`: [
            TraitVPtr(<S as L>),
            Method(<S as M>::foo_m),
        ]
-  --> $DIR/vtable-multi-level.rs:85:1
+  --> $DIR/vtable-multi-level.rs:123:1
    |
-LL | trait M: K + L {
-   | ^^^^^^^^^^^^^^
+LL | impl M for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as N>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
@@ -194,10 +179,46 @@ error: vtable entries for `<S as N>`: [
            TraitVPtr(<S as M>),
            Method(<S as N>::foo_n),
        ]
-  --> $DIR/vtable-multi-level.rs:91:1
+  --> $DIR/vtable-multi-level.rs:127:1
+   |
+LL | impl N for S {}
+   | ^^^^^^^^^^^^
+
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<S as A>::foo_a),
+           Method(<S as B>::foo_b),
+           TraitVPtr(<S as B>),
+           Method(<S as C>::foo_c),
+           Method(<S as D>::foo_d),
+           TraitVPtr(<S as D>),
+           Method(<S as E>::foo_e),
+           TraitVPtr(<S as E>),
+           Method(<S as F>::foo_f),
+           TraitVPtr(<S as F>),
+           Method(<S as G>::foo_g),
+           Method(<S as H>::foo_h),
+           TraitVPtr(<S as H>),
+           Method(<S as I>::foo_i),
+           TraitVPtr(<S as I>),
+           Method(<S as J>::foo_j),
+           TraitVPtr(<S as J>),
+           Method(<S as K>::foo_k),
+           TraitVPtr(<S as K>),
+           Method(<S as L>::foo_l),
+           TraitVPtr(<S as L>),
+           Method(<S as M>::foo_m),
+           TraitVPtr(<S as M>),
+           Method(<S as N>::foo_n),
+           TraitVPtr(<S as N>),
+           Method(<S as O>::foo_o),
+       ]
+  --> $DIR/vtable-multi-level.rs:131:1
    |
-LL | trait N: J + M {
-   | ^^^^^^^^^^^^^^
+LL | impl O for S {}
+   | ^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/tests/ui/traits/vtable/vtable-multiple.rs b/tests/ui/traits/vtable/vtable-multiple.rs
index beaaf4db6b1..51e20ee20c9 100644
--- a/tests/ui/traits/vtable/vtable-multiple.rs
+++ b/tests/ui/traits/vtable/vtable-multiple.rs
@@ -1,33 +1,29 @@
-//@ build-fail
 #![feature(rustc_attrs)]
 
-#[rustc_dump_vtable]
 trait A {
     fn foo_a(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait B {
-    //~^ error vtable
     fn foo_b(&self) {}
 }
 
-#[rustc_dump_vtable]
 trait C: A + B {
-    //~^ error vtable
     fn foo_c(&self) {}
 }
 
 struct S;
 
+#[rustc_dump_vtable]
 impl A for S {}
+//~^ error vtable
+
+#[rustc_dump_vtable]
 impl B for S {}
-impl C for S {}
+//~^ error vtable
 
-fn foo(c: &dyn C) {}
-fn bar(c: &dyn B) {}
+#[rustc_dump_vtable]
+impl C for S {}
+//~^ error vtable
 
-fn main() {
-    foo(&S);
-    bar(&S);
-}
+fn main() {}
diff --git a/tests/ui/traits/vtable/vtable-multiple.stderr b/tests/ui/traits/vtable/vtable-multiple.stderr
index 0dcd8443309..bae44148baa 100644
--- a/tests/ui/traits/vtable/vtable-multiple.stderr
+++ b/tests/ui/traits/vtable/vtable-multiple.stderr
@@ -1,27 +1,38 @@
-error: vtable entries for `<S as C>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
            Method(<S as A>::foo_a),
+       ]
+  --> $DIR/vtable-multiple.rs:18:1
+   |
+LL | impl A for S {}
+   | ^^^^^^^^^^^^
+
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
            Method(<S as B>::foo_b),
-           TraitVPtr(<S as B>),
-           Method(<S as C>::foo_c),
        ]
-  --> $DIR/vtable-multiple.rs:16:1
+  --> $DIR/vtable-multiple.rs:22:1
    |
-LL | trait C: A + B {
-   | ^^^^^^^^^^^^^^
+LL | impl B for S {}
+   | ^^^^^^^^^^^^
 
-error: vtable entries for `<S as B>`: [
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
+           Method(<S as A>::foo_a),
            Method(<S as B>::foo_b),
+           TraitVPtr(<S as B>),
+           Method(<S as C>::foo_c),
        ]
-  --> $DIR/vtable-multiple.rs:10:1
+  --> $DIR/vtable-multiple.rs:26:1
    |
-LL | trait B {
-   | ^^^^^^^
+LL | impl C for S {}
+   | ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/traits/vtable/vtable-vacant.rs b/tests/ui/traits/vtable/vtable-vacant.rs
index b3c76815703..b023565c56e 100644
--- a/tests/ui/traits/vtable/vtable-vacant.rs
+++ b/tests/ui/traits/vtable/vtable-vacant.rs
@@ -1,18 +1,14 @@
-//@ build-fail
 #![feature(rustc_attrs)]
 #![feature(negative_impls)]
 
 // B --> A
 
-#[rustc_dump_vtable]
 trait A {
     fn foo_a1(&self) {}
     fn foo_a2(&self) where Self: Send {}
 }
 
-#[rustc_dump_vtable]
 trait B: A {
-    //~^ error vtable
     fn foo_b1(&self) {}
     fn foo_b2(&self) where Self: Send {}
 }
@@ -20,11 +16,12 @@ trait B: A {
 struct S;
 impl !Send for S {}
 
+#[rustc_dump_vtable]
 impl A for S {}
-impl B for S {}
+//~^ error vtable
 
-fn foo(_: &dyn B) {}
+#[rustc_dump_vtable]
+impl B for S {}
+//~^ error vtable
 
-fn main() {
-    foo(&S);
-}
+fn main() {}
diff --git a/tests/ui/traits/vtable/vtable-vacant.stderr b/tests/ui/traits/vtable/vtable-vacant.stderr
index f6961ca010e..ed8466f7f2e 100644
--- a/tests/ui/traits/vtable/vtable-vacant.stderr
+++ b/tests/ui/traits/vtable/vtable-vacant.stderr
@@ -1,4 +1,16 @@
-error: vtable entries for `<S as B>`: [
+error: vtable entries: [
+           MetadataDropInPlace,
+           MetadataSize,
+           MetadataAlign,
+           Method(<S as A>::foo_a1),
+           Vacant,
+       ]
+  --> $DIR/vtable-vacant.rs:20:1
+   |
+LL | impl A for S {}
+   | ^^^^^^^^^^^^
+
+error: vtable entries: [
            MetadataDropInPlace,
            MetadataSize,
            MetadataAlign,
@@ -7,10 +19,10 @@ error: vtable entries for `<S as B>`: [
            Method(<S as B>::foo_b1),
            Vacant,
        ]
-  --> $DIR/vtable-vacant.rs:14:1
+  --> $DIR/vtable-vacant.rs:24:1
    |
-LL | trait B: A {
-   | ^^^^^^^^^^
+LL | impl B for S {}
+   | ^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
index 71717c6945e..eea2e75a238 100644
--- a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
+++ b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
@@ -17,7 +17,7 @@ LL |     let y = x as dyn MyAdd<i32>;
    |                  ^^^^^^^^^^^^^^ `MyAdd` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55
    |
 LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
diff --git a/tests/ui/wf/issue-87495.stderr b/tests/ui/wf/issue-87495.stderr
index 7be327e61d1..0c293e3576d 100644
--- a/tests/ui/wf/issue-87495.stderr
+++ b/tests/ui/wf/issue-87495.stderr
@@ -5,7 +5,7 @@ LL |     const CONST: (bool, dyn T);
    |                         ^^^^^ `T` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/issue-87495.rs:4:11
    |
 LL | trait T {
diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr
index 0b7f4cd4362..f3e4f2a63e9 100644
--- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr
+++ b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr
@@ -5,7 +5,7 @@ LL |     let t_box: Box<dyn Trait> = Box::new(S);
    |                                 ^^^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14
    |
 LL | trait Trait: Sized {}
@@ -22,7 +22,7 @@ LL |     takes_box(Box::new(S));
    |               ^^^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14
    |
 LL | trait Trait: Sized {}
@@ -39,7 +39,7 @@ LL |     Box::new(S) as Box<dyn Trait>;
    |     ^^^^^^^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14
    |
 LL | trait Trait: Sized {}
diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr
index 3f50e1192cf..716d0e78ff1 100644
--- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr
+++ b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr
@@ -5,7 +5,7 @@ LL |     let t: &dyn Trait = &S;
    |                         ^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14
    |
 LL | trait Trait: Sized {}
@@ -22,7 +22,7 @@ LL |     takes_trait(&S);
    |                 ^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14
    |
 LL | trait Trait: Sized {}
@@ -39,7 +39,7 @@ LL |     &S as &dyn Trait;
    |     ^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14
    |
 LL | trait Trait: Sized {}
diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
index 8f68f9c5b6b..a7405ce4caa 100644
--- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
+++ b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
@@ -19,7 +19,7 @@ LL |         Some(()) => &S,
    |                     ^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14
    |
 LL | trait Trait: Sized {}
@@ -40,7 +40,7 @@ LL |         None => &R,
    |                 ^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14
    |
 LL | trait Trait: Sized {}
diff --git a/tests/ui/wf/wf-dyn-incompatible.stderr b/tests/ui/wf/wf-dyn-incompatible.stderr
index 1803376aaa1..e61b37d9293 100644
--- a/tests/ui/wf/wf-dyn-incompatible.stderr
+++ b/tests/ui/wf/wf-dyn-incompatible.stderr
@@ -5,7 +5,7 @@ LL |     let _x: &dyn A;
    |             ^^^^^^ `A` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
-      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
   --> $DIR/wf-dyn-incompatible.rs:5:23
    |
 LL | trait A {
diff --git a/tests/ui/wf/wf-fn-where-clause.stderr b/tests/ui/wf/wf-fn-where-clause.stderr
index d73376e9861..b419bc8347f 100644
--- a/tests/ui/wf/wf-fn-where-clause.stderr
+++ b/tests/ui/wf/wf-fn-where-clause.stderr
@@ -22,7 +22,7 @@ LL | fn bar() where Vec<dyn Copy>:, {}
    |
    = note: the trait is not dyn compatible because it requires `Self: Sized`
    = note: for a trait to be dyn compatible it needs to allow building a vtable
-           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+           for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
 
 error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time
   --> $DIR/wf-fn-where-clause.rs:12:16
diff --git a/tests/ui/wf/wf-trait-default-fn-ret.rs b/tests/ui/wf/wf-trait-default-fn-ret.rs
index 2103dae8d23..a7f83dcf678 100644
--- a/tests/ui/wf/wf-trait-default-fn-ret.rs
+++ b/tests/ui/wf/wf-trait-default-fn-ret.rs
@@ -1,5 +1,4 @@
-// Check that we test WF conditions for fn arguments. Because the
-// current code is so goofy, this is only a warning for now.
+// Check that we test WF conditions for fn arguments.
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
diff --git a/tests/ui/wf/wf-trait-default-fn-ret.stderr b/tests/ui/wf/wf-trait-default-fn-ret.stderr
index f749ac7b1b3..f0d1b55edc4 100644
--- a/tests/ui/wf/wf-trait-default-fn-ret.stderr
+++ b/tests/ui/wf/wf-trait-default-fn-ret.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Self: Eq` is not satisfied
-  --> $DIR/wf-trait-default-fn-ret.rs:11:22
+  --> $DIR/wf-trait-default-fn-ret.rs:10:22
    |
 LL |     fn bar(&self) -> Bar<Self> {
    |                      ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
    |
 note: required by a bound in `Bar`
-  --> $DIR/wf-trait-default-fn-ret.rs:8:14
+  --> $DIR/wf-trait-default-fn-ret.rs:7:14
    |
 LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
    |              ^^ required by this bound in `Bar`