about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--bootstrap.example.toml3
-rw-r--r--compiler/rustc_abi/src/callconv/reg.rs22
-rw-r--r--compiler/rustc_abi/src/layout.rs71
-rw-r--r--compiler/rustc_abi/src/layout/simple.rs27
-rw-r--r--compiler/rustc_abi/src/lib.rs87
-rw-r--r--compiler/rustc_ast/src/ast.rs3
-rw-r--r--compiler/rustc_ast/src/lib.rs1
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs4
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl10
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs7
-rw-r--r--compiler/rustc_attr_parsing/src/lints.rs18
-rw-r--r--compiler/rustc_attr_parsing/src/parser.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs3
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs20
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs76
-rw-r--r--compiler/rustc_borrowck/src/root_cx.rs22
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs15
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/comments.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/types.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/builder/autodiff.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs72
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs71
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs11
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/alignment.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/check_validity_requirement.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0719.md14
-rw-r--r--compiler/rustc_expand/src/mbe/macro_check.rs11
-rw-r--r--compiler/rustc_feature/src/removed.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/lints.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs55
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/opaque_types.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs28
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs17
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs4
-rw-r--r--compiler/rustc_interface/src/passes.rs26
-rw-r--r--compiler/rustc_interface/src/util.rs76
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp52
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs7
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs4
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs2
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs37
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs2
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/patch.rs30
-rw-r--r--compiler/rustc_mir_transform/src/simplify_branches.rs19
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs21
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs19
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs135
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs46
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/tokenstream/tests.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs4
-rw-r--r--compiler/rustc_resolve/src/ident.rs33
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs99
-rw-r--r--compiler/rustc_resolve/src/lib.rs6
-rw-r--r--compiler/rustc_session/src/config.rs12
-rw-r--r--compiler/rustc_session/src/config/cfg.rs10
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/callconv/arm.rs2
-rw-r--r--compiler/rustc_target/src/callconv/loongarch.rs2
-rw-r--r--compiler/rustc_target/src/callconv/mips.rs2
-rw-r--r--compiler/rustc_target/src/callconv/mips64.rs4
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs2
-rw-r--r--compiler/rustc_target/src/callconv/nvptx64.rs4
-rw-r--r--compiler/rustc_target/src/callconv/powerpc64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/riscv.rs2
-rw-r--r--compiler/rustc_target/src/callconv/sparc.rs2
-rw-r--r--compiler/rustc_target/src/callconv/sparc64.rs2
-rw-r--r--compiler/rustc_target/src/callconv/xtensa.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs17
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs45
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs2
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs10
-rw-r--r--compiler/rustc_ty_utils/src/layout/invariant.rs6
-rw-r--r--compiler/rustc_type_ir/src/flags.rs1
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs2
-rw-r--r--library/alloc/src/collections/btree/map.rs2
-rw-r--r--library/alloc/src/rc.rs4
-rw-r--r--library/alloc/src/sync.rs16
-rw-r--r--library/core/src/num/niche_types.rs3
-rw-r--r--library/core/src/slice/iter.rs69
-rw-r--r--library/coretests/tests/iter/sources.rs11
-rw-r--r--library/proc_macro/src/bridge/client.rs19
-rw-r--r--library/proc_macro/src/bridge/closure.rs4
-rw-r--r--library/proc_macro/src/bridge/mod.rs28
-rw-r--r--library/proc_macro/src/bridge/server.rs16
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--library/std/src/net/hostname.rs22
-rw-r--r--library/std/src/net/mod.rs6
-rw-r--r--library/std/src/path.rs187
-rw-r--r--library/std/src/sys/net/connection/socket/windows.rs80
-rw-r--r--library/std/src/sys/net/hostname/mod.rs14
-rw-r--r--library/std/src/sys/net/hostname/unix.rs62
-rw-r--r--library/std/src/sys/net/hostname/unsupported.rs6
-rw-r--r--library/std/src/sys/net/hostname/windows.rs24
-rw-r--r--library/std/src/sys/net/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs12
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt2
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs2
-rw-r--r--library/std/src/sys/pal/windows/mod.rs4
-rw-r--r--library/std/src/sys/pal/windows/winsock.rs80
-rw-r--r--library/std/src/thread/current.rs24
-rw-r--r--library/std/src/thread/mod.rs4
-rw-r--r--library/std/tests/path.rs38
-rw-r--r--src/bootstrap/defaults/bootstrap.dist.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs53
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs21
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs29
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs18
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs12
-rw-r--r--src/bootstrap/src/core/builder/mod.rs2
-rw-r--r--src/bootstrap/src/core/builder/tests.rs44
-rw-r--r--src/bootstrap/src/core/config/config.rs7
-rw-r--r--src/bootstrap/src/core/config/mod.rs10
-rw-r--r--src/bootstrap/src/core/config/toml/build.rs2
-rw-r--r--src/bootstrap/src/lib.rs4
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs7
-rw-r--r--src/ci/citool/tests/test-jobs.yml2
-rw-r--r--src/ci/docker/host-x86_64/pr-check-1/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile1
-rw-r--r--src/ci/github-actions/jobs.yml14
-rw-r--r--src/doc/rustc/src/lints/levels.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/split-dwarf-out-dir.md7
-rw-r--r--src/etc/lldb_providers.py5
-rw-r--r--src/librustdoc/clean/types.rs18
-rw-r--r--src/librustdoc/html/highlight.rs3
-rw-r--r--src/librustdoc/html/highlight/tests.rs14
-rw-r--r--src/librustdoc/html/render/context.rs3
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/html/render/span_map.rs68
-rw-r--r--src/librustdoc/html/sources.rs7
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs2
-rw-r--r--src/tools/compiletest/src/common.rs9
-rw-r--r--src/tools/compiletest/src/directives.rs217
-rw-r--r--src/tools/compiletest/src/directives/auxiliary.rs35
-rw-r--r--src/tools/compiletest/src/directives/cfg.rs14
-rw-r--r--src/tools/compiletest/src/directives/needs.rs6
-rw-r--r--src/tools/compiletest/src/executor.rs35
-rw-r--r--src/tools/compiletest/src/lib.rs32
-rw-r--r--src/tools/compiletest/src/runtest/debugger.rs27
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs6
-rw-r--r--src/tools/miri/src/machine.rs2
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs2
-rw-r--r--tests/codegen-llvm/autodiff/abi_handling.rs4
-rw-r--r--tests/codegen-llvm/autodiff/batched.rs2
-rw-r--r--tests/codegen-llvm/autodiff/scalar.rs2
-rw-r--r--tests/codegen-llvm/autodiff/sret.rs2
-rw-r--r--tests/codegen-llvm/autodiff/void_ret.rs41
-rw-r--r--tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs9
-rw-r--r--tests/codegen-llvm/unwind-and-panic-abort.rs9
-rw-r--r--tests/codegen-llvm/wasm_exceptions.rs57
-rw-r--r--tests/crashes/125772.rs2
-rw-r--r--tests/crashes/129095.rs13
-rw-r--r--tests/crashes/131292.rs2
-rw-r--r--tests/crashes/134174.rs17
-rw-r--r--tests/crashes/134654.rs15
-rw-r--r--tests/crashes/135570.rs15
-rw-r--r--tests/crashes/136381.rs18
-rw-r--r--tests/crashes/137190-1.rs10
-rw-r--r--tests/crashes/137468.rs16
-rw-r--r--tests/crashes/34127.rs2
-rw-r--r--tests/run-make/split-debuginfo/rmake.rs150
-rw-r--r--tests/rustdoc-ui/issues/issue-91713.stdout4
-rw-r--r--tests/rustdoc/doc-auto-cfg-public-in-private.rs16
-rw-r--r--tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs4
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs1
-rw-r--r--tests/ui/associated-type-bounds/duplicate-bound-err.rs114
-rw-r--r--tests/ui/associated-type-bounds/duplicate-bound-err.stderr268
-rw-r--r--tests/ui/associated-type-bounds/duplicate-bound.rs240
-rw-r--r--tests/ui/associated-type-bounds/duplicate.rs278
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr751
-rw-r--r--tests/ui/associated-types/associated-types-overridden-binding-2.stderr2
-rw-r--r--tests/ui/associated-types/associated-types-overridden-binding.stderr2
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs14
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr63
-rw-r--r--tests/ui/attributes/empty-repr.stderr1
-rw-r--r--tests/ui/borrowck/fn-item-check-type-params.stderr12
-rw-r--r--tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr6
-rw-r--r--tests/ui/borrowck/issue-17545.stderr3
-rw-r--r--tests/ui/closures/impl-closure-147146.rs7
-rw-r--r--tests/ui/closures/impl-closure-147146.stderr15
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs21
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr19
-rw-r--r--tests/ui/const-generics/generic_arg_infer/in-signature.stderr36
-rw-r--r--tests/ui/coroutine/handle_opaques_before_coroutines.rs15
-rw-r--r--tests/ui/empty/empty-attributes.stderr4
-rw-r--r--tests/ui/error-codes/E0121.stderr11
-rw-r--r--tests/ui/error-codes/E0719.rs5
-rw-r--r--tests/ui/error-codes/E0719.stderr34
-rw-r--r--tests/ui/errors/auxiliary/remapped_dep.rs2
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.local-self.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr2
-rw-r--r--tests/ui/errors/remap-path-prefix-reverse.rs1
-rw-r--r--tests/ui/errors/remap-path-prefix.rs2
-rw-r--r--tests/ui/errors/span-format_args-issue-140578.rs32
-rw-r--r--tests/ui/errors/span-format_args-issue-140578.stderr43
-rw-r--r--tests/ui/fn/issue-80179.stderr21
-rw-r--r--tests/ui/fn/suggest-return-closure.stderr30
-rw-r--r--tests/ui/fn/suggest-return-future.stderr22
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr5
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.stderr54
-rw-r--r--tests/ui/implied-bounds/bevy_world_query.rs6
-rw-r--r--tests/ui/indexing/ambiguity-after-deref-step.rs9
-rw-r--r--tests/ui/indexing/ambiguity-after-deref-step.stderr17
-rw-r--r--tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr6
-rw-r--r--tests/ui/keyword/soup.rs30
-rw-r--r--tests/ui/macros/macro-use-all-and-none.stderr3
-rw-r--r--tests/ui/methods/overflow-if-subtyping.rs30
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr6
-rw-r--r--tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr6
-rw-r--r--tests/ui/nll/local-outlives-static-via-hrtb.stderr10
-rw-r--r--tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr5
-rw-r--r--tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr5
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed20
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs20
-rw-r--r--tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr36
-rw-r--r--tests/ui/proc-macro/expand-expr.rs2
-rw-r--r--tests/ui/proc-macro/pretty-print-hack-show.rs1
-rw-r--r--tests/ui/proc-macro/quote/not-quotable.stderr4
-rw-r--r--tests/ui/regions/multiple-sources-for-outlives-requirement.rs11
-rw-r--r--tests/ui/regions/multiple-sources-for-outlives-requirement.stderr20
-rw-r--r--tests/ui/regions/regions-infer-proc-static-upvar.stderr6
-rw-r--r--tests/ui/regions/regions-pattern-typing-issue-19552.stderr6
-rw-r--r--tests/ui/repr/repr-empty-packed.stderr1
-rw-r--r--tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr44
-rw-r--r--tests/ui/static/static-lifetime-bound.stderr6
-rw-r--r--tests/ui/static/static-region-bound.stderr6
-rw-r--r--tests/ui/suggestions/auxiliary/hidden-struct.rs26
-rw-r--r--tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs18
-rw-r--r--tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr44
-rw-r--r--tests/ui/suggestions/return-cycle-2.stderr11
-rw-r--r--tests/ui/suggestions/return-cycle.stderr11
-rw-r--r--tests/ui/suggestions/suggest-fn-ptr-for-fn-item-in-fn-ret.stderr11
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.rs1
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr4
-rw-r--r--tests/ui/test-attrs/test-panic-abort.rs1
-rw-r--r--tests/ui/test-attrs/test-panic-abort.run.stdout2
-rw-r--r--tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs60
-rw-r--r--tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs25
-rw-r--r--tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs7
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.stderr11
-rw-r--r--tests/ui/type/pattern_types/const_generics.rs3
-rw-r--r--tests/ui/type/pattern_types/transmute.current.stderr (renamed from tests/ui/type/pattern_types/transmute.stderr)4
-rw-r--r--tests/ui/type/pattern_types/transmute.next.stderr21
-rw-r--r--tests/ui/type/pattern_types/transmute.rs3
-rw-r--r--tests/ui/typeck/issue-80779.stderr22
-rw-r--r--tests/ui/typeck/issue-98260.stderr11
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr141
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item_help.stderr11
-rw-r--r--tests/ui/variance/leaking-unnameables.stderr11
-rw-r--r--tests/ui/wf/wf-in-where-clause-static.current.stderr6
-rw-r--r--tests/ui/wf/wf-in-where-clause-static.next.stderr6
-rw-r--r--triagebot.toml1
320 files changed, 3991 insertions, 2794 deletions
diff --git a/bootstrap.example.toml b/bootstrap.example.toml
index 0a39c6d8f24..f623a3db002 100644
--- a/bootstrap.example.toml
+++ b/bootstrap.example.toml
@@ -476,9 +476,6 @@
 # when the stage 0 compiler is actually built from in-tree sources.
 #build.compiletest-allow-stage0 = false
 
-# Whether to use the precompiled stage0 libtest with compiletest.
-#build.compiletest-use-stage0-libtest = true
-
 # Default value for the `--extra-checks` flag of tidy.
 #
 # See `./x test tidy --help` for details.
diff --git a/compiler/rustc_abi/src/callconv/reg.rs b/compiler/rustc_abi/src/callconv/reg.rs
index 8cf140dbaad..66c8056d0c2 100644
--- a/compiler/rustc_abi/src/callconv/reg.rs
+++ b/compiler/rustc_abi/src/callconv/reg.rs
@@ -42,22 +42,22 @@ impl Reg {
         let dl = cx.data_layout();
         match self.kind {
             RegKind::Integer => match self.size.bits() {
-                1 => dl.i1_align.abi,
-                2..=8 => dl.i8_align.abi,
-                9..=16 => dl.i16_align.abi,
-                17..=32 => dl.i32_align.abi,
-                33..=64 => dl.i64_align.abi,
-                65..=128 => dl.i128_align.abi,
+                1 => dl.i1_align,
+                2..=8 => dl.i8_align,
+                9..=16 => dl.i16_align,
+                17..=32 => dl.i32_align,
+                33..=64 => dl.i64_align,
+                65..=128 => dl.i128_align,
                 _ => panic!("unsupported integer: {self:?}"),
             },
             RegKind::Float => match self.size.bits() {
-                16 => dl.f16_align.abi,
-                32 => dl.f32_align.abi,
-                64 => dl.f64_align.abi,
-                128 => dl.f128_align.abi,
+                16 => dl.f16_align,
+                32 => dl.f32_align,
+                64 => dl.f64_align,
+                128 => dl.f128_align,
                 _ => panic!("unsupported float: {self:?}"),
             },
-            RegKind::Vector => dl.llvmlike_vector_align(self.size).abi,
+            RegKind::Vector => dl.llvmlike_vector_align(self.size),
         }
     }
 }
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 5004d0c8022..14356813b7b 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -174,11 +174,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             // Non-power-of-two vectors have padding up to the next power-of-two.
             // If we're a packed repr, remove the padding while keeping the alignment as close
             // to a vector as possible.
-            (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) })
+            (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size))
         } else {
             (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size))
         };
-        let size = size.align_to(align.abi);
+        let size = size.align_to(align);
 
         Ok(LayoutData {
             variants: Variants::Single { index: VariantIdx::new(0) },
@@ -190,7 +190,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             largest_niche: elt.largest_niche,
             uninhabited: false,
             size,
-            align,
+            align: AbiAlign::new(align),
             max_repr_align: None,
             unadjusted_abi_align: elt.align.abi,
             randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)),
@@ -388,7 +388,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 return Err(LayoutCalculatorError::UnexpectedUnsized(*field));
             }
 
-            align = align.max(field.align);
+            align = align.max(field.align.abi);
             max_repr_align = max_repr_align.max(field.max_repr_align);
             size = cmp::max(size, field.size);
 
@@ -423,13 +423,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         }
 
         if let Some(pack) = repr.pack {
-            align = align.min(AbiAlign::new(pack));
+            align = align.min(pack);
         }
         // The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
         // See documentation on `LayoutData::unadjusted_abi_align`.
-        let unadjusted_abi_align = align.abi;
+        let unadjusted_abi_align = align;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAlign::new(repr_align));
+            align = align.max(repr_align);
         }
         // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
@@ -441,14 +441,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             Ok(Some((repr, _))) => match repr {
                 // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt
                 BackendRepr::Scalar(_) | BackendRepr::ScalarPair(_, _)
-                    if repr.scalar_align(dl).unwrap() != align.abi =>
+                    if repr.scalar_align(dl).unwrap() != align =>
                 {
                     BackendRepr::Memory { sized: true }
                 }
                 // Vectors require at least element alignment, else disable the opt
-                BackendRepr::SimdVector { element, count: _ }
-                    if element.align(dl).abi > align.abi =>
-                {
+                BackendRepr::SimdVector { element, count: _ } if element.align(dl).abi > align => {
                     BackendRepr::Memory { sized: true }
                 }
                 // the alignment tests passed and we can use this
@@ -474,8 +472,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             backend_repr,
             largest_niche: None,
             uninhabited: false,
-            align,
-            size: size.align_to(align.abi),
+            align: AbiAlign::new(align),
+            size: size.align_to(align),
             max_repr_align,
             unadjusted_abi_align,
             randomization_seed: combined_seed,
@@ -611,7 +609,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
 
             let mut align = dl.aggregate_align;
             let mut max_repr_align = repr.align;
-            let mut unadjusted_abi_align = align.abi;
+            let mut unadjusted_abi_align = align;
 
             let mut variant_layouts = variants
                 .iter_enumerated()
@@ -619,7 +617,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?;
                     st.variants = Variants::Single { index: j };
 
-                    align = align.max(st.align);
+                    align = align.max(st.align.abi);
                     max_repr_align = max_repr_align.max(st.max_repr_align);
                     unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
 
@@ -646,7 +644,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             let (niche_start, niche_scalar) = niche.reserve(dl, count)?;
             let niche_offset = niche.offset;
             let niche_size = niche.value.size(dl);
-            let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
+            let size = variant_layouts[largest_variant_index].size.align_to(align);
 
             let all_variants_fit = variant_layouts.iter_enumerated_mut().all(|(i, layout)| {
                 if i == largest_variant_index {
@@ -699,7 +697,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 .iter_enumerated()
                 .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO);
             let same_size = size == variant_layouts[largest_variant_index].size;
-            let same_align = align == variant_layouts[largest_variant_index].align;
+            let same_align = align == variant_layouts[largest_variant_index].align.abi;
 
             let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited());
             let abi = if same_size && same_align && others_zst {
@@ -746,7 +744,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 largest_niche,
                 uninhabited,
                 size,
-                align,
+                align: AbiAlign::new(align),
                 max_repr_align,
                 unadjusted_abi_align,
                 randomization_seed: combined_seed,
@@ -818,7 +816,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
 
         let mut align = dl.aggregate_align;
         let mut max_repr_align = repr.align;
-        let mut unadjusted_abi_align = align.abi;
+        let mut unadjusted_abi_align = align;
 
         let mut size = Size::ZERO;
 
@@ -860,7 +858,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     }
                 }
                 size = cmp::max(size, st.size);
-                align = align.max(st.align);
+                align = align.max(st.align.abi);
                 max_repr_align = max_repr_align.max(st.max_repr_align);
                 unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
                 Ok(st)
@@ -868,7 +866,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
 
         // Align the maximum variant size to the largest alignment.
-        size = size.align_to(align.abi);
+        size = size.align_to(align);
 
         // FIXME(oli-obk): deduplicate and harden these checks
         if size.bytes() >= dl.obj_size_bound() {
@@ -1042,7 +1040,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 };
                 if pair_offsets[FieldIdx::new(0)] == Size::ZERO
                     && pair_offsets[FieldIdx::new(1)] == *offset
-                    && align == pair.align
+                    && align == pair.align.abi
                     && size == pair.size
                 {
                     // We can use `ScalarPair` only when it matches our
@@ -1066,7 +1064,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     // Also need to bump up the size and alignment, so that the entire value fits
                     // in here.
                     variant.size = cmp::max(variant.size, size);
-                    variant.align.abi = cmp::max(variant.align.abi, align.abi);
+                    variant.align.abi = cmp::max(variant.align.abi, align);
                 }
             }
         }
@@ -1092,7 +1090,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             largest_niche,
             uninhabited,
             backend_repr: abi,
-            align,
+            align: AbiAlign::new(align),
             size,
             max_repr_align,
             unadjusted_abi_align,
@@ -1169,7 +1167,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 // To allow unsizing `&Foo<Type>` -> `&Foo<dyn Trait>`, the layout of the struct must
                 // not depend on the layout of the tail.
                 let max_field_align =
-                    fields_excluding_tail.iter().map(|f| f.align.abi.bytes()).max().unwrap_or(1);
+                    fields_excluding_tail.iter().map(|f| f.align.bytes()).max().unwrap_or(1);
                 let largest_niche_size = fields_excluding_tail
                     .iter()
                     .filter_map(|f| f.largest_niche)
@@ -1189,7 +1187,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     } else {
                         // Returns `log2(effective-align)`. The calculation assumes that size is an
                         // integer multiple of align, except for ZSTs.
-                        let align = layout.align.abi.bytes();
+                        let align = layout.align.bytes();
                         let size = layout.size.bytes();
                         let niche_size = layout.largest_niche.map(|n| n.available(dl)).unwrap_or(0);
                         // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields.
@@ -1288,7 +1286,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
             let prefix_align =
                 if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
-            align = align.max(AbiAlign::new(prefix_align));
+            align = align.max(prefix_align);
             offset = prefix_size.align_to(prefix_align);
         }
         for &i in &inverse_memory_index {
@@ -1312,7 +1310,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 field.align
             };
             offset = offset.align_to(field_align.abi);
-            align = align.max(field_align);
+            align = align.max(field_align.abi);
             max_repr_align = max_repr_align.max(field.max_repr_align);
 
             debug!("univariant offset: {:?} field: {:#?}", offset, field);
@@ -1339,9 +1337,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
 
         // The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
         // See documentation on `LayoutData::unadjusted_abi_align`.
-        let unadjusted_abi_align = align.abi;
+        let unadjusted_abi_align = align;
         if let Some(repr_align) = repr.align {
-            align = align.max(AbiAlign::new(repr_align));
+            align = align.max(repr_align);
         }
         // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate.
         let align = align;
@@ -1360,7 +1358,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices()));
             inverse_memory_index.into_iter().map(|it| it.index() as u32).collect()
         };
-        let size = min_size.align_to(align.abi);
+        let size = min_size.align_to(align);
         // FIXME(oli-obk): deduplicate and harden these checks
         if size.bytes() >= dl.obj_size_bound() {
             return Err(LayoutCalculatorError::SizeOverflow);
@@ -1383,8 +1381,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     layout_of_single_non_zst_field = Some(field);
 
                     // Field fills the struct and it has a scalar or scalar pair ABI.
-                    if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size
-                    {
+                    if offsets[i].bytes() == 0 && align == field.align.abi && size == field.size {
                         match field.backend_repr {
                             // For plain scalars, or vectors of them, we can't unpack
                             // newtypes for `#[repr(C)]`, as that affects C ABIs.
@@ -1428,7 +1425,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                             };
                             if offsets[i] == pair_offsets[FieldIdx::new(0)]
                                 && offsets[j] == pair_offsets[FieldIdx::new(1)]
-                                && align == pair.align
+                                && align == pair.align.abi
                                 && size == pair.size
                             {
                                 // We can use `ScalarPair` only when it matches our
@@ -1450,7 +1447,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                 Some(l) => l.unadjusted_abi_align,
                 None => {
                     // `repr(transparent)` with all ZST fields.
-                    align.abi
+                    align
                 }
             }
         } else {
@@ -1465,7 +1462,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             backend_repr: abi,
             largest_niche,
             uninhabited,
-            align,
+            align: AbiAlign::new(align),
             size,
             max_repr_align,
             unadjusted_abi_align,
@@ -1488,7 +1485,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         for i in layout.fields.index_by_increasing_offset() {
             let offset = layout.fields.offset(i);
             let f = &fields[FieldIdx::new(i)];
-            write!(s, "[o{}a{}s{}", offset.bytes(), f.align.abi.bytes(), f.size.bytes()).unwrap();
+            write!(s, "[o{}a{}s{}", offset.bytes(), f.align.bytes(), f.size.bytes()).unwrap();
             if let Some(n) = f.largest_niche {
                 write!(
                     s,
diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs
index 0d0706defc2..b3807c87273 100644
--- a/compiler/rustc_abi/src/layout/simple.rs
+++ b/compiler/rustc_abi/src/layout/simple.rs
@@ -4,7 +4,8 @@ use rustc_hashes::Hash64;
 use rustc_index::{Idx, IndexVec};
 
 use crate::{
-    BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size, Variants,
+    AbiAlign, BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size,
+    Variants,
 };
 
 /// "Simple" layout constructors that cannot fail.
@@ -20,10 +21,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             backend_repr: BackendRepr::Memory { sized },
             largest_niche: None,
             uninhabited: false,
-            align: dl.i8_align,
+            align: AbiAlign::new(dl.i8_align),
             size: Size::ZERO,
             max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
+            unadjusted_abi_align: dl.i8_align,
             randomization_seed: Hash64::new(0),
         }
     }
@@ -37,10 +38,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             backend_repr: BackendRepr::Memory { sized: true },
             largest_niche: None,
             uninhabited: true,
-            align: dl.i8_align,
+            align: AbiAlign::new(dl.i8_align),
             size: Size::ZERO,
             max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
+            unadjusted_abi_align: dl.i8_align,
             randomization_seed: Hash64::ZERO,
         }
     }
@@ -89,10 +90,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
 
     pub fn scalar_pair<C: HasDataLayout>(cx: &C, a: Scalar, b: Scalar) -> Self {
         let dl = cx.data_layout();
-        let b_align = b.align(dl);
-        let align = a.align(dl).max(b_align).max(dl.aggregate_align);
-        let b_offset = a.size(dl).align_to(b_align.abi);
-        let size = (b_offset + b.size(dl)).align_to(align.abi);
+        let b_align = b.align(dl).abi;
+        let align = a.align(dl).abi.max(b_align).max(dl.aggregate_align);
+        let b_offset = a.size(dl).align_to(b_align);
+        let size = (b_offset + b.size(dl)).align_to(align);
 
         // HACK(nox): We iter on `b` and then `a` because `max_by_key`
         // returns the last maximum.
@@ -112,10 +113,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             backend_repr: BackendRepr::ScalarPair(a, b),
             largest_niche,
             uninhabited: false,
-            align,
+            align: AbiAlign::new(align),
             size,
             max_repr_align: None,
-            unadjusted_abi_align: align.abi,
+            unadjusted_abi_align: align,
             randomization_seed: Hash64::new(combined_seed),
         }
     }
@@ -138,10 +139,10 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
             backend_repr: BackendRepr::Memory { sized: true },
             largest_niche: None,
             uninhabited: true,
-            align: dl.i8_align,
+            align: AbiAlign::new(dl.i8_align),
             size: Size::ZERO,
             max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
+            unadjusted_abi_align: dl.i8_align,
             randomization_seed: Hash64::ZERO,
         }
     }
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 369874521e5..de44c8755a0 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -229,7 +229,7 @@ pub struct PointerSpec {
     /// The size of the bitwise representation of the pointer.
     pointer_size: Size,
     /// The alignment of pointers for this address space
-    pointer_align: AbiAlign,
+    pointer_align: Align,
     /// The size of the value a pointer can be offset by in this address space.
     pointer_offset: Size,
     /// Pointers into this address space contain extra metadata
@@ -242,20 +242,20 @@ pub struct PointerSpec {
 #[derive(Debug, PartialEq, Eq)]
 pub struct TargetDataLayout {
     pub endian: Endian,
-    pub i1_align: AbiAlign,
-    pub i8_align: AbiAlign,
-    pub i16_align: AbiAlign,
-    pub i32_align: AbiAlign,
-    pub i64_align: AbiAlign,
-    pub i128_align: AbiAlign,
-    pub f16_align: AbiAlign,
-    pub f32_align: AbiAlign,
-    pub f64_align: AbiAlign,
-    pub f128_align: AbiAlign,
-    pub aggregate_align: AbiAlign,
+    pub i1_align: Align,
+    pub i8_align: Align,
+    pub i16_align: Align,
+    pub i32_align: Align,
+    pub i64_align: Align,
+    pub i128_align: Align,
+    pub f16_align: Align,
+    pub f32_align: Align,
+    pub f64_align: Align,
+    pub f128_align: Align,
+    pub aggregate_align: Align,
 
     /// Alignments for vector types.
-    pub vector_align: Vec<(Size, AbiAlign)>,
+    pub vector_align: Vec<(Size, Align)>,
 
     pub default_address_space: AddressSpace,
     pub default_address_space_pointer_spec: PointerSpec,
@@ -282,25 +282,25 @@ impl Default for TargetDataLayout {
         let align = |bits| Align::from_bits(bits).unwrap();
         TargetDataLayout {
             endian: Endian::Big,
-            i1_align: AbiAlign::new(align(8)),
-            i8_align: AbiAlign::new(align(8)),
-            i16_align: AbiAlign::new(align(16)),
-            i32_align: AbiAlign::new(align(32)),
-            i64_align: AbiAlign::new(align(32)),
-            i128_align: AbiAlign::new(align(32)),
-            f16_align: AbiAlign::new(align(16)),
-            f32_align: AbiAlign::new(align(32)),
-            f64_align: AbiAlign::new(align(64)),
-            f128_align: AbiAlign::new(align(128)),
-            aggregate_align: AbiAlign { abi: align(8) },
+            i1_align: align(8),
+            i8_align: align(8),
+            i16_align: align(16),
+            i32_align: align(32),
+            i64_align: align(32),
+            i128_align: align(32),
+            f16_align: align(16),
+            f32_align: align(32),
+            f64_align: align(64),
+            f128_align: align(128),
+            aggregate_align: align(8),
             vector_align: vec![
-                (Size::from_bits(64), AbiAlign::new(align(64))),
-                (Size::from_bits(128), AbiAlign::new(align(128))),
+                (Size::from_bits(64), align(64)),
+                (Size::from_bits(128), align(128)),
             ],
             default_address_space: AddressSpace::ZERO,
             default_address_space_pointer_spec: PointerSpec {
                 pointer_size: Size::from_bits(64),
-                pointer_align: AbiAlign::new(align(64)),
+                pointer_align: align(64),
                 pointer_offset: Size::from_bits(64),
                 _is_fat: false,
             },
@@ -360,7 +360,7 @@ impl TargetDataLayout {
                     .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
             };
             let abi = parse_bits(s, "alignment", cause)?;
-            Ok(AbiAlign::new(align_from_bits(abi)?))
+            Ok(align_from_bits(abi)?)
         };
 
         // Parse an alignment sequence, possibly in the form `<align>[:<preferred_alignment>]`,
@@ -596,7 +596,7 @@ impl TargetDataLayout {
 
     /// psABI-mandated alignment for a vector type, if any
     #[inline]
-    fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAlign> {
+    fn cabi_vector_align(&self, vec_size: Size) -> Option<Align> {
         self.vector_align
             .iter()
             .find(|(size, _align)| *size == vec_size)
@@ -605,10 +605,9 @@ impl TargetDataLayout {
 
     /// an alignment resembling the one LLVM would pick for a vector
     #[inline]
-    pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign {
-        self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new(
-            Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(),
-        ))
+    pub fn llvmlike_vector_align(&self, vec_size: Size) -> Align {
+        self.cabi_vector_align(vec_size)
+            .unwrap_or(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap())
     }
 
     /// Get the pointer size in the default data address space.
@@ -654,21 +653,19 @@ impl TargetDataLayout {
     /// Get the pointer alignment in the default data address space.
     #[inline]
     pub fn pointer_align(&self) -> AbiAlign {
-        self.default_address_space_pointer_spec.pointer_align
+        AbiAlign::new(self.default_address_space_pointer_spec.pointer_align)
     }
 
     /// Get the pointer alignment in a specific address space.
     #[inline]
     pub fn pointer_align_in(&self, c: AddressSpace) -> AbiAlign {
-        if c == self.default_address_space {
-            return self.default_address_space_pointer_spec.pointer_align;
-        }
-
-        if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
+        AbiAlign::new(if c == self.default_address_space {
+            self.default_address_space_pointer_spec.pointer_align
+        } else if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
             e.1.pointer_align
         } else {
             panic!("Use of unknown address space {c:?}");
-        }
+        })
     }
 }
 
@@ -1185,13 +1182,13 @@ impl Integer {
         use Integer::*;
         let dl = cx.data_layout();
 
-        match self {
+        AbiAlign::new(match self {
             I8 => dl.i8_align,
             I16 => dl.i16_align,
             I32 => dl.i32_align,
             I64 => dl.i64_align,
             I128 => dl.i128_align,
-        }
+        })
     }
 
     /// Returns the largest signed value that can be represented by this Integer.
@@ -1311,12 +1308,12 @@ impl Float {
         use Float::*;
         let dl = cx.data_layout();
 
-        match self {
+        AbiAlign::new(match self {
             F16 => dl.f16_align,
             F32 => dl.f32_align,
             F64 => dl.f64_align,
             F128 => dl.f128_align,
-        }
+        })
     }
 }
 
@@ -2159,7 +2156,7 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
 
     /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
     pub fn is_1zst(&self) -> bool {
-        self.is_sized() && self.size.bytes() == 0 && self.align.abi.bytes() == 1
+        self.is_sized() && self.size.bytes() == 0 && self.align.bytes() == 1
     }
 
     /// Returns `true` if the type is a ZST and not unsized.
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 3e8fddd9954..082d5e88ac7 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -114,8 +114,7 @@ impl PartialEq<Symbol> for Path {
 impl PartialEq<&[Symbol]> for Path {
     #[inline]
     fn eq(&self, names: &&[Symbol]) -> bool {
-        self.segments.len() == names.len()
-            && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2)
+        self.segments.iter().eq(*names)
     }
 }
 
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index f1951049b47..5fe218776e5 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -15,6 +15,7 @@
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
+#![feature(iter_order_by)]
 #![feature(macro_metavar_expr)]
 #![feature(rustdoc_internals)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index a5d8fbfac61..4111182c3b7 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -48,9 +48,7 @@ impl TokenTree {
         match (self, other) {
             (TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
             (TokenTree::Delimited(.., delim, tts), TokenTree::Delimited(.., delim2, tts2)) => {
-                delim == delim2
-                    && tts.len() == tts2.len()
-                    && tts.iter().zip(tts2.iter()).all(|(a, b)| a.eq_unspanned(b))
+                delim == delim2 && tts.iter().eq_by(tts2.iter(), |a, b| a.eq_unspanned(b))
             }
             _ => false,
         }
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index 81ec17077c1..6c5346e8355 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -8,7 +8,15 @@ attr_parsing_deprecated_item_suggestion =
 
 attr_parsing_empty_attribute =
     unused attribute
-    .suggestion = remove this attribute
+    .suggestion = {$valid_without_list ->
+        [true] remove these parentheses
+        *[other] remove this attribute
+    }
+    .note = {$valid_without_list ->
+        [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all
+        *[other] using `{$attr_path}` with an empty list has no effect
+    }
+
 
 attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
     .help = `#[{$name}]` can {$only}be applied to {$applied}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index d7ccf3c7806..e8bb4caa416 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -597,7 +597,12 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
     }
 
     pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
-        self.emit_lint(AttributeLintKind::EmptyAttribute { first_span: span }, span);
+        let attr_path = self.attr_path.clone();
+        let valid_without_list = self.template.word;
+        self.emit_lint(
+            AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
+            span,
+        );
     }
 }
 
diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs
index ab8ba0daf1f..3a2a3704669 100644
--- a/compiler/rustc_attr_parsing/src/lints.rs
+++ b/compiler/rustc_attr_parsing/src/lints.rs
@@ -43,12 +43,18 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi
                     ),
                 },
             ),
-        AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint(
-            rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
-            *id,
-            *first_span,
-            session_diagnostics::EmptyAttributeList { attr_span: *first_span },
-        ),
+        AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
+            lint_emitter.emit_node_span_lint(
+                rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
+                *id,
+                *first_span,
+                session_diagnostics::EmptyAttributeList {
+                    attr_span: *first_span,
+                    attr_path: attr_path.clone(),
+                    valid_without_list: *valid_without_list,
+                },
+            )
+        }
         AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter
             .emit_node_span_lint(
                 // This check is here because `deprecated` had its own lint group and removing this would be a breaking change
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 4f903594225..3f4f5679015 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -49,7 +49,7 @@ impl<'a> PathParser<'a> {
     }
 
     pub fn segments_is(&self, segments: &[Symbol]) -> bool {
-        self.len() == segments.len() && self.segments().zip(segments).all(|(a, b)| a.name == *b)
+        self.segments().map(|segment| &segment.name).eq(segments)
     }
 
     pub fn word(&self) -> Option<Ident> {
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index 2c2b14c8a68..1194ac5872c 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -503,9 +503,12 @@ pub(crate) struct EmptyConfusables {
 
 #[derive(LintDiagnostic)]
 #[diag(attr_parsing_empty_attribute)]
+#[note]
 pub(crate) struct EmptyAttributeList {
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub attr_span: Span,
+    pub attr_path: AttrPath,
+    pub valid_without_list: bool,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index c9be5575da5..7c9011505d6 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -426,7 +426,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     }
 
     pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> {
-        struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,)
+        struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path)
     }
 
     pub(crate) fn cannot_return_reference_to_local(
@@ -480,7 +480,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     }
 
     pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> {
-        struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",)
+        struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed")
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7e20a5133e0..efb622e2155 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2992,6 +2992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         self.buffer_error(err);
     }
 
+    #[tracing::instrument(level = "debug", skip(self, explanation))]
     fn report_local_value_does_not_live_long_enough(
         &self,
         location: Location,
@@ -3001,13 +3002,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         borrow_spans: UseSpans<'tcx>,
         explanation: BorrowExplanation<'tcx>,
     ) -> Diag<'infcx> {
-        debug!(
-            "report_local_value_does_not_live_long_enough(\
-             {:?}, {:?}, {:?}, {:?}, {:?}\
-             )",
-            location, name, borrow, drop_span, borrow_spans
-        );
-
         let borrow_span = borrow_spans.var_or_use_path_span();
         if let BorrowExplanation::MustBeValidFor {
             category,
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 7ca07bb9b43..638d89f5bcb 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -416,6 +416,26 @@ impl<'tcx> BorrowExplanation<'tcx> {
                 {
                     self.add_object_lifetime_default_note(tcx, err, unsize_ty);
                 }
+
+                let mut preds = path
+                    .iter()
+                    .filter_map(|constraint| match constraint.category {
+                        ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred),
+                        _ => None,
+                    })
+                    .collect::<Vec<Span>>();
+                preds.sort();
+                preds.dedup();
+                if !preds.is_empty() {
+                    let s = if preds.len() == 1 { "" } else { "s" };
+                    err.span_note(
+                        preds,
+                        format!(
+                            "requirement{s} that the value outlives `{region_name}` introduced here"
+                        ),
+                    );
+                }
+
                 self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
             }
             _ => {}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 4c380ddcf70..268cb47fd12 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) {
 fn mir_borrowck(
     tcx: TyCtxt<'_>,
     def: LocalDefId,
-) -> Result<&ConcreteOpaqueTypes<'_>, ErrorGuaranteed> {
+) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> {
     assert!(!tcx.is_typeck_child(def.to_def_id()));
     let (input_body, _) = tcx.mir_promoted(def);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
@@ -130,7 +130,7 @@ fn mir_borrowck(
         Err(guar)
     } else if input_body.should_skip() {
         debug!("Skipping borrowck because of injected body");
-        let opaque_types = ConcreteOpaqueTypes(Default::default());
+        let opaque_types = DefinitionSiteHiddenTypes(Default::default());
         Ok(tcx.arena.alloc(opaque_types))
     } else {
         let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 0910e8ef4b3..e98c60e6338 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1382,10 +1382,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// The constraints we get from equating the hidden type of each use of an opaque
-    /// with its final concrete type may end up getting preferred over other, potentially
+    /// with its final hidden type may end up getting preferred over other, potentially
     /// longer constraint paths.
     ///
-    /// Given that we compute the final concrete type by relying on this existing constraint
+    /// Given that we compute the final hidden type by relying on this existing constraint
     /// path, this can easily end up hiding the actual reason for why we require these regions
     /// to be equal.
     ///
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
index 0af636aa734..8d89f3e0d87 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
@@ -8,7 +8,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries};
 use rustc_infer::traits::ObligationCause;
 use rustc_macros::extension;
-use rustc_middle::mir::{Body, ConcreteOpaqueTypes, ConstraintCategory};
+use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes};
 use rustc_middle::ty::{
     self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef,
     OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable,
@@ -129,9 +129,9 @@ fn nll_var_to_universal_region<'tcx>(
 /// Collect all defining uses of opaque types inside of this typeck root. This
 /// expects the hidden type to be mapped to the definition parameters of the opaque
 /// and errors if we end up with distinct hidden types.
-fn add_concrete_opaque_type<'tcx>(
+fn add_hidden_type<'tcx>(
     tcx: TyCtxt<'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     def_id: LocalDefId,
     hidden_ty: OpaqueHiddenType<'tcx>,
 ) {
@@ -139,7 +139,7 @@ fn add_concrete_opaque_type<'tcx>(
     // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
     // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
     // only know that once we convert the generic parameters to those of the opaque type.
-    if let Some(prev) = concrete_opaque_types.0.get_mut(&def_id) {
+    if let Some(prev) = hidden_types.0.get_mut(&def_id) {
         if prev.ty != hidden_ty.ty {
             let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| {
                 let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
@@ -151,15 +151,15 @@ fn add_concrete_opaque_type<'tcx>(
         // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
         prev.span = prev.span.substitute_dummy(hidden_ty.span);
     } else {
-        concrete_opaque_types.0.insert(def_id, hidden_ty);
+        hidden_types.0.insert(def_id, hidden_ty);
     }
 }
 
-fn get_concrete_opaque_type<'tcx>(
-    concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
+fn get_hidden_type<'tcx>(
+    hidden_types: &DefinitionSiteHiddenTypes<'tcx>,
     def_id: LocalDefId,
 ) -> Option<EarlyBinder<'tcx, OpaqueHiddenType<'tcx>>> {
-    concrete_opaque_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
+    hidden_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
 }
 
 #[derive(Debug)]
@@ -173,22 +173,22 @@ struct DefiningUse<'tcx> {
 }
 
 /// This computes the actual hidden types of the opaque types and maps them to their
-/// definition sites. Outside of registering the computed concrete types this function
+/// definition sites. Outside of registering the computed hidden types this function
 /// does not mutate the current borrowck state.
 ///
 /// While it may fail to infer the hidden type and return errors, we always apply
-/// the computed concrete hidden type to all opaque type uses to check whether they
+/// the computed hidden type to all opaque type uses to check whether they
 /// are correct. This is necessary to support non-defining uses of opaques in their
 /// defining scope.
 ///
 /// It also means that this whole function is not really soundness critical as we
 /// recheck all uses of the opaques regardless.
-pub(crate) fn compute_concrete_opaque_types<'tcx>(
+pub(crate) fn compute_definition_site_hidden_types<'tcx>(
     infcx: &BorrowckInferCtxt<'tcx>,
     universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
     constraints: &MirTypeckRegionConstraints<'tcx>,
     location_map: Rc<DenseLocationMap>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
 ) -> Vec<DeferredOpaqueTypeError<'tcx>> {
     let mut errors = Vec::new();
@@ -201,8 +201,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
     // We start by checking each use of an opaque type during type check and
     // check whether the generic arguments of the opaque type are fully
     // universal, if so, it's a defining use.
-    let defining_uses =
-        collect_defining_uses(&mut rcx, concrete_opaque_types, opaque_types, &mut errors);
+    let defining_uses = collect_defining_uses(&mut rcx, hidden_types, opaque_types, &mut errors);
 
     // We now compute and apply member constraints for all regions in the hidden
     // types of each defining use. This mutates the region values of the `rcx` which
@@ -210,11 +209,11 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
     apply_member_constraints(&mut rcx, &defining_uses);
 
     // After applying member constraints, we now check whether all member regions ended
-    // up equal to one of their choice regions and compute the actual concrete type of
+    // up equal to one of their choice regions and compute the actual hidden type of
     // the opaque type definition. This is stored in the `root_cx`.
-    compute_concrete_types_from_defining_uses(
+    compute_definition_site_hidden_types_from_defining_uses(
         &rcx,
-        concrete_opaque_types,
+        hidden_types,
         &defining_uses,
         &mut errors,
     );
@@ -224,7 +223,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
 #[instrument(level = "debug", skip_all, ret)]
 fn collect_defining_uses<'tcx>(
     rcx: &mut RegionCtxt<'_, 'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
 ) -> Vec<DefiningUse<'tcx>> {
@@ -244,9 +243,9 @@ fn collect_defining_uses<'tcx>(
             // with `TypingMode::Borrowck`.
             if infcx.tcx.use_typing_mode_borrowck() {
                 match err {
-                    NonDefiningUseReason::Tainted(guar) => add_concrete_opaque_type(
+                    NonDefiningUseReason::Tainted(guar) => add_hidden_type(
                         infcx.tcx,
-                        concrete_opaque_types,
+                        hidden_types,
                         opaque_type_key.def_id,
                         OpaqueHiddenType::new_error(infcx.tcx, guar),
                     ),
@@ -277,9 +276,9 @@ fn collect_defining_uses<'tcx>(
     defining_uses
 }
 
-fn compute_concrete_types_from_defining_uses<'tcx>(
+fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
     rcx: &RegionCtxt<'_, 'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     defining_uses: &[DefiningUse<'tcx>],
     errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
 ) {
@@ -358,9 +357,9 @@ fn compute_concrete_types_from_defining_uses<'tcx>(
                 },
             ));
         }
-        add_concrete_opaque_type(
+        add_hidden_type(
             tcx,
-            concrete_opaque_types,
+            hidden_types,
             opaque_type_key.def_id,
             OpaqueHiddenType { span: hidden_type.span, ty },
         );
@@ -489,20 +488,20 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
 ///
 /// It does this by equating the hidden type of each use with the instantiated final
 /// hidden type of the opaque.
-pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
+pub(crate) fn apply_definition_site_hidden_types<'tcx>(
     infcx: &BorrowckInferCtxt<'tcx>,
     body: &Body<'tcx>,
     universal_regions: &UniversalRegions<'tcx>,
     region_bound_pairs: &RegionBoundPairs<'tcx>,
     known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
     constraints: &mut MirTypeckRegionConstraints<'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
 ) -> Vec<DeferredOpaqueTypeError<'tcx>> {
     let tcx = infcx.tcx;
     let mut errors = Vec::new();
     for &(key, hidden_type) in opaque_types {
-        let Some(expected) = get_concrete_opaque_type(concrete_opaque_types, key.def_id) else {
+        let Some(expected) = get_hidden_type(hidden_types, key.def_id) else {
             if !tcx.use_typing_mode_borrowck() {
                 if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
                     && alias_ty.def_id == key.def_id.to_def_id()
@@ -521,12 +520,7 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
                 hidden_type.span,
                 "non-defining use in the defining scope with no defining uses",
             );
-            add_concrete_opaque_type(
-                tcx,
-                concrete_opaque_types,
-                key.def_id,
-                OpaqueHiddenType::new_error(tcx, guar),
-            );
+            add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
             continue;
         };
 
@@ -566,18 +560,13 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
                 "equating opaque types",
             ),
         ) {
-            add_concrete_opaque_type(
-                tcx,
-                concrete_opaque_types,
-                key.def_id,
-                OpaqueHiddenType::new_error(tcx, guar),
-            );
+            add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
         }
     }
     errors
 }
 
-/// In theory `apply_concrete_opaque_types` could introduce new uses of opaque types.
+/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types.
 /// We do not check these new uses so this could be unsound.
 ///
 /// We detect any new uses and simply delay a bug if they occur. If this results in
@@ -682,13 +671,6 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// (*) C1 and C2 were introduced in the comments on
     /// `register_member_constraints`. Read that comment for more context.
-    ///
-    /// # Parameters
-    ///
-    /// - `def_id`, the `impl Trait` type
-    /// - `args`, the args used to instantiate this opaque type
-    /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
-    ///   `opaque_defn.concrete_ty`
     #[instrument(level = "debug", skip(self))]
     fn infer_opaque_definition_from_instantiation(
         &self,
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index cd4e9683f2d..21c11e12873 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -12,12 +12,12 @@ use smallvec::SmallVec;
 use crate::consumers::BorrowckConsumer;
 use crate::nll::compute_closure_requirements_modulo_opaques;
 use crate::region_infer::opaque_types::{
-    apply_computed_concrete_opaque_types, clone_and_resolve_opaque_types,
-    compute_concrete_opaque_types, detect_opaque_types_added_while_handling_opaque_types,
+    apply_definition_site_hidden_types, clone_and_resolve_opaque_types,
+    compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types,
 };
 use crate::type_check::{Locations, constraint_conversion};
 use crate::{
-    ClosureRegionRequirements, CollectRegionConstraintsResult, ConcreteOpaqueTypes,
+    ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes,
     PropagatedBorrowCheckResults, borrowck_check_region_constraints,
     borrowck_collect_region_constraints,
 };
@@ -27,7 +27,7 @@ use crate::{
 pub(super) struct BorrowCheckRootCtxt<'tcx> {
     pub tcx: TyCtxt<'tcx>,
     root_def_id: LocalDefId,
-    concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
+    hidden_types: DefinitionSiteHiddenTypes<'tcx>,
     /// The region constraints computed by [borrowck_collect_region_constraints]. This uses
     /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before
     /// their parents.
@@ -49,7 +49,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
         BorrowCheckRootCtxt {
             tcx,
             root_def_id,
-            concrete_opaque_types: Default::default(),
+            hidden_types: Default::default(),
             collect_region_constraints_results: Default::default(),
             propagated_borrowck_results: Default::default(),
             tainted_by_errors: None,
@@ -72,11 +72,11 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
         &self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars
     }
 
-    pub(super) fn finalize(self) -> Result<&'tcx ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
+    pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
         if let Some(guar) = self.tainted_by_errors {
             Err(guar)
         } else {
-            Ok(self.tcx.arena.alloc(self.concrete_opaque_types))
+            Ok(self.tcx.arena.alloc(self.hidden_types))
         }
     }
 
@@ -88,12 +88,12 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
                 &input.universal_region_relations,
                 &mut input.constraints,
             );
-            input.deferred_opaque_type_errors = compute_concrete_opaque_types(
+            input.deferred_opaque_type_errors = compute_definition_site_hidden_types(
                 &input.infcx,
                 &input.universal_region_relations,
                 &input.constraints,
                 Rc::clone(&input.location_map),
-                &mut self.concrete_opaque_types,
+                &mut self.hidden_types,
                 &opaque_types,
             );
             per_body_info.push((num_entries, opaque_types));
@@ -103,14 +103,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
             self.collect_region_constraints_results.values_mut().zip(per_body_info)
         {
             if input.deferred_opaque_type_errors.is_empty() {
-                input.deferred_opaque_type_errors = apply_computed_concrete_opaque_types(
+                input.deferred_opaque_type_errors = apply_definition_site_hidden_types(
                     &input.infcx,
                     &input.body_owned,
                     &input.universal_region_relations.universal_regions,
                     &input.region_bound_pairs,
                     &input.known_type_outlives_obligations,
                     &mut input.constraints,
-                    &mut self.concrete_opaque_types,
+                    &mut self.hidden_types,
                     &opaque_types,
                 );
             }
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index f4a923797e2..ddc59bfe141 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -377,8 +377,7 @@ mod llvm_enzyme {
                 (ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => {
                     let a = &a.item.path;
                     let b = &b.item.path;
-                    a.segments.len() == b.segments.len()
-                        && a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident)
+                    a.segments.iter().eq_by(&b.segments, |a, b| a.ident == b.ident)
                 }
                 _ => false,
             }
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 75db5d77783..5b378de8bbd 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -356,21 +356,14 @@ fn contains_maybe_sized_bound(bounds: &[GenericBound]) -> bool {
     bounds.iter().any(is_maybe_sized_bound)
 }
 
-fn path_segment_is_exact_match(path_segments: &[ast::PathSegment], syms: &[Symbol]) -> bool {
-    path_segments.iter().zip(syms).all(|(segment, &symbol)| segment.ident.name == symbol)
-}
-
 fn is_sized_marker(path: &ast::Path) -> bool {
     const CORE_UNSIZE: [Symbol; 3] = [sym::core, sym::marker, sym::Sized];
     const STD_UNSIZE: [Symbol; 3] = [sym::std, sym::marker, sym::Sized];
-    if path.segments.len() == 4 && path.is_global() {
-        path_segment_is_exact_match(&path.segments[1..], &CORE_UNSIZE)
-            || path_segment_is_exact_match(&path.segments[1..], &STD_UNSIZE)
-    } else if path.segments.len() == 3 {
-        path_segment_is_exact_match(&path.segments, &CORE_UNSIZE)
-            || path_segment_is_exact_match(&path.segments, &STD_UNSIZE)
+    let segments = || path.segments.iter().map(|segment| segment.ident.name);
+    if path.is_global() {
+        segments().skip(1).eq(CORE_UNSIZE) || segments().skip(1).eq(STD_UNSIZE)
     } else {
-        *path == sym::Sized
+        segments().eq(CORE_UNSIZE) || segments().eq(STD_UNSIZE) || *path == sym::Sized
     }
 }
 
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index d70888205a5..bffc0407e81 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -768,7 +768,7 @@ fn report_missing_placeholders(
 
     if !found_foreign && invalid_refs.is_empty() {
         // Show example if user didn't use any format specifiers
-        let show_example = used.iter().all(|used| !used);
+        let show_example = !used.contains(&true);
 
         if !show_example {
             if unused.len() > 1 {
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 4541e2cd3b4..57cf62ea612 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
+#![feature(iter_order_by)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_codegen_cranelift/src/abi/comments.rs b/compiler/rustc_codegen_cranelift/src/abi/comments.rs
index c74efeb59f3..d1b2b9a502a 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/comments.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/comments.rs
@@ -89,7 +89,7 @@ pub(super) fn add_local_place_comments<'tcx>(
         format!("{:?}", local),
         format!("{:?}", ty),
         size.bytes(),
-        align.abi.bytes(),
+        align.bytes(),
         if extra.is_empty() { "" } else { "                " },
         extra,
     ));
diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
index 2031842062d..7a909a740b0 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
@@ -233,7 +233,7 @@ pub(super) fn from_casted_value<'tcx>(
         // It may also be smaller for example when the type is a wrapper around an integer with a
         // larger alignment than the integer.
         std::cmp::max(abi_param_size, layout_size),
-        u32::try_from(layout.align.abi.bytes()).unwrap(),
+        u32::try_from(layout.align.bytes()).unwrap(),
     );
     let mut block_params_iter = block_params.iter().copied();
     for (offset, _) in abi_params {
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 41e11e1de61..2cc5b82ddd3 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -846,7 +846,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
                     let layout = fx.layout_of(fx.monomorphize(ty));
                     let val = match null_op {
                         NullOp::SizeOf => layout.size.bytes(),
-                        NullOp::AlignOf => layout.align.abi.bytes(),
+                        NullOp::AlignOf => layout.align.bytes(),
                         NullOp::OffsetOf(fields) => fx
                             .tcx
                             .offset_of_subfield(
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index 286e02b986b..4c438742f3d 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -304,7 +304,7 @@ impl DebugContext {
         entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id)));
         entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line));
 
-        entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.abi.bytes()));
+        entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.bytes()));
 
         let mut expr = Expression::new();
         expr.op_addr(address_for_data(data_id));
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
index 25b922c8be4..0d49f32373c 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
@@ -166,7 +166,7 @@ impl DebugContext {
         let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id);
         tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name)));
         tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
-        tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.abi.bytes()));
+        tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.bytes()));
 
         for (i, (ty, dw_ty)) in components.into_iter().enumerate() {
             let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member);
@@ -178,9 +178,7 @@ impl DebugContext {
             member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
             member_entry.set(
                 gimli::DW_AT_alignment,
-                AttributeValue::Udata(
-                    FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.abi.bytes(),
-                ),
+                AttributeValue::Udata(FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.bytes()),
             );
             member_entry.set(
                 gimli::DW_AT_data_member_location,
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 8e34436fb5e..5fd7c4d4f41 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -165,6 +165,10 @@ impl CodegenBackend for CraneliftCodegenBackend {
         ""
     }
 
+    fn name(&self) -> &'static str {
+        "cranelift"
+    }
+
     fn init(&self, sess: &Session) {
         use rustc_session::config::{InstrumentCoverage, Lto};
         match sess.lto() {
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 643c7feb89a..d994f3e32ec 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -167,7 +167,7 @@ pub(crate) fn size_and_align_of<'tcx>(
     if layout.is_sized() {
         return (
             fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64),
-            fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64),
+            fx.bcx.ins().iconst(fx.pointer_type, layout.align.bytes() as i64),
         );
     }
 
@@ -186,7 +186,7 @@ pub(crate) fn size_and_align_of<'tcx>(
             // times the unit size.
             (
                 fx.bcx.ins().imul_imm(info.unwrap(), unit.size.bytes() as i64),
-                fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64),
+                fx.bcx.ins().iconst(fx.pointer_type, unit.align.bytes() as i64),
             )
         }
         ty::Foreign(_) => {
@@ -224,7 +224,7 @@ pub(crate) fn size_and_align_of<'tcx>(
             let unsized_offset_unadjusted = layout.fields.offset(i).bytes();
             let unsized_offset_unadjusted =
                 fx.bcx.ins().iconst(fx.pointer_type, unsized_offset_unadjusted as i64);
-            let sized_align = layout.align.abi.bytes();
+            let sized_align = layout.align.bytes();
             let sized_align = fx.bcx.ins().iconst(fx.pointer_type, sized_align as i64);
 
             // Recurse to get the size of the dynamically sized field (must be
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index 4519fa1a270..04e10cf1708 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -383,7 +383,7 @@ impl<'tcx> CPlace<'tcx> {
 
         let stack_slot = fx.create_stack_slot(
             u32::try_from(layout.size.bytes()).unwrap(),
-            u32::try_from(layout.align.abi.bytes()).unwrap(),
+            u32::try_from(layout.align.bytes()).unwrap(),
         );
         CPlace { inner: CPlaceInner::Addr(stack_slot, None), layout }
     }
@@ -641,8 +641,8 @@ impl<'tcx> CPlace<'tcx> {
                         let size = dst_layout.size.bytes();
                         // `emit_small_memory_copy` uses `u8` for alignments, just use the maximum
                         // alignment that fits in a `u8` if the actual alignment is larger.
-                        let src_align = src_layout.align.abi.bytes().try_into().unwrap_or(128);
-                        let dst_align = dst_layout.align.abi.bytes().try_into().unwrap_or(128);
+                        let src_align = src_layout.align.bytes().try_into().unwrap_or(128);
+                        let dst_align = dst_layout.align.bytes().try_into().unwrap_or(128);
                         fx.bcx.emit_small_memory_copy(
                             fx.target_config,
                             to_addr,
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 9815fb07eaa..c9ae96777de 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -147,7 +147,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
             let layout = tcx
                 .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
                 .unwrap();
-            let align = layout.align.abi.bytes();
+            let align = layout.align.bytes();
             // For types with size 1, the alignment can be 1 and only 1
             // So, we can skip the call to ``get_aligned`.
             // In the future, we can add a GCC API to query the type align,
@@ -186,9 +186,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
             (i128_type, u128_type)
         } else {
             /*let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.i128)).unwrap();
-            let i128_align = layout.align.abi.bytes();
+            let i128_align = layout.align.bytes();
             let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.u128)).unwrap();
-            let u128_align = layout.align.abi.bytes();*/
+            let u128_align = layout.align.bytes();*/
 
             // TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in
             // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast).
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f76f933cad4..ec7eab8489a 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -184,6 +184,10 @@ impl CodegenBackend for GccCodegenBackend {
         crate::DEFAULT_LOCALE_RESOURCE
     }
 
+    fn name(&self) -> &'static str {
+        "gcc"
+    }
+
     fn init(&self, _sess: &Session) {
         #[cfg(feature = "master")]
         {
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index abd63120397..896d6755c75 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -5,9 +5,10 @@ use rustc_ast::expand::allocator::{
 };
 use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
 use rustc_middle::bug;
-use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{DebugInfo, OomStrategy};
+use rustc_span::sym;
 use rustc_symbol_mangling::mangle_internal_symbol;
 
 use crate::attributes::llfn_attrs_from_instance;
@@ -59,7 +60,26 @@ pub(crate) unsafe fn codegen(
             let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
             let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
 
-            create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false);
+            let alloc_attr_flag = match method.name {
+                sym::alloc => CodegenFnAttrFlags::ALLOCATOR,
+                sym::dealloc => CodegenFnAttrFlags::DEALLOCATOR,
+                sym::realloc => CodegenFnAttrFlags::REALLOCATOR,
+                sym::alloc_zeroed => CodegenFnAttrFlags::ALLOCATOR_ZEROED,
+                _ => unreachable!("Unknown allocator method!"),
+            };
+
+            let mut attrs = CodegenFnAttrs::new();
+            attrs.flags |= alloc_attr_flag;
+            create_wrapper_function(
+                tcx,
+                &cx,
+                &from_name,
+                Some(&to_name),
+                &args,
+                output,
+                false,
+                &attrs,
+            );
         }
     }
 
@@ -72,6 +92,7 @@ pub(crate) unsafe fn codegen(
         &[usize, usize], // size, align
         None,
         true,
+        &CodegenFnAttrs::new(),
     );
 
     unsafe {
@@ -93,6 +114,7 @@ pub(crate) unsafe fn codegen(
             &[],
             None,
             false,
+            &CodegenFnAttrs::new(),
         );
     }
 
@@ -139,6 +161,7 @@ fn create_wrapper_function(
     args: &[&Type],
     output: Option<&Type>,
     no_return: bool,
+    attrs: &CodegenFnAttrs,
 ) {
     let ty = cx.type_func(args, output.unwrap_or_else(|| cx.type_void()));
     let llfn = declare_simple_fn(
@@ -150,8 +173,7 @@ fn create_wrapper_function(
         ty,
     );
 
-    let attrs = CodegenFnAttrs::new();
-    llfn_attrs_from_instance(cx, tcx, llfn, &attrs, None);
+    llfn_attrs_from_instance(cx, tcx, llfn, attrs, None);
 
     let no_return = if no_return {
         // -> ! DIFlagNoReturn
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index c3485f56391..4a749642265 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -378,5 +378,12 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
 
     let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None);
 
-    builder.store_to_place(call, dest.val);
+    let fn_ret_ty = builder.cx.val_ty(call);
+    if fn_ret_ty != builder.cx.type_void() && fn_ret_ty != builder.cx.type_struct(&[], false) {
+        // If we return void or an empty struct, then our caller (due to how we generated it)
+        // does not expect a return value. As such, we have no pointer (or place) into which
+        // we could store our value, and would store into an undef, which would cause UB.
+        // As such, we just ignore the return value in those cases.
+        builder.store_to_place(call, dest.val);
+    }
 }
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index a110ecbb75d..40375ef6510 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -564,7 +564,7 @@ impl<'ll> CodegenCx<'ll, '_> {
         let g = self.define_global(&sym, llty).unwrap_or_else(|| {
             bug!("symbol `{}` is already defined", sym);
         });
-        set_global_alignment(self, g, self.tcx.data_layout.i8_align.abi);
+        set_global_alignment(self, g, self.tcx.data_layout.i8_align);
         llvm::set_initializer(g, llval);
         llvm::set_linkage(g, llvm::Linkage::PrivateLinkage);
         llvm::set_section(g, c"__TEXT,__cstring,cstring_literals");
@@ -680,7 +680,7 @@ impl<'ll> CodegenCx<'ll, '_> {
         let methname_g = self.define_global(&methname_sym, methname_llty).unwrap_or_else(|| {
             bug!("symbol `{}` is already defined", methname_sym);
         });
-        set_global_alignment(self, methname_g, self.tcx.data_layout.i8_align.abi);
+        set_global_alignment(self, methname_g, self.tcx.data_layout.i8_align);
         llvm::set_initializer(methname_g, methname_llval);
         llvm::set_linkage(methname_g, llvm::Linkage::PrivateLinkage);
         llvm::set_section(
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index aa5c17269fb..b1da6f7c740 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -34,7 +34,7 @@ use smallvec::SmallVec;
 use crate::back::write::to_llvm_code_model;
 use crate::callee::get_fn;
 use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
-use crate::llvm::Metadata;
+use crate::llvm::{Metadata, MetadataKindId};
 use crate::type_::Type;
 use crate::value::Value;
 use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
@@ -1006,11 +1006,11 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
     pub(crate) fn set_metadata<'a>(
         &self,
         val: &'a Value,
-        kind_id: impl Into<llvm::MetadataKindId>,
+        kind_id: MetadataKindId,
         md: &'ll Metadata,
     ) {
         let node = self.get_metadata_value(md);
-        llvm::LLVMSetMetadata(val, kind_id.into(), node);
+        llvm::LLVMSetMetadata(val, kind_id, node);
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
index bc4f6bb6a82..d50eb533ffd 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
@@ -2,26 +2,25 @@
 
 use std::ffi::CString;
 
-use crate::common::AsCCharPtr;
 use crate::coverageinfo::ffi;
 use crate::llvm;
 
 pub(crate) fn covmap_var_name() -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovmapVarNameToString(s);
     }))
     .expect("covmap variable name should not contain NUL")
 }
 
 pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s);
     }))
     .expect("covmap section name should not contain NUL")
 }
 
 pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s);
     }))
     .expect("covfun section name should not contain NUL")
@@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>(
     unsafe {
         llvm::LLVMRustCoverageCreatePGOFuncNameVar(
             llfn,
-            mangled_fn_name.as_c_char_ptr(),
+            mangled_fn_name.as_ptr(),
             mangled_fn_name.len(),
         )
     }
@@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8
     let (pointers, lengths) = filenames
         .into_iter()
         .map(AsRef::as_ref)
-        .map(|s: &str| (s.as_c_char_ptr(), s.len()))
+        .map(|s: &str| (s.as_ptr(), s.len()))
         .unzip::<_, _, Vec<_>, Vec<_>>();
 
     llvm::build_byte_buffer(|buffer| unsafe {
@@ -89,12 +88,12 @@ pub(crate) fn write_function_mappings_to_buffer(
 /// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`,
 /// as required for parts of the LLVM coverage mapping format.
 pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
-    unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) }
+    unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) }
 }
 
 /// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h)
 /// as a raw numeric value. For historical reasons, the numeric value is 1 less
 /// than the number in the version's name, so `Version7` is actually `6u32`.
 pub(crate) fn mapping_version() -> u32 {
-    unsafe { llvm::LLVMRustCoverageMappingVersion() }
+    llvm::LLVMRustCoverageMappingVersion()
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 4b74c04ed7a..bc20c759413 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1043,7 +1043,7 @@ fn create_member_type<'ll, 'tcx>(
             file_metadata,
             line_number,
             layout.size.bits(),
-            layout.align.abi.bits() as u32,
+            layout.align.bits() as u32,
             offset.bits(),
             flags,
             type_di_node,
@@ -1611,16 +1611,12 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
         let v = [llvm::LLVMValueAsMetadata(cx.const_usize(0)), typeid];
         llvm::LLVMRustGlobalAddMetadata(
             vtable,
-            llvm::MD_type as c_uint,
+            llvm::MD_type,
             llvm::LLVMMDNodeInContext2(cx.llcx, v.as_ptr(), v.len()),
         );
         let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64));
         let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1);
-        llvm::LLVMGlobalSetMetadata(
-            vtable,
-            llvm::MetadataType::MD_vcall_visibility as c_uint,
-            vcall_visibility_metadata,
-        );
+        llvm::LLVMGlobalSetMetadata(vtable, llvm::MD_vcall_visibility, vcall_visibility_metadata);
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 62d38d463ab..1ae6e6e5eec 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -289,7 +289,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>(
                 file_metadata,
                 line_number,
                 enum_type_and_layout.size.bits(),
-                enum_type_and_layout.align.abi.bits() as u32,
+                enum_type_and_layout.align.bits() as u32,
                 DIFlags::FlagZero,
                 tag_member_di_node,
                 create_DIArray(DIB(cx), &[]),
@@ -449,7 +449,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
             file_di_node,
             line_number,
             enum_type_and_layout.size.bits(),
-            enum_type_and_layout.align.abi.bits() as u32,
+            enum_type_and_layout.align.bits() as u32,
             Size::ZERO.bits(),
             discr,
             DIFlags::FlagZero,
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 013108d1286..467655b0bfc 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -297,7 +297,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 let align = if name == sym::unaligned_volatile_load {
                     1
                 } else {
-                    result.layout.align.abi.bytes() as u32
+                    result.layout.align.bytes() as u32
                 };
                 unsafe {
                     llvm::LLVMSetAlignment(load, align);
@@ -1047,7 +1047,7 @@ fn codegen_emcc_try<'ll, 'tcx>(
         // create an alloca and pass a pointer to that.
         let ptr_size = bx.tcx().data_layout.pointer_size();
         let ptr_align = bx.tcx().data_layout.pointer_align().abi;
-        let i8_align = bx.tcx().data_layout.i8_align.abi;
+        let i8_align = bx.tcx().data_layout.i8_align;
         // Required in order for there to be no padding between the fields.
         assert!(i8_align <= ptr_align);
         let catch_data = bx.alloca(2 * ptr_size, ptr_align);
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index b9584a9117f..2405a25c702 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -232,6 +232,10 @@ impl CodegenBackend for LlvmCodegenBackend {
         crate::DEFAULT_LOCALE_RESOURCE
     }
 
+    fn name(&self) -> &'static str {
+        "llvm"
+    }
+
     fn init(&self, sess: &Session) {
         llvm_util::init(sess); // Make sure llvm is inited
     }
@@ -350,7 +354,14 @@ impl CodegenBackend for LlvmCodegenBackend {
 
         // Run the linker on any artifacts that resulted from the LLVM run.
         // This should produce either a finished executable or library.
-        link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, metadata, outputs);
+        link_binary(
+            sess,
+            &LlvmArchiveBuilderBuilder,
+            codegen_results,
+            metadata,
+            outputs,
+            self.name(),
+        );
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index afd2991a09c..e9f92267a7d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -29,6 +29,7 @@ use super::debuginfo::{
     DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind,
 };
 use crate::llvm;
+use crate::llvm::MetadataKindId;
 
 /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
 /// which has a different ABI from Rust or C++ `bool`.
@@ -513,31 +514,6 @@ pub(crate) enum FileType {
     ObjectFile,
 }
 
-/// LLVMMetadataType
-#[derive(Copy, Clone)]
-#[repr(C)]
-#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
-pub(crate) enum MetadataType {
-    MD_dbg = 0,
-    MD_tbaa = 1,
-    MD_prof = 2,
-    MD_fpmath = 3,
-    MD_range = 4,
-    MD_tbaa_struct = 5,
-    MD_invariant_load = 6,
-    MD_alias_scope = 7,
-    MD_noalias = 8,
-    MD_nontemporal = 9,
-    MD_mem_parallel_loop_access = 10,
-    MD_nonnull = 11,
-    MD_unpredictable = 15,
-    MD_align = 17,
-    MD_type = 19,
-    MD_vcall_visibility = 28,
-    MD_noundef = 29,
-    MD_kcfi_type = 36,
-}
-
 /// Must match the layout of `LLVMInlineAsmDialect`.
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
@@ -1035,16 +1011,6 @@ pub(crate) type GetSymbolsCallback =
     unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
 pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
 
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub(crate) struct MetadataKindId(c_uint);
-
-impl From<MetadataType> for MetadataKindId {
-    fn from(value: MetadataType) -> Self {
-        Self(value as c_uint)
-    }
-}
-
 unsafe extern "C" {
     // Create and destroy contexts.
     pub(crate) fn LLVMContextDispose(C: &'static mut Context);
@@ -1139,7 +1105,11 @@ unsafe extern "C" {
     pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t);
     pub(crate) fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value);
     pub(crate) safe fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: MetadataKindId, Node: &'a Value);
-    pub(crate) fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
+    pub(crate) fn LLVMGlobalSetMetadata<'a>(
+        Val: &'a Value,
+        KindID: MetadataKindId,
+        Metadata: &'a Metadata,
+    );
     pub(crate) safe fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
 
     // Operations on constants of any type
@@ -2059,7 +2029,7 @@ unsafe extern "C" {
     // Operations on all values
     pub(crate) fn LLVMRustGlobalAddMetadata<'a>(
         Val: &'a Value,
-        KindID: c_uint,
+        KindID: MetadataKindId,
         Metadata: &'a Metadata,
     );
     pub(crate) fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
@@ -2256,8 +2226,11 @@ unsafe extern "C" {
         ConstraintsLen: size_t,
     ) -> bool;
 
+    /// A list of pointer-length strings is passed as two pointer-length slices,
+    /// one slice containing pointers and one slice containing their corresponding
+    /// lengths. The implementation will check that both slices have the same length.
     pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer(
-        Filenames: *const *const c_char,
+        Filenames: *const *const c_uchar, // See "PTR_LEN_STR".
         FilenamesLen: size_t,
         Lengths: *const size_t,
         LengthsLen: size_t,
@@ -2280,18 +2253,25 @@ unsafe extern "C" {
 
     pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar(
         F: &Value,
-        FuncName: *const c_char,
+        FuncName: *const c_uchar, // See "PTR_LEN_STR".
         FuncNameLen: size_t,
     ) -> &Value;
-    pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64;
-
-    pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString);
+    pub(crate) fn LLVMRustCoverageHashBytes(
+        Bytes: *const c_uchar, // See "PTR_LEN_STR".
+        NumBytes: size_t,
+    ) -> u64;
 
-    pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString);
-
-    pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
+    pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString(
+        M: &Module,
+        OutStr: &RustString,
+    );
+    pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString(
+        M: &Module,
+        OutStr: &RustString,
+    );
+    pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
 
-    pub(crate) fn LLVMRustCoverageMappingVersion() -> u32;
+    pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32;
     pub(crate) fn LLVMRustDebugMetadataVersion() -> u32;
     pub(crate) fn LLVMRustVersionMajor() -> u32;
     pub(crate) fn LLVMRustVersionMinor() -> u32;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
new file mode 100644
index 00000000000..a8a671b5c85
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
@@ -0,0 +1,71 @@
+use libc::c_uint;
+
+pub(crate) use self::fixed_kinds::*;
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub(crate) struct MetadataKindId(c_uint);
+
+macro_rules! declare_fixed_metadata_kinds {
+    (
+        $(
+            FIXED_MD_KIND($variant:ident, $value:literal)
+        )*
+    ) => {
+        // Use a submodule to group all declarations into one `#[expect(..)]`.
+        #[expect(dead_code)]
+        mod fixed_kinds {
+            use super::MetadataKindId;
+            $(
+                #[expect(non_upper_case_globals)]
+                pub(crate) const $variant: MetadataKindId = MetadataKindId($value);
+            )*
+        }
+    };
+}
+
+// Must be kept in sync with the corresponding static assertions in `RustWrapper.cpp`.
+declare_fixed_metadata_kinds! {
+    FIXED_MD_KIND(MD_dbg, 0)
+    FIXED_MD_KIND(MD_tbaa, 1)
+    FIXED_MD_KIND(MD_prof, 2)
+    FIXED_MD_KIND(MD_fpmath, 3)
+    FIXED_MD_KIND(MD_range, 4)
+    FIXED_MD_KIND(MD_tbaa_struct, 5)
+    FIXED_MD_KIND(MD_invariant_load, 6)
+    FIXED_MD_KIND(MD_alias_scope, 7)
+    FIXED_MD_KIND(MD_noalias, 8)
+    FIXED_MD_KIND(MD_nontemporal, 9)
+    FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+    FIXED_MD_KIND(MD_nonnull, 11)
+    FIXED_MD_KIND(MD_dereferenceable, 12)
+    FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+    FIXED_MD_KIND(MD_make_implicit, 14)
+    FIXED_MD_KIND(MD_unpredictable, 15)
+    FIXED_MD_KIND(MD_invariant_group, 16)
+    FIXED_MD_KIND(MD_align, 17)
+    FIXED_MD_KIND(MD_loop, 18)
+    FIXED_MD_KIND(MD_type, 19)
+    FIXED_MD_KIND(MD_section_prefix, 20)
+    FIXED_MD_KIND(MD_absolute_symbol, 21)
+    FIXED_MD_KIND(MD_associated, 22)
+    FIXED_MD_KIND(MD_callees, 23)
+    FIXED_MD_KIND(MD_irr_loop, 24)
+    FIXED_MD_KIND(MD_access_group, 25)
+    FIXED_MD_KIND(MD_callback, 26)
+    FIXED_MD_KIND(MD_preserve_access_index, 27)
+    FIXED_MD_KIND(MD_vcall_visibility, 28)
+    FIXED_MD_KIND(MD_noundef, 29)
+    FIXED_MD_KIND(MD_annotation, 30)
+    FIXED_MD_KIND(MD_nosanitize, 31)
+    FIXED_MD_KIND(MD_func_sanitize, 32)
+    FIXED_MD_KIND(MD_exclude, 33)
+    FIXED_MD_KIND(MD_memprof, 34)
+    FIXED_MD_KIND(MD_callsite, 35)
+    FIXED_MD_KIND(MD_kcfi_type, 36)
+    FIXED_MD_KIND(MD_pcsections, 37)
+    FIXED_MD_KIND(MD_DIAssignID, 38)
+    FIXED_MD_KIND(MD_coro_outside_frame, 39)
+    FIXED_MD_KIND(MD_mmra, 40)
+    FIXED_MD_KIND(MD_noalias_addrspace, 41)
+}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index 1115d82fa85..9a53dacb1df 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -11,13 +11,14 @@ use rustc_llvm::RustString;
 
 pub(crate) use self::CallConv::*;
 pub(crate) use self::CodeGenOptSize::*;
-pub(crate) use self::MetadataType::*;
 pub(crate) use self::ffi::*;
+pub(crate) use self::metadata_kind::*;
 use crate::common::AsCCharPtr;
 
 pub(crate) mod diagnostic;
 pub(crate) mod enzyme_ffi;
 mod ffi;
+mod metadata_kind;
 
 pub(crate) use self::enzyme_ffi::*;
 
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 9ecaf5f24fe..5b97898a4b8 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -306,7 +306,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
             llvm::LLVMRustGlobalAddMetadata(
                 function,
-                llvm::MD_type as c_uint,
+                llvm::MD_type,
                 llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
             )
         }
@@ -318,7 +318,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
             llvm::LLVMGlobalSetMetadata(
                 function,
-                llvm::MD_type as c_uint,
+                llvm::MD_type,
                 llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
             )
         }
@@ -333,7 +333,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe {
             llvm::LLVMRustGlobalAddMetadata(
                 function,
-                llvm::MD_kcfi_type as c_uint,
+                llvm::MD_kcfi_type,
                 llvm::LLVMMDNodeInContext2(
                     self.llcx,
                     &llvm::LLVMValueAsMetadata(kcfi_type_metadata),
@@ -348,7 +348,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe {
             llvm::LLVMGlobalSetMetadata(
                 function,
-                llvm::MD_kcfi_type as c_uint,
+                llvm::MD_kcfi_type,
                 llvm::LLVMMDNodeInContext2(
                     self.llcx,
                     &llvm::LLVMValueAsMetadata(kcfi_type_metadata),
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index d48c7cf874a..234366e491c 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -193,7 +193,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(
     // the offset again.
 
     bx.switch_to_block(maybe_reg);
-    if gr_type && layout.align.abi.bytes() > 8 {
+    if gr_type && layout.align.bytes() > 8 {
         reg_off_v = bx.add(reg_off_v, bx.const_i32(15));
         reg_off_v = bx.and(reg_off_v, bx.const_i32(-16));
     }
@@ -291,7 +291,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
         bx.inbounds_ptradd(va_list_addr, bx.const_usize(1)) // fpr
     };
 
-    let mut num_regs = bx.load(bx.type_i8(), num_regs_addr, dl.i8_align.abi);
+    let mut num_regs = bx.load(bx.type_i8(), num_regs_addr, dl.i8_align);
 
     // "Align" the register count when the type is passed as `i64`.
     if is_i64 || (is_f64 && is_soft_float_abi) {
@@ -329,7 +329,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
         // Increase the used-register count.
         let reg_incr = if is_i64 || (is_f64 && is_soft_float_abi) { 2 } else { 1 };
         let new_num_regs = bx.add(num_regs, bx.cx.const_u8(reg_incr));
-        bx.store(new_num_regs, num_regs_addr, dl.i8_align.abi);
+        bx.store(new_num_regs, num_regs_addr, dl.i8_align);
 
         bx.br(end);
 
@@ -339,7 +339,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
     let mem_addr = {
         bx.switch_to_block(in_mem);
 
-        bx.store(bx.const_u8(max_regs), num_regs_addr, dl.i8_align.abi);
+        bx.store(bx.const_u8(max_regs), num_regs_addr, dl.i8_align);
 
         // Everything in the overflow area is rounded up to a size of at least 4.
         let overflow_area_align = Align::from_bytes(4).unwrap();
@@ -761,7 +761,7 @@ fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>(
     // byte boundary if alignment needed by type exceeds 8 byte boundary.
     // It isn't stated explicitly in the standard, but in practice we use
     // alignment greater than 16 where necessary.
-    if layout.layout.align.abi.bytes() > 8 {
+    if layout.layout.align.bytes() > 8 {
         unreachable!("all instances of VaArgSafe have an alignment <= 8");
     }
 
@@ -814,7 +814,7 @@ fn emit_xtensa_va_arg<'ll, 'tcx>(
     let va_ndx_offset = va_reg_offset + 4;
     let offset_ptr = bx.inbounds_ptradd(va_list_addr, bx.cx.const_usize(va_ndx_offset));
 
-    let offset = bx.load(bx.type_i32(), offset_ptr, bx.tcx().data_layout.i32_align.abi);
+    let offset = bx.load(bx.type_i32(), offset_ptr, bx.tcx().data_layout.i32_align);
     let offset = round_up_to_alignment(bx, offset, layout.align.abi);
 
     let slot_size = layout.size.align_to(Align::from_bytes(4).unwrap()).bytes() as i32;
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index d6c304c1b14..db2f2dd65b0 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -79,6 +79,7 @@ pub fn link_binary(
     codegen_results: CodegenResults,
     metadata: EncodedMetadata,
     outputs: &OutputFilenames,
+    codegen_backend: &'static str,
 ) {
     let _timer = sess.timer("link_binary");
     let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
@@ -154,6 +155,7 @@ pub fn link_binary(
                         &codegen_results,
                         &metadata,
                         path.as_ref(),
+                        codegen_backend,
                     );
                 }
             }
@@ -680,6 +682,7 @@ fn link_natively(
     codegen_results: &CodegenResults,
     metadata: &EncodedMetadata,
     tmpdir: &Path,
+    codegen_backend: &'static str,
 ) {
     info!("preparing {:?} to {:?}", crate_type, out_filename);
     let (linker_path, flavor) = linker_and_flavor(sess);
@@ -705,6 +708,7 @@ fn link_natively(
         codegen_results,
         metadata,
         self_contained_components,
+        codegen_backend,
     );
 
     linker::disable_localization(&mut cmd);
@@ -2208,6 +2212,7 @@ fn linker_with_args(
     codegen_results: &CodegenResults,
     metadata: &EncodedMetadata,
     self_contained_components: LinkSelfContainedComponents,
+    codegen_backend: &'static str,
 ) -> Command {
     let self_contained_crt_objects = self_contained_components.is_crt_objects_enabled();
     let cmd = &mut *super::linker::get_linker(
@@ -2216,6 +2221,7 @@ fn linker_with_args(
         flavor,
         self_contained_components.are_any_components_enabled(),
         &codegen_results.crate_info.target_cpu,
+        codegen_backend,
     );
     let link_output_kind = link_output_kind(sess, crate_type);
 
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 624ab1b5084..e644a43f883 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -52,6 +52,7 @@ pub(crate) fn get_linker<'a>(
     flavor: LinkerFlavor,
     self_contained: bool,
     target_cpu: &'a str,
+    codegen_backend: &'static str,
 ) -> Box<dyn Linker + 'a> {
     let msvc_tool = find_msvc_tools::find_tool(&sess.target.arch, "link.exe");
 
@@ -154,6 +155,7 @@ pub(crate) fn get_linker<'a>(
             is_ld: cc == Cc::No,
             is_gnu: flavor.is_gnu(),
             uses_lld: flavor.uses_lld(),
+            codegen_backend,
         }) as Box<dyn Linker>,
         LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>,
         LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
@@ -367,6 +369,7 @@ struct GccLinker<'a> {
     is_ld: bool,
     is_gnu: bool,
     uses_lld: bool,
+    codegen_backend: &'static str,
 }
 
 impl<'a> GccLinker<'a> {
@@ -423,9 +426,15 @@ impl<'a> GccLinker<'a> {
         if let Some(path) = &self.sess.opts.unstable_opts.profile_sample_use {
             self.link_arg(&format!("-plugin-opt=sample-profile={}", path.display()));
         };
+        let prefix = if self.codegen_backend == "gcc" {
+            // The GCC linker plugin requires a leading dash.
+            "-"
+        } else {
+            ""
+        };
         self.link_args(&[
-            &format!("-plugin-opt={opt_level}"),
-            &format!("-plugin-opt=mcpu={}", self.target_cpu),
+            &format!("-plugin-opt={prefix}{opt_level}"),
+            &format!("-plugin-opt={prefix}mcpu={}", self.target_cpu),
         ]);
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 2602bf82095..0a4b0f8d494 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -617,7 +617,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
                     mir::NullOp::AlignOf => {
                         assert!(bx.cx().type_is_sized(ty));
-                        let val = layout.align.abi.bytes();
+                        let val = layout.align.bytes();
                         bx.cx().const_usize(val)
                     }
                     mir::NullOp::OffsetOf(fields) => {
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index 577012151e4..e1bd8014d7a 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -21,7 +21,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
     if layout.is_sized() {
         let size = bx.const_usize(layout.size.bytes());
-        let align = bx.const_usize(layout.align.abi.bytes());
+        let align = bx.const_usize(layout.align.bytes());
         return (size, align);
     }
     match t.kind() {
@@ -49,7 +49,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 // All slice sizes must fit into `isize`, so this multiplication cannot
                 // wrap -- neither signed nor unsigned.
                 bx.unchecked_sumul(info.unwrap(), bx.const_usize(unit.size.bytes())),
-                bx.const_usize(unit.align.abi.bytes()),
+                bx.const_usize(unit.align.bytes()),
             )
         }
         ty::Foreign(_) => {
@@ -82,7 +82,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             // This function does not return so we can now return whatever we want.
             let size = bx.const_usize(layout.size.bytes());
-            let align = bx.const_usize(layout.align.abi.bytes());
+            let align = bx.const_usize(layout.align.bytes());
             (size, align)
         }
         ty::Adt(..) | ty::Tuple(..) => {
@@ -94,7 +94,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             let i = layout.fields.count() - 1;
             let unsized_offset_unadjusted = layout.fields.offset(i).bytes();
-            let sized_align = layout.align.abi.bytes();
+            let sized_align = layout.align.bytes();
             debug!(
                 "DST {} offset of dyn field: {}, statically sized align: {}",
                 t, unsized_offset_unadjusted, sized_align
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 29ec7eb1da3..2400160075e 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -41,6 +41,8 @@ pub trait CodegenBackend {
     /// Called before `init` so that all other functions are able to emit translatable diagnostics.
     fn locale_resource(&self) -> &'static str;
 
+    fn name(&self) -> &'static str;
+
     fn init(&self, _sess: &Session) {}
 
     fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
@@ -96,7 +98,14 @@ pub trait CodegenBackend {
         metadata: EncodedMetadata,
         outputs: &OutputFilenames,
     ) {
-        link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, metadata, outputs);
+        link_binary(
+            sess,
+            &ArArchiveBuilderBuilder,
+            codegen_results,
+            metadata,
+            outputs,
+            self.name(),
+        );
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 74f8a0a7b09..f0819423aa0 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -528,7 +528,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 if !layout.is_sized() {
                     span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
                 }
-                let val = layout.align.abi.bytes();
+                let val = layout.align.bytes();
                 ImmTy::from_uint(val, usize_layout())
             }
             OffsetOf(fields) => {
diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs
index 9507b24f603..9aafc7efd8a 100644
--- a/compiler/rustc_const_eval/src/util/alignment.rs
+++ b/compiler/rustc_const_eval/src/util/alignment.rs
@@ -37,7 +37,7 @@ where
             debug!(
                 "is_disaligned({:?}) - align = {}, packed = {}; not disaligned",
                 place,
-                layout.align.abi.bytes(),
+                layout.align.bytes(),
                 pack.bytes()
             );
             false
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index b1f29598750..1dea7e4252d 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -129,7 +129,7 @@ fn check_validity_requirement_lax<'tcx>(
     if let Some(pointee) = this.ty.builtin_deref(false) {
         let pointee = cx.layout_of(pointee)?;
         // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied.
-        if pointee.align.abi.bytes() > 1 {
+        if pointee.align.bytes() > 1 {
             // 0x01-filling is not aligned.
             return Ok(false);
         }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0719.md b/compiler/rustc_error_codes/src/error_codes/E0719.md
index cd981db1058..6aec38b42a3 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0719.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0719.md
@@ -1,4 +1,4 @@
-An associated type value was specified more than once.
+An associated item was specified more than once in a trait object.
 
 Erroneous code example:
 
@@ -7,21 +7,15 @@ trait FooTrait {}
 trait BarTrait {}
 
 // error: associated type `Item` in trait `Iterator` is specified twice
-struct Foo<T: Iterator<Item: FooTrait, Item: BarTrait>> { f: T }
+type Foo = dyn Iterator<Item = u32, Item = u32>;
 ```
 
-`Item` in trait `Iterator` cannot be specified multiple times for struct `Foo`.
-To fix this, create a new trait that is a combination of the desired traits and
-specify the associated type with the new trait.
+To fix this, remove the duplicate specifier:
 
 Corrected example:
 
 ```
-trait FooTrait {}
-trait BarTrait {}
-trait FooBarTrait: FooTrait + BarTrait {}
-
-struct Foo<T: Iterator<Item: FooBarTrait>> { f: T } // ok!
+type Foo = dyn Iterator<Item = u32>; // ok!
 ```
 
 For more information about associated types, see [the book][bk-at]. For more
diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index ebd6e887f7d..0eae44a05e7 100644
--- a/compiler/rustc_expand/src/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
@@ -210,8 +210,7 @@ pub(super) fn check_meta_variables(
     guar.map_or(Ok(()), Err)
 }
 
-/// Checks `lhs` as part of the LHS of a macro definition, extends `binders` with new binders, and
-/// sets `valid` to false in case of errors.
+/// Checks `lhs` as part of the LHS of a macro definition.
 ///
 /// Arguments:
 /// - `psess` is used to emit diagnostics and lints
@@ -306,8 +305,7 @@ fn get_binder_info<'a>(
     binders.get(&name).or_else(|| macros.find_map(|state| state.binders.get(&name)))
 }
 
-/// Checks `rhs` as part of the RHS of a macro definition and sets `valid` to false in case of
-/// errors.
+/// Checks `rhs` as part of the RHS of a macro definition.
 ///
 /// Arguments:
 /// - `psess` is used to emit diagnostics and lints
@@ -372,7 +370,7 @@ enum NestedMacroState {
 }
 
 /// Checks `tts` as part of the RHS of a macro definition, tries to recognize nested macro
-/// definitions, and sets `valid` to false in case of errors.
+/// definitions.
 ///
 /// Arguments:
 /// - `psess` is used to emit diagnostics and lints
@@ -491,8 +489,7 @@ fn check_nested_occurrences(
     }
 }
 
-/// Checks the body of nested macro, returns where the check stopped, and sets `valid` to false in
-/// case of errors.
+/// Checks the body of nested macro, returns where the check stopped.
 ///
 /// The token trees are checked as long as they look like a list of (LHS) => {RHS} token trees. This
 /// check is a best-effort to detect a macro definition. It returns the position in `tts` where we
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 3c51f91331a..539d67e0b6b 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -102,9 +102,9 @@ declare_features! (
     /// Allows deriving traits as per `SmartPointer` specification
     (removed, derive_smart_pointer, "1.84.0", Some(123430), Some("replaced by `CoercePointee`"), 131284),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
-    (removed, doc_auto_cfg, "1.58.0", Some(43781), Some("merged into `doc_cfg`"), 138907),
+    (removed, doc_auto_cfg, "CURRENT_RUSTC_VERSION", Some(43781), Some("merged into `doc_cfg`"), 138907),
     /// Allows `#[doc(cfg_hide(...))]`.
-    (removed, doc_cfg_hide, "1.57.0", Some(43781), Some("merged into `doc_cfg`"), 138907),
+    (removed, doc_cfg_hide, "CURRENT_RUSTC_VERSION", Some(43781), Some("merged into `doc_cfg`"), 138907),
     /// Allows using `#[doc(keyword = "...")]`.
     (removed, doc_keyword, "1.58.0", Some(51315),
      Some("merged into `#![feature(rustdoc_internals)]`"), 90420),
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 493236718a8..bc1c47e95c3 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1298,10 +1298,7 @@ impl AttributeExt for Attribute {
     #[inline]
     fn path_matches(&self, name: &[Symbol]) -> bool {
         match &self {
-            Attribute::Unparsed(n) => {
-                n.path.segments.len() == name.len()
-                    && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
-            }
+            Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name),
             _ => false,
         }
     }
diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs
index b7a0a6a0c19..c9de6f6b5d5 100644
--- a/compiler/rustc_hir/src/lints.rs
+++ b/compiler/rustc_hir/src/lints.rs
@@ -31,6 +31,12 @@ pub struct AttributeLint<Id> {
 
 #[derive(Clone, Debug, HashStable_Generic)]
 pub enum AttributeLintKind {
+    /// Copy of `IllFormedAttributeInput`
+    /// specifically for the `invalid_macro_export_arguments` lint until that is removed,
+    /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
+    InvalidMacroExportArguments {
+        suggestions: Vec<String>,
+    },
     UnusedDuplicate {
         this: Span,
         other: Span,
@@ -41,13 +47,8 @@ pub enum AttributeLintKind {
     },
     EmptyAttribute {
         first_span: Span,
-    },
-
-    /// Copy of `IllFormedAttributeInput`
-    /// specifically for the `invalid_macro_export_arguments` lint until that is removed,
-    /// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
-    InvalidMacroExportArguments {
-        suggestions: Vec<String>,
+        attr_path: AttrPath,
+        valid_without_list: bool,
     },
     InvalidTarget {
         name: AttrPath,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 886ebddc75c..e1e6860e430 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -219,7 +219,7 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
     // `async-std` (and `pub async fn` in general).
-    // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
+    // Since rustdoc doesn't care about the hidden type behind `impl Trait`, just don't look at it!
     // See https://github.com/rust-lang/rust/issues/75100
     if tcx.sess.opts.actually_rustdoc {
         return;
@@ -252,7 +252,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
     Ok(())
 }
 
-/// Check that the concrete type behind `impl Trait` actually implements `Trait`.
+/// Check that the hidden type behind `impl Trait` actually implements `Trait`.
 ///
 /// This is mostly checked at the places that specify the opaque type, but we
 /// check those cases in the `param_env` of that function, which may have
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index 38ae7852ca9..b069a74bf5a 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -195,11 +195,10 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Closure(..)
             | ty::CoroutineClosure(..)
             | ty::Coroutine(..)
-            | ty::CoroutineWitness(..)
-            | ty::Alias(ty::Free, _)
-            | ty::Bound(..)
-            | ty::Placeholder(_)
-            | ty::Infer(_) => {
+            | ty::CoroutineWitness(..) => {
+                Err(self.tcx.dcx().delayed_bug("cannot define inherent `impl` for closure types"))
+            }
+            ty::Alias(ty::Free, _) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => {
                 bug!("unexpected impl self type of impl: {:?} {:?}", id, self_ty);
             }
             // We could bail out here, but that will silence other useful errors.
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 621431ae234..5a61248cab8 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -230,10 +230,12 @@ pub(crate) fn orphan_check_impl(
             ty::Closure(..)
             | ty::CoroutineClosure(..)
             | ty::Coroutine(..)
-            | ty::CoroutineWitness(..)
-            | ty::Bound(..)
-            | ty::Placeholder(..)
-            | ty::Infer(..) => {
+            | ty::CoroutineWitness(..) => {
+                return Err(tcx
+                    .dcx()
+                    .delayed_bug("cannot define inherent `impl` for closure types"));
+            }
+            ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
                 let sp = tcx.def_span(impl_def_id);
                 span_bug!(sp, "weird self type for autotrait impl")
             }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index b72e743f95b..02baaec3713 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1140,7 +1140,7 @@ fn recover_infer_ret_ty<'tcx>(
     // recursive function definition to leak out into the fn sig.
     let mut recovered_ret_ty = None;
     if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
-        diag.span_suggestion(
+        diag.span_suggestion_verbose(
             infer_ret_ty.span,
             "replace with the correct return type",
             suggestable_ret_ty,
@@ -1152,7 +1152,7 @@ fn recover_infer_ret_ty<'tcx>(
         tcx.param_env(def_id),
         ret_ty,
     ) {
-        diag.span_suggestion(
+        diag.span_suggestion_verbose(
             infer_ret_ty.span,
             "replace with an appropriate return type",
             sugg,
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index ba54fa8cc0d..9841fafc82c 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -12,7 +12,7 @@ use tracing::{debug, instrument};
 
 use super::ItemCtxt;
 use super::predicates_of::assert_only_contains_predicates_from;
-use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
+use crate::hir_ty_lowering::{HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter};
 
 /// For associated types we include both bounds written on the type
 /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
@@ -37,7 +37,14 @@ fn associated_type_bounds<'tcx>(
 
         let icx = ItemCtxt::new(tcx, assoc_item_def_id);
         let mut bounds = Vec::new();
-        icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
+        icx.lowerer().lower_bounds(
+            item_ty,
+            hir_bounds,
+            &mut bounds,
+            ty::List::empty(),
+            filter,
+            OverlappingAsssocItemConstraints::Allowed,
+        );
 
         match filter {
             PredicateFilter::All
@@ -347,7 +354,14 @@ fn opaque_type_bounds<'tcx>(
     ty::print::with_reduced_queries!({
         let icx = ItemCtxt::new(tcx, opaque_def_id);
         let mut bounds = Vec::new();
-        icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
+        icx.lowerer().lower_bounds(
+            item_ty,
+            hir_bounds,
+            &mut bounds,
+            ty::List::empty(),
+            filter,
+            OverlappingAsssocItemConstraints::Allowed,
+        );
         // Implicit bounds are added to opaque types unless a `?Trait` bound is found
         match filter {
             PredicateFilter::All
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index dd3590f9ac5..ffdf2a2f4c0 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -18,7 +18,9 @@ use super::item_bounds::explicit_item_bounds_with_filter;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
 use crate::delegation::inherit_predicates_for_delegation_item;
-use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};
+use crate::hir_ty_lowering::{
+    HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
+};
 
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
 /// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
@@ -187,6 +189,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             &mut bounds,
             ty::List::empty(),
             PredicateFilter::All,
+            OverlappingAsssocItemConstraints::Allowed,
         );
         icx.lowerer().add_sizedness_bounds(
             &mut bounds,
@@ -289,6 +292,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                     &mut bounds,
                     bound_vars,
                     PredicateFilter::All,
+                    OverlappingAsssocItemConstraints::Allowed,
                 );
                 predicates.extend(bounds);
             }
@@ -659,7 +663,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
 
     let self_param_ty = tcx.types.self_param;
     let mut bounds = Vec::new();
-    icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
+    icx.lowerer().lower_bounds(
+        self_param_ty,
+        superbounds,
+        &mut bounds,
+        ty::List::empty(),
+        filter,
+        OverlappingAsssocItemConstraints::Allowed,
+    );
     match filter {
         PredicateFilter::All
         | PredicateFilter::SelfOnly
@@ -984,6 +995,7 @@ impl<'tcx> ItemCtxt<'tcx> {
                 &mut bounds,
                 bound_vars,
                 filter,
+                OverlappingAsssocItemConstraints::Allowed,
             );
         }
 
@@ -1063,6 +1075,7 @@ pub(super) fn const_conditions<'tcx>(
                     &mut bounds,
                     bound_vars,
                     PredicateFilter::ConstIfConst,
+                    OverlappingAsssocItemConstraints::Allowed,
                 );
             }
             _ => {}
@@ -1083,6 +1096,7 @@ pub(super) fn const_conditions<'tcx>(
             &mut bounds,
             ty::List::empty(),
             PredicateFilter::ConstIfConst,
+            OverlappingAsssocItemConstraints::Allowed,
         );
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index b6d898886ac..a02990fe4ab 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -177,7 +177,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
                 let tables = tcx.typeck(item_def_id);
                 if let Some(guar) = tables.tainted_by_errors {
                     self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
-                } else if let Some(&hidden_type) = tables.concrete_opaque_types.get(&self.def_id) {
+                } else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) {
                     self.insert_found(hidden_type);
                 } else {
                     self.non_defining_use_in_defining_scope(item_def_id);
@@ -185,8 +185,8 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
             }
             DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
                 Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
-                Ok(concrete_opaque_types) => {
-                    if let Some(&hidden_type) = concrete_opaque_types.0.get(&self.def_id) {
+                Ok(hidden_types) => {
+                    if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) {
                         debug!(?hidden_type, "found constraint");
                         self.insert_found(hidden_type);
                     } else if let Err(guar) = tcx
@@ -247,7 +247,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
             let tables = tcx.typeck(owner_def_id);
             if let Some(guar) = tables.tainted_by_errors {
                 Ty::new_error(tcx, guar)
-            } else if let Some(hidden_ty) = tables.concrete_opaque_types.get(&def_id) {
+            } else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) {
                 hidden_ty.ty
             } else {
                 assert!(!tcx.next_trait_solver_globally());
@@ -261,8 +261,8 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
             }
         }
         DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
-            Ok(concrete_opaque_types) => {
-                if let Some(hidden_ty) = concrete_opaque_types.0.get(&def_id) {
+            Ok(hidden_types) => {
+                if let Some(hidden_ty) = hidden_types.0.get(&def_id) {
                     hidden_ty.ty
                 } else {
                     let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 366b3943a05..f8d0ea3e7bf 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeV
 use rustc_span::Span;
 use tracing::debug;
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub(crate) struct Parameter(pub u32);
 
 impl From<ty::ParamTy> for Parameter {
@@ -167,15 +167,20 @@ pub(crate) fn setup_constraining_predicates<'tcx>(
     // which is `O(nt)` where `t` is the depth of type-parameter constraints,
     // remembering that `t` should be less than 7 in practice.
     //
+    // FIXME(hkBst): the big-O bound above would be accurate for the number
+    // of calls to `parameters_for`, which itself is some O(complexity of type).
+    // That would make this potentially cubic instead of merely quadratic...
+    // ...unless we cache those `parameters_for` calls.
+    //
     // Basically, I iterate over all projections and swap every
     // "ready" projection to the start of the list, such that
     // all of the projections before `i` are topologically sorted
     // and constrain all the parameters in `input_parameters`.
     //
-    // In the example, `input_parameters` starts by containing `U` - which
-    // is constrained by the trait-ref - and so on the first pass we
+    // In the first example, `input_parameters` starts by containing `U`,
+    // which is constrained by the self type `U`. Then, on the first pass we
     // observe that `<U as Iterator>::Item = T` is a "ready" projection that
-    // constrains `T` and swap it to front. As it is the sole projection,
+    // constrains `T` and swap it to the front. As it is the sole projection,
     // no more swaps can take place afterwards, with the result being
     //   * <U as Iterator>::Item = T
     //   * T: Debug
@@ -193,33 +198,25 @@ pub(crate) fn setup_constraining_predicates<'tcx>(
         for j in i..predicates.len() {
             // Note that we don't have to care about binders here,
             // as the impl trait ref never contains any late-bound regions.
-            if let ty::ClauseKind::Projection(projection) = predicates[j].0.kind().skip_binder() {
-                // Special case: watch out for some kind of sneaky attempt
-                // to project out an associated type defined by this very
-                // trait.
-                let unbound_trait_ref = projection.projection_term.trait_ref(tcx);
-                if Some(unbound_trait_ref) == impl_trait_ref {
-                    continue;
-                }
-
-                // A projection depends on its input types and determines its output
-                // type. For example, if we have
-                //     `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
-                // Then the projection only applies if `T` is known, but it still
-                // does not determine `U`.
-                let inputs = parameters_for(tcx, projection.projection_term, true);
-                let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(p));
-                if !relies_only_on_inputs {
-                    continue;
-                }
+            if let ty::ClauseKind::Projection(projection) = predicates[j].0.kind().skip_binder() &&
+
+            // Special case: watch out for some kind of sneaky attempt to
+            // project out an associated type defined by this very trait.
+            !impl_trait_ref.is_some_and(|t| t == projection.projection_term.trait_ref(tcx)) &&
+
+            // A projection depends on its input types and determines its output
+            // type. For example, if we have
+            //     `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
+            // then the projection only applies if `T` is known, but it still
+            // does not determine `U`.
+                parameters_for(tcx, projection.projection_term, true).iter().all(|p| input_parameters.contains(p))
+            {
                 input_parameters.extend(parameters_for(tcx, projection.term, false));
-            } else {
-                continue;
+
+                predicates.swap(i, j);
+                i += 1;
+                changed = true;
             }
-            // fancy control flow to bypass borrow checker
-            predicates.swap(i, j);
-            i += 1;
-            changed = true;
         }
         debug!(
             "setup_constraining_predicates: predicates={:?} \
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 99dc8e6e522..8682fdc5494 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -21,7 +21,8 @@ use tracing::{debug, instrument};
 use super::errors::GenericsArgsErrExtend;
 use crate::errors;
 use crate::hir_ty_lowering::{
-    AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
+    AssocItemQSelf, FeedConstTy, HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter,
+    RegionInferReason,
 };
 
 #[derive(Debug, Default)]
@@ -338,6 +339,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
         bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
         predicate_filter: PredicateFilter,
+        overlapping_assoc_constraints: OverlappingAsssocItemConstraints,
     ) where
         'tcx: 'hir,
     {
@@ -362,6 +364,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         param_ty,
                         bounds,
                         predicate_filter,
+                        overlapping_assoc_constraints,
                     );
                 }
                 hir::GenericBound::Outlives(lifetime) => {
@@ -402,7 +405,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         trait_ref: ty::PolyTraitRef<'tcx>,
         constraint: &hir::AssocItemConstraint<'tcx>,
         bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
-        duplicates: &mut FxIndexMap<DefId, Span>,
+        duplicates: Option<&mut FxIndexMap<DefId, Span>>,
         path_span: Span,
         predicate_filter: PredicateFilter,
     ) -> Result<(), ErrorGuaranteed> {
@@ -458,17 +461,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             )
             .expect("failed to find associated item");
 
-        duplicates
-            .entry(assoc_item.def_id)
-            .and_modify(|prev_span| {
-                self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
-                    span: constraint.span,
-                    prev_span: *prev_span,
-                    item_name: constraint.ident,
-                    def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
-                });
-            })
-            .or_insert(constraint.span);
+        if let Some(duplicates) = duplicates {
+            duplicates
+                .entry(assoc_item.def_id)
+                .and_modify(|prev_span| {
+                    self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
+                        span: constraint.span,
+                        prev_span: *prev_span,
+                        item_name: constraint.ident,
+                        def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
+                    });
+                })
+                .or_insert(constraint.span);
+        }
 
         let projection_term = if let ty::AssocTag::Fn = assoc_tag {
             let bound_vars = tcx.late_bound_vars(constraint.hir_id);
@@ -600,6 +605,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             bounds,
                             projection_ty.bound_vars(),
                             predicate_filter,
+                            OverlappingAsssocItemConstraints::Allowed,
                         );
                     }
                     PredicateFilter::SelfOnly
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 81deb35920a..0a41659ec66 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -134,11 +134,12 @@ fn is_valid_cmse_inputs<'tcx>(
 
     // this type is only used for layout computation, which does not rely on regions
     let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
+    let fn_sig = tcx.erase_and_anonymize_regions(fn_sig);
 
     for (index, ty) in fn_sig.inputs().iter().enumerate() {
         let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?;
 
-        let align = layout.layout.align().abi.bytes();
+        let align = layout.layout.align().bytes();
         let size = layout.layout.size().bytes();
 
         accum += size;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
index c248cd7fec2..c0b13773089 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
@@ -23,7 +23,9 @@ use tracing::{debug, instrument};
 
 use super::HirTyLowerer;
 use crate::errors::SelfInTypeAlias;
-use crate::hir_ty_lowering::{GenericArgCountMismatch, PredicateFilter, RegionInferReason};
+use crate::hir_ty_lowering::{
+    GenericArgCountMismatch, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
+};
 
 impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// Lower a trait object type from the HIR to our internal notion of a type.
@@ -60,6 +62,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 dummy_self,
                 &mut user_written_bounds,
                 PredicateFilter::SelfOnly,
+                OverlappingAsssocItemConstraints::Forbidden,
             );
             if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
                 potential_assoc_types.extend(invalid_args);
@@ -157,10 +160,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 self.dcx()
                     .struct_span_err(
                         span,
-                        format!(
-                            "conflicting associated type bounds for `{item}` when \
-                            expanding trait alias"
-                        ),
+                        format!("conflicting associated type bounds for `{item}`"),
                     )
                     .with_span_label(
                         old_proj_span,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 9b198d04454..eb660804c2b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -332,6 +332,15 @@ pub(crate) enum GenericArgPosition {
     MethodCall,
 }
 
+/// Whether to allow duplicate associated iten constraints in a trait ref, e.g.
+/// `Trait<Assoc = Ty, Assoc = Ty>`. This is forbidden in `dyn Trait<...>`
+/// but allowed everywhere else.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub(crate) enum OverlappingAsssocItemConstraints {
+    Allowed,
+    Forbidden,
+}
+
 /// A marker denoting that the generic arguments that were
 /// provided did not match the respective generic parameters.
 #[derive(Clone, Debug)]
@@ -752,6 +761,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         self_ty: Ty<'tcx>,
         bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
         predicate_filter: PredicateFilter,
+        overlapping_assoc_item_constraints: OverlappingAsssocItemConstraints,
     ) -> GenericArgCountResult {
         let tcx = self.tcx();
 
@@ -908,7 +918,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
         }
 
-        let mut dup_constraints = FxIndexMap::default();
+        let mut dup_constraints = (overlapping_assoc_item_constraints
+            == OverlappingAsssocItemConstraints::Forbidden)
+            .then_some(FxIndexMap::default());
+
         for constraint in trait_segment.args().constraints {
             // Don't register any associated item constraints for negative bounds,
             // since we should have emitted an error for them earlier, and they
@@ -927,7 +940,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 poly_trait_ref,
                 constraint,
                 bounds,
-                &mut dup_constraints,
+                dup_constraints.as_mut(),
                 constraint.span,
                 predicate_filter,
             );
@@ -2484,6 +2497,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     &mut bounds,
                     ty::List::empty(),
                     PredicateFilter::All,
+                    OverlappingAsssocItemConstraints::Allowed,
                 );
                 self.add_sizedness_bounds(
                     &mut bounds,
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index b38639ed8c6..13c744ab461 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -275,7 +275,7 @@ fn check_duplicate_params<'tcx>(
     span: Span,
 ) -> Result<(), ErrorGuaranteed> {
     let mut base_params = cgp::parameters_for(tcx, parent_args, true);
-    base_params.sort_by_key(|param| param.0);
+    base_params.sort_unstable();
     if let (_, [duplicate, ..]) = base_params.partition_dedup() {
         let param = impl1_args[duplicate.0 as usize];
         return Err(tcx
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 833ce433d56..35253e4c291 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -611,19 +611,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         typeck_results.rvalue_scopes = rvalue_scopes;
     }
 
-    /// Unify the inference variables corresponding to coroutine witnesses, and save all the
-    /// predicates that were stalled on those inference variables.
-    ///
-    /// This process allows to conservatively save all predicates that do depend on the coroutine
-    /// interior types, for later processing by `check_coroutine_obligations`.
-    ///
-    /// We must not attempt to select obligations after this method has run, or risk query cycle
-    /// ICE.
+    /// Drain all obligations that are stalled on coroutines defined in this body.
     #[instrument(level = "debug", skip(self))]
-    pub(crate) fn resolve_coroutine_interiors(&self) {
-        // Try selecting all obligations that are not blocked on inference variables.
-        // Once we start unifying coroutine witnesses, trying to select obligations on them will
-        // trigger query cycle ICEs, as doing so requires MIR.
+    pub(crate) fn drain_stalled_coroutine_obligations(&self) {
+        // Make as much inference progress as possible before
+        // draining the stalled coroutine obligations as this may
+        // change obligations from being stalled on infer vars to
+        // being stalled on a coroutine.
         self.select_obligations_where_possible(|_| {});
 
         let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 7ca8580e098..c8943d4634e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2803,9 +2803,7 @@ impl<'a, 'b, 'tcx> ArgMatchingCtxt<'a, 'b, 'tcx> {
         if let Some((assoc, fn_sig)) = self.similar_assoc(call_name)
             && fn_sig.inputs()[1..]
                 .iter()
-                .zip(input_types.iter())
-                .all(|(expected, found)| self.may_coerce(*expected, *found))
-            && fn_sig.inputs()[1..].len() == input_types.len()
+                .eq_by(input_types, |expected, found| self.may_coerce(*expected, found))
         {
             let assoc_name = assoc.name();
             err.span_suggestion_verbose(
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 43a23822fd1..9f5a85b6926 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -5,6 +5,7 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
+#![feature(iter_order_by)]
 #![feature(never_type)]
 // tidy-alphabetical-end
 
@@ -242,18 +243,15 @@ fn typeck_with_inspect<'tcx>(
 
     debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
 
-    // This must be the last thing before `report_ambiguity_errors`.
-    fcx.resolve_coroutine_interiors();
-
-    debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
-
     // We need to handle opaque types before emitting ambiguity errors as applying
     // defining uses may guide type inference.
     if fcx.next_trait_solver() {
         fcx.handle_opaque_type_uses_next();
     }
 
-    fcx.select_obligations_where_possible(|_| {});
+    // This must be the last thing before `report_ambiguity_errors` below except `select_obligations_where_possible`.
+    // So don't put anything after this.
+    fcx.drain_stalled_coroutine_obligations();
     if fcx.infcx.tainted_by_errors().is_none() {
         fcx.report_ambiguity_errors();
     }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 024b9ee08c2..44602e62899 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1914,9 +1914,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(ref args) = call_args
                             && fn_sig.inputs()[1..]
                                 .iter()
-                                .zip(args.into_iter())
-                                .all(|(expected, found)| self.may_coerce(*expected, *found))
-                            && fn_sig.inputs()[1..].len() == args.len()
+                                .eq_by(args, |expected, found| self.may_coerce(*expected, *found))
                         {
                             err.span_suggestion_verbose(
                                 item_name.span,
diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs
index 5cefa506b5a..4c1fe69405e 100644
--- a/compiler/rustc_hir_typeck/src/opaque_types.rs
+++ b/compiler/rustc_hir_typeck/src/opaque_types.rs
@@ -15,7 +15,7 @@ use crate::FnCtxt;
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
     /// This takes all the opaque type uses during HIR typeck. It first computes
-    /// the concrete hidden type by iterating over all defining uses.
+    /// the hidden type by iterating over all defining uses.
     ///
     /// A use during HIR typeck is defining if all non-lifetime arguments are
     /// unique generic parameters and the hidden type does not reference any
@@ -35,8 +35,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         }
         debug!(?opaque_types);
 
-        self.compute_concrete_opaque_types(&opaque_types);
-        self.apply_computed_concrete_opaque_types(&opaque_types);
+        self.compute_definition_site_hidden_types(&opaque_types);
+        self.apply_definition_site_hidden_types(&opaque_types);
     }
 }
 
@@ -71,7 +71,7 @@ impl<'tcx> UsageKind<'tcx> {
 }
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
-    fn compute_concrete_opaque_types(
+    fn compute_definition_site_hidden_types(
         &mut self,
         opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     ) {
@@ -142,7 +142,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
 
             self.typeck_results
                 .borrow_mut()
-                .concrete_opaque_types
+                .hidden_types
                 .insert(def_id, OpaqueHiddenType::new_error(tcx, guar));
             self.set_tainted_by_errors(guar);
         }
@@ -161,7 +161,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         ) {
             match err {
                 NonDefiningUseReason::Tainted(guar) => {
-                    self.typeck_results.borrow_mut().concrete_opaque_types.insert(
+                    self.typeck_results.borrow_mut().hidden_types.insert(
                         opaque_type_key.def_id,
                         OpaqueHiddenType::new_error(self.tcx, guar),
                     );
@@ -197,20 +197,19 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         let prev = self
             .typeck_results
             .borrow_mut()
-            .concrete_opaque_types
+            .hidden_types
             .insert(opaque_type_key.def_id, hidden_type);
         assert!(prev.is_none());
         UsageKind::HasDefiningUse
     }
 
-    fn apply_computed_concrete_opaque_types(
+    fn apply_definition_site_hidden_types(
         &mut self,
         opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     ) {
         let tcx = self.tcx;
         for &(key, hidden_type) in opaque_types {
-            let expected =
-                *self.typeck_results.borrow_mut().concrete_opaque_types.get(&key.def_id).unwrap();
+            let expected = *self.typeck_results.borrow_mut().hidden_types.get(&key.def_id).unwrap();
 
             let expected = EarlyBinder::bind(expected.ty).instantiate(tcx, key.args);
             self.demand_eqtype(hidden_type.span, expected, hidden_type.ty);
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index d01eeb9a4b6..697029e55f7 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -550,13 +550,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     fn visit_opaque_types_next(&mut self) {
         let mut fcx_typeck_results = self.fcx.typeck_results.borrow_mut();
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
-        for hidden_ty in fcx_typeck_results.concrete_opaque_types.values() {
+        for hidden_ty in fcx_typeck_results.hidden_types.values() {
             assert!(!hidden_ty.has_infer());
         }
 
-        assert_eq!(self.typeck_results.concrete_opaque_types.len(), 0);
-        self.typeck_results.concrete_opaque_types =
-            mem::take(&mut fcx_typeck_results.concrete_opaque_types);
+        assert_eq!(self.typeck_results.hidden_types.len(), 0);
+        self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types);
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -588,7 +587,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 hidden_type.span,
                 DefiningScopeKind::HirTypeck,
             ) {
-                self.typeck_results.concrete_opaque_types.insert(
+                self.typeck_results.hidden_types.insert(
                     opaque_type_key.def_id,
                     ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
                 );
@@ -600,16 +599,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 DefiningScopeKind::HirTypeck,
             );
 
-            if let Some(prev) = self
-                .typeck_results
-                .concrete_opaque_types
-                .insert(opaque_type_key.def_id, hidden_type)
+            if let Some(prev) =
+                self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type)
             {
-                let entry = &mut self
-                    .typeck_results
-                    .concrete_opaque_types
-                    .get_mut(&opaque_type_key.def_id)
-                    .unwrap();
+                let entry =
+                    &mut self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap();
                 if prev.ty != hidden_type.ty {
                     if let Some(guar) = self.typeck_results.tainted_by_errors {
                         entry.ty = Ty::new_error(tcx, guar);
@@ -628,7 +622,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
         let recursive_opaques: Vec<_> = self
             .typeck_results
-            .concrete_opaque_types
+            .hidden_types
             .iter()
             .filter(|&(&def_id, hidden_ty)| {
                 hidden_ty
@@ -636,7 +630,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     .visit_with(&mut HasRecursiveOpaque {
                         def_id,
                         seen: Default::default(),
-                        opaques: &self.typeck_results.concrete_opaque_types,
+                        opaques: &self.typeck_results.hidden_types,
                         tcx,
                     })
                     .is_break()
@@ -651,7 +645,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 .with_code(E0720)
                 .emit();
             self.typeck_results
-                .concrete_opaque_types
+                .hidden_types
                 .insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
         }
     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index c9fc124d3bf..f3ebfde06ab 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -131,23 +131,6 @@ pub struct InferCtxtInner<'tcx> {
     /// `$0: 'static`. This will get checked later by regionck. (We
     /// can't generally check these things right away because we have
     /// to wait until types are resolved.)
-    ///
-    /// These are stored in a map keyed to the id of the innermost
-    /// enclosing fn body / static initializer expression. This is
-    /// because the location where the obligation was incurred can be
-    /// relevant with respect to which sublifetime assumptions are in
-    /// place. The reason that we store under the fn-id, and not
-    /// something more fine-grained, is so that it is easier for
-    /// regionck to be sure that it has found *all* the region
-    /// obligations (otherwise, it's easy to fail to walk to a
-    /// particular node-id).
-    ///
-    /// Before running `resolve_regions_and_report_errors`, the creator
-    /// of the inference context is expected to invoke
-    /// [`InferCtxt::process_registered_region_obligations`]
-    /// for each body-id in this map, which will process the
-    /// obligations within. This is expected to be done 'late enough'
-    /// that all type inference variables have been bound and so forth.
     region_obligations: Vec<TypeOutlivesConstraint<'tcx>>,
 
     /// The outlives bounds that we assume must hold about placeholders that
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index b989d419057..a640dcb1b4e 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -170,6 +170,10 @@ impl<'tcx> InferCtxt<'tcx> {
         std::mem::take(&mut self.inner.borrow_mut().region_obligations)
     }
 
+    pub fn clone_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
+        self.inner.borrow().region_obligations.clone()
+    }
+
     pub fn register_region_assumption(&self, assumption: ty::ArgOutlivesPredicate<'tcx>) {
         let mut inner = self.inner.borrow_mut();
         inner.undo_log.push(UndoLog::PushRegionAssumption);
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 761a5c80918..c1bba0b0197 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1122,18 +1122,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
 
     sess.time("layout_testing", || layout_test::test_layout(tcx));
     sess.time("abi_testing", || abi_test::test_abi(tcx));
-
-    // If `-Zvalidate-mir` is set, we also want to compute the final MIR for each item
-    // (either its `mir_for_ctfe` or `optimized_mir`) since that helps uncover any bugs
-    // in MIR optimizations that may only be reachable through codegen, or other codepaths
-    // that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts.
-    if tcx.sess.opts.unstable_opts.validate_mir {
-        sess.time("ensuring_final_MIR_is_computable", || {
-            tcx.par_hir_body_owners(|def_id| {
-                tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
-            });
-        });
-    }
 }
 
 /// Runs the type-checking, region checking and other miscellaneous analysis
@@ -1199,6 +1187,20 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
         // we will fail to emit overlap diagnostics. Thus we invoke it here unconditionally.
         let _ = tcx.all_diagnostic_items(());
     });
+
+    // If `-Zvalidate-mir` is set, we also want to compute the final MIR for each item
+    // (either its `mir_for_ctfe` or `optimized_mir`) since that helps uncover any bugs
+    // in MIR optimizations that may only be reachable through codegen, or other codepaths
+    // that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts.
+    // Nevertheless, wait after type checking is finished, as optimizing code that does not
+    // type-check is very prone to ICEs.
+    if tcx.sess.opts.unstable_opts.validate_mir {
+        sess.time("ensuring_final_MIR_is_computable", || {
+            tcx.par_hir_body_owners(|def_id| {
+                tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
+            });
+        });
+    }
 }
 
 /// Runs the codegen backend, after which the AST and analysis can
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 76ccd12797e..be2fd0787b9 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use std::any::Any;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -6,13 +7,20 @@ use std::{env, thread};
 
 use rustc_ast as ast;
 use rustc_attr_parsing::{ShouldEmit, validate_attr};
+use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder;
+use rustc_codegen_ssa::back::link::link_binary;
 use rustc_codegen_ssa::traits::CodegenBackend;
+use rustc_codegen_ssa::{CodegenResults, CrateInfo};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::jobserver::Proxy;
 use rustc_data_structures::sync;
 use rustc_errors::LintBuffer;
-use rustc_metadata::{DylibError, load_symbol_from_dylib};
-use rustc_middle::ty::CurrentGcx;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
+use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib};
+use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::ty::{CurrentGcx, TyCtxt};
+use rustc_session::config::{
+    Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple,
+};
 use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
 use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint};
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -316,12 +324,13 @@ pub fn get_codegen_backend(
         let backend = backend_name
             .or(target.default_codegen_backend.as_deref())
             .or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND"))
-            .unwrap_or("llvm");
+            .unwrap_or("dummy");
 
         match backend {
             filename if filename.contains('.') => {
                 load_backend_from_dylib(early_dcx, filename.as_ref())
             }
+            "dummy" => || Box::new(DummyCodegenBackend),
             #[cfg(feature = "llvm")]
             "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
             backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
@@ -334,6 +343,63 @@ pub fn get_codegen_backend(
     unsafe { load() }
 }
 
+struct DummyCodegenBackend;
+
+impl CodegenBackend for DummyCodegenBackend {
+    fn locale_resource(&self) -> &'static str {
+        ""
+    }
+
+    fn name(&self) -> &'static str {
+        "dummy"
+    }
+
+    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
+        Box::new(CodegenResults {
+            modules: vec![],
+            allocator_module: None,
+            crate_info: CrateInfo::new(tcx, String::new()),
+        })
+    }
+
+    fn join_codegen(
+        &self,
+        ongoing_codegen: Box<dyn Any>,
+        _sess: &Session,
+        _outputs: &OutputFilenames,
+    ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
+        (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default())
+    }
+
+    fn link(
+        &self,
+        sess: &Session,
+        codegen_results: CodegenResults,
+        metadata: EncodedMetadata,
+        outputs: &OutputFilenames,
+    ) {
+        // JUSTIFICATION: TyCtxt no longer available here
+        #[allow(rustc::bad_opt_access)]
+        if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) {
+            #[allow(rustc::untranslatable_diagnostic)]
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            sess.dcx().fatal(format!(
+                "crate type {} not supported by the dummy codegen backend",
+                sess.opts.crate_types[0],
+            ));
+        }
+
+        link_binary(
+            sess,
+            &ArArchiveBuilderBuilder,
+            codegen_results,
+            metadata,
+            outputs,
+            self.name(),
+        );
+    }
+}
+
 // This is used for rustdoc, but it uses similar machinery to codegen backend
 // loading, so we leave the code here. It is potentially useful for other tools
 // that want to invoke the rustc binary while linking to rustc as well.
@@ -542,6 +608,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu
                 stem,
                 None,
                 sess.io.temps_dir.clone(),
+                sess.opts.unstable_opts.split_dwarf_out_dir.clone(),
                 sess.opts.cg.extra_filename.clone(),
                 sess.opts.output_types.clone(),
             )
@@ -571,6 +638,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu
                 out_filestem,
                 ofile,
                 sess.io.temps_dir.clone(),
+                sess.opts.unstable_opts.split_dwarf_out_dir.clone(),
                 sess.opts.cg.extra_filename.clone(),
                 sess.opts.output_types.clone(),
             )
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 4a778125918..2b83ea24ac6 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1824,3 +1824,55 @@ extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() {
   return 6; // Default fallback depth
 }
 #endif
+
+// Statically assert that the fixed metadata kind IDs declared in
+// `metadata_kind.rs` match the ones actually used by LLVM.
+#define FIXED_MD_KIND(VARIANT, VALUE)                                          \
+  static_assert(::llvm::LLVMContext::VARIANT == VALUE);
+// Must be kept in sync with the corresponding list in `metadata_kind.rs`.
+FIXED_MD_KIND(MD_dbg, 0)
+FIXED_MD_KIND(MD_tbaa, 1)
+FIXED_MD_KIND(MD_prof, 2)
+FIXED_MD_KIND(MD_fpmath, 3)
+FIXED_MD_KIND(MD_range, 4)
+FIXED_MD_KIND(MD_tbaa_struct, 5)
+FIXED_MD_KIND(MD_invariant_load, 6)
+FIXED_MD_KIND(MD_alias_scope, 7)
+FIXED_MD_KIND(MD_noalias, 8)
+FIXED_MD_KIND(MD_nontemporal, 9)
+FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+FIXED_MD_KIND(MD_nonnull, 11)
+FIXED_MD_KIND(MD_dereferenceable, 12)
+FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+FIXED_MD_KIND(MD_make_implicit, 14)
+FIXED_MD_KIND(MD_unpredictable, 15)
+FIXED_MD_KIND(MD_invariant_group, 16)
+FIXED_MD_KIND(MD_align, 17)
+FIXED_MD_KIND(MD_loop, 18)
+FIXED_MD_KIND(MD_type, 19)
+FIXED_MD_KIND(MD_section_prefix, 20)
+FIXED_MD_KIND(MD_absolute_symbol, 21)
+FIXED_MD_KIND(MD_associated, 22)
+FIXED_MD_KIND(MD_callees, 23)
+FIXED_MD_KIND(MD_irr_loop, 24)
+FIXED_MD_KIND(MD_access_group, 25)
+FIXED_MD_KIND(MD_callback, 26)
+FIXED_MD_KIND(MD_preserve_access_index, 27)
+FIXED_MD_KIND(MD_vcall_visibility, 28)
+FIXED_MD_KIND(MD_noundef, 29)
+FIXED_MD_KIND(MD_annotation, 30)
+FIXED_MD_KIND(MD_nosanitize, 31)
+FIXED_MD_KIND(MD_func_sanitize, 32)
+FIXED_MD_KIND(MD_exclude, 33)
+FIXED_MD_KIND(MD_memprof, 34)
+FIXED_MD_KIND(MD_callsite, 35)
+FIXED_MD_KIND(MD_kcfi_type, 36)
+FIXED_MD_KIND(MD_pcsections, 37)
+FIXED_MD_KIND(MD_DIAssignID, 38)
+FIXED_MD_KIND(MD_coro_outside_frame, 39)
+FIXED_MD_KIND(MD_mmra, 40)
+FIXED_MD_KIND(MD_noalias_addrspace, 41)
+// If some fixed metadata kinds are not present and consistent in all supported
+// LLVM versions, it's fine to omit them from this list; in that case Rust-side
+// code cannot declare them as fixed IDs and must look them up by name instead.
+#undef FIXED_MD_KIND
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index fa6a2db38ef..feaad5bb96e 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -27,7 +27,7 @@ macro_rules! arena_types {
                     rustc_middle::mir::Body<'tcx>
                 >,
             [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
-            [decode] borrowck_result: rustc_middle::mir::ConcreteOpaqueTypes<'tcx>,
+            [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>,
             [] resolver: rustc_data_structures::steal::Steal<(
                 rustc_middle::ty::ResolverAstLowering,
                 std::sync::Arc<rustc_ast::Crate>,
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index a509c40c89c..2e6c9f207e2 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -84,11 +84,10 @@ impl Debug for CoroutineLayout<'_> {
     }
 }
 
-/// All the opaque types that are restricted to concrete types
-/// by this function. Unlike the value in `TypeckResults`, this has
-/// unerased regions.
+/// All the opaque types that have had their hidden type fully computed.
+/// Unlike the value in `TypeckResults`, this has unerased regions.
 #[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)]
-pub struct ConcreteOpaqueTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
+pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
 
 /// The result of the `mir_const_qualif` query.
 ///
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 326df9239aa..895c8c0295a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1244,7 +1244,7 @@ rustc_queries! {
 
     /// Borrow-checks the given typeck root, e.g. functions, const/static items,
     /// and its children, e.g. closures, inline consts.
-    query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
+    query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
         desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
     }
 
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 8dd80aab946..944bd9756a9 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -167,7 +167,7 @@ pub struct TypeckResults<'tcx> {
     /// We also store the type here, so that the compiler can use it as a hint
     /// for figuring out hidden types, even if they are only set in dead code
     /// (which doesn't show up in MIR).
-    pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+    pub hidden_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
@@ -250,7 +250,7 @@ impl<'tcx> TypeckResults<'tcx> {
             coercion_casts: Default::default(),
             used_trait_imports: Default::default(),
             tainted_by_errors: None,
-            concrete_opaque_types: Default::default(),
+            hidden_types: Default::default(),
             closure_min_captures: Default::default(),
             closure_fake_reads: Default::default(),
             rvalue_scopes: Default::default(),
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index e2f09fdcb4b..a3e9054fdcb 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -104,7 +104,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
         .expect("failed to build vtable representation");
     assert!(layout.is_sized(), "can't create a vtable for an unsized type");
     let size = layout.size.bytes();
-    let align = layout.align.abi.bytes();
+    let align = layout.align.bytes();
 
     let ptr_size = tcx.data_layout.pointer_size();
     let ptr_align = tcx.data_layout.pointer_align().abi;
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 5bd6fdcf485..35a21a2a834 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -3,6 +3,7 @@ use rustc_ast::InlineAsmOptions;
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, TyCtxt, layout};
+use rustc_span::sym;
 use rustc_target::spec::PanicStrategy;
 
 /// A pass that runs which is targeted at ensuring that codegen guarantees about
@@ -33,6 +34,19 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
             return;
         }
 
+        // Represent whether this compilation target fundamentally doesn't
+        // support unwinding at all at an ABI level. If this the target has no
+        // support for unwinding then cleanup actions, for example, are all
+        // unnecessary and can be considered unreachable.
+        //
+        // Currently this is only true for wasm targets on panic=abort when the
+        // `exception-handling` target feature is disabled. In such a
+        // configuration it's illegal to emit exception-related instructions so
+        // it's not possible to unwind.
+        let target_supports_unwinding = !(tcx.sess.target.is_like_wasm
+            && tcx.sess.panic_strategy() == PanicStrategy::Abort
+            && !tcx.asm_target_features(def_id).contains(&sym::exception_handling));
+
         // Here we test for this function itself whether its ABI allows
         // unwinding or not.
         let body_ty = tcx.type_of(def_id).skip_binder();
@@ -54,12 +68,18 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
             let Some(terminator) = &mut block.terminator else { continue };
             let span = terminator.source_info.span;
 
-            // If we see an `UnwindResume` terminator inside a function that cannot unwind, we need
-            // to replace it with `UnwindTerminate`.
-            if let TerminatorKind::UnwindResume = &terminator.kind
-                && !body_can_unwind
-            {
-                terminator.kind = TerminatorKind::UnwindTerminate(UnwindTerminateReason::Abi);
+            // If we see an `UnwindResume` terminator inside a function then:
+            //
+            // * If the target doesn't support unwinding at all, then this is an
+            //   unreachable block.
+            // * If the body cannot unwind, we need to replace it with
+            //   `UnwindTerminate`.
+            if let TerminatorKind::UnwindResume = &terminator.kind {
+                if !target_supports_unwinding {
+                    terminator.kind = TerminatorKind::Unreachable;
+                } else if !body_can_unwind {
+                    terminator.kind = TerminatorKind::UnwindTerminate(UnwindTerminateReason::Abi);
+                }
             }
 
             if block.is_cleanup {
@@ -93,8 +113,9 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
                 _ => continue,
             };
 
-            if !call_can_unwind {
-                // If this function call can't unwind, then there's no need for it
+            if !call_can_unwind || !target_supports_unwinding {
+                // If this function call can't unwind, or if the target doesn't
+                // support unwinding at all, then there's no need for it
                 // to have a landing pad. This means that we can remove any cleanup
                 // registered for it (and turn it into `UnwindAction::Unreachable`).
                 let cleanup = block.terminator_mut().unwind_mut().unwrap();
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 5c984984d3c..491e910ff6f 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -476,7 +476,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
                 };
                 let val = match null_op {
                     NullOp::SizeOf if layout.is_sized() => layout.size.bytes(),
-                    NullOp::AlignOf if layout.is_sized() => layout.align.abi.bytes(),
+                    NullOp::AlignOf if layout.is_sized() => layout.align.bytes(),
                     NullOp::OffsetOf(fields) => self
                         .ecx
                         .tcx
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index ebec3d12500..29f6879aacd 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -618,7 +618,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 }
                 let val = match null_op {
                     NullOp::SizeOf => arg_layout.size.bytes(),
-                    NullOp::AlignOf => arg_layout.align.abi.bytes(),
+                    NullOp::AlignOf => arg_layout.align.bytes(),
                     NullOp::OffsetOf(fields) => self
                         .ecx
                         .tcx
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index aaacc5866a2..5fffba55f17 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -609,7 +609,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 let op_layout = self.ecx.layout_of(ty).ok()?;
                 let val = match null_op {
                     NullOp::SizeOf => op_layout.size.bytes(),
-                    NullOp::AlignOf => op_layout.align.abi.bytes(),
+                    NullOp::AlignOf => op_layout.align.bytes(),
                     NullOp::OffsetOf(fields) => self
                         .tcx
                         .offset_of_subfield(self.typing_env, op_layout, fields.iter())
diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs
index d831ab50b1a..cc8ea76011b 100644
--- a/compiler/rustc_mir_transform/src/patch.rs
+++ b/compiler/rustc_mir_transform/src/patch.rs
@@ -11,6 +11,8 @@ use tracing::debug;
 /// once with `apply`. This is useful for MIR transformation passes.
 pub(crate) struct MirPatch<'tcx> {
     term_patch_map: FxHashMap<BasicBlock, TerminatorKind<'tcx>>,
+    /// Set of statements that should be replaced by `Nop`.
+    nop_statements: Vec<Location>,
     new_blocks: Vec<BasicBlockData<'tcx>>,
     new_statements: Vec<(Location, StatementKind<'tcx>)>,
     new_locals: Vec<LocalDecl<'tcx>>,
@@ -33,6 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
     pub(crate) fn new(body: &Body<'tcx>) -> Self {
         let mut result = MirPatch {
             term_patch_map: Default::default(),
+            nop_statements: vec![],
             new_blocks: vec![],
             new_statements: vec![],
             new_locals: vec![],
@@ -212,6 +215,15 @@ impl<'tcx> MirPatch<'tcx> {
         self.term_patch_map.insert(block, new);
     }
 
+    /// Mark given statement to be replaced by a `Nop`.
+    ///
+    /// This method only works on statements from the initial body, and cannot be used to remove
+    /// statements from `add_statement` or `add_assign`.
+    #[tracing::instrument(level = "debug", skip(self))]
+    pub(crate) fn nop_statement(&mut self, loc: Location) {
+        self.nop_statements.push(loc);
+    }
+
     /// Queues the insertion of a statement at a given location. The statement
     /// currently at that location, and all statements that follow, are shifted
     /// down. If multiple statements are queued for addition at the same
@@ -257,11 +269,8 @@ impl<'tcx> MirPatch<'tcx> {
         bbs.extend(self.new_blocks);
         body.local_decls.extend(self.new_locals);
 
-        // The order in which we patch terminators does not change the result.
-        #[allow(rustc::potential_query_instability)]
-        for (src, patch) in self.term_patch_map {
-            debug!("MirPatch: patching block {:?}", src);
-            bbs[src].terminator_mut().kind = patch;
+        for loc in self.nop_statements {
+            bbs[loc.block].statements[loc.statement_index].make_nop();
         }
 
         let mut new_statements = self.new_statements;
@@ -285,6 +294,17 @@ impl<'tcx> MirPatch<'tcx> {
                 .insert(loc.statement_index, Statement::new(source_info, stmt));
             delta += 1;
         }
+
+        // The order in which we patch terminators does not change the result.
+        #[allow(rustc::potential_query_instability)]
+        for (src, patch) in self.term_patch_map {
+            debug!("MirPatch: patching block {:?}", src);
+            let bb = &mut bbs[src];
+            if let TerminatorKind::Unreachable = patch {
+                bb.statements.clear();
+            }
+            bb.terminator_mut().kind = patch;
+        }
     }
 
     fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo {
diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs
index 886f4d6e509..ed94a058ec6 100644
--- a/compiler/rustc_mir_transform/src/simplify_branches.rs
+++ b/compiler/rustc_mir_transform/src/simplify_branches.rs
@@ -2,6 +2,8 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 use tracing::trace;
 
+use crate::patch::MirPatch;
+
 pub(super) enum SimplifyConstCondition {
     AfterConstProp,
     Final,
@@ -19,8 +21,10 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("Running SimplifyConstCondition on {:?}", body.source);
         let typing_env = body.typing_env(tcx);
-        'blocks: for block in body.basic_blocks_mut() {
-            for stmt in block.statements.iter_mut() {
+        let mut patch = MirPatch::new(body);
+
+        'blocks: for (bb, block) in body.basic_blocks.iter_enumerated() {
+            for (statement_index, stmt) in block.statements.iter().enumerate() {
                 // Simplify `assume` of a known value: either a NOP or unreachable.
                 if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
                     && let NonDivergingIntrinsic::Assume(discr) = intrinsic
@@ -28,17 +32,16 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
                     && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
                 {
                     if constant {
-                        stmt.make_nop();
+                        patch.nop_statement(Location { block: bb, statement_index });
                     } else {
-                        block.statements.clear();
-                        block.terminator_mut().kind = TerminatorKind::Unreachable;
+                        patch.patch_terminator(bb, TerminatorKind::Unreachable);
                         continue 'blocks;
                     }
                 }
             }
 
-            let terminator = block.terminator_mut();
-            terminator.kind = match terminator.kind {
+            let terminator = block.terminator();
+            let terminator = match terminator.kind {
                 TerminatorKind::SwitchInt {
                     discr: Operand::Constant(ref c), ref targets, ..
                 } => {
@@ -58,7 +61,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
                 },
                 _ => continue,
             };
+            patch.patch_terminator(bb, terminator);
         }
+        patch.apply(body);
     }
 
     fn is_required(&self) -> bool {
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index a2e6ef6f0fe..d58c264841c 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -473,7 +473,10 @@ where
         // fails to reach a fixpoint but ends up getting an error after
         // running for some additional step.
         //
-        // cc trait-system-refactor-initiative#105
+        // FIXME(@lcnr): While I believe an error here to be possible, we
+        // currently don't have any test which actually triggers it. @lqd
+        // created a minimization for an ICE in typenum, but that one no
+        // longer fails here. cc trait-system-refactor-initiative#105.
         let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
         let certainty = Certainty::Maybe { cause, opaque_types_jank: OpaqueTypesJank::AllGood };
         self.probe_trait_candidate(source)
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index c40739d12e6..9b3dc1f691f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -664,7 +664,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
 pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
     cx: I,
     self_ty: I::Ty,
-) -> Result<(ty::Binder<I, (I::FnInputTys, I::Ty)>, I::FunctionId, I::GenericArgs), NoSolution> {
+) -> Result<(ty::Binder<I, (I::Ty, I::Ty)>, I::FunctionId, I::GenericArgs), NoSolution> {
     match self_ty.kind() {
         ty::FnDef(def_id, args) => {
             let sig = cx.fn_sig(def_id);
@@ -673,7 +673,8 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
                 && cx.fn_is_const(def_id)
             {
                 Ok((
-                    sig.instantiate(cx, args).map_bound(|sig| (sig.inputs(), sig.output())),
+                    sig.instantiate(cx, args)
+                        .map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
                     def_id,
                     args,
                 ))
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index cb72c1cd92b..65a5edf6b72 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -234,12 +234,12 @@ where
         let self_ty = goal.predicate.self_ty();
         let (inputs_and_output, def_id, args) =
             structural_traits::extract_fn_def_from_const_callable(cx, self_ty)?;
+        let (inputs, output) = ecx.instantiate_binder_with_infer(inputs_and_output);
 
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        let output_is_sized_pred = inputs_and_output.map_bound(|(_, output)| {
-            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
-        });
+        let output_is_sized_pred =
+            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
         let requirements = cx
             .const_conditions(def_id.into())
             .iter_instantiated(cx, args)
@@ -251,15 +251,12 @@ where
             })
             .chain([(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))]);
 
-        let pred = inputs_and_output
-            .map_bound(|(inputs, _)| {
-                ty::TraitRef::new(
-                    cx,
-                    goal.predicate.def_id(),
-                    [goal.predicate.self_ty(), Ty::new_tup(cx, inputs.as_slice())],
-                )
-            })
-            .to_host_effect_clause(cx, goal.predicate.constness);
+        let pred = ty::Binder::dummy(ty::TraitRef::new(
+            cx,
+            goal.predicate.def_id(),
+            [goal.predicate.self_ty(), inputs],
+        ))
+        .to_host_effect_clause(cx, goal.predicate.constness);
 
         Self::probe_and_consider_implied_clause(
             ecx,
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 85110530ae9..f25003bbfe9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -633,28 +633,19 @@ where
     // the certainty of all the goals.
     #[instrument(level = "trace", skip(self))]
     pub(super) fn try_evaluate_added_goals(&mut self) -> Result<Certainty, NoSolution> {
-        let mut response = Ok(Certainty::overflow(false));
         for _ in 0..FIXPOINT_STEP_LIMIT {
-            // FIXME: This match is a bit ugly, it might be nice to change the inspect
-            // stuff to use a closure instead. which should hopefully simplify this a bit.
             match self.evaluate_added_goals_step() {
-                Ok(Some(cert)) => {
-                    response = Ok(cert);
-                    break;
-                }
                 Ok(None) => {}
+                Ok(Some(cert)) => return Ok(cert),
                 Err(NoSolution) => {
-                    response = Err(NoSolution);
-                    break;
+                    self.tainted = Err(NoSolution);
+                    return Err(NoSolution);
                 }
             }
         }
 
-        if response.is_err() {
-            self.tainted = Err(NoSolution);
-        }
-
-        response
+        debug!("try_evaluate_added_goals: encountered overflow");
+        Ok(Certainty::overflow(false))
     }
 
     /// Iterate over all added goals: returning `Ok(Some(_))` in case we can stop rerunning.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 653c59c5d42..0674b3d42ab 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -451,23 +451,22 @@ where
                     return ecx.forced_ambiguity(MaybeCause::Ambiguity);
                 }
             };
+        let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
 
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
-            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
-        });
+        let output_is_sized_pred =
+            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
 
-        let pred = tupled_inputs_and_output
-            .map_bound(|(inputs, output)| ty::ProjectionPredicate {
-                projection_term: ty::AliasTerm::new(
-                    cx,
-                    goal.predicate.def_id(),
-                    [goal.predicate.self_ty(), inputs],
-                ),
-                term: output.into(),
-            })
-            .upcast(cx);
+        let pred = ty::ProjectionPredicate {
+            projection_term: ty::AliasTerm::new(
+                cx,
+                goal.predicate.def_id(),
+                [goal.predicate.self_ty(), inputs],
+            ),
+            term: output.into(),
+        }
+        .upcast(cx);
 
         Self::probe_and_consider_implied_clause(
             ecx,
@@ -497,76 +496,56 @@ where
                 goal_kind,
                 env_region,
             )?;
+        let AsyncCallableRelevantTypes {
+            tupled_inputs_ty,
+            output_coroutine_ty,
+            coroutine_return_ty,
+        } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
 
         // A built-in `AsyncFn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
-            |AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
-                ty::TraitRef::new(
-                    cx,
-                    cx.require_trait_lang_item(SolverTraitLangItem::Sized),
-                    [output_ty],
-                )
-            },
+        let output_is_sized_pred = ty::TraitRef::new(
+            cx,
+            cx.require_trait_lang_item(SolverTraitLangItem::Sized),
+            [output_coroutine_ty],
         );
 
-        let pred = tupled_inputs_and_output_and_coroutine
-            .map_bound(
-                |AsyncCallableRelevantTypes {
-                     tupled_inputs_ty,
-                     output_coroutine_ty,
-                     coroutine_return_ty,
-                 }| {
-                    let (projection_term, term) = if cx
-                        .is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture)
-                    {
-                        (
-                            ty::AliasTerm::new(
-                                cx,
-                                goal.predicate.def_id(),
-                                [goal.predicate.self_ty(), tupled_inputs_ty],
-                            ),
-                            output_coroutine_ty.into(),
-                        )
-                    } else if cx
-                        .is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture)
-                    {
-                        (
-                            ty::AliasTerm::new(
-                                cx,
-                                goal.predicate.def_id(),
-                                [
-                                    I::GenericArg::from(goal.predicate.self_ty()),
-                                    tupled_inputs_ty.into(),
-                                    env_region.into(),
-                                ],
-                            ),
-                            output_coroutine_ty.into(),
-                        )
-                    } else if cx
-                        .is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput)
-                    {
-                        (
-                            ty::AliasTerm::new(
-                                cx,
-                                goal.predicate.def_id(),
-                                [
-                                    I::GenericArg::from(goal.predicate.self_ty()),
-                                    tupled_inputs_ty.into(),
-                                ],
-                            ),
-                            coroutine_return_ty.into(),
-                        )
-                    } else {
-                        panic!(
-                            "no such associated type in `AsyncFn*`: {:?}",
-                            goal.predicate.def_id()
-                        )
-                    };
-                    ty::ProjectionPredicate { projection_term, term }
-                },
-            )
-            .upcast(cx);
+        let (projection_term, term) =
+            if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture) {
+                (
+                    ty::AliasTerm::new(
+                        cx,
+                        goal.predicate.def_id(),
+                        [goal.predicate.self_ty(), tupled_inputs_ty],
+                    ),
+                    output_coroutine_ty.into(),
+                )
+            } else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture) {
+                (
+                    ty::AliasTerm::new(
+                        cx,
+                        goal.predicate.def_id(),
+                        [
+                            I::GenericArg::from(goal.predicate.self_ty()),
+                            tupled_inputs_ty.into(),
+                            env_region.into(),
+                        ],
+                    ),
+                    output_coroutine_ty.into(),
+                )
+            } else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput) {
+                (
+                    ty::AliasTerm::new(
+                        cx,
+                        goal.predicate.def_id(),
+                        [goal.predicate.self_ty(), tupled_inputs_ty],
+                    ),
+                    coroutine_return_ty.into(),
+                )
+            } else {
+                panic!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id())
+            };
+        let pred = ty::ProjectionPredicate { projection_term, term }.upcast(cx);
 
         Self::probe_and_consider_implied_clause(
             ecx,
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 3974114e9b4..e790ecd595b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -369,18 +369,16 @@ where
                     return ecx.forced_ambiguity(MaybeCause::Ambiguity);
                 }
             };
+        let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
 
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
-            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
-        });
+        let output_is_sized_pred =
+            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
 
-        let pred = tupled_inputs_and_output
-            .map_bound(|(inputs, _)| {
-                ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
-            })
-            .upcast(cx);
+        let pred =
+            ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
+                .upcast(cx);
         Self::probe_and_consider_implied_clause(
             ecx,
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
@@ -408,28 +406,26 @@ where
                 // This region doesn't matter because we're throwing away the coroutine type
                 Region::new_static(cx),
             )?;
+        let AsyncCallableRelevantTypes {
+            tupled_inputs_ty,
+            output_coroutine_ty,
+            coroutine_return_ty: _,
+        } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
 
         // A built-in `AsyncFn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
-            |AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
-                ty::TraitRef::new(
-                    cx,
-                    cx.require_trait_lang_item(SolverTraitLangItem::Sized),
-                    [output_coroutine_ty],
-                )
-            },
+        let output_is_sized_pred = ty::TraitRef::new(
+            cx,
+            cx.require_trait_lang_item(SolverTraitLangItem::Sized),
+            [output_coroutine_ty],
         );
 
-        let pred = tupled_inputs_and_output_and_coroutine
-            .map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| {
-                ty::TraitRef::new(
-                    cx,
-                    goal.predicate.def_id(),
-                    [goal.predicate.self_ty(), tupled_inputs_ty],
-                )
-            })
-            .upcast(cx);
+        let pred = ty::TraitRef::new(
+            cx,
+            goal.predicate.def_id(),
+            [goal.predicate.self_ty(), tupled_inputs_ty],
+        )
+        .upcast(cx);
         Self::probe_and_consider_implied_clause(
             ecx,
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 88b67d792de..c26c7b9122a 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -9,6 +9,7 @@
 #![feature(default_field_values)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
+#![feature(iter_order_by)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_parse/src/parser/tokenstream/tests.rs b/compiler/rustc_parse/src/parser/tokenstream/tests.rs
index 19b2c98f5af..63177a72744 100644
--- a/compiler/rustc_parse/src/parser/tokenstream/tests.rs
+++ b/compiler/rustc_parse/src/parser/tokenstream/tests.rs
@@ -15,7 +15,7 @@ fn sp(a: u32, b: u32) -> Span {
 }
 
 fn cmp_token_stream(a: &TokenStream, b: &TokenStream) -> bool {
-    a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.eq_unspanned(y))
+    a.iter().eq_by(b.iter(), |x, y| x.eq_unspanned(y))
 }
 
 #[test]
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index d9f8085083e..0652461e975 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -120,7 +120,7 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
 impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Type inference occasionally gives us opaque types in places where corresponding patterns
     /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
-    /// types, we use the corresponding concrete type if possible.
+    /// types, we use the corresponding hidden type if possible.
     // FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing
     // opaque types defined in a body.
     #[inline]
@@ -146,7 +146,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// know it.
     fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
         self.typeck_results
-            .concrete_opaque_types
+            .hidden_types
             .get(&key.def_id)
             .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
     }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 51489019950..4415300777f 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -901,6 +901,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 binding,
                 if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
                 parent_scope,
+                module,
                 finalize,
                 shadowing,
             );
@@ -1025,6 +1026,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         binding: Option<NameBinding<'ra>>,
         shadowed_glob: Option<NameBinding<'ra>>,
         parent_scope: &ParentScope<'ra>,
+        module: Module<'ra>,
         finalize: Finalize,
         shadowing: Shadowing,
     ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
@@ -1076,6 +1078,37 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
         }
 
+        // If we encounter a re-export for a type with private fields, it will not be able to
+        // be constructed through this re-export. We track that case here to expand later
+        // privacy errors with appropriate information.
+        if let Res::Def(_, def_id) = binding.res() {
+            let struct_ctor = match def_id.as_local() {
+                Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
+                None => {
+                    let ctor = self.cstore().ctor_untracked(def_id);
+                    ctor.map(|(ctor_kind, ctor_def_id)| {
+                        let ctor_res = Res::Def(
+                            DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
+                            ctor_def_id,
+                        );
+                        let ctor_vis = self.tcx.visibility(ctor_def_id);
+                        let field_visibilities = self
+                            .tcx
+                            .associated_item_def_ids(def_id)
+                            .iter()
+                            .map(|field_id| self.tcx.visibility(field_id))
+                            .collect();
+                        (ctor_res, ctor_vis, field_visibilities)
+                    })
+                }
+            };
+            if let Some((_, _, fields)) = struct_ctor
+                && fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
+            {
+                self.inaccessible_ctor_reexport.insert(path_span, binding.span);
+            }
+        }
+
         self.record_use(ident, binding, used);
         return Ok(binding);
     }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 9e3c0938836..8c2ddda7f98 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1942,44 +1942,77 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                     return true;
                 };
 
+                let update_message =
+                    |this: &mut Self, err: &mut Diag<'_>, source: &PathSource<'_, '_, '_>| {
+                        match source {
+                            // e.g. `if let Enum::TupleVariant(field1, field2) = _`
+                            PathSource::TupleStruct(_, pattern_spans) => {
+                                err.primary_message(
+                                "cannot match against a tuple struct which contains private fields",
+                            );
+
+                                // Use spans of the tuple struct pattern.
+                                Some(Vec::from(*pattern_spans))
+                            }
+                            // e.g. `let _ = Enum::TupleVariant(field1, field2);`
+                            PathSource::Expr(Some(Expr {
+                                kind: ExprKind::Call(path, args),
+                                span: call_span,
+                                ..
+                            })) => {
+                                err.primary_message(
+                                "cannot initialize a tuple struct which contains private fields",
+                            );
+                                this.suggest_alternative_construction_methods(
+                                    def_id,
+                                    err,
+                                    path.span,
+                                    *call_span,
+                                    &args[..],
+                                );
+                                // Use spans of the tuple struct definition.
+                                this.r
+                                    .field_idents(def_id)
+                                    .map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
+                            }
+                            _ => None,
+                        }
+                    };
                 let is_accessible = self.r.is_accessible_from(ctor_vis, self.parent_scope.module);
+                if let Some(use_span) = self.r.inaccessible_ctor_reexport.get(&span)
+                    && is_accessible
+                {
+                    err.span_note(
+                        *use_span,
+                        "the type is accessed through this re-export, but the type's constructor \
+                         is not visible in this import's scope due to private fields",
+                    );
+                    if is_accessible
+                        && fields
+                            .iter()
+                            .all(|vis| self.r.is_accessible_from(*vis, self.parent_scope.module))
+                    {
+                        err.span_suggestion_verbose(
+                            span,
+                            "the type can be constructed directly, because its fields are \
+                             available from the current scope",
+                            // Using `tcx.def_path_str` causes the compiler to hang.
+                            // We don't need to handle foreign crate types because in that case you
+                            // can't access the ctor either way.
+                            format!(
+                                "crate{}", // The method already has leading `::`.
+                                self.r.tcx.def_path(def_id).to_string_no_crate_verbose(),
+                            ),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                    update_message(self, err, &source);
+                }
                 if !is_expected(ctor_def) || is_accessible {
                     return true;
                 }
 
-                let field_spans = match source {
-                    // e.g. `if let Enum::TupleVariant(field1, field2) = _`
-                    PathSource::TupleStruct(_, pattern_spans) => {
-                        err.primary_message(
-                            "cannot match against a tuple struct which contains private fields",
-                        );
-
-                        // Use spans of the tuple struct pattern.
-                        Some(Vec::from(pattern_spans))
-                    }
-                    // e.g. `let _ = Enum::TupleVariant(field1, field2);`
-                    PathSource::Expr(Some(Expr {
-                        kind: ExprKind::Call(path, args),
-                        span: call_span,
-                        ..
-                    })) => {
-                        err.primary_message(
-                            "cannot initialize a tuple struct which contains private fields",
-                        );
-                        self.suggest_alternative_construction_methods(
-                            def_id,
-                            err,
-                            path.span,
-                            *call_span,
-                            &args[..],
-                        );
-                        // Use spans of the tuple struct definition.
-                        self.r
-                            .field_idents(def_id)
-                            .map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
-                    }
-                    _ => None,
-                };
+                let field_spans = update_message(self, err, &source);
 
                 if let Some(spans) =
                     field_spans.filter(|spans| spans.len() > 0 && fields.len() == spans.len())
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 8959068b2a6..b44b1c966a4 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1167,6 +1167,11 @@ pub struct Resolver<'ra, 'tcx> {
     /// Crate-local macro expanded `macro_export` referred to by a module-relative path.
     macro_expanded_macro_export_errors: BTreeSet<(Span, Span)> = BTreeSet::new(),
 
+    /// When a type is re-exported that has an inaccessible constructor because it has fields that
+    /// are inaccessible from the import's scope, we mark that as the type won't be able to be built
+    /// through the re-export. We use this information to extend the existing diagnostic.
+    inaccessible_ctor_reexport: FxHashMap<Span, Span>,
+
     arenas: &'ra ResolverArenas<'ra>,
     dummy_binding: NameBinding<'ra>,
     builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
@@ -1595,6 +1600,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             glob_map: Default::default(),
             used_imports: FxHashSet::default(),
             maybe_unused_trait_imports: Default::default(),
+            inaccessible_ctor_reexport: Default::default(),
 
             arenas,
             dummy_binding: arenas.new_pub_res_binding(Res::Err, DUMMY_SP, LocalExpnId::ROOT),
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 811f2890fe3..d1426ff55fb 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1195,6 +1195,7 @@ pub struct OutputFilenames {
     filestem: String,
     pub single_output_file: Option<OutFileName>,
     temps_directory: Option<PathBuf>,
+    explicit_dwo_out_directory: Option<PathBuf>,
     pub outputs: OutputTypes,
 }
 
@@ -1227,6 +1228,7 @@ impl OutputFilenames {
         out_filestem: String,
         single_output_file: Option<OutFileName>,
         temps_directory: Option<PathBuf>,
+        explicit_dwo_out_directory: Option<PathBuf>,
         extra: String,
         outputs: OutputTypes,
     ) -> Self {
@@ -1234,6 +1236,7 @@ impl OutputFilenames {
             out_directory,
             single_output_file,
             temps_directory,
+            explicit_dwo_out_directory,
             outputs,
             crate_stem: format!("{out_crate_name}{extra}"),
             filestem: format!("{out_filestem}{extra}"),
@@ -1283,7 +1286,14 @@ impl OutputFilenames {
         codegen_unit_name: &str,
         invocation_temp: Option<&str>,
     ) -> PathBuf {
-        self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp)
+        let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp);
+        if let Some(dwo_out) = &self.explicit_dwo_out_directory {
+            let mut o = dwo_out.clone();
+            o.push(p.file_name().unwrap());
+            o
+        } else {
+            p
+        }
     }
 
     /// Like `temp_path`, but also supports things where there is no corresponding
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index f3d91ce4a5d..a72f6201dce 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -259,11 +259,11 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
     });
     let mut has_atomic = false;
     for (i, align) in [
-        (8, layout.i8_align.abi),
-        (16, layout.i16_align.abi),
-        (32, layout.i32_align.abi),
-        (64, layout.i64_align.abi),
-        (128, layout.i128_align.abi),
+        (8, layout.i8_align),
+        (16, layout.i16_align),
+        (32, layout.i32_align),
+        (64, layout.i64_align),
+        (128, layout.i128_align),
     ] {
         if i >= sess.target.min_atomic_width() && i <= sess.target.max_atomic_width() {
             if !has_atomic {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 732cf61effc..6dd90546de1 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2634,6 +2634,8 @@ written to standard error output)"),
                  file which is ignored by the linker
         `single`: sections which do not require relocation are written into object file but ignored
                   by the linker"),
+    split_dwarf_out_dir : Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
+        "location for writing split DWARF objects (`.dwo`) if enabled"),
     split_lto_unit: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable LTO unit splitting (default: no)"),
     src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 63b0de377c9..b34a64108e3 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -940,6 +940,7 @@ symbols! {
         ermsb_target_feature,
         exact_div,
         except,
+        exception_handling: "exception-handling",
         exchange_malloc,
         exclusive_range_pattern,
         exhaustive_integer_patterns,
diff --git a/compiler/rustc_target/src/callconv/arm.rs b/compiler/rustc_target/src/callconv/arm.rs
index 70830fa07b6..abc9a404e2e 100644
--- a/compiler/rustc_target/src/callconv/arm.rs
+++ b/compiler/rustc_target/src/callconv/arm.rs
@@ -77,7 +77,7 @@ where
         }
     }
 
-    let align = arg.layout.align.abi.bytes();
+    let align = arg.layout.align.bytes();
     let total = arg.layout.size;
     arg.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, total));
 }
diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs
index 9213d73e24e..bc3c9601fa3 100644
--- a/compiler/rustc_target/src/callconv/loongarch.rs
+++ b/compiler/rustc_target/src/callconv/loongarch.rs
@@ -322,7 +322,7 @@ fn classify_arg<'a, Ty, C>(
     }
 
     let total = arg.layout.size;
-    let align = arg.layout.align.abi.bits();
+    let align = arg.layout.align.bits();
 
     // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
     // the argument list with the address."
diff --git a/compiler/rustc_target/src/callconv/mips.rs b/compiler/rustc_target/src/callconv/mips.rs
index 48a01da865b..8ffd7bd1778 100644
--- a/compiler/rustc_target/src/callconv/mips.rs
+++ b/compiler/rustc_target/src/callconv/mips.rs
@@ -24,7 +24,7 @@ where
     }
     let dl = cx.data_layout();
     let size = arg.layout.size;
-    let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
+    let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align);
 
     if arg.layout.is_aggregate() {
         let pad_i32 = !offset.is_aligned(align);
diff --git a/compiler/rustc_target/src/callconv/mips64.rs b/compiler/rustc_target/src/callconv/mips64.rs
index 0209838bec1..8386a15933c 100644
--- a/compiler/rustc_target/src/callconv/mips64.rs
+++ b/compiler/rustc_target/src/callconv/mips64.rs
@@ -110,9 +110,9 @@ where
                 // We only care about aligned doubles
                 if let BackendRepr::Scalar(scalar) = field.backend_repr {
                     if scalar.primitive() == Primitive::Float(Float::F64) {
-                        if offset.is_aligned(dl.f64_align.abi) {
+                        if offset.is_aligned(dl.f64_align) {
                             // Insert enough integers to cover [last_offset, offset)
-                            assert!(last_offset.is_aligned(dl.f64_align.abi));
+                            assert!(last_offset.is_aligned(dl.f64_align));
                             for _ in 0..((offset - last_offset).bits() / 64)
                                 .min((prefix.len() - prefix_index) as u64)
                             {
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 7a7c63c475b..c59af581a1f 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -332,7 +332,7 @@ impl CastTarget {
         self.prefix
             .iter()
             .filter_map(|x| x.map(|reg| reg.align(cx)))
-            .fold(cx.data_layout().aggregate_align.abi.max(self.rest.align(cx)), |acc, align| {
+            .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), |acc, align| {
                 acc.max(align)
             })
     }
diff --git a/compiler/rustc_target/src/callconv/nvptx64.rs b/compiler/rustc_target/src/callconv/nvptx64.rs
index 44977de7fcb..dc32dd87a7e 100644
--- a/compiler/rustc_target/src/callconv/nvptx64.rs
+++ b/compiler/rustc_target/src/callconv/nvptx64.rs
@@ -21,7 +21,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
 
 /// the pass mode used for aggregates in arg and ret position
 fn classify_aggregate<Ty>(arg: &mut ArgAbi<'_, Ty>) {
-    let align_bytes = arg.layout.align.abi.bytes();
+    let align_bytes = arg.layout.align.bytes();
     let size = arg.layout.size;
 
     let reg = match align_bytes {
@@ -60,7 +60,7 @@ where
     //     "`extern \"ptx-kernel\"` doesn't allow passing types other than primitives and structs"
     // );
 
-    let align_bytes = arg.layout.align.abi.bytes();
+    let align_bytes = arg.layout.align.bytes();
 
     let unit = match align_bytes {
         1 => Reg::i8(),
diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs
index 89ec85e4b66..be1d13816ef 100644
--- a/compiler/rustc_target/src/callconv/powerpc64.rs
+++ b/compiler/rustc_target/src/callconv/powerpc64.rs
@@ -89,7 +89,7 @@ where
         // Aggregates larger than i64 should be padded at the tail to fill out a whole number
         // of i64s or i128s, depending on the aggregate alignment. Always use an array for
         // this, even if there is only a single element.
-        let reg = if arg.layout.align.abi.bytes() > 8 { Reg::i128() } else { Reg::i64() };
+        let reg = if arg.layout.align.bytes() > 8 { Reg::i128() } else { Reg::i64() };
         arg.cast_to(Uniform::consecutive(
             reg,
             size.align_to(Align::from_bytes(reg.size.bytes()).unwrap()),
diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs
index 161e2c1645f..16de3fe070d 100644
--- a/compiler/rustc_target/src/callconv/riscv.rs
+++ b/compiler/rustc_target/src/callconv/riscv.rs
@@ -328,7 +328,7 @@ fn classify_arg<'a, Ty, C>(
     }
 
     let total = arg.layout.size;
-    let align = arg.layout.align.abi.bits();
+    let align = arg.layout.align.bits();
 
     // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
     // the argument list with the address."
diff --git a/compiler/rustc_target/src/callconv/sparc.rs b/compiler/rustc_target/src/callconv/sparc.rs
index 48a01da865b..8ffd7bd1778 100644
--- a/compiler/rustc_target/src/callconv/sparc.rs
+++ b/compiler/rustc_target/src/callconv/sparc.rs
@@ -24,7 +24,7 @@ where
     }
     let dl = cx.data_layout();
     let size = arg.layout.size;
-    let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
+    let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align);
 
     if arg.layout.is_aggregate() {
         let pad_i32 = !offset.is_aligned(align);
diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs
index ecc9067ced3..62c8ed1dc21 100644
--- a/compiler/rustc_target/src/callconv/sparc64.rs
+++ b/compiler/rustc_target/src/callconv/sparc64.rs
@@ -29,7 +29,7 @@ where
 
     data.has_float = true;
 
-    if !data.last_offset.is_aligned(dl.f64_align.abi) && data.last_offset < offset {
+    if !data.last_offset.is_aligned(dl.f64_align) && data.last_offset < offset {
         if data.prefix_index == data.prefix.len() {
             return data;
         }
diff --git a/compiler/rustc_target/src/callconv/xtensa.rs b/compiler/rustc_target/src/callconv/xtensa.rs
index a73a70a1a0c..561ee98787d 100644
--- a/compiler/rustc_target/src/callconv/xtensa.rs
+++ b/compiler/rustc_target/src/callconv/xtensa.rs
@@ -48,7 +48,7 @@ where
     }
 
     let size = arg.layout.size.bits();
-    let needed_align = arg.layout.align.abi.bits();
+    let needed_align = arg.layout.align.bits();
     let mut must_use_stack = false;
 
     // Determine the number of GPRs needed to pass the current argument
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index ecc74264160..39e604bcce7 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -158,12 +158,22 @@ pub(crate) fn base(
             SplitDebuginfo::Off,
         ]),
 
+        // Tell the linker that we would like it to avoid irreproducible binaries.
+        //
         // This environment variable is pretty magical but is intended for
         // producing deterministic builds. This was first discovered to be used
         // by the `ar` tool as a way to control whether or not mtime entries in
-        // the archive headers were set to zero or not. It appears that
-        // eventually the linker got updated to do the same thing and now reads
-        // this environment variable too in recent versions.
+        // the archive headers were set to zero or not.
+        //
+        // In `ld64-351.8`, shipped with Xcode 9.3, the linker was updated to
+        // read this flag too. Linker versions that don't support this flag
+        // may embed modification timestamps in binaries (especially in debug
+        // information).
+        //
+        // A cleaner alternative would be to pass the `-reproducible` flag,
+        // though that is only supported since `ld64-819.6` shipped with Xcode
+        // 14, which is too new for our minimum supported version:
+        // https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#host-tooling
         //
         // For some more info see the commentary on #47086
         link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index d485eb7266b..bec12750728 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1897,6 +1897,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         other: bool,
         param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
+        let parent_map = self.tcx.visible_parent_map(());
         let alternative_candidates = |def_id: DefId| {
             let mut impl_candidates: Vec<_> = self
                 .tcx
@@ -1921,7 +1922,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         // FIXME(compiler-errors): This could be generalized, both to
                         // be more granular, and probably look past other `#[fundamental]`
                         // types, too.
-                        self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx)
+                        let mut did = def.did();
+                        if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
+                            // don't suggest foreign `#[doc(hidden)]` types
+                            if !did.is_local() {
+                                while let Some(parent) = parent_map.get(&did) {
+                                    if self.tcx.is_doc_hidden(did) {
+                                        return false;
+                                    }
+                                    did = *parent;
+                                }
+                            }
+                            true
+                        } else {
+                            false
+                        }
                     } else {
                         true
                     }
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 b3d1b8e3888..9052031ce4f 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -21,7 +21,7 @@ use rustc_infer::traits::{
 };
 use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::{ErrorGuaranteed, ExpnKind, Span};
+use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span};
 use tracing::{info, instrument};
 
 pub use self::overflow::*;
@@ -154,9 +154,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             })
             .collect();
 
-        // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last.
+        // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last,
+        // and `Subtype` obligations from `FormatLiteral` desugarings come first.
         // This lets us display diagnostics with more relevant type information and hide redundant
         // E0282 errors.
+        #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
+        enum ErrorSortKey {
+            SubtypeFormat(usize, usize),
+            OtherKind,
+            SizedTrait,
+            MetaSizedTrait,
+            PointeeSizedTrait,
+            Coerce,
+            WellFormed,
+        }
         errors.sort_by_key(|e| {
             let maybe_sizedness_did = match e.obligation.predicate.kind().skip_binder() {
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred.def_id()),
@@ -165,12 +176,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             };
 
             match e.obligation.predicate.kind().skip_binder() {
-                _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => 1,
-                _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => 2,
-                _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => 3,
-                ty::PredicateKind::Coerce(_) => 4,
-                ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 5,
-                _ => 0,
+                ty::PredicateKind::Subtype(_)
+                    if matches!(
+                        e.obligation.cause.span.desugaring_kind(),
+                        Some(DesugaringKind::FormatLiteral { .. })
+                    ) =>
+                {
+                    let (_, row, col, ..) =
+                        self.tcx.sess.source_map().span_to_location_info(e.obligation.cause.span);
+                    ErrorSortKey::SubtypeFormat(row, col)
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => {
+                    ErrorSortKey::SizedTrait
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => {
+                    ErrorSortKey::MetaSizedTrait
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => {
+                    ErrorSortKey::PointeeSizedTrait
+                }
+                ty::PredicateKind::Coerce(_) => ErrorSortKey::Coerce,
+                ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
+                    ErrorSortKey::WellFormed
+                }
+                _ => ErrorSortKey::OtherKind,
             }
         });
 
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index 2b33b8ac9f8..debc4fda15a 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -77,6 +77,8 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// Prefer this method over `resolve_regions_with_normalize`, unless you are
     /// doing something specific for normalization.
+    ///
+    /// This function assumes that all infer variables are already constrained.
     fn resolve_regions(
         &self,
         body_id: LocalDefId,
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 7540cbe3fd1..e55ffb4d5fd 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -55,6 +55,12 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
     span: Span,
     disable_implied_bounds_hack: bool,
 ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
+    // Inside mir borrowck, each computation starts with an empty list.
+    assert!(
+        ocx.infcx.inner.borrow().region_obligations().is_empty(),
+        "compute_implied_outlives_bounds assumes region obligations are empty before starting"
+    );
+
     let normalize_ty = |ty| -> Result<_, NoSolution> {
         // We must normalize the type so we can compute the right outlives components.
         // for example, if we have some constrained param type like `T: Trait<Out = U>`,
@@ -143,7 +149,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
         && ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
     {
         for TypeOutlivesConstraint { sup_type, sub_region, .. } in
-            ocx.infcx.take_registered_region_obligations()
+            ocx.infcx.clone_registered_region_obligations()
         {
             let mut components = smallvec![];
             push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 1dd31990ab7..fb4f28412d4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2359,7 +2359,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 if self.infcx.can_define_opaque_ty(def_id) {
                     unreachable!()
                 } else {
-                    // We can resolve the `impl Trait` to its concrete type,
+                    // We can resolve the opaque type to its hidden type,
                     // which enforces a DAG between the functions requiring
                     // the auto trait bounds in question.
                     match self.tcx().type_of_opaque(def_id) {
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index a02e8ecf613..7f626e8c4e8 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -361,7 +361,7 @@ pub(crate) mod rustc {
 
                 ty::Ref(region, ty, mutability) => {
                     let layout = layout_of(cx, *ty)?;
-                    let referent_align = layout.align.abi.bytes_usize();
+                    let referent_align = layout.align.bytes_usize();
                     let referent_size = layout.size.bytes_usize();
 
                     Ok(Tree::Ref(Reference {
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index f59bc2117d5..317d101dafe 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -795,7 +795,7 @@ fn variant_info_for_adt<'tcx>(
                     name,
                     offset: offset.bytes(),
                     size: field_layout.size.bytes(),
-                    align: field_layout.align.abi.bytes(),
+                    align: field_layout.align.bytes(),
                     type_name: None,
                 }
             })
@@ -804,7 +804,7 @@ fn variant_info_for_adt<'tcx>(
         VariantInfo {
             name: n,
             kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact },
-            align: layout.align.abi.bytes(),
+            align: layout.align.bytes(),
             size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
             fields: field_info,
         }
@@ -877,7 +877,7 @@ fn variant_info_for_coroutine<'tcx>(
                 name: *name,
                 offset: offset.bytes(),
                 size: field_layout.size.bytes(),
-                align: field_layout.align.abi.bytes(),
+                align: field_layout.align.bytes(),
                 type_name: None,
             }
         })
@@ -905,7 +905,7 @@ fn variant_info_for_coroutine<'tcx>(
                         }),
                         offset: offset.bytes(),
                         size: field_layout.size.bytes(),
-                        align: field_layout.align.abi.bytes(),
+                        align: field_layout.align.bytes(),
                         // Include the type name if there is no field name, or if the name is the
                         // __awaitee placeholder symbol which means a child future being `.await`ed.
                         type_name: (field_name.is_none() || field_name == Some(sym::__awaitee))
@@ -946,7 +946,7 @@ fn variant_info_for_coroutine<'tcx>(
                 name: Some(Symbol::intern(&ty::CoroutineArgs::variant_name(variant_idx))),
                 kind: SizeKind::Exact,
                 size: variant_size.bytes(),
-                align: variant_layout.align.abi.bytes(),
+                align: variant_layout.align.bytes(),
                 fields,
             }
         })
diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs
index 1311ee31182..b768269215f 100644
--- a/compiler/rustc_ty_utils/src/layout/invariant.rs
+++ b/compiler/rustc_ty_utils/src/layout/invariant.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout};
 pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
     let tcx = cx.tcx();
 
-    if !layout.size.bytes().is_multiple_of(layout.align.abi.bytes()) {
+    if !layout.size.bytes().is_multiple_of(layout.align.bytes()) {
         bug!("size is not a multiple of align, in the following layout:\n{layout:#?}");
     }
     if layout.size.bytes() >= tcx.data_layout.obj_size_bound() {
@@ -300,8 +300,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
                 if variant.align.abi > layout.align.abi {
                     bug!(
                         "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}",
-                        layout.align.abi.bytes(),
-                        variant.align.abi.bytes(),
+                        layout.align.bytes(),
+                        variant.align.bytes(),
                     )
                 }
                 // Skip empty variants.
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs
index 24704c5bb53..ea3903d401e 100644
--- a/compiler/rustc_type_ir/src/flags.rs
+++ b/compiler/rustc_type_ir/src/flags.rs
@@ -347,6 +347,7 @@ impl<I: Interner> FlagComputation<I> {
 
     fn add_ty_pat(&mut self, pat: <I as Interner>::Pat) {
         self.add_flags(pat.flags());
+        self.add_exclusive_binder(pat.outer_exclusive_binder());
     }
 
     fn add_predicate(&mut self, binder: ty::Binder<I, ty::PredicateKind<I>>) {
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index f743b84bce6..feafcee7bad 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -80,7 +80,7 @@ pub enum TypingMode<I: Interner> {
     /// the old solver as well.
     PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
     /// After analysis, mostly during codegen and MIR optimizations, we're able to
-    /// reveal all opaque types. As the concrete type should *never* be observable
+    /// reveal all opaque types. As the hidden type should *never* be observable
     /// directly by the user, this should not be used by checks which may expose
     /// such details to the user.
     ///
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 9dfbbd91322..adcb444d08c 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -2413,7 +2413,7 @@ impl<K, V> Default for BTreeMap<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: PartialEq, V: PartialEq, A: Allocator + Clone> PartialEq for BTreeMap<K, V, A> {
     fn eq(&self, other: &BTreeMap<K, V, A>) -> bool {
-        self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
+        self.iter().eq(other)
     }
 }
 
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 627e5c7f976..023238a00db 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -277,7 +277,9 @@ use crate::vec::Vec;
 // This is repr(C) to future-proof against possible field-reordering, which
 // would interfere with otherwise safe [into|from]_raw() of transmutable
 // inner types.
-#[repr(C)]
+// repr(align(2)) (forcing alignment to at least 2) is required because usize
+// has 1-byte alignment on AVR.
+#[repr(C, align(2))]
 struct RcInner<T: ?Sized> {
     strong: Cell<usize>,
     weak: Cell<usize>,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 3a8695d34a8..6432bdfbbed 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -341,7 +341,7 @@ pub struct Weak<
     // but it is not necessarily a valid pointer.
     // `Weak::new` sets this to `usize::MAX` so that it doesn’t need
     // to allocate space on the heap. That's not a value a real pointer
-    // will ever have because RcInner has alignment at least 2.
+    // will ever have because ArcInner has alignment at least 2.
     ptr: NonNull<ArcInner<T>>,
     alloc: A,
 }
@@ -366,7 +366,9 @@ impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
 // This is repr(C) to future-proof against possible field-reordering, which
 // would interfere with otherwise safe [into|from]_raw() of transmutable
 // inner types.
-#[repr(C)]
+// Unlike RcInner, repr(align(2)) is not strictly required because atomic types
+// have the alignment same as its size, but we use it for consistency and clarity.
+#[repr(C, align(2))]
 struct ArcInner<T: ?Sized> {
     strong: Atomic<usize>,
 
@@ -1613,9 +1615,9 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     pub fn as_ptr(this: &Self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
 
-        // SAFETY: This cannot go through Deref::deref or RcInnerPtr::inner because
+        // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because
         // this is required to retain raw/mut provenance such that e.g. `get_mut` can
-        // write through the pointer after the Rc is recovered through `from_raw`.
+        // write through the pointer after the Arc is recovered through `from_raw`.
         unsafe { &raw mut (*ptr).data }
     }
 
@@ -2450,7 +2452,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
     /// they must not be dereferenced or have active borrows for the duration
     /// of the returned borrow, and their inner type must be exactly the same as the
-    /// inner type of this Rc (including lifetimes). This is trivially the case if no
+    /// inner type of this Arc (including lifetimes). This is trivially the case if no
     /// such pointers exist, for example immediately after `Arc::new`.
     ///
     /// # Examples
@@ -3022,7 +3024,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
             // Otherwise, we're guaranteed the pointer came from a nondangling Weak.
             // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T.
             let offset = unsafe { data_offset(ptr) };
-            // Thus, we reverse the offset to get the whole RcInner.
+            // Thus, we reverse the offset to get the whole ArcInner.
             // SAFETY: the pointer originated from a Weak, so this offset is safe.
             unsafe { ptr.byte_sub(offset) as *mut ArcInner<T> }
         };
@@ -4015,7 +4017,7 @@ impl<T: ?Sized, A: Allocator> Unpin for Arc<T, A> {}
 /// valid instance of T, but the T is allowed to be dropped.
 unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> usize {
     // Align the unsized value to the end of the ArcInner.
-    // Because RcInner is repr(C), it will always be the last field in memory.
+    // Because ArcInner is repr(C), it will always be the last field in memory.
     // SAFETY: since the only unsized types possible are slices, trait objects,
     // and extern types, the input safety requirement is currently enough to
     // satisfy the requirements of align_of_val_raw; this is an implementation
diff --git a/library/core/src/num/niche_types.rs b/library/core/src/num/niche_types.rs
index 610d9d8cf92..9ac0eb72bdc 100644
--- a/library/core/src/num/niche_types.rs
+++ b/library/core/src/num/niche_types.rs
@@ -112,7 +112,8 @@ impl Nanoseconds {
     pub const ZERO: Self = unsafe { Nanoseconds::new_unchecked(0) };
 }
 
-impl Default for Nanoseconds {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl const Default for Nanoseconds {
     #[inline]
     fn default() -> Self {
         Self::ZERO
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index ae910e05252..7053ae86e73 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -2203,16 +2203,13 @@ unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
 #[unstable(feature = "array_windows", issue = "75027")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ArrayWindows<'a, T: 'a, const N: usize> {
-    slice_head: *const T,
-    num: usize,
-    marker: PhantomData<&'a [T; N]>,
+    v: &'a [T],
 }
 
 impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
     #[inline]
     pub(super) const fn new(slice: &'a [T]) -> Self {
-        let num_windows = slice.len().saturating_sub(N - 1);
-        Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
+        Self { v: slice }
     }
 }
 
@@ -2222,49 +2219,34 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
 
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
-        if self.num == 0 {
-            return None;
+        let ret = self.v.first_chunk();
+        if ret.is_some() {
+            self.v = &self.v[1..];
         }
-        // SAFETY:
-        // This is safe because it's indexing into a slice guaranteed to be length > N.
-        let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
-        // SAFETY: Guaranteed that there are at least 1 item remaining otherwise
-        // earlier branch would've been hit
-        self.slice_head = unsafe { self.slice_head.add(1) };
-
-        self.num -= 1;
-        Some(ret)
+        ret
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.num, Some(self.num))
+        let size = self.v.len().saturating_sub(N - 1);
+        (size, Some(size))
     }
 
     #[inline]
     fn count(self) -> usize {
-        self.num
+        self.len()
     }
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
-        if self.num <= n {
-            self.num = 0;
-            return None;
-        }
-        // SAFETY:
-        // This is safe because it's indexing into a slice guaranteed to be length > N.
-        let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
-        // SAFETY: Guaranteed that there are at least n items remaining
-        self.slice_head = unsafe { self.slice_head.add(n + 1) };
-
-        self.num -= n + 1;
-        Some(ret)
+        let idx = n.min(self.v.len());
+        self.v = &self.v[idx..];
+        self.next()
     }
 
     #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.nth(self.num.checked_sub(1)?)
+    fn last(self) -> Option<Self::Item> {
+        self.v.last_chunk()
     }
 }
 
@@ -2272,32 +2254,25 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
 impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T; N]> {
-        if self.num == 0 {
-            return None;
+        let ret = self.v.last_chunk();
+        if ret.is_some() {
+            self.v = &self.v[..self.v.len() - 1];
         }
-        // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
-        let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
-        self.num -= 1;
-        Some(ret)
+        ret
     }
 
     #[inline]
     fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
-        if self.num <= n {
-            self.num = 0;
-            return None;
-        }
-        // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
-        let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
-        self.num -= n + 1;
-        Some(ret)
+        let idx = self.v.len().saturating_sub(n);
+        self.v = &self.v[..idx];
+        self.next_back()
     }
 }
 
 #[unstable(feature = "array_windows", issue = "75027")]
 impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
     fn is_empty(&self) -> bool {
-        self.num == 0
+        self.v.len() < N
     }
 }
 
diff --git a/library/coretests/tests/iter/sources.rs b/library/coretests/tests/iter/sources.rs
index 506febaa056..5a391cb6775 100644
--- a/library/coretests/tests/iter/sources.rs
+++ b/library/coretests/tests/iter/sources.rs
@@ -31,6 +31,17 @@ fn test_repeat_take_collect() {
 }
 
 #[test]
+#[should_panic = "iterator is infinite"]
+fn test_repeat_count() {
+    repeat(42).count();
+}
+
+#[test]
+fn test_repeat_last() {
+    assert_eq!(repeat(42).last(), Some(42));
+}
+
+#[test]
 fn test_repeat_with() {
     #[derive(PartialEq, Debug)]
     struct NotClone(usize);
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index e7d547966a5..92558f2b7d9 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -26,18 +26,16 @@ macro_rules! define_client_handles {
         $(
             pub(crate) struct $oty {
                 handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
             }
 
+            impl !Send for $oty {}
+            impl !Sync for $oty {}
+
             // Forward `Drop::drop` to the inherent `drop` method.
             impl Drop for $oty {
                 fn drop(&mut self) {
                     $oty {
                         handle: self.handle,
-                        _marker: PhantomData,
                     }.drop();
                 }
             }
@@ -64,7 +62,6 @@ macro_rules! define_client_handles {
                 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
                     $oty {
                         handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
                     }
                 }
             }
@@ -74,12 +71,11 @@ macro_rules! define_client_handles {
             #[derive(Copy, Clone, PartialEq, Eq, Hash)]
             pub(crate) struct $ity {
                 handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
             }
 
+            impl !Send for $ity {}
+            impl !Sync for $ity {}
+
             impl<S> Encode<S> for $ity {
                 fn encode(self, w: &mut Writer, s: &mut S) {
                     self.handle.encode(w, s);
@@ -90,7 +86,6 @@ macro_rules! define_client_handles {
                 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
                     $ity {
                         handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
                     }
                 }
             }
@@ -144,7 +139,7 @@ macro_rules! define_client_side {
 
                     buf.clear();
                     api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
-                    reverse_encode!(buf; $($arg),*);
+                    $($arg.encode(&mut buf, &mut ());)*
 
                     buf = bridge.dispatch.call(buf);
 
diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs
index e0e688434dc..e5133907854 100644
--- a/library/proc_macro/src/bridge/closure.rs
+++ b/library/proc_macro/src/bridge/closure.rs
@@ -6,9 +6,7 @@ use std::marker::PhantomData;
 pub(super) struct Closure<'a, A, R> {
     call: unsafe extern "C" fn(*mut Env, A) -> R,
     env: *mut Env,
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
+    // Prevent Send and Sync impls.
     //
     // The `'a` lifetime parameter represents the lifetime of `Env`.
     _marker: PhantomData<*mut &'a mut ()>,
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index d60a76fff5d..1b09deb6bfe 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -119,26 +119,6 @@ macro_rules! with_api_handle_types {
     };
 }
 
-// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
-// to match the ordering in `reverse_decode`.
-macro_rules! reverse_encode {
-    ($writer:ident;) => {};
-    ($writer:ident; $first:ident $(, $rest:ident)*) => {
-        reverse_encode!($writer; $($rest),*);
-        $first.encode(&mut $writer, &mut ());
-    }
-}
-
-// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
-// to avoid borrow conflicts from borrows started by `&mut` arguments.
-macro_rules! reverse_decode {
-    ($reader:ident, $s:ident;) => {};
-    ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
-        reverse_decode!($reader, $s; $($rest: $rest_ty),*);
-        let $first = <$first_ty>::decode(&mut $reader, $s);
-    }
-}
-
 #[allow(unsafe_code)]
 mod arena;
 #[allow(unsafe_code)]
@@ -180,13 +160,11 @@ pub struct BridgeConfig<'a> {
 
     /// If 'true', always invoke the default panic hook
     force_show_panics: bool,
-
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
-    _marker: marker::PhantomData<*mut ()>,
 }
 
+impl !Send for BridgeConfig<'_> {}
+impl !Sync for BridgeConfig<'_> {}
+
 #[forbid(unsafe_code)]
 #[allow(non_camel_case_types)]
 mod api_tags {
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index 5beda7c3c96..0bb30698aa1 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -178,7 +178,7 @@ macro_rules! define_dispatcher_impl {
                     $(api_tags::Method::$name(m) => match m {
                         $(api_tags::$name::$method => {
                             let mut call_method = || {
-                                reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
+                                $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)*
                                 $name::$method(server, $($arg),*)
                             };
                             // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
@@ -295,12 +295,7 @@ impl ExecutionStrategy for SameThread {
 
         let mut dispatch = |buf| dispatcher.dispatch(buf);
 
-        run_client(BridgeConfig {
-            input,
-            dispatch: (&mut dispatch).into(),
-            force_show_panics,
-            _marker: marker::PhantomData,
-        })
+        run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
     }
 }
 
@@ -331,12 +326,7 @@ where
                 client.recv().expect("server died while client waiting for reply")
             };
 
-            run_client(BridgeConfig {
-                input,
-                dispatch: (&mut dispatch).into(),
-                force_show_panics,
-                _marker: marker::PhantomData,
-            })
+            run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
         });
 
         while let Some(b) = server.recv() {
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 162b4fdcc8a..613abd7024e 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -27,7 +27,6 @@
 #![feature(panic_can_unwind)]
 #![feature(restricted_std)]
 #![feature(rustc_attrs)]
-#![feature(stmt_expr_attributes)]
 #![feature(extend_one)]
 #![recursion_limit = "256"]
 #![allow(internal_features)]
diff --git a/library/std/src/net/hostname.rs b/library/std/src/net/hostname.rs
new file mode 100644
index 00000000000..b1010cec600
--- /dev/null
+++ b/library/std/src/net/hostname.rs
@@ -0,0 +1,22 @@
+use crate::ffi::OsString;
+
+/// Returns the system hostname.
+///
+/// This can error out in platform-specific error cases;
+/// for example, uefi and wasm, where hostnames aren't
+/// supported.
+///
+/// # Underlying system calls
+///
+/// | Platform | System call                                                                                             |
+/// |----------|---------------------------------------------------------------------------------------------------------|
+/// | UNIX     | [`gethostname`](https://www.man7.org/linux/man-pages/man2/gethostname.2.html)                           |
+/// | Windows  | [`GetHostNameW`](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostnamew) |
+///
+/// Note that platform-specific behavior [may change in the future][changes].
+///
+/// [changes]: crate::io#platform-specific-behavior
+#[unstable(feature = "gethostname", issue = "135142")]
+pub fn hostname() -> crate::io::Result<OsString> {
+    crate::sys::net::hostname()
+}
diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs
index 40f1a93e39d..3e4447eb33f 100644
--- a/library/std/src/net/mod.rs
+++ b/library/std/src/net/mod.rs
@@ -1,7 +1,8 @@
 //! Networking primitives for TCP/UDP communication.
 //!
 //! This module provides networking functionality for the Transmission Control and User
-//! Datagram Protocols, as well as types for IP and socket addresses.
+//! Datagram Protocols, as well as types for IP and socket addresses and functions related
+//! to network properties.
 //!
 //! # Organization
 //!
@@ -24,6 +25,8 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::net::AddrParseError;
 
+#[unstable(feature = "gethostname", issue = "135142")]
+pub use self::hostname::hostname;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -35,6 +38,7 @@ pub use self::tcp::{Incoming, TcpListener, TcpStream};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::udp::UdpSocket;
 
+mod hostname;
 mod ip_addr;
 mod socket_addr;
 mod tcp;
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 718c7c2e3b1..6e3b1e6e47d 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1412,6 +1412,99 @@ impl PathBuf {
         }
     }
 
+    /// Sets whether the path has a trailing [separator](MAIN_SEPARATOR).
+    ///
+    /// The value returned by [`has_trailing_sep`](Path::has_trailing_sep) will be equivalent to
+    /// the provided value if possible.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::path::PathBuf;
+    ///
+    /// let mut p = PathBuf::from("dir");
+    ///
+    /// assert!(!p.has_trailing_sep());
+    /// p.set_trailing_sep(false);
+    /// assert!(!p.has_trailing_sep());
+    /// p.set_trailing_sep(true);
+    /// assert!(p.has_trailing_sep());
+    /// p.set_trailing_sep(false);
+    /// assert!(!p.has_trailing_sep());
+    ///
+    /// p = PathBuf::from("/");
+    /// assert!(p.has_trailing_sep());
+    /// p.set_trailing_sep(false);
+    /// assert!(p.has_trailing_sep());
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    pub fn set_trailing_sep(&mut self, trailing_sep: bool) {
+        if trailing_sep { self.push_trailing_sep() } else { self.pop_trailing_sep() }
+    }
+
+    /// Adds a trailing [separator](MAIN_SEPARATOR) to the path.
+    ///
+    /// This acts similarly to [`Path::with_trailing_sep`], but mutates the underlying `PathBuf`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::ffi::OsStr;
+    /// use std::path::PathBuf;
+    ///
+    /// let mut p = PathBuf::from("dir");
+    ///
+    /// assert!(!p.has_trailing_sep());
+    /// p.push_trailing_sep();
+    /// assert!(p.has_trailing_sep());
+    /// p.push_trailing_sep();
+    /// assert!(p.has_trailing_sep());
+    ///
+    /// p = PathBuf::from("dir/");
+    /// p.push_trailing_sep();
+    /// assert_eq!(p.as_os_str(), OsStr::new("dir/"));
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    pub fn push_trailing_sep(&mut self) {
+        if !self.has_trailing_sep() {
+            self.push("");
+        }
+    }
+
+    /// Removes a trailing [separator](MAIN_SEPARATOR) from the path, if possible.
+    ///
+    /// This acts similarly to [`Path::trim_trailing_sep`], but mutates the underlying `PathBuf`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::ffi::OsStr;
+    /// use std::path::PathBuf;
+    ///
+    /// let mut p = PathBuf::from("dir//");
+    ///
+    /// assert!(p.has_trailing_sep());
+    /// assert_eq!(p.as_os_str(), OsStr::new("dir//"));
+    /// p.pop_trailing_sep();
+    /// assert!(!p.has_trailing_sep());
+    /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
+    /// p.pop_trailing_sep();
+    /// assert!(!p.has_trailing_sep());
+    /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
+    ///
+    /// p = PathBuf::from("/");
+    /// assert!(p.has_trailing_sep());
+    /// p.pop_trailing_sep();
+    /// assert!(p.has_trailing_sep());
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    pub fn pop_trailing_sep(&mut self) {
+        self.inner.truncate(self.trim_trailing_sep().as_os_str().len());
+    }
+
     /// Updates [`self.file_name`] to `file_name`.
     ///
     /// If [`self.file_name`] was [`None`], this is equivalent to pushing
@@ -1610,7 +1703,7 @@ impl PathBuf {
         let new = extension.as_encoded_bytes();
         if !new.is_empty() {
             // truncate until right after the file name
-            // this is necessary for trimming the trailing slash
+            // this is necessary for trimming the trailing separator
             let end_file_name = file_name[file_name.len()..].as_ptr().addr();
             let start = self.inner.as_encoded_bytes().as_ptr().addr();
             self.inner.truncate(end_file_name.wrapping_sub(start));
@@ -2755,6 +2848,94 @@ impl Path {
         self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.and(after))
     }
 
+    /// Checks whether the path ends in a trailing [separator](MAIN_SEPARATOR).
+    ///
+    /// This is generally done to ensure that a path is treated as a directory, not a file,
+    /// although it does not actually guarantee that such a path is a directory on the underlying
+    /// file system.
+    ///
+    /// Despite this behavior, two paths are still considered the same in Rust whether they have a
+    /// trailing separator or not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::path::Path;
+    ///
+    /// assert!(Path::new("dir/").has_trailing_sep());
+    /// assert!(!Path::new("file.rs").has_trailing_sep());
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    #[must_use]
+    #[inline]
+    pub fn has_trailing_sep(&self) -> bool {
+        self.as_os_str().as_encoded_bytes().last().copied().is_some_and(is_sep_byte)
+    }
+
+    /// Ensures that a path has a trailing [separator](MAIN_SEPARATOR),
+    /// allocating a [`PathBuf`] if necessary.
+    ///
+    /// The resulting path will return true for [`has_trailing_sep`](Self::has_trailing_sep).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::ffi::OsStr;
+    /// use std::path::Path;
+    ///
+    /// assert_eq!(Path::new("dir//").with_trailing_sep().as_os_str(), OsStr::new("dir//"));
+    /// assert_eq!(Path::new("dir/").with_trailing_sep().as_os_str(), OsStr::new("dir/"));
+    /// assert!(!Path::new("dir").has_trailing_sep());
+    /// assert!(Path::new("dir").with_trailing_sep().has_trailing_sep());
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    #[must_use]
+    #[inline]
+    pub fn with_trailing_sep(&self) -> Cow<'_, Path> {
+        if self.has_trailing_sep() { Cow::Borrowed(self) } else { Cow::Owned(self.join("")) }
+    }
+
+    /// Trims a trailing [separator](MAIN_SEPARATOR) from a path, if possible.
+    ///
+    /// The resulting path will return false for [`has_trailing_sep`](Self::has_trailing_sep) for
+    /// most paths.
+    ///
+    /// Some paths, like `/`, cannot be trimmed in this way.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_trailing_sep)]
+    /// use std::ffi::OsStr;
+    /// use std::path::Path;
+    ///
+    /// assert_eq!(Path::new("dir//").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+    /// assert_eq!(Path::new("dir/").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+    /// assert_eq!(Path::new("dir").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+    /// assert_eq!(Path::new("/").trim_trailing_sep().as_os_str(), OsStr::new("/"));
+    /// assert_eq!(Path::new("//").trim_trailing_sep().as_os_str(), OsStr::new("//"));
+    /// ```
+    #[unstable(feature = "path_trailing_sep", issue = "142503")]
+    #[must_use]
+    #[inline]
+    pub fn trim_trailing_sep(&self) -> &Path {
+        if self.has_trailing_sep() && (!self.has_root() || self.parent().is_some()) {
+            let mut bytes = self.inner.as_encoded_bytes();
+            while let Some((last, init)) = bytes.split_last()
+                && is_sep_byte(*last)
+            {
+                bytes = init;
+            }
+
+            // SAFETY: Trimming trailing ASCII bytes will retain the validity of the string.
+            Path::new(unsafe { OsStr::from_encoded_bytes_unchecked(bytes) })
+        } else {
+            self
+        }
+    }
+
     /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
     ///
     /// If `path` is absolute, it replaces the current path.
@@ -2907,7 +3088,7 @@ impl Path {
     ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
     ///   an additional [`CurDir`] component.
     ///
-    /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
+    /// * Trailing separators are normalized away, so `/a/b` and `/a/b/` are equivalent.
     ///
     /// Note that no other normalization takes place; in particular, `a/c`
     /// and `a/b/../c` are distinct, to account for the possibility that `b`
@@ -3718,7 +3899,7 @@ impl Error for NormalizeError {}
 ///
 /// On POSIX platforms, the path is resolved using [POSIX semantics][posix-semantics],
 /// except that it stops short of resolving symlinks. This means it will keep `..`
-/// components and trailing slashes.
+/// components and trailing separators.
 ///
 /// On Windows, for verbatim paths, this will simply return the path as given. For other
 /// paths, this is currently equivalent to calling
diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs
index b71d8b1357b..5b6f4cedf1b 100644
--- a/library/std/src/sys/net/connection/socket/windows.rs
+++ b/library/std/src/sys/net/connection/socket/windows.rs
@@ -8,9 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
 use crate::os::windows::io::{
     AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
 };
-use crate::sync::atomic::Atomic;
-use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
 use crate::sys::c;
+use crate::sys::pal::winsock::last_error;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 use crate::{cmp, mem, ptr, sys};
@@ -112,84 +111,11 @@ pub(super) mod netc {
     }
 }
 
+pub use crate::sys::pal::winsock::{cleanup, cvt, cvt_gai, cvt_r, startup as init};
+
 #[expect(missing_debug_implementations)]
 pub struct Socket(OwnedSocket);
 
-static WSA_INITIALIZED: Atomic<bool> = Atomic::<bool>::new(false);
-
-/// Checks whether the Windows socket interface has been started already, and
-/// if not, starts it.
-#[inline]
-pub fn init() {
-    if !WSA_INITIALIZED.load(Relaxed) {
-        wsa_startup();
-    }
-}
-
-#[cold]
-fn wsa_startup() {
-    unsafe {
-        let mut data: c::WSADATA = mem::zeroed();
-        let ret = c::WSAStartup(
-            0x202, // version 2.2
-            &mut data,
-        );
-        assert_eq!(ret, 0);
-        if WSA_INITIALIZED.swap(true, AcqRel) {
-            // If another thread raced with us and called WSAStartup first then call
-            // WSACleanup so it's as though WSAStartup was only called once.
-            c::WSACleanup();
-        }
-    }
-}
-
-pub fn cleanup() {
-    // We don't need to call WSACleanup here because exiting the process will cause
-    // the OS to clean everything for us, which is faster than doing it manually.
-    // See #141799.
-}
-
-/// Returns the last error from the Windows socket interface.
-fn last_error() -> io::Error {
-    io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
-}
-
-#[doc(hidden)]
-pub trait IsMinusOne {
-    fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
-    ($($t:ident)*) => ($(impl IsMinusOne for $t {
-        fn is_minus_one(&self) -> bool {
-            *self == -1
-        }
-    })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
-/// and if so, returns the last error from the Windows socket interface. This
-/// function must be called before another call to the socket API is made.
-pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
-    if t.is_minus_one() { Err(last_error()) } else { Ok(t) }
-}
-
-/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
-pub fn cvt_gai(err: c_int) -> io::Result<()> {
-    if err == 0 { Ok(()) } else { Err(last_error()) }
-}
-
-/// Just to provide the same interface as sys/pal/unix/net.rs
-pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-where
-    T: IsMinusOne,
-    F: FnMut() -> T,
-{
-    cvt(f())
-}
-
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
         let family = match *addr {
diff --git a/library/std/src/sys/net/hostname/mod.rs b/library/std/src/sys/net/hostname/mod.rs
new file mode 100644
index 00000000000..8ffe4894d71
--- /dev/null
+++ b/library/std/src/sys/net/hostname/mod.rs
@@ -0,0 +1,14 @@
+cfg_select! {
+    all(target_family = "unix", not(target_os = "espidf")) => {
+        mod unix;
+        pub use unix::hostname;
+    }
+    target_os = "windows" => {
+        mod windows;
+        pub use windows::hostname;
+    }
+    _ => {
+        mod unsupported;
+        pub use unsupported::hostname;
+    }
+}
diff --git a/library/std/src/sys/net/hostname/unix.rs b/library/std/src/sys/net/hostname/unix.rs
new file mode 100644
index 00000000000..bc6fa82a38f
--- /dev/null
+++ b/library/std/src/sys/net/hostname/unix.rs
@@ -0,0 +1,62 @@
+use crate::ffi::OsString;
+use crate::io;
+use crate::os::unix::ffi::OsStringExt;
+use crate::sys::pal::os::errno;
+
+pub fn hostname() -> io::Result<OsString> {
+    // Query the system for the maximum host name length.
+    let host_name_max = match unsafe { libc::sysconf(libc::_SC_HOST_NAME_MAX) } {
+        // If this fails (possibly because there is no maximum length), then
+        // assume a maximum length of _POSIX_HOST_NAME_MAX (255).
+        -1 => 255,
+        max => max as usize,
+    };
+
+    // Reserve space for the nul terminator too.
+    let mut buf = Vec::<u8>::try_with_capacity(host_name_max + 1)?;
+    loop {
+        // SAFETY: `buf.capacity()` bytes of `buf` are writable.
+        let r = unsafe { libc::gethostname(buf.as_mut_ptr().cast(), buf.capacity()) };
+        match (r != 0).then(errno) {
+            None => {
+                // Unfortunately, the UNIX specification says that the name will
+                // be truncated if it does not fit in the buffer, without returning
+                // an error. As additionally, the truncated name may still be null-
+                // terminated, there is no reliable way to  detect truncation.
+                // Fortunately, most platforms ignore what the specification says
+                // and return an error (mostly ENAMETOOLONG). Should that not be
+                // the case, the following detects truncation if the null-terminator
+                // was omitted. Note that this check does not impact performance at
+                // all as we need to find the length of the string anyways.
+                //
+                // Use `strnlen` as it does not place an initialization requirement
+                // on the bytes after the nul terminator.
+                //
+                // SAFETY: `buf.capacity()` bytes of `buf` are accessible, and are
+                // initialized up to and including a possible nul terminator.
+                let len = unsafe { libc::strnlen(buf.as_ptr().cast(), buf.capacity()) };
+                if len < buf.capacity() {
+                    // If the string is nul-terminated, we assume that is has not
+                    // been truncated, as the capacity *should be* enough to hold
+                    // `HOST_NAME_MAX` bytes.
+                    // SAFETY: `len + 1` bytes have been initialized (we exclude
+                    // the nul terminator from the string).
+                    unsafe { buf.set_len(len) };
+                    return Ok(OsString::from_vec(buf));
+                }
+            }
+            // As `buf.capacity()` is always less than or equal to `isize::MAX`
+            // (Rust allocations cannot exceed that limit), the only way `EINVAL`
+            // can be returned is if the system uses `EINVAL` to report that the
+            // name does not fit in the provided buffer. In that case (or in the
+            // case of `ENAMETOOLONG`), resize the buffer and try again.
+            Some(libc::EINVAL | libc::ENAMETOOLONG) => {}
+            // Other error codes (e.g. EPERM) have nothing to do with the buffer
+            // size and should be returned to the user.
+            Some(err) => return Err(io::Error::from_raw_os_error(err)),
+        }
+
+        // Resize the buffer (according to `Vec`'s resizing rules) and try again.
+        buf.try_reserve(buf.capacity() + 1)?;
+    }
+}
diff --git a/library/std/src/sys/net/hostname/unsupported.rs b/library/std/src/sys/net/hostname/unsupported.rs
new file mode 100644
index 00000000000..d868f68f32d
--- /dev/null
+++ b/library/std/src/sys/net/hostname/unsupported.rs
@@ -0,0 +1,6 @@
+use crate::ffi::OsString;
+use crate::io::{Error, Result};
+
+pub fn hostname() -> Result<OsString> {
+    Err(Error::UNSUPPORTED_PLATFORM)
+}
diff --git a/library/std/src/sys/net/hostname/windows.rs b/library/std/src/sys/net/hostname/windows.rs
new file mode 100644
index 00000000000..24eed100f32
--- /dev/null
+++ b/library/std/src/sys/net/hostname/windows.rs
@@ -0,0 +1,24 @@
+use crate::ffi::OsString;
+use crate::io::Result;
+use crate::mem::MaybeUninit;
+use crate::os::windows::ffi::OsStringExt;
+use crate::sys::pal::c;
+use crate::sys::pal::winsock::{self, cvt};
+
+pub fn hostname() -> Result<OsString> {
+    winsock::startup();
+
+    // The documentation of GetHostNameW says that a buffer size of 256 is
+    // always enough.
+    let mut buffer = [const { MaybeUninit::<u16>::uninit() }; 256];
+    // SAFETY: these parameters specify a valid, writable region of memory.
+    cvt(unsafe { c::GetHostNameW(buffer.as_mut_ptr().cast(), buffer.len() as i32) })?;
+    // Use `lstrlenW` here as it does not require the bytes after the nul
+    // terminator to be initialized.
+    // SAFETY: if `GetHostNameW` returns successfully, the name is nul-terminated.
+    let len = unsafe { c::lstrlenW(buffer.as_ptr().cast()) };
+    // SAFETY: the length of the name is `len`, hence `len` bytes have been
+    //         initialized by `GetHostNameW`.
+    let name = unsafe { buffer[..len as usize].assume_init_ref() };
+    Ok(OsString::from_wide(name))
+}
diff --git a/library/std/src/sys/net/mod.rs b/library/std/src/sys/net/mod.rs
index dffc4ea7f81..bfe5cf53128 100644
--- a/library/std/src/sys/net/mod.rs
+++ b/library/std/src/sys/net/mod.rs
@@ -2,3 +2,6 @@
 /// `UdpSocket` as well as related functionality like DNS resolving.
 mod connection;
 pub use connection::*;
+
+mod hostname;
+pub use hostname::hostname;
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 51463eef5b7..28b05d8a68a 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -148,6 +148,13 @@ mod imp {
 
         let mut guard_page_range = unsafe { install_main_guard() };
 
+        // Even for panic=immediate-abort, installing the guard pages is important for soundness.
+        // That said, we do not care about giving nice stackoverflow messages via our custom
+        // signal handler, just exit early and let the user enjoy the segfault.
+        if cfg!(panic = "immediate-abort") {
+            return;
+        }
+
         // SAFETY: assuming all platforms define struct sigaction as "zero-initializable"
         let mut action: sigaction = unsafe { mem::zeroed() };
         for &signal in &[SIGSEGV, SIGBUS] {
@@ -179,6 +186,9 @@ mod imp {
     /// Must be called only once
     #[forbid(unsafe_op_in_unsafe_fn)]
     pub unsafe fn cleanup() {
+        if cfg!(panic = "immediate-abort") {
+            return;
+        }
         // FIXME: I probably cause more bugs than I'm worth!
         // see https://github.com/rust-lang/rust/issues/111272
         unsafe { drop_handler(MAIN_ALTSTACK.load(Ordering::Relaxed)) };
@@ -230,7 +240,7 @@ mod imp {
     /// Mutates the alternate signal stack
     #[forbid(unsafe_op_in_unsafe_fn)]
     pub unsafe fn make_handler(main_thread: bool, thread_name: Option<Box<str>>) -> Handler {
-        if !NEED_ALTSTACK.load(Ordering::Acquire) {
+        if cfg!(panic = "immediate-abort") || !NEED_ALTSTACK.load(Ordering::Acquire) {
             return Handler::null();
         }
 
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index abc1c19827f..9009aa09f48 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2170,6 +2170,7 @@ GetFileType
 GETFINALPATHNAMEBYHANDLE_FLAGS
 GetFinalPathNameByHandleW
 GetFullPathNameW
+GetHostNameW
 GetLastError
 GetModuleFileNameW
 GetModuleHandleA
@@ -2270,6 +2271,7 @@ LPPROGRESS_ROUTINE
 LPPROGRESS_ROUTINE_CALLBACK_REASON
 LPTHREAD_START_ROUTINE
 LPWSAOVERLAPPED_COMPLETION_ROUTINE
+lstrlenW
 M128A
 MAX_PATH
 MAXIMUM_REPARSE_DATA_BUFFER_SIZE
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 989a1246650..98f277b3378 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -49,6 +49,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetFileSizeEx(hfile : HANDLE,
 windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE);
 windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32);
+windows_targets::link!("ws2_32.dll" "system" fn GetHostNameW(name : PWSTR, namelen : i32) -> i32);
 windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR);
 windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(hmodule : HMODULE, lpfilename : PWSTR, nsize : u32) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpmodulename : PCSTR) -> HMODULE);
@@ -134,6 +135,7 @@ windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *
 windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32);
+windows_targets::link!("kernel32.dll" "system" fn lstrlenW(lpstring : PCWSTR) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn recvfrom(s : SOCKET, buf : PSTR, len : i32, flags : i32, from : *mut SOCKADDR, fromlen : *mut i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn select(nfds : i32, readfds : *mut FD_SET, writefds : *mut FD_SET, exceptfds : *mut FD_SET, timeout : *const TIMEVAL) -> i32);
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 3357946b8f7..18ab3498267 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -22,7 +22,8 @@ pub mod os;
 pub mod pipe;
 pub mod time;
 cfg_select! {
-    not(target_vendor = "uwp") => {
+    // We don't care about printing nice error messages for panic=immediate-abort
+    all(not(target_vendor = "uwp"), not(panic = "immediate-abort")) => {
         pub mod stack_overflow;
     }
     _ => {
@@ -30,6 +31,7 @@ cfg_select! {
         pub use self::stack_overflow_uwp as stack_overflow;
     }
 }
+pub mod winsock;
 
 /// Map a [`Result<T, WinError>`] to [`io::Result<T>`](crate::io::Result<T>).
 pub trait IoResult<T> {
diff --git a/library/std/src/sys/pal/windows/winsock.rs b/library/std/src/sys/pal/windows/winsock.rs
new file mode 100644
index 00000000000..b110a43ef3a
--- /dev/null
+++ b/library/std/src/sys/pal/windows/winsock.rs
@@ -0,0 +1,80 @@
+use super::c;
+use crate::ffi::c_int;
+use crate::sync::atomic::Atomic;
+use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
+use crate::{io, mem};
+
+static WSA_STARTED: Atomic<bool> = Atomic::<bool>::new(false);
+
+/// Checks whether the Windows socket interface has been started already, and
+/// if not, starts it.
+#[inline]
+pub fn startup() {
+    if !WSA_STARTED.load(Relaxed) {
+        wsa_startup();
+    }
+}
+
+#[cold]
+fn wsa_startup() {
+    unsafe {
+        let mut data: c::WSADATA = mem::zeroed();
+        let ret = c::WSAStartup(
+            0x202, // version 2.2
+            &mut data,
+        );
+        assert_eq!(ret, 0);
+        if WSA_STARTED.swap(true, AcqRel) {
+            // If another thread raced with us and called WSAStartup first then call
+            // WSACleanup so it's as though WSAStartup was only called once.
+            c::WSACleanup();
+        }
+    }
+}
+
+pub fn cleanup() {
+    // We don't need to call WSACleanup here because exiting the process will cause
+    // the OS to clean everything for us, which is faster than doing it manually.
+    // See #141799.
+}
+
+/// Returns the last error from the Windows socket interface.
+pub fn last_error() -> io::Error {
+    io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
+}
+
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
+/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
+/// and if so, returns the last error from the Windows socket interface. This
+/// function must be called before another call to the socket API is made.
+pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() { Err(last_error()) } else { Ok(t) }
+}
+
+/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
+pub fn cvt_gai(err: c_int) -> io::Result<()> {
+    if err == 0 { Ok(()) } else { Err(last_error()) }
+}
+
+/// Just to provide the same interface as sys/pal/unix/net.rs
+pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
+where
+    T: IsMinusOne,
+    F: FnMut() -> T,
+{
+    cvt(f())
+}
diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs
index 7da1621da45..f00212bfcb6 100644
--- a/library/std/src/thread/current.rs
+++ b/library/std/src/thread/current.rs
@@ -133,12 +133,32 @@ pub(super) fn set_current(thread: Thread) -> Result<(), Thread> {
     Ok(())
 }
 
-/// Gets the id of the thread that invokes it.
+/// Gets the unique identifier of the thread which invokes it.
+///
+/// Calling this function may be more efficient than accessing the current
+/// thread id through the current thread handle. i.e. `thread::current().id()`.
 ///
 /// This function will always succeed, will always return the same value for
 /// one thread and is guaranteed not to call the global allocator.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(current_thread_id)]
+///
+/// use std::thread;
+///
+/// let other_thread = thread::spawn(|| {
+///     thread::current_id()
+/// });
+///
+/// let other_thread_id = other_thread.join().unwrap();
+/// assert_ne!(thread::current_id(), other_thread_id);
+/// ```
 #[inline]
-pub(crate) fn current_id() -> ThreadId {
+#[must_use]
+#[unstable(feature = "current_thread_id", issue = "147194")]
+pub fn current_id() -> ThreadId {
     // If accessing the persistent thread ID takes multiple TLS accesses, try
     // to retrieve it from the current thread handle, which will only take one
     // TLS access.
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 4d09b2b4e9d..1768369792a 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -183,7 +183,9 @@ mod current;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use current::current;
-pub(crate) use current::{current_id, current_or_unnamed, current_os_id, drop_current};
+#[unstable(feature = "current_thread_id", issue = "147194")]
+pub use current::current_id;
+pub(crate) use current::{current_or_unnamed, current_os_id, drop_current};
 use current::{set_current, try_with_current};
 
 mod spawnhook;
diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs
index 837a14b808f..c60edbdf961 100644
--- a/library/std/tests/path.rs
+++ b/library/std/tests/path.rs
@@ -1,4 +1,9 @@
-#![feature(clone_to_uninit, maybe_uninit_slice, normalize_lexically)]
+// tidy-alphabetical-start
+#![feature(clone_to_uninit)]
+#![feature(maybe_uninit_slice)]
+#![feature(normalize_lexically)]
+#![feature(path_trailing_sep)]
+// tidy-alphabetical-end
 
 use std::clone::CloneToUninit;
 use std::ffi::OsStr;
@@ -2542,3 +2547,34 @@ fn compare_path_like_to_str_like() {
     assert!(path_buf == s);
     assert!(s == path_buf);
 }
+
+#[test]
+fn test_trim_trailing_sep() {
+    assert_eq!(Path::new("/").trim_trailing_sep().as_os_str(), OsStr::new("/"));
+    assert_eq!(Path::new("//").trim_trailing_sep().as_os_str(), OsStr::new("//"));
+    assert_eq!(Path::new("").trim_trailing_sep().as_os_str(), OsStr::new(""));
+    assert_eq!(Path::new(".").trim_trailing_sep().as_os_str(), OsStr::new("."));
+    assert_eq!(Path::new("./").trim_trailing_sep().as_os_str(), OsStr::new("."));
+    assert_eq!(Path::new(".//").trim_trailing_sep().as_os_str(), OsStr::new("."));
+    assert_eq!(Path::new("..").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+    assert_eq!(Path::new("../").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+    assert_eq!(Path::new("..//").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+
+    #[cfg(any(windows, target_os = "cygwin"))]
+    {
+        assert_eq!(Path::new("\\").trim_trailing_sep().as_os_str(), OsStr::new("\\"));
+        assert_eq!(Path::new("\\\\").trim_trailing_sep().as_os_str(), OsStr::new("\\\\"));
+        assert_eq!(Path::new("c:/").trim_trailing_sep().as_os_str(), OsStr::new("c:/"));
+        assert_eq!(Path::new("c://").trim_trailing_sep().as_os_str(), OsStr::new("c://"));
+        assert_eq!(Path::new("c:./").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+        assert_eq!(Path::new("c:.//").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+        assert_eq!(Path::new("c:../").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+        assert_eq!(Path::new("c:..//").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+        assert_eq!(Path::new("c:\\").trim_trailing_sep().as_os_str(), OsStr::new("c:\\"));
+        assert_eq!(Path::new("c:\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:\\\\"));
+        assert_eq!(Path::new("c:.\\").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+        assert_eq!(Path::new("c:.\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+        assert_eq!(Path::new("c:..\\").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+        assert_eq!(Path::new("c:..\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+    }
+}
diff --git a/src/bootstrap/defaults/bootstrap.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml
index b111a20f8d8..bb0592ce947 100644
--- a/src/bootstrap/defaults/bootstrap.dist.toml
+++ b/src/bootstrap/defaults/bootstrap.dist.toml
@@ -7,8 +7,6 @@ test-stage = 2
 doc-stage = 2
 # When compiling from source, you usually want all tools.
 extended = true
-# Use libtest built from the source tree instead of the precompiled one from stage 0.
-compiletest-use-stage0-libtest = false
 
 # Most users installing from source want to build all parts of the project from source.
 [llvm]
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 043457f64e5..20c54a28dda 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -8,8 +8,8 @@ use crate::core::build_steps::compile::{
 };
 use crate::core::build_steps::tool;
 use crate::core::build_steps::tool::{
-    COMPILETEST_ALLOW_FEATURES, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, ToolTargetBuildMode,
-    get_tool_target_compiler, prepare_tool_cargo,
+    SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, ToolTargetBuildMode, get_tool_target_compiler,
+    prepare_tool_cargo,
 };
 use crate::core::builder::{
     self, Alias, Builder, Cargo, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description,
@@ -654,7 +654,7 @@ macro_rules! tool_check_step {
             // The part of this path after the final '/' is also used as a display name.
             path: $path:literal
             $(, alt_path: $alt_path:literal )*
-            // Closure that returns `Mode` based on the passed `&Builder<'_>`
+            // `Mode` to use when checking this tool
             , mode: $mode:expr
             // Subset of nightly features that are allowed to be used when checking
             $(, allow_features: $allow_features:expr )?
@@ -682,8 +682,7 @@ macro_rules! tool_check_step {
 
             fn make_run(run: RunConfig<'_>) {
                 let target = run.target;
-                let builder = run.builder;
-                let mode = $mode(builder);
+                let mode: Mode = $mode;
 
                 let compiler = prepare_compiler_for_check(run.builder, target, mode);
 
@@ -704,7 +703,7 @@ macro_rules! tool_check_step {
                     _value
                 };
                 let extra_features: &[&str] = &[$($($enable_features),*)?];
-                let mode = $mode(builder);
+                let mode: Mode = $mode;
                 run_tool_check_step(builder, compiler, target, $path, mode, allow_features, extra_features);
             }
 
@@ -767,57 +766,50 @@ fn run_tool_check_step(
 tool_check_step!(Rustdoc {
     path: "src/tools/rustdoc",
     alt_path: "src/librustdoc",
-    mode: |_builder| Mode::ToolRustcPrivate
+    mode: Mode::ToolRustcPrivate
 });
 // Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
 // of a submodule. Since the SourceType only drives the deny-warnings
 // behavior, treat it as in-tree so that any new warnings in clippy will be
 // rejected.
-tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustcPrivate });
-tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustcPrivate });
-tool_check_step!(CargoMiri {
-    path: "src/tools/miri/cargo-miri",
-    mode: |_builder| Mode::ToolRustcPrivate
-});
-tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustcPrivate });
+tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustcPrivate });
+tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustcPrivate });
+tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustcPrivate });
+tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustcPrivate });
 tool_check_step!(RustAnalyzer {
     path: "src/tools/rust-analyzer",
-    mode: |_builder| Mode::ToolRustcPrivate,
+    mode: Mode::ToolRustcPrivate,
     allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
     enable_features: ["in-rust-tree"],
 });
 tool_check_step!(MiroptTestTools {
     path: "src/tools/miropt-test-tools",
-    mode: |_builder| Mode::ToolBootstrap
+    mode: Mode::ToolBootstrap
 });
 // We want to test the local std
 tool_check_step!(TestFloatParse {
     path: "src/tools/test-float-parse",
-    mode: |_builder| Mode::ToolStd,
+    mode: Mode::ToolStd,
     allow_features: TEST_FLOAT_PARSE_ALLOW_FEATURES
 });
 tool_check_step!(FeaturesStatusDump {
     path: "src/tools/features-status-dump",
-    mode: |_builder| Mode::ToolBootstrap
+    mode: Mode::ToolBootstrap
 });
 
-tool_check_step!(Bootstrap {
-    path: "src/bootstrap",
-    mode: |_builder| Mode::ToolBootstrap,
-    default: false
-});
+tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
 
 // `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
 // check to make it easier to work on.
 tool_check_step!(RunMakeSupport {
     path: "src/tools/run-make-support",
-    mode: |_builder| Mode::ToolBootstrap,
+    mode: Mode::ToolBootstrap,
     default: false
 });
 
 tool_check_step!(CoverageDump {
     path: "src/tools/coverage-dump",
-    mode: |_builder| Mode::ToolBootstrap,
+    mode: Mode::ToolBootstrap,
     default: false
 });
 
@@ -825,23 +817,18 @@ tool_check_step!(CoverageDump {
 // so this is mainly for people working on compiletest to run locally.
 tool_check_step!(Compiletest {
     path: "src/tools/compiletest",
-    mode: |builder: &Builder<'_>| if builder.config.compiletest_use_stage0_libtest {
-        Mode::ToolBootstrap
-    } else {
-        Mode::ToolStd
-    },
-    allow_features: COMPILETEST_ALLOW_FEATURES,
+    mode: Mode::ToolBootstrap,
     default: false,
 });
 
 tool_check_step!(Linkchecker {
     path: "src/tools/linkchecker",
-    mode: |_builder| Mode::ToolBootstrap,
+    mode: Mode::ToolBootstrap,
     default: false
 });
 
 tool_check_step!(BumpStage0 {
     path: "src/tools/bump-stage0",
-    mode: |_builder| Mode::ToolBootstrap,
+    mode: Mode::ToolBootstrap,
     default: false
 });
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 7865b685659..37462c63f1b 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -1024,12 +1024,9 @@ macro_rules! tool_doc {
                         run.builder.ensure(Rustc::from_build_compiler(run.builder, compilers.build_compiler(), target));
                         compilers.build_compiler()
                     }
-                    Mode::ToolBootstrap => {
-                        // bootstrap/host tools should be documented with the stage 0 compiler
-                        prepare_doc_compiler(run.builder, run.builder.host_target, 1)
-                    }
                     Mode::ToolTarget => {
-                        // target tools should be documented with the in-tree compiler
+                        // when shipping multiple docs together in one folder,
+                        // they all need to use the same rustdoc version
                         prepare_doc_compiler(run.builder, run.builder.host_target, run.builder.top_stage)
                     }
                     _ => {
@@ -1132,7 +1129,11 @@ macro_rules! tool_doc {
 tool_doc!(
     BuildHelper,
     "src/build_helper",
-    mode = Mode::ToolBootstrap,
+    // ideally, this would use ToolBootstrap,
+    // but we distribute these docs together in the same folder
+    // as a bunch of stage1 tools, and you can't mix rustdoc versions
+    // because that breaks cross-crate data (particularly search)
+    mode = Mode::ToolTarget,
     is_library = true,
     crates = ["build_helper"]
 );
@@ -1175,25 +1176,25 @@ tool_doc!(
     // "specialization" feature in its build script when it detects a nightly toolchain.
     allow_features: "specialization"
 );
-tool_doc!(Tidy, "src/tools/tidy", mode = Mode::ToolBootstrap, crates = ["tidy"]);
+tool_doc!(Tidy, "src/tools/tidy", mode = Mode::ToolTarget, crates = ["tidy"]);
 tool_doc!(
     Bootstrap,
     "src/bootstrap",
-    mode = Mode::ToolBootstrap,
+    mode = Mode::ToolTarget,
     is_library = true,
     crates = ["bootstrap"]
 );
 tool_doc!(
     RunMakeSupport,
     "src/tools/run-make-support",
-    mode = Mode::ToolBootstrap,
+    mode = Mode::ToolTarget,
     is_library = true,
     crates = ["run_make_support"]
 );
 tool_doc!(
     Compiletest,
     "src/tools/compiletest",
-    mode = Mode::ToolBootstrap,
+    mode = Mode::ToolTarget,
     is_library = true,
     crates = ["compiletest"]
 );
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index ca2731819e7..00aea8feab7 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -18,8 +18,8 @@ use crate::core::build_steps::llvm::get_llvm_version;
 use crate::core::build_steps::run::get_completion_paths;
 use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
 use crate::core::build_steps::tool::{
-    self, COMPILETEST_ALLOW_FEATURES, RustcPrivateCompilers, SourceType,
-    TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool, ToolTargetBuildMode, get_tool_target_compiler,
+    self, RustcPrivateCompilers, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool,
+    ToolTargetBuildMode, get_tool_target_compiler,
 };
 use crate::core::build_steps::toolstate::ToolState;
 use crate::core::build_steps::{compile, dist, llvm};
@@ -36,7 +36,7 @@ use crate::utils::helpers::{
     linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date,
 };
 use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
-use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, debug, envify};
+use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify};
 
 const ADB_TEST_DIR: &str = "/data/local/tmp/work";
 
@@ -786,26 +786,26 @@ impl Step for CompiletestTest {
     fn run(self, builder: &Builder<'_>) {
         let host = self.host;
 
+        // Now that compiletest uses only stable Rust, building it always uses
+        // the stage 0 compiler. However, some of its unit tests need to be able
+        // to query information from an in-tree compiler, so we treat `--stage`
+        // as selecting the stage of that secondary compiler.
+
         if builder.top_stage == 0 && !builder.config.compiletest_allow_stage0 {
             eprintln!("\
-ERROR: `--stage 0` runs compiletest self-tests against the stage0 (precompiled) compiler, not the in-tree compiler, and will almost always cause tests to fail
+ERROR: `--stage 0` causes compiletest to query information from the stage0 (precompiled) compiler, instead of the in-tree compiler, which can cause some tests to fail inappropriately
 NOTE: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `--set build.compiletest-allow-stage0=true`."
             );
             crate::exit!(1);
         }
 
-        let compiler = builder.compiler(builder.top_stage, host);
-        debug!(?compiler);
+        let bootstrap_compiler = builder.compiler(0, host);
+        let staged_compiler = builder.compiler(builder.top_stage, host);
 
-        // We need `ToolStd` for the locally-built sysroot because
-        // compiletest uses unstable features of the `test` crate.
-        builder.std(compiler, host);
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
-            // compiletest uses libtest internals; make it use the in-tree std to make sure it never
-            // breaks when std sources change.
-            Mode::ToolStd,
+            bootstrap_compiler,
+            Mode::ToolBootstrap,
             host,
             Kind::Test,
             "src/tools/compiletest",
@@ -816,9 +816,8 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         // Used for `compiletest` self-tests to have the path to the *staged* compiler. Getting this
         // right is important, as `compiletest` is intended to only support one target spec JSON
         // format, namely that of the staged compiler.
-        cargo.env("TEST_RUSTC", builder.rustc(compiler));
+        cargo.env("TEST_RUSTC", builder.rustc(staged_compiler));
 
-        cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
         run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder);
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 4f096d50ea5..819e903020c 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -380,7 +380,6 @@ macro_rules! bootstrap_tool {
     ($(
         $name:ident, $path:expr, $tool_name:expr
         $(,is_external_tool = $external:expr)*
-        $(,is_unstable_tool = $unstable:expr)*
         $(,allow_features = $allow_features:expr)?
         $(,submodules = $submodules:expr)?
         $(,artifact_kind = $artifact_kind:expr)?
@@ -438,19 +437,11 @@ macro_rules! bootstrap_tool {
                     }
                 )*
 
-                let is_unstable = false $(|| $unstable)*;
-                let compiletest_wants_stage0 = $tool_name == "compiletest" && builder.config.compiletest_use_stage0_libtest;
-
                 builder.ensure(ToolBuild {
                     build_compiler: self.compiler,
                     target: self.target,
                     tool: $tool_name,
-                    mode: if is_unstable && !compiletest_wants_stage0 {
-                        // use in-tree libraries for unstable features
-                        Mode::ToolStd
-                    } else {
-                        Mode::ToolBootstrap
-                    },
+                    mode: Mode::ToolBootstrap,
                     path: $path,
                     source_type: if false $(|| $external)* {
                         SourceType::Submodule
@@ -483,8 +474,6 @@ macro_rules! bootstrap_tool {
     }
 }
 
-pub(crate) const COMPILETEST_ALLOW_FEATURES: &str = "internal_output_capture";
-
 bootstrap_tool!(
     // This is marked as an external tool because it includes dependencies
     // from submodules. Trying to keep the lints in sync between all the repos
@@ -495,7 +484,7 @@ bootstrap_tool!(
     Tidy, "src/tools/tidy", "tidy";
     Linkchecker, "src/tools/linkchecker", "linkchecker";
     CargoTest, "src/tools/cargotest", "cargotest";
-    Compiletest, "src/tools/compiletest", "compiletest", is_unstable_tool = true, allow_features = COMPILETEST_ALLOW_FEATURES;
+    Compiletest, "src/tools/compiletest", "compiletest";
     BuildManifest, "src/tools/build-manifest", "build-manifest";
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
     RustInstaller, "src/tools/rust-installer", "rust-installer";
@@ -509,8 +498,7 @@ bootstrap_tool!(
     CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata";
     GenerateCopyright, "src/tools/generate-copyright", "generate-copyright";
     GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
-    // rustdoc-gui-test has a crate dependency on compiletest, so it needs the same unstable features.
-    RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = COMPILETEST_ALLOW_FEATURES;
+    RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test";
     CoverageDump, "src/tools/coverage-dump", "coverage-dump";
     UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
     FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 9fc4ce669c2..a404aec5120 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -10,7 +10,7 @@ use crate::core::config::flags::Color;
 use crate::utils::build_stamp;
 use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags};
 use crate::{
-    BootstrapCommand, CLang, Compiler, Config, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
+    BootstrapCommand, CLang, Compiler, Config, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
     RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t,
 };
 
@@ -851,8 +851,6 @@ impl Builder<'_> {
 
         rustflags.arg("-Zmacro-backtrace");
 
-        let want_rustdoc = self.doc_tests != DocTests::No;
-
         // Clear the output directory if the real rustc we're using has changed;
         // Cargo cannot detect this as it thinks rustc is bootstrap/debug/rustc.
         //
@@ -881,7 +879,8 @@ impl Builder<'_> {
             .env("RUSTC_REAL", self.rustc(compiler))
             .env("RUSTC_STAGE", build_compiler_stage.to_string())
             .env("RUSTC_SYSROOT", sysroot)
-            .env("RUSTC_LIBDIR", libdir)
+            .env("RUSTC_LIBDIR", &libdir)
+            .env("RUSTDOC_LIBDIR", libdir)
             .env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
             .env("RUSTDOC_REAL", rustdoc_path)
             .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir());
@@ -919,11 +918,6 @@ impl Builder<'_> {
             rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
         }
 
-        if !matches!(cmd_kind, Kind::Build | Kind::Check | Kind::Clippy | Kind::Fix) && want_rustdoc
-        {
-            cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
-        }
-
         let debuginfo_level = match mode {
             Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
             Mode::Std => self.config.rust_debuginfo_level_std,
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 006dea4b98d..fc06db8f80b 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1145,7 +1145,7 @@ impl<'a> Builder<'a> {
                 test::RunMakeCargo,
             ),
             Kind::Miri => describe!(test::Crate),
-            Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
+            Kind::Bench => describe!(test::Crate, test::CrateLibrustc, test::CrateRustdoc),
             Kind::Doc => describe!(
                 doc::UnstableBook,
                 doc::UnstableBookGen,
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index a3c8380a3c7..3306435758b 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1158,13 +1158,12 @@ mod snapshot {
         [doc] embedded-book (book) <host>
         [doc] edition-guide (book) <host>
         [doc] style-guide (book) <host>
-        [build] rustdoc 0 <host>
-        [doc] rustc 0 <host> -> Tidy 1 <host>
-        [doc] rustc 0 <host> -> Bootstrap 1 <host>
+        [doc] rustc 1 <host> -> Tidy 2 <host>
+        [doc] rustc 1 <host> -> Bootstrap 2 <host>
         [doc] rustc 1 <host> -> releases 2 <host>
-        [doc] rustc 0 <host> -> RunMakeSupport 1 <host>
-        [doc] rustc 0 <host> -> BuildHelper 1 <host>
-        [doc] rustc 0 <host> -> Compiletest 1 <host>
+        [doc] rustc 1 <host> -> RunMakeSupport 2 <host>
+        [doc] rustc 1 <host> -> BuildHelper 2 <host>
+        [doc] rustc 1 <host> -> Compiletest 2 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
         "
         );
@@ -2005,21 +2004,6 @@ mod snapshot {
     }
 
     #[test]
-    fn check_compiletest_stage1_libtest() {
-        let ctx = TestCtx::new();
-        insta::assert_snapshot!(
-            ctx.config("check")
-                .path("compiletest")
-                .args(&["--set", "build.compiletest-use-stage0-libtest=false"])
-                .render_steps(), @r"
-        [build] llvm <host>
-        [build] rustc 0 <host> -> rustc 1 <host>
-        [build] rustc 1 <host> -> std 1 <host>
-        [check] rustc 1 <host> -> Compiletest 2 <host>
-        ");
-    }
-
-    #[test]
     fn check_codegen() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
@@ -2146,6 +2130,17 @@ mod snapshot {
     }
 
     #[test]
+    fn test_compiletest_self_test() {
+        let ctx = TestCtx::new();
+        let steps = ctx.config("test").arg("compiletest").render_steps();
+        insta::assert_snapshot!(steps, @r"
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustdoc 0 <host>
+        ");
+    }
+
+    #[test]
     fn test_compiletest_suites_stage1() {
         let ctx = TestCtx::new();
         insta::assert_snapshot!(
@@ -2690,8 +2685,11 @@ mod snapshot {
                 .path("src/tools/compiletest")
                 .stage(2)
                 .render_steps(), @r"
-        [build] rustdoc 0 <host>
-        [doc] rustc 0 <host> -> Compiletest 1 <host>
+        [build] llvm <host>
+        [build] rustc 0 <host> -> rustc 1 <host>
+        [build] rustc 1 <host> -> std 1 <host>
+        [build] rustdoc 1 <host>
+        [doc] rustc 1 <host> -> Compiletest 2 <host>
         ");
     }
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 271ce4cb950..1fcc1174e85 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -310,9 +310,6 @@ pub struct Config {
     /// sources.
     pub compiletest_allow_stage0: bool,
 
-    /// Whether to use the precompiled stage0 libtest with compiletest.
-    pub compiletest_use_stage0_libtest: bool,
-
     /// Default value for `--extra-checks`
     pub tidy_extra_checks: Option<String>,
     pub is_running_on_ci: bool,
@@ -497,7 +494,8 @@ impl Config {
             optimized_compiler_builtins: build_optimized_compiler_builtins,
             jobs: build_jobs,
             compiletest_diff_tool: build_compiletest_diff_tool,
-            compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest,
+            // No longer has any effect; kept (for now) to avoid breaking people's configs.
+            compiletest_use_stage0_libtest: _,
             tidy_extra_checks: build_tidy_extra_checks,
             ccache: build_ccache,
             exclude: build_exclude,
@@ -1197,7 +1195,6 @@ impl Config {
             compiler_docs: build_compiler_docs.unwrap_or(false),
             compiletest_allow_stage0: build_compiletest_allow_stage0.unwrap_or(false),
             compiletest_diff_tool: build_compiletest_diff_tool,
-            compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest.unwrap_or(true),
             config: toml_path,
             configure_args: build_configure_args.unwrap_or_default(),
             control_flow_guard: rust_control_flow_guard.unwrap_or(false),
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 56b87823a36..007ed4aaba1 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -47,11 +47,17 @@ use crate::str::FromStr;
 #[macro_export]
 macro_rules! define_config {
     ($(#[$attr:meta])* struct $name:ident {
-        $($field:ident: Option<$field_ty:ty> = $field_key:literal,)*
+        $(
+            $(#[$field_attr:meta])*
+            $field:ident: Option<$field_ty:ty> = $field_key:literal,
+        )*
     }) => {
         $(#[$attr])*
         pub struct $name {
-            $(pub $field: Option<$field_ty>,)*
+            $(
+                $(#[$field_attr])*
+                pub $field: Option<$field_ty>,
+            )*
         }
 
         impl Merge for $name {
diff --git a/src/bootstrap/src/core/config/toml/build.rs b/src/bootstrap/src/core/config/toml/build.rs
index a9d4d3961c9..c63673dd980 100644
--- a/src/bootstrap/src/core/config/toml/build.rs
+++ b/src/bootstrap/src/core/config/toml/build.rs
@@ -70,6 +70,8 @@ define_config! {
         jobs: Option<u32> = "jobs",
         compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
         compiletest_allow_stage0: Option<bool> = "compiletest-allow-stage0",
+        /// No longer has any effect; kept (for now) to avoid breaking people's configs.
+        /// FIXME(#146929): Remove this in 2026.
         compiletest_use_stage0_libtest: Option<bool> = "compiletest-use-stage0-libtest",
         tidy_extra_checks: Option<String> = "tidy-extra-checks",
         ccache: Option<StringOrBool> = "ccache",
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index d798639cc96..dd30f05b728 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -327,8 +327,8 @@ pub enum Mode {
     ToolTarget,
 
     /// Build a tool which uses the locally built std, placing output in the
-    /// "stageN-tools" directory. Its usage is quite rare, mainly used by
-    /// compiletest which needs libtest.
+    /// "stageN-tools" directory. Its usage is quite rare; historically it was
+    /// needed by compiletest, but now it is mainly used by `test-float-parse`.
     ToolStd,
 
     /// Build a tool which uses the `rustc_private` mechanism, and thus
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index f311c84bec9..853fc4e6623 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -557,8 +557,13 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         summary: "New option `build.windows-rc` that will override which resource compiler on Windows will be used to compile Rust.",
     },
     ChangeInfo {
-        change_id: 99999,
+        change_id: 147046,
         severity: ChangeSeverity::Warning,
         summary: "The `rust.use-lld` option has been renamed to `rust.bootstrap-override-lld`. Note that it only serves for overriding the linker used when building Rust code in bootstrap to be LLD.",
     },
+    ChangeInfo {
+        change_id: 146929,
+        severity: ChangeSeverity::Info,
+        summary: "`compiletest` is now always built with the stage 0 compiler, so `build.compiletest-use-stage0-libtest` has no effect.",
+    },
 ];
diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml
index d82b3e7648e..512c8062857 100644
--- a/src/ci/citool/tests/test-jobs.yml
+++ b/src/ci/citool/tests/test-jobs.yml
@@ -27,7 +27,7 @@ runners:
     <<: *base-job
 envs:
   env-x86_64-apple-tests: &env-x86_64-apple-tests
-    SCRIPT: ./x.py check compiletest --set build.compiletest-use-stage0-libtest=true && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact
+    SCRIPT: ./x.py check compiletest && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact
     RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc
     RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
     # Ensure that host tooling is tested on our minimum supported macOS version.
diff --git a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
index 04ac0f33daf..776bbb12e44 100644
--- a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
+++ b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile
@@ -43,7 +43,6 @@ ENV SCRIPT \
   python3 ../x.py check bootstrap && \
   /scripts/check-default-config-profiles.sh && \
   python3 ../x.py build src/tools/build-manifest && \
-  python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \
   python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
   python3 ../x.py check --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
   /scripts/validate-toolstate.sh && \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 95357d22937..278e40eb71f 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -90,5 +90,4 @@ ENV HOST_TARGET x86_64-unknown-linux-gnu
 COPY scripts/shared.sh /scripts/
 
 ENV SCRIPT /tmp/checktools.sh ../x.py && \
-  python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \
   python3 ../x.py test tests/rustdoc-gui --stage 2 --test-args "'--jobs 1'"
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 8303699ce8a..4384ec76769 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -430,7 +430,8 @@ auto:
       # Ensure that host tooling is built to support our minimum support macOS version.
       MACOSX_DEPLOYMENT_TARGET: 10.12
       MACOSX_STD_DEPLOYMENT_TARGET: 10.12
-      SELECT_XCODE: /Applications/Xcode_15.2.app
+      SELECT_XCODE: /Applications/Xcode_15.4.app
+      USE_XCODE_CLANG: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-macos
@@ -450,21 +451,24 @@ auto:
 
   - name: dist-aarch64-apple
     env:
-      SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
+      SCRIPT: >-
+        ./x.py dist bootstrap
+        --include-default-paths
+        --host=aarch64-apple-darwin
+        --target=aarch64-apple-darwin
       RUST_CONFIGURE_ARGS: >-
         --enable-full-tools
         --enable-sanitizers
         --enable-profiler
         --set rust.jemalloc
-        --set llvm.ninja=false
         --set rust.lto=thin
         --set rust.codegen-units=1
-      SELECT_XCODE: /Applications/Xcode_15.4.app
-      USE_XCODE_CLANG: 1
       # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else
       # supports the hardware.
       MACOSX_DEPLOYMENT_TARGET: 11.0
       MACOSX_STD_DEPLOYMENT_TARGET: 11.0
+      SELECT_XCODE: /Applications/Xcode_15.4.app
+      USE_XCODE_CLANG: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-macos
diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md
index 5b002b435a5..09b55da741d 100644
--- a/src/doc/rustc/src/lints/levels.md
+++ b/src/doc/rustc/src/lints/levels.md
@@ -38,7 +38,7 @@ talk about later in this section.
 
 Sometimes, it can be helpful to suppress lints, but at the same time ensure that
 the code in question still emits them. The 'expect' level does exactly this. If
-the lint in question is not emitted, the `unfulfilled_lint_expectation` lint
+the lint in question is not emitted, the `unfulfilled_lint_expectations` lint
 triggers on the `expect` attribute, notifying you that the expectation is no
 longer fulfilled.
 
diff --git a/src/doc/unstable-book/src/compiler-flags/split-dwarf-out-dir.md b/src/doc/unstable-book/src/compiler-flags/split-dwarf-out-dir.md
new file mode 100644
index 00000000000..a2070730b42
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/split-dwarf-out-dir.md
@@ -0,0 +1,7 @@
+# `split-dwarf-out-dir`
+
+On systems which use DWARF debug info this flag causes `.dwo` files produced
+by `-C split-debuginfo` to be written to the specified directory rather than
+placed next to the object files. This is mostly useful if you have a build
+system which needs to control where to find compile outputs without running the
+compiler and have to put your `.dwo` files in a separate directory.
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 65f18baa937..3eb964d2fba 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -761,7 +761,8 @@ class MSVCTupleSyntheticProvider:
 
     def get_child_at_index(self, index: int) -> SBValue:
         child: SBValue = self.valobj.GetChildAtIndex(index)
-        return child.CreateChildAtOffset(str(index), 0, child.GetType())
+        offset = self.valobj.GetType().GetFieldAtIndex(index).byte_offset
+        return self.valobj.CreateChildAtOffset(str(index), offset, child.GetType())
 
     def update(self):
         pass
@@ -772,7 +773,7 @@ class MSVCTupleSyntheticProvider:
     def get_type_name(self) -> str:
         name = self.valobj.GetTypeName()
         # remove "tuple$<" and ">", str.removeprefix and str.removesuffix require python 3.9+
-        name = name[7:-1]
+        name = name[7:-1].strip()
         return "(" + name + ")"
 
 
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index c2cf39c4be0..6e3dfa0ac22 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1084,8 +1084,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
 
     let mut changed_auto_active_status = None;
 
-    // First we get all `doc(auto_cfg)` attributes.
-    for attr in attrs.clone() {
+    // We get all `doc(auto_cfg)`, `cfg` and `target_feature` attributes.
+    for attr in attrs {
         if let Some(ident) = attr.ident()
             && ident.name == sym::doc
             && let Some(attrs) = attr.meta_item_list()
@@ -1146,15 +1146,9 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
                     }
                 }
             }
-        }
-    }
-
-    // If there is no `doc(cfg())`, then we retrieve the `cfg()` attributes (because
-    // `doc(cfg())` overrides `cfg()`).
-    for attr in attrs {
-        if let hir::Attribute::Parsed(AttributeKind::TargetFeature { features, .. }) = attr {
-            // treat #[target_feature(enable = "feat")] attributes as if they were
-            // #[doc(cfg(target_feature = "feat"))] attributes as well
+        } else if let hir::Attribute::Parsed(AttributeKind::TargetFeature { features, .. }) = attr {
+            // Treat `#[target_feature(enable = "feat")]` attributes as if they were
+            // `#[doc(cfg(target_feature = "feat"))]` attributes as well.
             for (feature, _) in features {
                 cfg_info.current_cfg &= Cfg::Cfg(sym::target_feature, Some(*feature));
             }
@@ -1685,7 +1679,7 @@ impl Type {
         match (self_cleared, other_cleared) {
             // Recursive cases.
             (Type::Tuple(a), Type::Tuple(b)) => {
-                a.len() == b.len() && a.iter().zip(b).all(|(a, b)| a.is_doc_subtype_of(b, cache))
+                a.iter().eq_by(b, |a, b| a.is_doc_subtype_of(b, cache))
             }
             (Type::Slice(a), Type::Slice(b)) => a.is_doc_subtype_of(b, cache),
             (Type::Array(a, al), Type::Array(b, bl)) => al == bl && a.is_doc_subtype_of(b, cache),
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index fad15573cde..1dcb4dcc3ff 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -12,15 +12,16 @@ use std::iter;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind};
+use rustc_span::BytePos;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::Symbol;
-use rustc_span::{BytePos, DUMMY_SP, Span};
 
 use super::format;
 use crate::clean::PrimitiveType;
 use crate::display::Joined as _;
 use crate::html::escape::EscapeBodyText;
 use crate::html::macro_expansion::ExpandedCode;
+use crate::html::render::span_map::{DUMMY_SP, Span};
 use crate::html::render::{Context, LinkFromSrc};
 
 /// This type is needed in case we want to render links on items to allow to go to their definition.
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index 2603e887bea..4d1bee9b3a1 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -1,6 +1,7 @@
 use expect_test::expect_file;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_span::create_default_session_globals_then;
+use test::Bencher;
 
 use super::{DecorationInfo, write_code};
 
@@ -81,3 +82,16 @@ let a = 4;";
         expect_file!["fixtures/decorations.html"].assert_eq(&html);
     });
 }
+
+#[bench]
+fn bench_html_highlighting(b: &mut Bencher) {
+    let src = include_str!("../../../../compiler/rustc_ast/src/visit.rs");
+
+    create_default_session_globals_then(|| {
+        b.iter(|| {
+            let mut out = String::new();
+            write_code(&mut out, src, None, None, None);
+            out
+        });
+    });
+}
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 5f92ab2fada..4c06d0da470 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -30,6 +30,7 @@ use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::macro_expansion::ExpandedCode;
 use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary};
+use crate::html::render::span_map::Span;
 use crate::html::render::write_shared::write_shared;
 use crate::html::url_parts_builder::UrlPartsBuilder;
 use crate::html::{layout, sources, static_files};
@@ -139,7 +140,7 @@ pub(crate) struct SharedContext<'tcx> {
 
     /// Correspondence map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
-    pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
+    pub(crate) span_correspondence_map: FxHashMap<Span, LinkFromSrc>,
     pub(crate) expanded_codes: FxHashMap<BytePos, Vec<ExpandedCode>>,
     /// The [`Cache`] used during rendering.
     pub(crate) cache: Cache,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 97dcaf57cdf..d6371e4dbab 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -36,7 +36,7 @@ mod ordered_json;
 mod print_item;
 pub(crate) mod sidebar;
 mod sorted_template;
-mod span_map;
+pub(crate) mod span_map;
 mod type_layout;
 mod write_shared;
 
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index ef7ce33298d..bc9417b1bb1 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -8,11 +8,48 @@ use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, QPath};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::{BytePos, ExpnKind, Span};
+use rustc_span::{BytePos, ExpnKind};
 
 use crate::clean::{self, PrimitiveType, rustc_span};
 use crate::html::sources;
 
+/// This is a stripped down version of [`rustc_span::Span`] that only contains the start and end byte positions of the span.
+///
+/// Profiling showed that the `Span` interner was taking up a lot of the run-time when highlighting, and since we
+/// never actually use the context and parent that are stored in a normal `Span`, we can replace its usages with this
+/// one, which is much cheaper to construct.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub(crate) struct Span {
+    lo: BytePos,
+    hi: BytePos,
+}
+
+impl From<rustc_span::Span> for Span {
+    fn from(value: rustc_span::Span) -> Self {
+        Self { lo: value.lo(), hi: value.hi() }
+    }
+}
+
+impl Span {
+    pub(crate) fn lo(self) -> BytePos {
+        self.lo
+    }
+
+    pub(crate) fn hi(self) -> BytePos {
+        self.hi
+    }
+
+    pub(crate) fn with_lo(self, lo: BytePos) -> Self {
+        Self { lo, hi: self.hi() }
+    }
+
+    pub(crate) fn with_hi(self, hi: BytePos) -> Self {
+        Self { lo: self.lo(), hi }
+    }
+}
+
+pub(crate) const DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0) };
+
 /// This enum allows us to store two different kinds of information:
 ///
 /// In case the `span` definition comes from the same crate, we can simply get the `span` and use
@@ -96,7 +133,7 @@ impl SpanMapVisitor<'_> {
                         })
                         .unwrap_or(path.span)
                 };
-                self.matches.insert(span, link);
+                self.matches.insert(span.into(), link);
             }
             Res::Local(_) if let Some(span) = self.tcx.hir_res_span(path.res) => {
                 let path_span = if only_use_last_segment
@@ -106,11 +143,12 @@ impl SpanMapVisitor<'_> {
                 } else {
                     path.span
                 };
-                self.matches.insert(path_span, LinkFromSrc::Local(clean::Span::new(span)));
+                self.matches.insert(path_span.into(), LinkFromSrc::Local(clean::Span::new(span)));
             }
             Res::PrimTy(p) => {
                 // FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
-                self.matches.insert(path.span, LinkFromSrc::Primitive(PrimitiveType::from(p)));
+                self.matches
+                    .insert(path.span.into(), LinkFromSrc::Primitive(PrimitiveType::from(p)));
             }
             Res::Err => {}
             _ => {}
@@ -127,7 +165,7 @@ impl SpanMapVisitor<'_> {
             if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
                 return;
             }
-            self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
+            self.matches.insert(span.into(), LinkFromSrc::Doc(item.owner_id.to_def_id()));
         }
     }
 
@@ -138,7 +176,7 @@ impl SpanMapVisitor<'_> {
     /// so, we loop until we find the macro definition by using `outer_expn_data` in a loop.
     /// Finally, we get the information about the macro itself (`span` if "local", `DefId`
     /// otherwise) and store it inside the span map.
-    fn handle_macro(&mut self, span: Span) -> bool {
+    fn handle_macro(&mut self, span: rustc_span::Span) -> bool {
         if !span.from_expansion() {
             return false;
         }
@@ -176,7 +214,7 @@ impl SpanMapVisitor<'_> {
         // The "call_site" includes the whole macro with its "arguments". We only want
         // the macro name.
         let new_span = new_span.with_hi(new_span.lo() + BytePos(macro_name.len() as u32));
-        self.matches.insert(new_span, link_from_src);
+        self.matches.insert(new_span.into(), link_from_src);
         true
     }
 
@@ -233,7 +271,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         intravisit::walk_path(self, path);
     }
 
-    fn visit_qpath(&mut self, qpath: &QPath<'tcx>, id: HirId, _span: Span) {
+    fn visit_qpath(&mut self, qpath: &QPath<'tcx>, id: HirId, _span: rustc_span::Span) {
         match *qpath {
             QPath::TypeRelative(qself, path) => {
                 if matches!(path.res, Res::Err) {
@@ -249,7 +287,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
                         self.handle_path(&path, false);
                     }
                 } else {
-                    self.infer_id(path.hir_id, Some(id), path.ident.span);
+                    self.infer_id(path.hir_id, Some(id), path.ident.span.into());
                 }
 
                 rustc_ast::visit::try_visit!(self.visit_ty_unambig(qself));
@@ -267,7 +305,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         }
     }
 
-    fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
+    fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: rustc_span::Span, id: HirId) {
         // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
         // file, we want to link to it. Otherwise no need to create a link.
         if !span.overlaps(m.spans.inner_span) {
@@ -275,8 +313,10 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
             // name only and not all the "mod foo;".
             if let Node::Item(item) = self.tcx.hir_node(id) {
                 let (ident, _) = item.expect_mod();
-                self.matches
-                    .insert(ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)));
+                self.matches.insert(
+                    ident.span.into(),
+                    LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
+                );
             }
         } else {
             // If it's a "mod foo {}", we want to look to its documentation page.
@@ -288,9 +328,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
         match expr.kind {
             ExprKind::MethodCall(segment, ..) => {
-                self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span)
+                self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span.into())
             }
-            ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span),
+            ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span.into()),
             _ => {
                 if self.handle_macro(expr.span) {
                     // We don't want to go deeper into the macro.
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 9c5518a780e..c79f63fbc20 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -348,7 +348,12 @@ pub(crate) fn print_src(
         highlight::write_code(
             fmt,
             s,
-            Some(highlight::HrefContext { context, file_span, root_path, current_href }),
+            Some(highlight::HrefContext {
+                context,
+                file_span: file_span.into(),
+                root_path,
+                current_href,
+            }),
             Some(decoration_info),
             Some(line_info),
         );
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index c4f24e09ddb..d7ffb25f8bd 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -13,6 +13,7 @@
 #![feature(if_let_guard)]
 #![feature(iter_advance_by)]
 #![feature(iter_intersperse)]
+#![feature(iter_order_by)]
 #![feature(rustc_private)]
 #![feature(test)]
 #![warn(rustc::internal)]
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 475d05b7d0e..f45df8d2d0d 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -77,11 +77,11 @@ pub(crate) enum Condition {
 pub(crate) const PASSES: &[Pass] = &[
     CHECK_DOC_CFG,
     CHECK_DOC_TEST_VISIBILITY,
+    PROPAGATE_DOC_CFG,
     STRIP_ALIASED_NON_LOCAL,
     STRIP_HIDDEN,
     STRIP_PRIVATE,
     STRIP_PRIV_IMPORTS,
-    PROPAGATE_DOC_CFG,
     PROPAGATE_STABILITY,
     COLLECT_INTRA_DOC_LINKS,
     COLLECT_TRAIT_IMPLS,
@@ -94,11 +94,11 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[
     ConditionalPass::always(COLLECT_TRAIT_IMPLS),
     ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY),
     ConditionalPass::always(CHECK_DOC_CFG),
+    ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
     ConditionalPass::always(STRIP_ALIASED_NON_LOCAL),
     ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden),
     ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
     ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate),
-    ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
     ConditionalPass::always(PROPAGATE_DOC_CFG),
     ConditionalPass::always(PROPAGATE_STABILITY),
     ConditionalPass::always(RUN_LINTS),
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index d78da9396fa..7d14ba7fcf1 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -43,8 +43,8 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_f
             expr.span,
             format!(
                 "casting from `{cast_from}` to a more-strictly-aligned pointer (`{cast_to}`) ({} < {} bytes)",
-                from_layout.align.abi.bytes(),
-                to_layout.align.abi.bytes(),
+                from_layout.align.bytes(),
+                to_layout.align.bytes(),
             ),
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs
index 92910cf8adf..ff5320719aa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs
@@ -72,7 +72,7 @@ fn is_literal_aligned(cx: &LateContext<'_>, lit: &Spanned<LitKind>, to: &Ty<'_>)
     cx.tcx
         .layout_of(cx.typing_env().as_query_input(to_mid_ty))
         .is_ok_and(|layout| {
-            let align = u128::from(layout.align.abi.bytes());
+            let align = u128::from(layout.align.bytes());
             u128::from(val) <= align
         })
 }
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 6da102b1b5f..6d959948918 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -661,18 +661,10 @@ pub struct Config {
     pub builtin_cfg_names: OnceLock<HashSet<String>>,
     pub supported_crate_types: OnceLock<HashSet<String>>,
 
-    /// FIXME: this is why we still need to depend on *staged* `std`, it's because we currently rely
-    /// on `#![feature(internal_output_capture)]` for [`std::io::set_output_capture`] to implement
-    /// `libtest`-esque `--no-capture`.
-    ///
     /// FIXME: rename this to the more canonical `no_capture`, or better, invert this to `capture`
     /// to avoid `!nocapture` double-negatives.
     pub nocapture: bool,
 
-    /// True if the experimental new output-capture implementation should be
-    /// used, avoiding the need for `#![feature(internal_output_capture)]`.
-    pub new_output_capture: bool,
-
     /// Needed both to construct [`build_helper::git::GitConfig`].
     pub nightly_branch: String,
     pub git_merge_commit_email: String,
@@ -790,7 +782,6 @@ impl Config {
             builtin_cfg_names: Default::default(),
             supported_crate_types: Default::default(),
             nocapture: Default::default(),
-            new_output_capture: Default::default(),
             nightly_branch: Default::default(),
             git_merge_commit_email: Default::default(),
             profiler_runtime: Default::default(),
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index e84a2278766..e6916610190 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -63,9 +63,10 @@ impl EarlyProps {
             &mut poisoned,
             testfile,
             rdr,
-            &mut |DirectiveLine { line_number, raw_directive: ln, .. }| {
-                parse_and_update_aux(config, ln, testfile, line_number, &mut props.aux);
-                config.parse_and_update_revisions(testfile, line_number, ln, &mut props.revisions);
+            // (dummy comment to force args into vertical layout)
+            &mut |ref ln: DirectiveLine<'_>| {
+                parse_and_update_aux(config, ln, testfile, &mut props.aux);
+                config.parse_and_update_revisions(testfile, ln, &mut props.revisions);
             },
         );
 
@@ -367,8 +368,8 @@ impl TestProps {
                 &mut poisoned,
                 testfile,
                 file,
-                &mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
-                    if !directive.applies_to_test_revision(test_revision) {
+                &mut |ref ln: DirectiveLine<'_>| {
+                    if !ln.applies_to_test_revision(test_revision) {
                         return;
                     }
 
@@ -378,7 +379,6 @@ impl TestProps {
                         ln,
                         ERROR_PATTERN,
                         testfile,
-                        line_number,
                         &mut self.error_patterns,
                         |r| r,
                     );
@@ -386,7 +386,6 @@ impl TestProps {
                         ln,
                         REGEX_ERROR_PATTERN,
                         testfile,
-                        line_number,
                         &mut self.regex_error_patterns,
                         |r| r,
                     );
@@ -395,7 +394,6 @@ impl TestProps {
                         ln,
                         DOC_FLAGS,
                         testfile,
-                        line_number,
                         &mut self.doc_flags,
                         |r| r,
                     );
@@ -414,7 +412,7 @@ impl TestProps {
                     }
 
                     if let Some(flags) =
-                        config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile, line_number)
+                        config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile)
                     {
                         let flags = split_flags(&flags);
                         for flag in &flags {
@@ -425,39 +423,28 @@ impl TestProps {
                         self.compile_flags.extend(flags);
                     }
                     if config
-                        .parse_name_value_directive(
-                            ln,
-                            INCORRECT_COMPILER_FLAGS,
-                            testfile,
-                            line_number,
-                        )
+                        .parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS, testfile)
                         .is_some()
                     {
                         panic!("`compiler-flags` directive should be spelled `compile-flags`");
                     }
 
-                    if let Some(edition) = config.parse_edition(ln, testfile, line_number) {
+                    if let Some(edition) = config.parse_edition(ln, testfile) {
                         // The edition is added at the start, since flags from //@compile-flags must
                         // be passed to rustc last.
                         self.compile_flags.insert(0, format!("--edition={}", edition.trim()));
                         has_edition = true;
                     }
 
-                    config.parse_and_update_revisions(
-                        testfile,
-                        line_number,
-                        ln,
-                        &mut self.revisions,
-                    );
+                    config.parse_and_update_revisions(testfile, ln, &mut self.revisions);
 
-                    if let Some(flags) =
-                        config.parse_name_value_directive(ln, RUN_FLAGS, testfile, line_number)
+                    if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS, testfile)
                     {
                         self.run_flags.extend(split_flags(&flags));
                     }
 
                     if self.pp_exact.is_none() {
-                        self.pp_exact = config.parse_pp_exact(ln, testfile, line_number);
+                        self.pp_exact = config.parse_pp_exact(ln, testfile);
                     }
 
                     config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
@@ -479,9 +466,7 @@ impl TestProps {
                     );
                     config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic);
 
-                    if let Some(m) =
-                        config.parse_name_value_directive(ln, PRETTY_MODE, testfile, line_number)
-                    {
+                    if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE, testfile) {
                         self.pretty_mode = m;
                     }
 
@@ -492,13 +477,12 @@ impl TestProps {
                     );
 
                     // Call a helper method to deal with aux-related directives.
-                    parse_and_update_aux(config, ln, testfile, line_number, &mut self.aux);
+                    parse_and_update_aux(config, ln, testfile, &mut self.aux);
 
                     config.push_name_value_directive(
                         ln,
                         EXEC_ENV,
                         testfile,
-                        line_number,
                         &mut self.exec_env,
                         Config::parse_env,
                     );
@@ -506,7 +490,6 @@ impl TestProps {
                         ln,
                         UNSET_EXEC_ENV,
                         testfile,
-                        line_number,
                         &mut self.unset_exec_env,
                         |r| r.trim().to_owned(),
                     );
@@ -514,7 +497,6 @@ impl TestProps {
                         ln,
                         RUSTC_ENV,
                         testfile,
-                        line_number,
                         &mut self.rustc_env,
                         Config::parse_env,
                     );
@@ -522,7 +504,6 @@ impl TestProps {
                         ln,
                         UNSET_RUSTC_ENV,
                         testfile,
-                        line_number,
                         &mut self.unset_rustc_env,
                         |r| r.trim().to_owned(),
                     );
@@ -530,7 +511,6 @@ impl TestProps {
                         ln,
                         FORBID_OUTPUT,
                         testfile,
-                        line_number,
                         &mut self.forbid_output,
                         |r| r,
                     );
@@ -566,7 +546,7 @@ impl TestProps {
                     }
 
                     if let Some(code) = config
-                        .parse_name_value_directive(ln, FAILURE_STATUS, testfile, line_number)
+                        .parse_name_value_directive(ln, FAILURE_STATUS, testfile)
                         .and_then(|code| code.trim().parse::<i32>().ok())
                     {
                         self.failure_status = Some(code);
@@ -588,7 +568,6 @@ impl TestProps {
                         ln,
                         ASSEMBLY_OUTPUT,
                         testfile,
-                        line_number,
                         &mut self.assembly_output,
                         |r| r.trim().to_string(),
                     );
@@ -602,7 +581,7 @@ impl TestProps {
                     // Unlike the other `name_value_directive`s this needs to be handled manually,
                     // because it sets a `bool` flag.
                     if let Some(known_bug) =
-                        config.parse_name_value_directive(ln, KNOWN_BUG, testfile, line_number)
+                        config.parse_name_value_directive(ln, KNOWN_BUG, testfile)
                     {
                         let known_bug = known_bug.trim();
                         if known_bug == "unknown"
@@ -632,24 +611,20 @@ impl TestProps {
                         ln,
                         TEST_MIR_PASS,
                         testfile,
-                        line_number,
                         &mut self.mir_unit_test,
                         |s| s.trim().to_string(),
                     );
                     config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base);
 
                     if let Some(flags) =
-                        config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile, line_number)
+                        config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile)
                     {
                         self.llvm_cov_flags.extend(split_flags(&flags));
                     }
 
-                    if let Some(flags) = config.parse_name_value_directive(
-                        ln,
-                        FILECHECK_FLAGS,
-                        testfile,
-                        line_number,
-                    ) {
+                    if let Some(flags) =
+                        config.parse_name_value_directive(ln, FILECHECK_FLAGS, testfile)
+                    {
                         self.filecheck_flags.extend(split_flags(&flags));
                     }
 
@@ -661,7 +636,6 @@ impl TestProps {
                         ln,
                         directives::CORE_STUBS_COMPILE_FLAGS,
                         testfile,
-                        line_number,
                     ) {
                         let flags = split_flags(&flags);
                         for flag in &flags {
@@ -672,12 +646,9 @@ impl TestProps {
                         self.core_stubs_compile_flags.extend(flags);
                     }
 
-                    if let Some(err_kind) = config.parse_name_value_directive(
-                        ln,
-                        DONT_REQUIRE_ANNOTATIONS,
-                        testfile,
-                        line_number,
-                    ) {
+                    if let Some(err_kind) =
+                        config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS, testfile)
+                    {
                         self.dont_require_annotations
                             .insert(ErrorKind::expect_from_user_str(err_kind.trim()));
                     }
@@ -734,7 +705,7 @@ impl TestProps {
         }
     }
 
-    fn update_fail_mode(&mut self, ln: &str, config: &Config) {
+    fn update_fail_mode(&mut self, ln: &DirectiveLine<'_>, config: &Config) {
         let check_ui = |mode: &str| {
             // Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows
             if config.mode != TestMode::Ui && config.mode != TestMode::Crashes {
@@ -769,7 +740,12 @@ impl TestProps {
         }
     }
 
-    fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
+    fn update_pass_mode(
+        &mut self,
+        ln: &DirectiveLine<'_>,
+        revision: Option<&str>,
+        config: &Config,
+    ) {
         let check_no_run = |s| match (config.mode, s) {
             (TestMode::Ui, _) => (),
             (TestMode::Crashes, _) => (),
@@ -814,7 +790,7 @@ impl TestProps {
         self.pass_mode
     }
 
-    pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) {
+    fn update_add_core_stubs(&mut self, ln: &DirectiveLine<'_>, config: &Config) {
         let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS);
         if add_core_stubs {
             if !matches!(config.mode, TestMode::Ui | TestMode::Codegen | TestMode::Assembly) {
@@ -905,10 +881,12 @@ pub(crate) struct CheckDirectiveResult<'ln> {
     trailing_directive: Option<&'ln str>,
 }
 
-pub(crate) fn check_directive<'a>(
-    directive_ln: &'a str,
+fn check_directive<'a>(
+    directive_ln: &DirectiveLine<'a>,
     mode: TestMode,
 ) -> CheckDirectiveResult<'a> {
+    let &DirectiveLine { raw_directive: directive_ln, .. } = directive_ln;
+
     let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, ""));
 
     let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name)
@@ -980,7 +958,7 @@ fn iter_directives(
         // Perform unknown directive check on Rust files.
         if testfile.extension() == Some("rs") {
             let CheckDirectiveResult { is_known_directive, trailing_directive } =
-                check_directive(directive_line.raw_directive, mode);
+                check_directive(&directive_line, mode);
 
             if !is_known_directive {
                 *poisoned = true;
@@ -1014,8 +992,7 @@ impl Config {
     fn parse_and_update_revisions(
         &self,
         testfile: &Utf8Path,
-        line_number: usize,
-        line: &str,
+        line: &DirectiveLine<'_>,
         existing: &mut Vec<String>,
     ) {
         const FORBIDDEN_REVISION_NAMES: [&str; 2] = [
@@ -1028,8 +1005,7 @@ impl Config {
         const FILECHECK_FORBIDDEN_REVISION_NAMES: [&str; 9] =
             ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"];
 
-        if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile, line_number)
-        {
+        if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile) {
             if self.mode == TestMode::RunMake {
                 panic!("`run-make` mode tests do not support revisions: {}", testfile);
             }
@@ -1074,13 +1050,8 @@ impl Config {
         (name.to_owned(), value.to_owned())
     }
 
-    fn parse_pp_exact(
-        &self,
-        line: &str,
-        testfile: &Utf8Path,
-        line_number: usize,
-    ) -> Option<Utf8PathBuf> {
-        if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile, line_number) {
+    fn parse_pp_exact(&self, line: &DirectiveLine<'_>, testfile: &Utf8Path) -> Option<Utf8PathBuf> {
+        if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile) {
             Some(Utf8PathBuf::from(&s))
         } else if self.parse_name_directive(line, "pp-exact") {
             testfile.file_name().map(Utf8PathBuf::from)
@@ -1089,7 +1060,9 @@ impl Config {
         }
     }
 
-    fn parse_custom_normalization(&self, raw_directive: &str) -> Option<NormalizeRule> {
+    fn parse_custom_normalization(&self, line: &DirectiveLine<'_>) -> Option<NormalizeRule> {
+        let &DirectiveLine { raw_directive, .. } = line;
+
         // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine`
         // instead of doing it here.
         let (directive_name, raw_value) = raw_directive.split_once(':')?;
@@ -1110,24 +1083,23 @@ impl Config {
         Some(NormalizeRule { kind, regex, replacement })
     }
 
-    fn parse_name_directive(&self, line: &str, directive: &str) -> bool {
+    fn parse_name_directive(&self, line: &DirectiveLine<'_>, directive: &str) -> bool {
+        let &DirectiveLine { raw_directive: line, .. } = line;
+
         // Ensure the directive is a whole word. Do not match "ignore-x86" when
         // the line says "ignore-x86_64".
         line.starts_with(directive)
             && matches!(line.as_bytes().get(directive.len()), None | Some(&b' ') | Some(&b':'))
     }
 
-    fn parse_negative_name_directive(&self, line: &str, directive: &str) -> bool {
-        line.starts_with("no-") && self.parse_name_directive(&line[3..], directive)
-    }
-
-    pub fn parse_name_value_directive(
+    fn parse_name_value_directive(
         &self,
-        line: &str,
+        line: &DirectiveLine<'_>,
         directive: &str,
         testfile: &Utf8Path,
-        line_number: usize,
     ) -> Option<String> {
+        let &DirectiveLine { line_number, raw_directive: line, .. } = line;
+
         let colon = directive.len();
         if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
             let value = line[(colon + 1)..].to_owned();
@@ -1144,52 +1116,37 @@ impl Config {
         }
     }
 
-    fn parse_edition(&self, line: &str, testfile: &Utf8Path, line_number: usize) -> Option<String> {
-        self.parse_name_value_directive(line, "edition", testfile, line_number)
+    fn parse_edition(&self, line: &DirectiveLine<'_>, testfile: &Utf8Path) -> Option<String> {
+        self.parse_name_value_directive(line, "edition", testfile)
     }
 
-    fn set_name_directive(&self, line: &str, directive: &str, value: &mut bool) {
-        match value {
-            true => {
-                if self.parse_negative_name_directive(line, directive) {
-                    *value = false;
-                }
-            }
-            false => {
-                if self.parse_name_directive(line, directive) {
-                    *value = true;
-                }
-            }
-        }
+    fn set_name_directive(&self, line: &DirectiveLine<'_>, directive: &str, value: &mut bool) {
+        // If the flag is already true, don't bother looking at the directive.
+        *value = *value || self.parse_name_directive(line, directive);
     }
 
     fn set_name_value_directive<T>(
         &self,
-        line: &str,
+        line: &DirectiveLine<'_>,
         directive: &str,
         testfile: &Utf8Path,
-        line_number: usize,
         value: &mut Option<T>,
         parse: impl FnOnce(String) -> T,
     ) {
         if value.is_none() {
-            *value =
-                self.parse_name_value_directive(line, directive, testfile, line_number).map(parse);
+            *value = self.parse_name_value_directive(line, directive, testfile).map(parse);
         }
     }
 
     fn push_name_value_directive<T>(
         &self,
-        line: &str,
+        line: &DirectiveLine<'_>,
         directive: &str,
         testfile: &Utf8Path,
-        line_number: usize,
         values: &mut Vec<T>,
         parse: impl FnOnce(String) -> T,
     ) {
-        if let Some(value) =
-            self.parse_name_value_directive(line, directive, testfile, line_number).map(parse)
-        {
+        if let Some(value) = self.parse_name_value_directive(line, directive, testfile).map(parse) {
             values.push(value);
         }
     }
@@ -1482,8 +1439,8 @@ pub(crate) fn make_test_description<R: Read>(
         &mut local_poisoned,
         path,
         src,
-        &mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
-            if !directive.applies_to_test_revision(test_revision) {
+        &mut |ref ln @ DirectiveLine { line_number, .. }| {
+            if !ln.applies_to_test_revision(test_revision) {
                 return;
             }
 
@@ -1507,9 +1464,9 @@ pub(crate) fn make_test_description<R: Read>(
             decision!(cfg::handle_ignore(config, ln));
             decision!(cfg::handle_only(config, ln));
             decision!(needs::handle_needs(&cache.needs, config, ln));
-            decision!(ignore_llvm(config, path, ln, line_number));
-            decision!(ignore_backends(config, path, ln, line_number));
-            decision!(needs_backends(config, path, ln, line_number));
+            decision!(ignore_llvm(config, path, ln));
+            decision!(ignore_backends(config, path, ln));
+            decision!(needs_backends(config, path, ln));
             decision!(ignore_cdb(config, ln));
             decision!(ignore_gdb(config, ln));
             decision!(ignore_lldb(config, ln));
@@ -1549,7 +1506,9 @@ pub(crate) fn make_test_description<R: Read>(
     }
 }
 
-fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
+fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     if config.debugger != Some(Debugger::Cdb) {
         return IgnoreDecision::Continue;
     }
@@ -1572,7 +1531,9 @@ fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
     IgnoreDecision::Continue
 }
 
-fn ignore_gdb(config: &Config, line: &str) -> IgnoreDecision {
+fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     if config.debugger != Some(Debugger::Gdb) {
         return IgnoreDecision::Continue;
     }
@@ -1620,7 +1581,9 @@ fn ignore_gdb(config: &Config, line: &str) -> IgnoreDecision {
     IgnoreDecision::Continue
 }
 
-fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
+fn ignore_lldb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     if config.debugger != Some(Debugger::Lldb) {
         return IgnoreDecision::Continue;
     }
@@ -1642,14 +1605,9 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
     IgnoreDecision::Continue
 }
 
-fn ignore_backends(
-    config: &Config,
-    path: &Utf8Path,
-    line: &str,
-    line_number: usize,
-) -> IgnoreDecision {
+fn ignore_backends(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
     if let Some(backends_to_ignore) =
-        config.parse_name_value_directive(line, "ignore-backends", path, line_number)
+        config.parse_name_value_directive(line, "ignore-backends", path)
     {
         for backend in backends_to_ignore.split_whitespace().map(|backend| {
             match CodegenBackend::try_from(backend) {
@@ -1669,15 +1627,8 @@ fn ignore_backends(
     IgnoreDecision::Continue
 }
 
-fn needs_backends(
-    config: &Config,
-    path: &Utf8Path,
-    line: &str,
-    line_number: usize,
-) -> IgnoreDecision {
-    if let Some(needed_backends) =
-        config.parse_name_value_directive(line, "needs-backends", path, line_number)
-    {
+fn needs_backends(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
+    if let Some(needed_backends) = config.parse_name_value_directive(line, "needs-backends", path) {
         if !needed_backends
             .split_whitespace()
             .map(|backend| match CodegenBackend::try_from(backend) {
@@ -1699,9 +1650,9 @@ fn needs_backends(
     IgnoreDecision::Continue
 }
 
-fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize) -> IgnoreDecision {
+fn ignore_llvm(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
     if let Some(needed_components) =
-        config.parse_name_value_directive(line, "needs-llvm-components", path, line_number)
+        config.parse_name_value_directive(line, "needs-llvm-components", path)
     {
         let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
         if let Some(missing_component) = needed_components
@@ -1723,7 +1674,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
         // Note that these `min` versions will check for not just major versions.
 
         if let Some(version_string) =
-            config.parse_name_value_directive(line, "min-llvm-version", path, line_number)
+            config.parse_name_value_directive(line, "min-llvm-version", path)
         {
             let min_version = extract_llvm_version(&version_string);
             // Ignore if actual version is smaller than the minimum required version.
@@ -1735,7 +1686,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
                 };
             }
         } else if let Some(version_string) =
-            config.parse_name_value_directive(line, "max-llvm-major-version", path, line_number)
+            config.parse_name_value_directive(line, "max-llvm-major-version", path)
         {
             let max_version = extract_llvm_version(&version_string);
             // Ignore if actual major version is larger than the maximum required major version.
@@ -1749,7 +1700,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
                 };
             }
         } else if let Some(version_string) =
-            config.parse_name_value_directive(line, "min-system-llvm-version", path, line_number)
+            config.parse_name_value_directive(line, "min-system-llvm-version", path)
         {
             let min_version = extract_llvm_version(&version_string);
             // Ignore if using system LLVM and actual version
@@ -1762,7 +1713,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
                 };
             }
         } else if let Some(version_range) =
-            config.parse_name_value_directive(line, "ignore-llvm-version", path, line_number)
+            config.parse_name_value_directive(line, "ignore-llvm-version", path)
         {
             // Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
             let (v_min, v_max) =
@@ -1788,7 +1739,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
                 }
             }
         } else if let Some(version_string) =
-            config.parse_name_value_directive(line, "exact-llvm-major-version", path, line_number)
+            config.parse_name_value_directive(line, "exact-llvm-major-version", path)
         {
             // Syntax is "exact-llvm-major-version: <version>"
             let version = extract_llvm_version(&version_string);
diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs
index 7c1ed2e7006..0675a6feac3 100644
--- a/src/tools/compiletest/src/directives/auxiliary.rs
+++ b/src/tools/compiletest/src/directives/auxiliary.rs
@@ -7,6 +7,7 @@ use camino::Utf8Path;
 
 use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO};
 use crate::common::Config;
+use crate::directives::DirectiveLine;
 
 /// Properties parsed from `aux-*` test directives.
 #[derive(Clone, Debug, Default)]
@@ -45,40 +46,28 @@ impl AuxProps {
 /// and update [`AuxProps`] accordingly.
 pub(super) fn parse_and_update_aux(
     config: &Config,
-    ln: &str,
+    directive_line: &DirectiveLine<'_>,
     testfile: &Utf8Path,
-    line_number: usize,
     aux: &mut AuxProps,
 ) {
+    let &DirectiveLine { raw_directive: ln, .. } = directive_line;
+
     if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) {
         return;
     }
 
-    config.push_name_value_directive(ln, AUX_BUILD, testfile, line_number, &mut aux.builds, |r| {
+    let ln = directive_line;
+
+    config.push_name_value_directive(ln, AUX_BUILD, testfile, &mut aux.builds, |r| {
         r.trim().to_string()
     });
-    config.push_name_value_directive(ln, AUX_BIN, testfile, line_number, &mut aux.bins, |r| {
+    config
+        .push_name_value_directive(ln, AUX_BIN, testfile, &mut aux.bins, |r| r.trim().to_string());
+    config.push_name_value_directive(ln, AUX_CRATE, testfile, &mut aux.crates, parse_aux_crate);
+    config.push_name_value_directive(ln, PROC_MACRO, testfile, &mut aux.proc_macros, |r| {
         r.trim().to_string()
     });
-    config.push_name_value_directive(
-        ln,
-        AUX_CRATE,
-        testfile,
-        line_number,
-        &mut aux.crates,
-        parse_aux_crate,
-    );
-    config.push_name_value_directive(
-        ln,
-        PROC_MACRO,
-        testfile,
-        line_number,
-        &mut aux.proc_macros,
-        |r| r.trim().to_string(),
-    );
-    if let Some(r) =
-        config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile, line_number)
-    {
+    if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile) {
         aux.codegen_backend = Some(r.trim().to_owned());
     }
 }
diff --git a/src/tools/compiletest/src/directives/cfg.rs b/src/tools/compiletest/src/directives/cfg.rs
index 802a1d63d1f..62a4b88a33a 100644
--- a/src/tools/compiletest/src/directives/cfg.rs
+++ b/src/tools/compiletest/src/directives/cfg.rs
@@ -1,12 +1,14 @@
 use std::collections::HashSet;
 
 use crate::common::{CompareMode, Config, Debugger};
-use crate::directives::IgnoreDecision;
+use crate::directives::{DirectiveLine, IgnoreDecision};
 
 const EXTRA_ARCHS: &[&str] = &["spirv"];
 
-pub(super) fn handle_ignore(config: &Config, line: &str) -> IgnoreDecision {
+pub(super) fn handle_ignore(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
     let parsed = parse_cfg_name_directive(config, line, "ignore");
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     match parsed.outcome {
         MatchOutcome::NoMatch => IgnoreDecision::Continue,
         MatchOutcome::Match => IgnoreDecision::Ignore {
@@ -21,8 +23,10 @@ pub(super) fn handle_ignore(config: &Config, line: &str) -> IgnoreDecision {
     }
 }
 
-pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision {
+pub(super) fn handle_only(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
     let parsed = parse_cfg_name_directive(config, line, "only");
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     match parsed.outcome {
         MatchOutcome::Match => IgnoreDecision::Continue,
         MatchOutcome::NoMatch => IgnoreDecision::Ignore {
@@ -43,9 +47,11 @@ pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision {
 /// or `only-windows`.
 fn parse_cfg_name_directive<'a>(
     config: &Config,
-    line: &'a str,
+    line: &'a DirectiveLine<'a>,
     prefix: &str,
 ) -> ParsedNameDirective<'a> {
+    let &DirectiveLine { raw_directive: line, .. } = line;
+
     if !line.as_bytes().starts_with(prefix.as_bytes()) {
         return ParsedNameDirective::not_a_directive();
     }
diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs
index 3b7a9478717..c8a729d8aab 100644
--- a/src/tools/compiletest/src/directives/needs.rs
+++ b/src/tools/compiletest/src/directives/needs.rs
@@ -1,10 +1,10 @@
 use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
-use crate::directives::{IgnoreDecision, llvm_has_libzstd};
+use crate::directives::{DirectiveLine, IgnoreDecision, llvm_has_libzstd};
 
 pub(super) fn handle_needs(
     cache: &CachedNeedsConditions,
     config: &Config,
-    ln: &str,
+    ln: &DirectiveLine<'_>,
 ) -> IgnoreDecision {
     // Note that we intentionally still put the needs- prefix here to make the file show up when
     // grepping for a directive name, even though we could technically strip that.
@@ -181,6 +181,8 @@ pub(super) fn handle_needs(
         },
     ];
 
+    let &DirectiveLine { raw_directive: ln, .. } = ln;
+
     let (name, rest) = match ln.split_once([':', ' ']) {
         Some((name, rest)) => (name, Some(rest)),
         None => (ln, None),
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
index c8e13d44573..c7aca6d1c5a 100644
--- a/src/tools/compiletest/src/executor.rs
+++ b/src/tools/compiletest/src/executor.rs
@@ -9,8 +9,8 @@ use std::borrow::Cow;
 use std::collections::HashMap;
 use std::hash::{BuildHasherDefault, DefaultHasher};
 use std::num::NonZero;
-use std::sync::{Arc, Mutex, mpsc};
-use std::{env, hint, io, mem, panic, thread};
+use std::sync::{Arc, mpsc};
+use std::{env, hint, mem, panic, thread};
 
 use camino::Utf8PathBuf;
 
@@ -130,10 +130,6 @@ fn run_test_inner(
         panic_hook::set_capture_buf(Default::default());
     }
 
-    if let CaptureKind::Old { ref buf } = capture {
-        io::set_output_capture(Some(Arc::clone(buf)));
-    }
-
     let stdout = capture.stdout();
     let stderr = capture.stderr();
 
@@ -144,9 +140,6 @@ fn run_test_inner(
         // Forward any captured panic message to (captured) stderr.
         write!(stderr, "{panic_buf}");
     }
-    if matches!(capture, CaptureKind::Old { .. }) {
-        io::set_output_capture(None);
-    }
 
     let outcome = match (should_panic, panic_payload) {
         (ShouldPanic::No, None) | (ShouldPanic::Yes, Some(_)) => TestOutcome::Succeeded,
@@ -167,31 +160,24 @@ enum CaptureKind {
     /// runners, whose output is always captured.)
     None,
 
-    /// Use the old output-capture implementation, which relies on the unstable
-    /// library feature `#![feature(internal_output_capture)]`.
-    Old { buf: Arc<Mutex<Vec<u8>>> },
-
-    /// Use the new output-capture implementation, which only uses stable Rust.
-    New { buf: output_capture::CaptureBuf },
+    /// Capture all console output that would be printed by test runners via
+    /// their `stdout` and `stderr` trait objects, or via the custom panic hook.
+    Capture { buf: output_capture::CaptureBuf },
 }
 
 impl CaptureKind {
     fn for_config(config: &Config) -> Self {
         if config.nocapture {
             Self::None
-        } else if config.new_output_capture {
-            Self::New { buf: output_capture::CaptureBuf::new() }
         } else {
-            // Create a capure buffer for `io::set_output_capture`.
-            Self::Old { buf: Default::default() }
+            Self::Capture { buf: output_capture::CaptureBuf::new() }
         }
     }
 
     fn should_set_panic_hook(&self) -> bool {
         match self {
             Self::None => false,
-            Self::Old { .. } => true,
-            Self::New { .. } => true,
+            Self::Capture { .. } => true,
         }
     }
 
@@ -205,16 +191,15 @@ impl CaptureKind {
 
     fn capture_buf_or<'a>(&'a self, fallback: &'a dyn ConsoleOut) -> &'a dyn ConsoleOut {
         match self {
-            Self::None | Self::Old { .. } => fallback,
-            Self::New { buf } => buf,
+            Self::None => fallback,
+            Self::Capture { buf } => buf,
         }
     }
 
     fn into_inner(self) -> Option<Vec<u8>> {
         match self {
             Self::None => None,
-            Self::Old { buf } => Some(buf.lock().unwrap_or_else(|e| e.into_inner()).to_vec()),
-            Self::New { buf } => Some(buf.into_inner().into()),
+            Self::Capture { buf } => Some(buf.into_inner().into()),
         }
     }
 }
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index ce2a3d4b5fb..15e31dadf97 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -1,9 +1,4 @@
 #![crate_name = "compiletest"]
-// Needed by the "new" test executor that does not depend on libtest.
-// FIXME(Zalathar): We should be able to get rid of `internal_output_capture`,
-// by having `runtest` manually capture all of its println-like output instead.
-// That would result in compiletest being written entirely in stable Rust!
-#![feature(internal_output_capture)]
 
 #[cfg(test)]
 mod tests;
@@ -178,12 +173,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         // FIXME: Temporarily retained so we can point users to `--no-capture`
         .optflag("", "nocapture", "")
         .optflag("", "no-capture", "don't capture stdout/stderr of tests")
-        .optopt(
-            "N",
-            "new-output-capture",
-            "enables or disables the new output-capture implementation",
-            "off|on",
-        )
         .optflag("", "profiler-runtime", "is the profiler runtime enabled for this target")
         .optflag("h", "help", "show this message")
         .reqopt("", "channel", "current Rust channel", "CHANNEL")
@@ -480,14 +469,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         supported_crate_types: OnceLock::new(),
 
         nocapture: matches.opt_present("no-capture"),
-        new_output_capture: {
-            let value = matches
-                .opt_str("new-output-capture")
-                .or_else(|| env::var("COMPILETEST_NEW_OUTPUT_CAPTURE").ok())
-                .unwrap_or_else(|| "on".to_owned());
-            parse_bool_option(&value)
-                .unwrap_or_else(|| panic!("unknown `--new-output-capture` value `{value}` given"))
-        },
 
         nightly_branch: matches.opt_str("nightly-branch").unwrap(),
         git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
@@ -503,19 +484,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
     }
 }
 
-/// Parses the same set of boolean values accepted by rustc command-line arguments.
-///
-/// Accepting all of these values is more complicated than just picking one
-/// pair, but has the advantage that contributors who are used to rustc
-/// shouldn't have to think about which values are legal.
-fn parse_bool_option(value: &str) -> Option<bool> {
-    match value {
-        "off" | "no" | "n" | "false" => Some(false),
-        "on" | "yes" | "y" | "true" => Some(true),
-        _ => None,
-    }
-}
-
 pub fn opt_str(maybestr: &Option<String>) -> &str {
     match *maybestr {
         None => "(none)",
diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs
index ba824124e87..3d439e98eb7 100644
--- a/src/tools/compiletest/src/runtest/debugger.rs
+++ b/src/tools/compiletest/src/runtest/debugger.rs
@@ -4,7 +4,6 @@ use std::io::{BufRead, BufReader};
 
 use camino::{Utf8Path, Utf8PathBuf};
 
-use crate::common::Config;
 use crate::runtest::ProcRes;
 
 /// Representation of information to invoke a debugger and check its output
@@ -20,11 +19,7 @@ pub(super) struct DebuggerCommands {
 }
 
 impl DebuggerCommands {
-    pub fn parse_from(
-        file: &Utf8Path,
-        config: &Config,
-        debugger_prefix: &str,
-    ) -> Result<Self, String> {
+    pub fn parse_from(file: &Utf8Path, debugger_prefix: &str) -> Result<Self, String> {
         let command_directive = format!("{debugger_prefix}-command");
         let check_directive = format!("{debugger_prefix}-check");
 
@@ -47,14 +42,10 @@ impl DebuggerCommands {
                 continue;
             };
 
-            if let Some(command) =
-                config.parse_name_value_directive(&line, &command_directive, file, line_no)
-            {
+            if let Some(command) = parse_name_value(&line, &command_directive) {
                 commands.push(command);
             }
-            if let Some(pattern) =
-                config.parse_name_value_directive(&line, &check_directive, file, line_no)
-            {
+            if let Some(pattern) = parse_name_value(&line, &check_directive) {
                 check_lines.push((line_no, pattern));
             }
         }
@@ -114,6 +105,18 @@ impl DebuggerCommands {
     }
 }
 
+/// Split off from the main `parse_name_value_directive`, so that improvements
+/// to directive handling aren't held back by debuginfo test commands.
+fn parse_name_value(line: &str, name: &str) -> Option<String> {
+    if let Some(after_name) = line.strip_prefix(name)
+        && let Some(value) = after_name.strip_prefix(':')
+    {
+        Some(value.to_owned())
+    } else {
+        None
+    }
+}
+
 /// Check that the pattern in `check_line` applies to `line`. Returns `true` if they do match.
 fn check_single_line(line: &str, check_line: &str) -> bool {
     // Allow check lines to leave parts unspecified (e.g., uninitialized
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 071c0863b7e..9175a38ffa5 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -59,7 +59,7 @@ impl TestCx<'_> {
         }
 
         // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "cdb")
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "cdb")
             .unwrap_or_else(|e| self.fatal(&e));
 
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
@@ -130,7 +130,7 @@ impl TestCx<'_> {
     }
 
     fn run_debuginfo_gdb_test_no_opt(&self) {
-        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "gdb")
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb")
             .unwrap_or_else(|e| self.fatal(&e));
         let mut cmds = dbg_cmds.commands.join("\n");
 
@@ -397,7 +397,7 @@ impl TestCx<'_> {
         }
 
         // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "lldb")
+        let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "lldb")
             .unwrap_or_else(|e| self.fatal(&e));
 
         // Write debugger script:
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index d307636e782..412640a112c 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1341,7 +1341,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
                     name = ecx.tcx.def_path_str(def_id),
                     krate = ecx.tcx.crate_name(def_id.krate),
                     decl_size = extern_decl_layout.size.bytes(),
-                    decl_align = extern_decl_layout.align.abi.bytes(),
+                    decl_align = extern_decl_layout.align.bytes(),
                     shim_size = info.size.bytes(),
                     shim_align = info.align.bytes(),
                 )
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index b74b1d5e166..b461a24a061 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -366,6 +366,13 @@ impl Rustc {
         self
     }
 
+    pub fn split_dwarf_out_dir(&mut self, out_dir: Option<&str>) -> &mut Self {
+        if let Some(out_dir) = out_dir {
+            self.cmd.arg(format!("-Zsplit-dwarf-out-dir={out_dir}"));
+        }
+        self
+    }
+
     /// Pass the `--verbose` flag.
     pub fn verbose(&mut self) -> &mut Self {
         self.cmd.arg("--verbose");
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
index 6960e230a68..275ad841f4b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
@@ -149,7 +149,7 @@ fn check_size_and_align(
 ) {
     let l = eval_goal(ra_fixture, minicore).unwrap();
     assert_eq!(l.size.bytes(), size, "size mismatch");
-    assert_eq!(l.align.abi.bytes(), align, "align mismatch");
+    assert_eq!(l.align.bytes(), align, "align mismatch");
 }
 
 #[track_caller]
@@ -161,7 +161,7 @@ fn check_size_and_align_expr(
 ) {
     let l = eval_expr(ra_fixture, minicore).unwrap();
     assert_eq!(l.size.bytes(), size, "size mismatch");
-    assert_eq!(l.align.abi.bytes(), align, "align mismatch");
+    assert_eq!(l.align.bytes(), align, "align mismatch");
 }
 
 #[track_caller]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index fa63baa5d2a..c93165a04c0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -2088,7 +2088,7 @@ impl<'db> Evaluator<'db> {
         if let Some(layout) = self.layout_cache.borrow().get(&ty.to_nextsolver(interner)) {
             return Ok(layout
                 .is_sized()
-                .then(|| (layout.size.bytes_usize(), layout.align.abi.bytes() as usize)));
+                .then(|| (layout.size.bytes_usize(), layout.align.bytes() as usize)));
         }
         if let DefWithBodyId::VariantId(f) = locals.body.owner
             && let Some((AdtId::EnumId(e), _)) = ty.as_adt()
@@ -2107,7 +2107,7 @@ impl<'db> Evaluator<'db> {
         let layout = layout?;
         Ok(layout
             .is_sized()
-            .then(|| (layout.size.bytes_usize(), layout.align.abi.bytes() as usize)))
+            .then(|| (layout.size.bytes_usize(), layout.align.bytes() as usize)))
     }
 
     /// A version of `self.size_of` which returns error if the type is unsized. `what` argument should
@@ -2800,7 +2800,7 @@ impl<'db> Evaluator<'db> {
                     )?;
                     // FIXME: there is some leak here
                     let size = layout.size.bytes_usize();
-                    let addr = self.heap_allocate(size, layout.align.abi.bytes() as usize)?;
+                    let addr = self.heap_allocate(size, layout.align.bytes() as usize)?;
                     self.write_memory(addr, &result)?;
                     IntervalAndTy { interval: Interval { addr, size }, ty }
                 };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index bb0d1f70fbb..40d76bf42e9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -768,7 +768,7 @@ impl Evaluator<'_> {
                         "align_of generic arg is not provided".into(),
                     ));
                 };
-                let align = self.layout(ty.to_nextsolver(interner))?.align.abi.bytes();
+                let align = self.layout(ty.to_nextsolver(interner))?.align.bytes();
                 destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
             }
             "size_of_val" => {
@@ -1431,7 +1431,7 @@ impl Evaluator<'_> {
                     field_types.iter().next_back().unwrap().1.clone().substitute(Interner, subst);
                 let sized_part_size =
                     layout.fields.offset(field_types.iter().count() - 1).bytes_usize();
-                let sized_part_align = layout.align.abi.bytes() as usize;
+                let sized_part_align = layout.align.bytes() as usize;
                 let (unsized_part_size, unsized_part_align) =
                     self.size_align_of_unsized(&last_field_ty, metadata, locals)?;
                 let align = sized_part_align.max(unsized_part_align) as isize;
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 9198086e9e6..4342624dd64 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -6174,7 +6174,7 @@ impl Layout {
     }
 
     pub fn align(&self) -> u64 {
-        self.0.align.abi.bytes()
+        self.0.align.bytes()
     }
 
     pub fn niches(&self) -> Option<u128> {
diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs
index 454ec698b91..5c8126898a8 100644
--- a/tests/codegen-llvm/autodiff/abi_handling.rs
+++ b/tests/codegen-llvm/autodiff/abi_handling.rs
@@ -1,7 +1,7 @@
 //@ revisions: debug release
 
-//@[debug] compile-flags: -Zautodiff=Enable -C opt-level=0 -Clto=fat
-//@[release] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
+//@[debug] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=0 -Clto=fat
+//@[release] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat
 //@ no-prefer-dynamic
 //@ needs-enzyme
 
diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs
index 306a6ed9d1f..dc82403212f 100644
--- a/tests/codegen-llvm/autodiff/batched.rs
+++ b/tests/codegen-llvm/autodiff/batched.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3  -Clto=fat
 //@ no-prefer-dynamic
 //@ needs-enzyme
 //
diff --git a/tests/codegen-llvm/autodiff/scalar.rs b/tests/codegen-llvm/autodiff/scalar.rs
index 55b989f920d..53672a89230 100644
--- a/tests/codegen-llvm/autodiff/scalar.rs
+++ b/tests/codegen-llvm/autodiff/scalar.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3  -Clto=fat
 //@ no-prefer-dynamic
 //@ needs-enzyme
 #![feature(autodiff)]
diff --git a/tests/codegen-llvm/autodiff/sret.rs b/tests/codegen-llvm/autodiff/sret.rs
index dbc253ce894..498cd3fea01 100644
--- a/tests/codegen-llvm/autodiff/sret.rs
+++ b/tests/codegen-llvm/autodiff/sret.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3  -Clto=fat
 //@ no-prefer-dynamic
 //@ needs-enzyme
 
diff --git a/tests/codegen-llvm/autodiff/void_ret.rs b/tests/codegen-llvm/autodiff/void_ret.rs
new file mode 100644
index 00000000000..98c6b98eef4
--- /dev/null
+++ b/tests/codegen-llvm/autodiff/void_ret.rs
@@ -0,0 +1,41 @@
+//@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C no-prepopulate-passes -C opt-level=3  -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+
+#![feature(autodiff)]
+use std::autodiff::*;
+
+// Usually we would store the return value of the differentiated function.
+// However, if the return type is void or an empty struct,
+// we don't need to store anything. Verify this, since it caused a bug.
+
+// CHECK:; void_ret::main
+// CHECK-NEXT:    ; Function Attrs:
+// CHECK-NEXT:    define internal
+// CHECK-NOT: store {} undef, ptr undef
+// CHECK: ret void
+
+#[autodiff_reverse(bar, Duplicated, Duplicated)]
+pub fn foo(r: &[f64; 10], res: &mut f64) {
+    let mut output = [0.0; 10];
+    output[0] = r[0];
+    output[1] = r[1] * r[2];
+    output[2] = r[4] * r[5];
+    output[3] = r[2] * r[6];
+    output[4] = r[1] * r[7];
+    output[5] = r[2] * r[8];
+    output[6] = r[1] * r[9];
+    output[7] = r[5] * r[6];
+    output[8] = r[5] * r[7];
+    output[9] = r[4] * r[8];
+    *res = output.iter().sum();
+}
+fn main() {
+    let inputs = Box::new([3.1; 10]);
+    let mut d_inputs = Box::new([0.0; 10]);
+    let mut res = Box::new(0.0);
+    let mut d_res = Box::new(1.0);
+
+    bar(&inputs, &mut d_inputs, &mut res, &mut d_res);
+    dbg!(&d_inputs);
+}
diff --git a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs
index 8d2745ba2f7..2ce1d1b2e00 100644
--- a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -1,4 +1,9 @@
 //@ compile-flags: -C panic=abort
+//@ revisions: NONWASM WASM WASMEXN
+//@ [NONWASM] ignore-wasm32
+//@ [WASM] only-wasm32
+//@ [WASMEXN] only-wasm32
+//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling
 
 // Test that `nounwind` attributes are also applied to extern `C-unwind` Rust functions
 // when the code is compiled with `panic=abort`.
@@ -9,7 +14,9 @@
 #[no_mangle]
 pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() {
     // Handle both legacy and v0 symbol mangling.
-    // CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
+    // NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}}
+    // WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}}
+    // WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}}
     may_unwind();
 }
 
diff --git a/tests/codegen-llvm/unwind-and-panic-abort.rs b/tests/codegen-llvm/unwind-and-panic-abort.rs
index 8efa140058a..c2838be00af 100644
--- a/tests/codegen-llvm/unwind-and-panic-abort.rs
+++ b/tests/codegen-llvm/unwind-and-panic-abort.rs
@@ -1,4 +1,9 @@
 //@ compile-flags: -C panic=abort
+//@ revisions: NONWASM WASM WASMEXN
+//@ [NONWASM] ignore-wasm32
+//@ [WASM] only-wasm32
+//@ [WASMEXN] only-wasm32
+//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling
 
 #![crate_type = "lib"]
 
@@ -9,7 +14,9 @@ extern "C-unwind" {
 // CHECK: Function Attrs:{{.*}}nounwind
 // CHECK-NEXT: define{{.*}}void @foo
 // Handle both legacy and v0 symbol mangling.
-// CHECK: call void @{{.*core9panicking19panic_cannot_unwind}}
+// NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}}
+// WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}}
+// WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}}
 #[no_mangle]
 pub unsafe extern "C" fn foo() {
     bar();
diff --git a/tests/codegen-llvm/wasm_exceptions.rs b/tests/codegen-llvm/wasm_exceptions.rs
index 796b69b722b..e718f599a3c 100644
--- a/tests/codegen-llvm/wasm_exceptions.rs
+++ b/tests/codegen-llvm/wasm_exceptions.rs
@@ -1,8 +1,9 @@
 //@ only-wasm32
-//@ compile-flags: -C panic=unwind -Z emscripten-wasm-eh
+//@ revisions: WASM WASMEXN
+//@ [WASMEXN] compile-flags: -C panic=unwind -Z emscripten-wasm-eh
 
 #![crate_type = "lib"]
-#![feature(core_intrinsics, wasm_exception_handling_intrinsics)]
+#![feature(core_intrinsics, wasm_exception_handling_intrinsics, link_llvm_intrinsics)]
 
 extern "C-unwind" {
     fn may_panic();
@@ -22,7 +23,8 @@ impl Drop for LogOnDrop {
     }
 }
 
-// CHECK-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0
+// WASM-LABEL: @test_cleanup() {{.*}}
+// WASMEXN-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0
 #[no_mangle]
 pub fn test_cleanup() {
     let _log_on_drop = LogOnDrop;
@@ -30,12 +32,16 @@ pub fn test_cleanup() {
         may_panic();
     }
 
-    // CHECK-NOT: call
-    // CHECK: invoke void @may_panic()
-    // CHECK: %cleanuppad = cleanuppad within none []
+    // WASMEXN-NOT: call
+    // WASMEXN: invoke void @may_panic()
+    // WASMEXN: %cleanuppad = cleanuppad within none []
+    //
+    // WASM: call void @may_panic()
+    // WASM-NOT: invoke void @may_panic()
 }
 
-// CHECK-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0
+// WASM-LABEL: @test_rtry() {{.*}}
+// WASMEXN-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0
 #[no_mangle]
 pub fn test_rtry() {
     unsafe {
@@ -51,23 +57,40 @@ pub fn test_rtry() {
         );
     }
 
-    // CHECK-NOT: call
-    // CHECK: invoke void @may_panic()
-    // CHECK: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller
-    // CHECK: {{.*}} = catchpad within {{.*}} [ptr null]
-    // CHECK: catchret
+    // WASMEXN-NOT: call
+    // WASMEXN: invoke void @may_panic()
+    // WASMEXN: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller
+    // WASMEXN: {{.*}} = catchpad within {{.*}} [ptr null]
+    // WASMEXN: catchret
+
+    // WASM: call void @may_panic()
+    // WASM-NOT: invoke void @may_panic()
+    // WASM-NOT: catchswitch
+    // WASM-NOT: catchpad
+    // WASM-NOT: catchret
 }
 
 // Make sure the intrinsic is not inferred as nounwind. This is a regression test for #132416.
-// CHECK-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0
+//
+// Note that this test uses the raw `wasm_throw` intrinsic because the one from
+// libstd was built with `-Cpanic=abort` and it's technically not valid to use
+// when this crate is compiled with `-Cpanic=unwind`.
+//
+// WASMEXN-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0
 #[no_mangle]
+#[cfg(wasmexn)]
 pub fn test_intrinsic() {
     let _log_on_drop = LogOnDrop;
+
+    unsafe extern "C-unwind" {
+        #[link_name = "llvm.wasm.throw"]
+        fn wasm_throw(tag: i32, ptr: *mut u8) -> !;
+    }
     unsafe {
-        core::arch::wasm32::throw::<0>(core::ptr::null_mut());
+        wasm_throw(0, core::ptr::null_mut());
     }
 
-    // CHECK-NOT: call
-    // CHECK: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null)
-    // CHECK: %cleanuppad = cleanuppad within none []
+    // WASMEXN-NOT: call
+    // WASMEXN: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null)
+    // WASMEXN: %cleanuppad = cleanuppad within none []
 }
diff --git a/tests/crashes/125772.rs b/tests/crashes/125772.rs
index 2965cfc9e7c..2b6cffd9463 100644
--- a/tests/crashes/125772.rs
+++ b/tests/crashes/125772.rs
@@ -1,5 +1,5 @@
 //@ known-bug: rust-lang/rust#125772
-//@ only-x86_64
+//@ only-64bit
 #![feature(generic_const_exprs)]
 
 struct Outer<const A: i64, const B: i64>();
diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs
deleted file mode 100644
index b1bb74708c2..00000000000
--- a/tests/crashes/129095.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: rust-lang/rust#129095
-//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
-
-#![feature(adt_const_params, unsized_const_params)]
-#![allow(incomplete_features)]
-
-pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
-    BYTES
-}
-
-pub fn main() {
-    assert_eq!(function_with_bytes::<b"AAAAA">(), &[0x41, 0x41, 0x41, 0x41]);
-}
diff --git a/tests/crashes/131292.rs b/tests/crashes/131292.rs
index 01e0eca0bd6..05b93d06b05 100644
--- a/tests/crashes/131292.rs
+++ b/tests/crashes/131292.rs
@@ -1,5 +1,5 @@
 //@ known-bug: #131292
-//@ only-x86_64
+//@ needs-asm-support
 use std::arch::asm;
 
 unsafe fn f6() {
diff --git a/tests/crashes/134174.rs b/tests/crashes/134174.rs
deleted file mode 100644
index 899cdc6faf3..00000000000
--- a/tests/crashes/134174.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #134175
-//@compile-flags: -Zvalidate-mir -Zinline-mir=yes
-use std::vec::IntoIter;
-
-pub(crate) trait Foo: Iterator<Item = <Self as Foo>::Key> {
-    type Key;
-}
-
-impl Foo for IntoIter<i16> {}
-
-fn sum_foo<F: Foo<Key = i32>>(f: F) -> i32 {
-    f.fold(0, |a, b| a + b)
-}
-
-fn main() {
-    let x = sum_foo(vec![11, 10, 1].into_iter());
-}
diff --git a/tests/crashes/134654.rs b/tests/crashes/134654.rs
deleted file mode 100644
index f2323fe4ecd..00000000000
--- a/tests/crashes/134654.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: #134654
-//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
-//@ only-x86_64
-
-#![feature(adt_const_params, unsized_const_params)]
-#![allow(incomplete_features)]
-
-fn function_with_bytes<const BYTES:
-    &'static [u8; 0xa9008fb6c9d81e42_0e25730562a601c8_u128]>() -> &'static [u8] {
-    BYTES
-}
-
-fn main() {
-    function_with_bytes::<b"aa">() == &[];
-}
diff --git a/tests/crashes/135570.rs b/tests/crashes/135570.rs
deleted file mode 100644
index 7919ceb26d5..00000000000
--- a/tests/crashes/135570.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: #135570
-//@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN
-//@ only-x86_64
-
-#![feature(adt_const_params, unsized_const_params)]
-#![allow(incomplete_features)]
-
-fn function_with_bytes<const BYTES: &'static [u8; 0xc7b889180b67b07d_bc1a3c88783d35b5_u128]>(
-) -> &'static [u8] {
-    BYTES
-}
-
-fn main() {
-    function_with_bytes::<b"aa">() == &[];
-}
diff --git a/tests/crashes/136381.rs b/tests/crashes/136381.rs
deleted file mode 100644
index 13ccc14a2c5..00000000000
--- a/tests/crashes/136381.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ known-bug: #136381
-//@ compile-flags: -Zvalidate-mir -Zmir-enable-passes=+GVN
-#![feature(trait_upcasting)]
-
-trait A {}
-trait B: A {
-    fn c(&self);
-}
-impl B for i32 {
-    fn c(self) {
-        todo!();
-    }
-}
-
-fn main() {
-    let baz: &dyn B = &1;
-    let bar: &dyn A = baz;
-}
diff --git a/tests/crashes/137190-1.rs b/tests/crashes/137190-1.rs
deleted file mode 100644
index bdfe883b712..00000000000
--- a/tests/crashes/137190-1.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #137190
-//@ compile-flags: -Zmir-opt-level=2 -Zvalidate-mir
-trait A {
-    fn b(&self);
-}
-trait C: A {}
-impl C for () {}
-fn main() {
-    (&() as &dyn C as &dyn A).b();
-}
diff --git a/tests/crashes/137468.rs b/tests/crashes/137468.rs
deleted file mode 100644
index cceb0502bd2..00000000000
--- a/tests/crashes/137468.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: #137468
-//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+GVN -Zvalidate-mir
-trait Supertrait<T> {}
-
-trait Identity {
-    type Selff;
-}
-
-trait Trait<P>: Supertrait<()> + Supertrait<<P as Identity>::Selff> {}
-
-impl<P> Trait<P> for () {}
-
-fn main() {
-    let x: &dyn Trait<()> = &();
-    let x: &dyn Supertrait<()> = x;
-}
diff --git a/tests/crashes/34127.rs b/tests/crashes/34127.rs
index ea36b48ecba..26ebe722475 100644
--- a/tests/crashes/34127.rs
+++ b/tests/crashes/34127.rs
@@ -1,6 +1,6 @@
 //@ compile-flags: -g -Copt-level=0 -Z verify-llvm-ir
 //@ known-bug: #34127
-//@ only-x86_64
+//@ only-64bit
 
 pub fn main() {
 let _a = [(); 1 << 63];
diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs
index e8de5aed172..e53b7101078 100644
--- a/tests/run-make/split-debuginfo/rmake.rs
+++ b/tests/run-make/split-debuginfo/rmake.rs
@@ -188,6 +188,25 @@ enum UnstableOptions {
 }
 
 #[track_caller]
+fn dwo_out_filenames(dwo_out: Option<&str>) -> BTreeSet<String> {
+    let dwo_out = if let Some(d) = dwo_out {
+        d
+    } else {
+        return BTreeSet::new();
+    };
+    let files = shallow_find_files(dwo_out, |path| {
+        // Fiilter out source files
+        !has_extension(path, "rs")
+    });
+    files
+        .iter()
+        .map(|p| {
+            format!("{}/{}", dwo_out, p.file_name().unwrap().to_os_string().into_string().unwrap())
+        })
+        .collect()
+}
+
+#[track_caller]
 fn cwd_filenames() -> BTreeSet<String> {
     let files = shallow_find_files(cwd(), |path| {
         // Fiilter out source files
@@ -197,6 +216,17 @@ fn cwd_filenames() -> BTreeSet<String> {
 }
 
 #[track_caller]
+fn dwo_out_dwo_filenames(dwo_out: &str) -> BTreeSet<String> {
+    let files = shallow_find_files(dwo_out, |p| has_extension(p, "dwo"));
+    files
+        .iter()
+        .map(|p| {
+            format!("{}/{}", dwo_out, p.file_name().unwrap().to_os_string().into_string().unwrap())
+        })
+        .collect()
+}
+
+#[track_caller]
 fn cwd_dwo_filenames() -> BTreeSet<String> {
     let files = shallow_find_files(cwd(), |path| has_extension(path, "dwo"));
     files.iter().map(|p| p.file_name().unwrap().to_os_string().into_string().unwrap()).collect()
@@ -376,17 +406,19 @@ mod shared_linux_other_tests {
         lto: LinkerPluginLto,
         remap_path_prefix: RemapPathPrefix,
         remap_path_scope: RemapPathScope,
+        split_dwarf_output_directory: Option<&str>,
     ) {
         run_in_tmpdir(|| {
             println!(
-                "checking: unstable_options={:?} + split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?}",
+                "checking: unstable_options={:?} + split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?} + split_dwarf_out_dir={:?}",
                 unstable_options,
                 split_kind,
                 level,
                 split_dwarf_kind,
                 lto,
                 remap_path_prefix,
-                remap_path_scope
+                remap_path_scope,
+                split_dwarf_output_directory,
             );
 
             match cross_crate_test {
@@ -398,6 +430,7 @@ mod shared_linux_other_tests {
                     lto,
                     remap_path_prefix,
                     remap_path_scope,
+                    split_dwarf_output_directory,
                 ),
                 CrossCrateTest::No => simple_split_debuginfo(
                     unstable_options,
@@ -407,6 +440,7 @@ mod shared_linux_other_tests {
                     lto,
                     remap_path_prefix,
                     remap_path_scope,
+                    split_dwarf_output_directory,
                 ),
             }
         });
@@ -420,7 +454,11 @@ mod shared_linux_other_tests {
         lto: LinkerPluginLto,
         remap_path_prefix: RemapPathPrefix,
         remap_path_scope: RemapPathScope,
+        split_dwarf_output_directory: Option<&str>,
     ) {
+        if let Some(dwo_out) = split_dwarf_output_directory {
+            run_make_support::rfs::create_dir(dwo_out);
+        }
         match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) {
             // packed-crosscrate-split
             // - Debuginfo in `.dwo` files
@@ -531,13 +569,19 @@ mod shared_linux_other_tests {
                     .input("bar.rs")
                     .crate_type("lib")
                     .split_debuginfo(split_kind.cli_value())
+                    .split_dwarf_out_dir(split_dwarf_output_directory)
                     .debuginfo(level.cli_value())
                     .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
                     .run();
 
-                let bar_found_files = cwd_filenames();
+                let mut bar_found_files = cwd_filenames();
+                bar_found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory));
 
-                let bar_dwo_files = cwd_dwo_filenames();
+                let bar_dwo_files = if let Some(dwo_out) = split_dwarf_output_directory {
+                    dwo_out_dwo_filenames(dwo_out)
+                } else {
+                    cwd_dwo_filenames()
+                };
                 assert_eq!(bar_dwo_files.len(), 1);
 
                 let mut bar_expected_files = BTreeSet::new();
@@ -553,13 +597,19 @@ mod shared_linux_other_tests {
                     .extern_("bar", "libbar.rlib")
                     .input("main.rs")
                     .split_debuginfo(split_kind.cli_value())
+                    .split_dwarf_out_dir(split_dwarf_output_directory)
                     .debuginfo(level.cli_value())
                     .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
                     .run();
 
-                let overall_found_files = cwd_filenames();
+                let mut overall_found_files = cwd_filenames();
+                overall_found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory));
 
-                let overall_dwo_files = cwd_dwo_filenames();
+                let overall_dwo_files = if let Some(dwo_out) = split_dwarf_output_directory {
+                    dwo_out_dwo_filenames(dwo_out)
+                } else {
+                    cwd_dwo_filenames()
+                };
                 assert_eq!(overall_dwo_files.len(), 2);
 
                 let mut overall_expected_files = BTreeSet::new();
@@ -648,7 +698,11 @@ mod shared_linux_other_tests {
         lto: LinkerPluginLto,
         remap_path_prefix: RemapPathPrefix,
         remap_path_scope: RemapPathScope,
+        split_dwarf_output_directory: Option<&str>,
     ) {
+        if let Some(dwo_out) = split_dwarf_output_directory {
+            run_make_support::rfs::create_dir(dwo_out);
+        }
         match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) {
             // off (unspecified):
             // - Debuginfo in `.o` files
@@ -921,14 +975,19 @@ mod shared_linux_other_tests {
                 rustc(unstable_options)
                     .input("foo.rs")
                     .split_debuginfo(split_kind.cli_value())
+                    .split_dwarf_out_dir(split_dwarf_output_directory)
                     .debuginfo(level.cli_value())
                     .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
                     .run();
-                let found_files = cwd_filenames();
-
-                let dwo_files = cwd_dwo_filenames();
+                let mut found_files = cwd_filenames();
+                found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory));
+
+                let dwo_files = if let Some(dwo_dir) = split_dwarf_output_directory {
+                    dwo_out_dwo_filenames(dwo_dir)
+                } else {
+                    cwd_dwo_filenames()
+                };
                 assert_eq!(dwo_files.len(), 1);
-
                 let mut expected_files = BTreeSet::new();
                 expected_files.extend(dwo_files);
                 expected_files.insert("foo".to_string());
@@ -1056,14 +1115,20 @@ mod shared_linux_other_tests {
                 rustc(unstable_options)
                     .input("foo.rs")
                     .split_debuginfo(split_kind.cli_value())
+                    .split_dwarf_out_dir(split_dwarf_output_directory)
                     .debuginfo(level.cli_value())
                     .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value()))
                     .remap_path_prefix(cwd(), remapped_prefix)
                     .run();
 
-                let found_files = cwd_filenames();
+                let mut found_files = cwd_filenames();
+                found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory));
 
-                let dwo_files = cwd_dwo_filenames();
+                let dwo_files = if let Some(dwo_out) = split_dwarf_output_directory {
+                    dwo_out_dwo_filenames(dwo_out)
+                } else {
+                    cwd_dwo_filenames()
+                };
                 assert_eq!(dwo_files.len(), 1);
 
                 let mut expected_files = BTreeSet::new();
@@ -1358,6 +1423,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // off
@@ -1370,6 +1436,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-split
@@ -1382,6 +1449,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-single
@@ -1394,6 +1462,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-lto-split
@@ -1406,6 +1475,7 @@ fn main() {
             LinkerPluginLto::Yes,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-lto-single
@@ -1418,6 +1488,7 @@ fn main() {
             LinkerPluginLto::Yes,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // FIXME: the remapping tests probably need to be reworked, see
@@ -1433,6 +1504,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-remapped-single
@@ -1445,6 +1517,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-remapped-scope
@@ -1457,6 +1530,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Yes("debuginfo"),
+            None,
         );
 
         // packed-remapped-wrong-scope
@@ -1469,6 +1543,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Yes("macro"),
+            None,
         );
 
         // packed-crosscrate-split
@@ -1481,6 +1556,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // packed-crosscrate-single
@@ -1493,6 +1569,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // unpacked-split
@@ -1505,6 +1582,20 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
+        );
+
+        // unpacked-split with split-dwarf-out-dir
+        shared_linux_other_tests::split_debuginfo(
+            CrossCrateTest::No,
+            UnstableOptions::Yes,
+            SplitDebuginfo::Unpacked,
+            DebuginfoLevel::Full,
+            SplitDwarfKind::Split,
+            LinkerPluginLto::Unspecified,
+            RemapPathPrefix::Unspecified,
+            RemapPathScope::Unspecified,
+            Some("other-dir"),
         );
 
         // unpacked-single
@@ -1517,6 +1608,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // unpacked-lto-split
@@ -1529,6 +1621,7 @@ fn main() {
             LinkerPluginLto::Yes,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // unpacked-lto-single
@@ -1541,6 +1634,7 @@ fn main() {
             LinkerPluginLto::Yes,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
 
         // unpacked-remapped-split
@@ -1553,6 +1647,20 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Unspecified,
+            None,
+        );
+
+        // unpacked-remapped-split with split-dwarf-out-dir
+        shared_linux_other_tests::split_debuginfo(
+            CrossCrateTest::No,
+            UnstableOptions::Yes,
+            SplitDebuginfo::Unpacked,
+            DebuginfoLevel::Full,
+            SplitDwarfKind::Split,
+            LinkerPluginLto::Unspecified,
+            RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
+            RemapPathScope::Unspecified,
+            Some("other-dir"),
         );
 
         // unpacked-remapped-single
@@ -1565,6 +1673,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Unspecified,
+            None,
         );
 
         // unpacked-remapped-scope
@@ -1577,6 +1686,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Yes("debuginfo"),
+            None,
         );
 
         // unpacked-remapped-wrong-scope
@@ -1589,6 +1699,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" },
             RemapPathScope::Yes("macro"),
+            None,
         );
 
         // unpacked-crosscrate-split
@@ -1601,6 +1712,20 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
+        );
+
+        // unpacked-crosscrate-split with split-dwarf-out-dir
+        shared_linux_other_tests::split_debuginfo(
+            CrossCrateTest::Yes,
+            UnstableOptions::Yes,
+            SplitDebuginfo::Unpacked,
+            DebuginfoLevel::Full,
+            SplitDwarfKind::Split,
+            LinkerPluginLto::Unspecified,
+            RemapPathPrefix::Unspecified,
+            RemapPathScope::Unspecified,
+            Some("other-dir"),
         );
 
         // unpacked-crosscrate-single
@@ -1613,6 +1738,7 @@ fn main() {
             LinkerPluginLto::Unspecified,
             RemapPathPrefix::Unspecified,
             RemapPathScope::Unspecified,
+            None,
         );
     }
 }
diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout
index 30aadfe89f4..d34714be6c9 100644
--- a/tests/rustdoc-ui/issues/issue-91713.stdout
+++ b/tests/rustdoc-ui/issues/issue-91713.stdout
@@ -1,11 +1,11 @@
 Available passes for running rustdoc:
        check-doc-cfg - checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs
 check_doc_test_visibility - run various visibility-related lints on doctests
+   propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items
 strip-aliased-non-local - strips all non-local private aliased items from the output
         strip-hidden - strips all `#[doc(hidden)]` items from the output
        strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports
   strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate
-   propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items
  propagate-stability - propagates stability to child items
 collect-intra-doc-links - resolves intra-doc links
  collect-trait-impls - retrieves trait impls for items in the crate
@@ -16,11 +16,11 @@ Default passes for rustdoc:
  collect-trait-impls
 check_doc_test_visibility
        check-doc-cfg
+collect-intra-doc-links
 strip-aliased-non-local
         strip-hidden  (when not --document-hidden-items)
        strip-private  (when not --document-private-items)
   strip-priv-imports  (when --document-private-items)
-collect-intra-doc-links
    propagate-doc-cfg
  propagate-stability
            run-lints
diff --git a/tests/rustdoc/doc-auto-cfg-public-in-private.rs b/tests/rustdoc/doc-auto-cfg-public-in-private.rs
new file mode 100644
index 00000000000..b78e3f1b932
--- /dev/null
+++ b/tests/rustdoc/doc-auto-cfg-public-in-private.rs
@@ -0,0 +1,16 @@
+// This test ensures that even though private items are removed from generated docs,
+// their `cfg`s will still impact their child items.
+
+#![feature(doc_cfg)]
+#![crate_name = "foo"]
+
+pub struct X;
+
+#[cfg(not(feature = "blob"))]
+fn foo() {
+    impl X {
+        //@ has 'foo/struct.X.html'
+        //@ has - '//*[@class="stab portability"]' 'Available on non-crate feature blob only.'
+        pub fn bar() {}
+    }
+}
diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs
index 8449479287f..48f328f4fad 100644
--- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs
+++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs
@@ -33,6 +33,10 @@ impl CodegenBackend for TheBackend {
         ""
     }
 
+    fn name(&self) -> &'static str {
+        "the-backend"
+    }
+
     fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
         Box::new(CodegenResults {
             modules: vec![],
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index df5f29e35fe..86f2d5f5954 100644
--- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -2,7 +2,6 @@
 // Testing that a librustc_ast can parse modules with canonicalized base path
 //@ ignore-cross-compile
 //@ ignore-remote
-// no-remap-src-base: Reading `file!()` (expectedly) fails when enabled.
 
 #![feature(rustc_private)]
 
diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs
new file mode 100644
index 00000000000..01cc05f2545
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs
@@ -0,0 +1,114 @@
+//@ edition: 2024
+
+#![feature(associated_const_equality, type_alias_impl_trait, return_type_notation)]
+#![allow(refining_impl_trait_internal)]
+
+use std::iter;
+
+fn rpit1() -> impl Iterator<Item: Copy, Item: Send> {
+    iter::empty()
+    //~^ ERROR type annotations needed
+}
+fn rpit2() -> impl Iterator<Item: Copy, Item: Copy> {
+    iter::empty()
+    //~^ ERROR type annotations needed
+}
+fn rpit3() -> impl Iterator<Item: 'static, Item: 'static> {
+    iter::empty()
+    //~^ ERROR type annotations needed
+}
+
+type Tait1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+type Tait2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+type Tait3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+
+type Tait4 = impl Iterator<Item: Copy, Item: Send>;
+//~^ ERROR unconstrained opaque type
+type Tait5 = impl Iterator<Item: Copy, Item: Copy>;
+//~^ ERROR unconstrained opaque type
+type Tait6 = impl Iterator<Item: 'static, Item: 'static>;
+//~^ ERROR unconstrained opaque type
+
+fn mismatch() -> impl Iterator<Item: Copy, Item: Send> {
+    //~^ ERROR [E0277]
+    iter::empty::<*const ()>()
+}
+
+fn mismatch_2() -> impl Iterator<Item: Copy, Item: Send> {
+    //~^ ERROR [E0277]
+    iter::empty::<String>()
+}
+
+trait Trait {
+    type Gat<T>;
+
+    const ASSOC: i32;
+
+    fn foo() -> impl Sized;
+}
+
+impl Trait for () {
+    type Gat<T> = ();
+
+    const ASSOC: i32 = 3;
+
+    fn foo() {}
+}
+
+impl Trait for u32 {
+    type Gat<T> = ();
+
+    const ASSOC: i32 = 4;
+
+    fn foo() -> u32 {
+        42
+    }
+}
+
+fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+
+fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+
+fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+
+type MustFail = dyn Iterator<Item = i32, Item = u32>;
+//~^ ERROR [E0719]
+//~| ERROR conflicting associated type bounds
+
+trait Trait2 {
+    const ASSOC: u32;
+}
+
+type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+//~^ ERROR [E0719]
+//~| ERROR conflicting associated type bounds
+
+type MustFail3 = dyn Iterator<Item = i32, Item = i32>;
+//~^ ERROR [E0719]
+
+type MustFail4 = dyn Trait2<ASSOC = 3u32, ASSOC = 3u32>;
+//~^ ERROR [E0719]
+
+trait Trait3 {
+    fn foo() -> impl Iterator<Item = i32, Item = u32>;
+}
+
+impl Trait3 for () {
+    fn foo() -> impl Iterator<Item = i32, Item = u32> {
+        //~^ ERROR[E0271]
+        //~| ERROR[E0271]
+        [2u32].into_iter()
+    }
+}
+
+fn main() {
+    uncallable(iter::empty::<u32>()); //~ ERROR [E0271]
+    uncallable(iter::empty::<i32>()); //~ ERROR [E0271]
+    uncallable_const(()); //~ ERROR [E0271]
+    uncallable_const(4u32); //~ ERROR [E0271]
+    uncallable_rtn(()); //~ ERROR [E0271]
+    uncallable_rtn(17u32); //~ ERROR [E0271]
+}
diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr
new file mode 100644
index 00000000000..1737d0dc5a3
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr
@@ -0,0 +1,268 @@
+error[E0282]: type annotations needed
+  --> $DIR/duplicate-bound-err.rs:9:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
+error[E0282]: type annotations needed
+  --> $DIR/duplicate-bound-err.rs:13:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
+error[E0282]: type annotations needed
+  --> $DIR/duplicate-bound-err.rs:17:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:21:51
+   |
+LL | type Tait1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
+   |                                                   ^^^^^^^^^
+   |
+   = note: `Tait1` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:23:51
+   |
+LL | type Tait2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
+   |                                                   ^^^^^^^^^
+   |
+   = note: `Tait2` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:25:57
+   |
+LL | type Tait3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
+   |                                                         ^^^^^^^^^
+   |
+   = note: `Tait3` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:28:14
+   |
+LL | type Tait4 = impl Iterator<Item: Copy, Item: Send>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Tait4` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:30:14
+   |
+LL | type Tait5 = impl Iterator<Item: Copy, Item: Copy>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Tait5` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate-bound-err.rs:32:14
+   |
+LL | type Tait6 = impl Iterator<Item: 'static, Item: 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Tait6` must be used in combination with a concrete type within the same crate
+
+error[E0277]: `*const ()` cannot be sent between threads safely
+  --> $DIR/duplicate-bound-err.rs:35:18
+   |
+LL | fn mismatch() -> impl Iterator<Item: Copy, Item: Send> {
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
+LL |
+LL |     iter::empty::<*const ()>()
+   |     -------------------------- return type was inferred to be `std::iter::Empty<*const ()>` here
+   |
+   = help: the trait `Send` is not implemented for `*const ()`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/duplicate-bound-err.rs:40:20
+   |
+LL | fn mismatch_2() -> impl Iterator<Item: Copy, Item: Send> {
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+LL |
+LL |     iter::empty::<String>()
+   |     ----------------------- return type was inferred to be `std::iter::Empty<String>` here
+
+error[E0271]: expected `IntoIter<u32, 1>` to be an iterator that yields `i32`, but it yields `u32`
+  --> $DIR/duplicate-bound-err.rs:100:17
+   |
+LL |     fn foo() -> impl Iterator<Item = i32, Item = u32> {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+...
+LL |         [2u32].into_iter()
+   |         ------------------ return type was inferred to be `std::array::IntoIter<u32, 1>` here
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate-bound-err.rs:77:42
+   |
+LL | type MustFail = dyn Iterator<Item = i32, Item = u32>;
+   |                              ----------  ^^^^^^^^^^ re-bound here
+   |                              |
+   |                              `Item` bound here first
+
+error: conflicting associated type bounds for `Item`
+  --> $DIR/duplicate-bound-err.rs:77:17
+   |
+LL | type MustFail = dyn Iterator<Item = i32, Item = u32>;
+   |                 ^^^^^^^^^^^^^----------^^----------^
+   |                              |           |
+   |                              |           `Item` is specified to be `u32` here
+   |                              `Item` is specified to be `i32` here
+
+error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified
+  --> $DIR/duplicate-bound-err.rs:85:43
+   |
+LL | type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+   |                             ------------  ^^^^^^^^^^^^ re-bound here
+   |                             |
+   |                             `ASSOC` bound here first
+
+error: conflicting associated type bounds for `ASSOC`
+  --> $DIR/duplicate-bound-err.rs:85:18
+   |
+LL | type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+   |                  ^^^^^^^^^^^------------^^------------^
+   |                             |             |
+   |                             |             `ASSOC` is specified to be `4` here
+   |                             `ASSOC` is specified to be `3` here
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate-bound-err.rs:89:43
+   |
+LL | type MustFail3 = dyn Iterator<Item = i32, Item = i32>;
+   |                               ----------  ^^^^^^^^^^ re-bound here
+   |                               |
+   |                               `Item` bound here first
+
+error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified
+  --> $DIR/duplicate-bound-err.rs:92:43
+   |
+LL | type MustFail4 = dyn Trait2<ASSOC = 3u32, ASSOC = 3u32>;
+   |                             ------------  ^^^^^^^^^^^^ re-bound here
+   |                             |
+   |                             `ASSOC` bound here first
+
+error[E0271]: expected `impl Iterator<Item = u32>` to be an iterator that yields `i32`, but it yields `u32`
+  --> $DIR/duplicate-bound-err.rs:100:17
+   |
+LL |     fn foo() -> impl Iterator<Item = i32, Item = u32> {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+   |
+note: required by a bound in `Trait3::foo::{anon_assoc#0}`
+  --> $DIR/duplicate-bound-err.rs:96:31
+   |
+LL |     fn foo() -> impl Iterator<Item = i32, Item = u32>;
+   |                               ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}`
+
+error[E0271]: expected `Empty<u32>` to be an iterator that yields `i32`, but it yields `u32`
+  --> $DIR/duplicate-bound-err.rs:108:16
+   |
+LL |     uncallable(iter::empty::<u32>());
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `uncallable`
+  --> $DIR/duplicate-bound-err.rs:71:32
+   |
+LL | fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+   |                                ^^^^^^^^^^ required by this bound in `uncallable`
+
+error[E0271]: expected `Empty<i32>` to be an iterator that yields `u32`, but it yields `i32`
+  --> $DIR/duplicate-bound-err.rs:109:16
+   |
+LL |     uncallable(iter::empty::<i32>());
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `uncallable`
+  --> $DIR/duplicate-bound-err.rs:71:44
+   |
+LL | fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+   |                                            ^^^^^^^^^^ required by this bound in `uncallable`
+
+error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4`
+  --> $DIR/duplicate-bound-err.rs:110:22
+   |
+LL |     uncallable_const(());
+   |     ---------------- ^^ expected `4`, found `3`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected constant `4`
+              found constant `3`
+note: required by a bound in `uncallable_const`
+  --> $DIR/duplicate-bound-err.rs:73:46
+   |
+LL | fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+   |                                              ^^^^^^^^^ required by this bound in `uncallable_const`
+
+error[E0271]: type mismatch resolving `<u32 as Trait>::ASSOC == 3`
+  --> $DIR/duplicate-bound-err.rs:111:22
+   |
+LL |     uncallable_const(4u32);
+   |     ---------------- ^^^^ expected `3`, found `4`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected constant `3`
+              found constant `4`
+note: required by a bound in `uncallable_const`
+  --> $DIR/duplicate-bound-err.rs:73:35
+   |
+LL | fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+   |                                   ^^^^^^^^^ required by this bound in `uncallable_const`
+
+error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4`
+  --> $DIR/duplicate-bound-err.rs:112:20
+   |
+LL |     uncallable_rtn(());
+   |     -------------- ^^ expected `4`, found `3`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected constant `4`
+              found constant `3`
+note: required by a bound in `uncallable_rtn`
+  --> $DIR/duplicate-bound-err.rs:75:75
+   |
+LL | fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+   |                                                                           ^^^^^^^^^ required by this bound in `uncallable_rtn`
+
+error[E0271]: type mismatch resolving `<u32 as Trait>::ASSOC == 3`
+  --> $DIR/duplicate-bound-err.rs:113:20
+   |
+LL |     uncallable_rtn(17u32);
+   |     -------------- ^^^^^ expected `3`, found `4`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected constant `3`
+              found constant `4`
+note: required by a bound in `uncallable_rtn`
+  --> $DIR/duplicate-bound-err.rs:75:48
+   |
+LL | fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+   |                                                ^^^^^^^^^ required by this bound in `uncallable_rtn`
+
+error: aborting due to 25 previous errors
+
+Some errors have detailed explanations: E0271, E0277, E0282, E0719.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs
new file mode 100644
index 00000000000..696710d76f6
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound.rs
@@ -0,0 +1,240 @@
+//@ edition: 2024
+//@ run-pass
+
+#![feature(associated_const_equality, return_type_notation)]
+#![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)]
+
+use std::iter;
+use std::mem::ManuallyDrop;
+
+struct Si1<T: Iterator<Item: Copy, Item: Send>> {
+    f: T,
+}
+struct Si2<T: Iterator<Item: Copy, Item: Copy>> {
+    f: T,
+}
+struct Si3<T: Iterator<Item: 'static, Item: 'static>> {
+    f: T,
+}
+struct Sw1<T>
+where
+    T: Iterator<Item: Copy, Item: Send>,
+{
+    f: T,
+}
+struct Sw2<T>
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+{
+    f: T,
+}
+struct Sw3<T>
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+{
+    f: T,
+}
+
+enum Ei1<T: Iterator<Item: Copy, Item: Send>> {
+    V(T),
+}
+enum Ei2<T: Iterator<Item: Copy, Item: Copy>> {
+    V(T),
+}
+enum Ei3<T: Iterator<Item: 'static, Item: 'static>> {
+    V(T),
+}
+enum Ew1<T>
+where
+    T: Iterator<Item: Copy, Item: Send>,
+{
+    V(T),
+}
+enum Ew2<T>
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+{
+    V(T),
+}
+enum Ew3<T>
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+{
+    V(T),
+}
+
+union Ui1<T: Iterator<Item: Copy, Item: Send>> {
+    f: ManuallyDrop<T>,
+}
+union Ui2<T: Iterator<Item: Copy, Item: Copy>> {
+    f: ManuallyDrop<T>,
+}
+union Ui3<T: Iterator<Item: 'static, Item: 'static>> {
+    f: ManuallyDrop<T>,
+}
+union Uw1<T>
+where
+    T: Iterator<Item: Copy, Item: Send>,
+{
+    f: ManuallyDrop<T>,
+}
+union Uw2<T>
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+{
+    f: ManuallyDrop<T>,
+}
+union Uw3<T>
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+{
+    f: ManuallyDrop<T>,
+}
+
+fn fi1<T: Iterator<Item: Copy, Item: Send>>() {}
+fn fi2<T: Iterator<Item: Copy, Item: Copy>>() {}
+fn fi3<T: Iterator<Item: 'static, Item: 'static>>() {}
+fn fw1<T>()
+where
+    T: Iterator<Item: Copy, Item: Send>,
+{
+}
+fn fw2<T>()
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+{
+}
+fn fw3<T>()
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+{
+}
+
+fn rpit1() -> impl Iterator<Item: Copy, Item: Send> {
+    iter::empty::<u32>()
+}
+fn rpit2() -> impl Iterator<Item: Copy, Item: Copy> {
+    iter::empty::<u32>()
+}
+fn rpit3() -> impl Iterator<Item: 'static, Item: 'static> {
+    iter::empty::<u32>()
+}
+fn apit1(_: impl Iterator<Item: Copy, Item: Send>) {}
+fn apit2(_: impl Iterator<Item: Copy, Item: Copy>) {}
+fn apit3(_: impl Iterator<Item: 'static, Item: 'static>) {}
+
+type Tait1<T: Iterator<Item: Copy, Item: Send>> = T;
+type Tait2<T: Iterator<Item: Copy, Item: Copy>> = T;
+type Tait3<T: Iterator<Item: 'static, Item: 'static>> = T;
+type Taw1<T>
+where
+    T: Iterator<Item: Copy, Item: Send>,
+= T;
+type Taw2<T>
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+= T;
+type Taw3<T>
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+= T;
+
+trait Tri1<T: Iterator<Item: Copy, Item: Send>> {}
+trait Tri2<T: Iterator<Item: Copy, Item: Copy>> {}
+trait Tri3<T: Iterator<Item: 'static, Item: 'static>> {}
+trait Trs1: Iterator<Item: Copy, Item: Send> {}
+trait Trs2: Iterator<Item: Copy, Item: Copy> {}
+trait Trs3: Iterator<Item: 'static, Item: 'static> {}
+trait Trw1<T>
+where
+    T: Iterator<Item: Copy, Item: Send>,
+{
+}
+trait Trw2<T>
+where
+    T: Iterator<Item: Copy, Item: Copy>,
+{
+}
+trait Trw3<T>
+where
+    T: Iterator<Item: 'static, Item: 'static>,
+{
+}
+trait Trsw1
+where
+    Self: Iterator<Item: Copy, Item: Send>,
+{
+}
+trait Trsw2
+where
+    Self: Iterator<Item: Copy, Item: Copy>,
+{
+}
+trait Trsw3
+where
+    Self: Iterator<Item: 'static, Item: 'static>,
+{
+}
+trait Tra1 {
+    type A: Iterator<Item: Copy, Item: Send>;
+}
+trait Tra2 {
+    type A: Iterator<Item: Copy, Item: Copy>;
+}
+trait Tra3 {
+    type A: Iterator<Item: 'static, Item: 'static>;
+}
+
+trait Trait {
+    type Gat<T>;
+
+    const ASSOC: i32;
+
+    fn foo() -> impl Sized;
+}
+
+impl Trait for () {
+    type Gat<T> = ();
+
+    const ASSOC: i32 = 3;
+
+    fn foo() {}
+}
+
+trait Subtrait: Trait<Gat<u32> = u32, Gat<u64> = u64> {}
+
+fn f<T: Trait<Gat<i32> = (), Gat<i64> = ()>>() {
+    let _: T::Gat<i32> = ();
+    let _: T::Gat<i64> = ();
+}
+
+fn g<T: Trait<Gat<i32> = (), Gat<i64> = &'static str>>() {
+    let _: T::Gat<i32> = ();
+    let _: T::Gat<i64> = "";
+}
+
+fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+
+fn callable(_: impl Iterator<Item = i32, Item = i32>) {}
+
+fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+
+fn callable_const(_: impl Trait<ASSOC = 3, ASSOC = 3>) {}
+
+fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+
+fn callable_rtn(_: impl Trait<foo(..): Send, foo(..): Send, foo(..): Eq>) {}
+
+trait Trait2 {
+    const ASSOC: u32;
+}
+
+trait Trait3 {
+    fn foo() -> impl Iterator<Item = i32, Item = u32>;
+}
+
+fn main() {
+    callable(iter::empty::<i32>());
+    callable_const(());
+    callable_rtn(());
+}
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
deleted file mode 100644
index e9d94787e98..00000000000
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ /dev/null
@@ -1,278 +0,0 @@
-#![feature(type_alias_impl_trait)]
-
-use std::iter;
-use std::mem::ManuallyDrop;
-
-struct SI1<T: Iterator<Item: Copy, Item: Send>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: T,
-}
-struct SI2<T: Iterator<Item: Copy, Item: Copy>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: T,
-}
-struct SI3<T: Iterator<Item: 'static, Item: 'static>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: T,
-}
-struct SW1<T>
-where
-    T: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: T,
-}
-struct SW2<T>
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: T,
-}
-struct SW3<T>
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: T,
-}
-
-enum EI1<T: Iterator<Item: Copy, Item: Send>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    V(T),
-}
-enum EI2<T: Iterator<Item: Copy, Item: Copy>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    V(T),
-}
-enum EI3<T: Iterator<Item: 'static, Item: 'static>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    V(T),
-}
-enum EW1<T>
-where
-    T: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    V(T),
-}
-enum EW2<T>
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    V(T),
-}
-enum EW3<T>
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    V(T),
-}
-
-union UI1<T: Iterator<Item: Copy, Item: Send>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: ManuallyDrop<T>,
-}
-union UI2<T: Iterator<Item: Copy, Item: Copy>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: ManuallyDrop<T>,
-}
-union UI3<T: Iterator<Item: 'static, Item: 'static>> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    f: ManuallyDrop<T>,
-}
-union UW1<T>
-where
-    T: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: ManuallyDrop<T>,
-}
-union UW2<T>
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: ManuallyDrop<T>,
-}
-union UW3<T>
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-    f: ManuallyDrop<T>,
-}
-
-fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FW1<T>()
-where
-    T: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-fn FW2<T>()
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-fn FW3<T>()
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-
-fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    iter::empty()
-    //~^ ERROR type annotations needed
-}
-fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    iter::empty()
-    //~^ ERROR type annotations needed
-}
-fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    iter::empty()
-    //~^ ERROR type annotations needed
-}
-fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-
-type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAW1<T>
-where
-    T: Iterator<Item: Copy, Item: Send>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-type TAW2<T>
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-type TAW3<T>
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-
-type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-
-trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS1: Iterator<Item: Copy, Item: Send> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRW1<T>
-where
-    T: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRW2<T>
-where
-    T: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRW3<T>
-where
-    T: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW1
-where
-    Self: Iterator<Item: Copy, Item: Send>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW2
-where
-    Self: Iterator<Item: Copy, Item: Copy>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW3
-where
-    Self: Iterator<Item: 'static, Item: 'static>,
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRA1 {
-    type A: Iterator<Item: Copy, Item: Send>;
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-trait TRA2 {
-    type A: Iterator<Item: Copy, Item: Copy>;
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-trait TRA3 {
-    type A: Iterator<Item: 'static, Item: 'static>;
-    //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-
-fn main() {}
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
deleted file mode 100644
index 68fbb345f6f..00000000000
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ /dev/null
@@ -1,751 +0,0 @@
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:6:36
-   |
-LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:10:36
-   |
-LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> {
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:14:39
-   |
-LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> {
-   |                        -------------  ^^^^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:20:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:27:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:34:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:40:34
-   |
-LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> {
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:44:34
-   |
-LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> {
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:48:37
-   |
-LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> {
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:54:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:61:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:68:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:74:35
-   |
-LL | union UI1<T: Iterator<Item: Copy, Item: Send>> {
-   |                       ----------  ^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:78:35
-   |
-LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> {
-   |                       ----------  ^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:82:38
-   |
-LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> {
-   |                       -------------  ^^^^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:88:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:95:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:102:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:108:32
-   |
-LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:110:32
-   |
-LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:112:35
-   |
-LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
-   |                    -------------  ^^^^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:116:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:122:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:128:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:133:42
-   |
-LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:139:42
-   |
-LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:145:45
-   |
-LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
-   |                              -------------  ^^^^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:151:40
-   |
-LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:153:40
-   |
-LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:155:43
-   |
-LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:158:35
-   |
-LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
-   |                       ----------  ^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:160:35
-   |
-LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
-   |                       ----------  ^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:162:38
-   |
-LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
-   |                       -------------  ^^^^^^^^^^^^^ re-bound here
-   |                       |
-   |                       `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:166:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:171:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:176:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:180:36
-   |
-LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:183:36
-   |
-LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:186:39
-   |
-LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
-   |                        -------------  ^^^^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:202:36
-   |
-LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:204:36
-   |
-LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
-   |                        ----------  ^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:206:39
-   |
-LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
-   |                        -------------  ^^^^^^^^^^^^^ re-bound here
-   |                        |
-   |                        `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:208:34
-   |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:208:34
-   |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:208:34
-   |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:212:34
-   |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:212:34
-   |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:212:34
-   |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:216:37
-   |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:216:37
-   |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:216:37
-   |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:222:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Send>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:228:29
-   |
-LL |     T: Iterator<Item: Copy, Item: Copy>,
-   |                 ----------  ^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:234:32
-   |
-LL |     T: Iterator<Item: 'static, Item: 'static>,
-   |                 -------------  ^^^^^^^^^^^^^ re-bound here
-   |                 |
-   |                 `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:240:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Send>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:240:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Send>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:240:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Send>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:248:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Copy>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:248:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Copy>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:248:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Copy>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:256:35
-   |
-LL |     Self: Iterator<Item: 'static, Item: 'static>,
-   |                    -------------  ^^^^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:256:35
-   |
-LL |     Self: Iterator<Item: 'static, Item: 'static>,
-   |                    -------------  ^^^^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:256:35
-   |
-LL |     Self: Iterator<Item: 'static, Item: 'static>,
-   |                    -------------  ^^^^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:263:34
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:263:34
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:268:34
-   |
-LL |     type A: Iterator<Item: Copy, Item: Copy>;
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:268:34
-   |
-LL |     type A: Iterator<Item: Copy, Item: Copy>;
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:273:37
-   |
-LL |     type A: Iterator<Item: 'static, Item: 'static>;
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:273:37
-   |
-LL |     type A: Iterator<Item: 'static, Item: 'static>;
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:133:42
-   |
-LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:136:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:139:42
-   |
-LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
-   |                              ----------  ^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:142:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:145:45
-   |
-LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
-   |                              -------------  ^^^^^^^^^^^^^ re-bound here
-   |                              |
-   |                              `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:148:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:180:51
-   |
-LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
-   |                                                   ^^^^^^^^^
-   |
-   = note: `ETAI1` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:183:51
-   |
-LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
-   |                                                   ^^^^^^^^^
-   |
-   = note: `ETAI2` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:186:57
-   |
-LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
-   |                                                         ^^^^^^^^^
-   |
-   = note: `ETAI3` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:189:14
-   |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `ETAI4` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
-   |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
-   |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:193:14
-   |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `ETAI5` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:193:40
-   |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:193:40
-   |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: unconstrained opaque type
-  --> $DIR/duplicate.rs:197:14
-   |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `ETAI6` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:197:43
-   |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:197:43
-   |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 87 previous errors
-
-Some errors have detailed explanations: E0282, E0719.
-For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
index 71a4a2610aa..e96a2446b6c 100644
--- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -1,4 +1,4 @@
-error: conflicting associated type bounds for `Item` when expanding trait alias
+error: conflicting associated type bounds for `Item`
   --> $DIR/associated-types-overridden-binding-2.rs:6:13
    |
 LL | trait I32Iterator = Iterator<Item = i32>;
diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr
index 3b20015dfca..08ab9b63ee9 100644
--- a/tests/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr
@@ -22,7 +22,7 @@ note: required by a bound in `I32Iterator`
 LL | trait I32Iterator = Iterator<Item = i32>;
    |                              ^^^^^^^^^^ required by this bound in `I32Iterator`
 
-error: conflicting associated type bounds for `Item` when expanding trait alias
+error: conflicting associated type bounds for `Item`
   --> $DIR/associated-types-overridden-binding.rs:10:13
    |
 LL | trait I32Iterator = Iterator<Item = i32>;
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
index 19a31d1889b..f97ec779b32 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
@@ -44,4 +44,18 @@ fn through_field_and_ref_move<'a>(x: &S<'a>) {
     outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x`
 }
 
+struct T;
+impl T {
+    fn outlives<'a>(&'a self, _: impl Sized + 'a) {}
+}
+fn through_method<'a>(x: &'a i32) {
+    let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough
+    T.outlives::<'a>(c());
+    T.outlives::<'a>(call_once(c));
+
+    let c = async move || { println!("{}", *x); };
+    T.outlives::<'a>(c()); //~ ERROR `c` does not live long enough
+    T.outlives::<'a>(call_once(c));
+}
+
 fn main() {}
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
index b7259074bf6..4aae9807dd2 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
@@ -28,6 +28,12 @@ LL |     outlives::<'a>(c());
 LL |     outlives::<'a>(call_once(c));
 LL | }
    | - `c` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $DIR/without-precise-captures-we-are-powerless.rs:7:33
+   |
+LL | fn outlives<'a>(_: impl Sized + 'a) {}
+   |                                 ^^
 
 error[E0597]: `x` does not live long enough
   --> $DIR/without-precise-captures-we-are-powerless.rs:26:13
@@ -73,6 +79,12 @@ LL |     outlives::<'a>(c());
 LL |     outlives::<'a>(call_once(c));
 LL | }
    | - `c` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $DIR/without-precise-captures-we-are-powerless.rs:7:33
+   |
+LL | fn outlives<'a>(_: impl Sized + 'a) {}
+   |                                 ^^
 
 error[E0505]: cannot move out of `c` because it is borrowed
   --> $DIR/without-precise-captures-we-are-powerless.rs:32:30
@@ -89,6 +101,12 @@ LL |     outlives::<'a>(c());
    |     argument requires that `c` is borrowed for `'a`
 LL |     outlives::<'a>(call_once(c));
    |                              ^ move out of `c` occurs here
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $DIR/without-precise-captures-we-are-powerless.rs:7:33
+   |
+LL | fn outlives<'a>(_: impl Sized + 'a) {}
+   |                                 ^^
 
 error[E0597]: `x` does not live long enough
   --> $DIR/without-precise-captures-we-are-powerless.rs:36:13
@@ -129,6 +147,12 @@ LL |     outlives::<'a>(c());
 LL |     outlives::<'a>(call_once(c));
 LL | }
    | - `c` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $DIR/without-precise-captures-we-are-powerless.rs:7:33
+   |
+LL | fn outlives<'a>(_: impl Sized + 'a) {}
+   |                                 ^^
 
 error[E0621]: explicit lifetime required in the type of `x`
   --> $DIR/without-precise-captures-we-are-powerless.rs:44:5
@@ -141,7 +165,44 @@ help: add explicit lifetime `'a` to the type of `x`
 LL | fn through_field_and_ref_move<'a>(x: &'a S<'a>) {
    |                                       ++
 
-error: aborting due to 10 previous errors
+error[E0597]: `x` does not live long enough
+  --> $DIR/without-precise-captures-we-are-powerless.rs:52:13
+   |
+LL | fn through_method<'a>(x: &'a i32) {
+   |                   -- lifetime `'a` defined here
+LL |     let c = async || { println!("{}", *x); };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
+LL |     T.outlives::<'a>(c());
+LL |     T.outlives::<'a>(call_once(c));
+   |     ------------------------------ argument requires that `x` is borrowed for `'a`
+...
+LL | }
+   |  - `x` dropped here while still borrowed
+
+error[E0597]: `c` does not live long enough
+  --> $DIR/without-precise-captures-we-are-powerless.rs:57:22
+   |
+LL | fn through_method<'a>(x: &'a i32) {
+   |                   -- lifetime `'a` defined here
+...
+LL |     let c = async move || { println!("{}", *x); };
+   |         - binding `c` declared here
+LL |     T.outlives::<'a>(c());
+   |     -----------------^---
+   |     |                |
+   |     |                borrowed value does not live long enough
+   |     argument requires that `c` is borrowed for `'a`
+LL |     T.outlives::<'a>(call_once(c));
+LL | }
+   | - `c` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $DIR/without-precise-captures-we-are-powerless.rs:49:47
+   |
+LL |     fn outlives<'a>(&'a self, _: impl Sized + 'a) {}
+   |                                               ^^
+
+error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0505, E0597, E0621.
 For more information about an error, try `rustc --explain E0505`.
diff --git a/tests/ui/attributes/empty-repr.stderr b/tests/ui/attributes/empty-repr.stderr
index 92901fa170c..6dfa2df75b7 100644
--- a/tests/ui/attributes/empty-repr.stderr
+++ b/tests/ui/attributes/empty-repr.stderr
@@ -4,6 +4,7 @@ error: unused attribute
 LL | #[repr()]
    | ^^^^^^^^^ help: remove this attribute
    |
+   = note: using `repr` with an empty list has no effect
 note: the lint level is defined here
   --> $DIR/empty-repr.rs:4:9
    |
diff --git a/tests/ui/borrowck/fn-item-check-type-params.stderr b/tests/ui/borrowck/fn-item-check-type-params.stderr
index aafb7e66ef5..7a0a7752a14 100644
--- a/tests/ui/borrowck/fn-item-check-type-params.stderr
+++ b/tests/ui/borrowck/fn-item-check-type-params.stderr
@@ -27,6 +27,12 @@ LL |     want(&String::new(), extend_lt);
    |     |     |
    |     |     creates a temporary value which is freed while still in use
    |     argument requires that borrow lasts for `'static`
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/fn-item-check-type-params.rs:47:33
+   |
+LL |     fn want<I, O>(_: I, _: impl Fn(I) -> O) {}
+   |                                 ^^^^^^^^^^
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/fn-item-check-type-params.rs:54:26
@@ -36,6 +42,12 @@ LL |     let val = extend_lt(&String::from("blah blah blah"));
    |               |          |
    |               |          creates a temporary value which is freed while still in use
    |               argument requires that borrow lasts for `'static`
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/fn-item-check-type-params.rs:22:21
+   |
+LL |     (T, Option<U>): Displayable,
+   |                     ^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr
index 5389226f7a7..7b840d54ed0 100644
--- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr
+++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr
@@ -22,6 +22,12 @@ LL |         force_send(async_load(&not_static));
 ...
 LL |     }
    |     - `not_static` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'1` introduced here
+  --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18
+   |
+LL | fn force_send<T: Send>(_: T) {}
+   |                  ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/borrowck/issue-17545.stderr b/tests/ui/borrowck/issue-17545.stderr
index 45e977e3947..63fd57cd233 100644
--- a/tests/ui/borrowck/issue-17545.stderr
+++ b/tests/ui/borrowck/issue-17545.stderr
@@ -10,6 +10,9 @@ LL | |     ));
    | |      -- temporary value is freed at the end of this statement
    | |______|
    |        argument requires that borrow lasts for `'a`
+   |
+note: requirement that the value outlives `'a` introduced here
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/closures/impl-closure-147146.rs b/tests/ui/closures/impl-closure-147146.rs
new file mode 100644
index 00000000000..b709e577354
--- /dev/null
+++ b/tests/ui/closures/impl-closure-147146.rs
@@ -0,0 +1,7 @@
+impl typeof(|| {}) {}
+//~^ ERROR `typeof` is a reserved keyword but unimplemented
+
+unsafe impl Send for typeof(|| {}) {}
+//~^ ERROR `typeof` is a reserved keyword but unimplemented
+
+fn main() {}
diff --git a/tests/ui/closures/impl-closure-147146.stderr b/tests/ui/closures/impl-closure-147146.stderr
new file mode 100644
index 00000000000..6da16b5d450
--- /dev/null
+++ b/tests/ui/closures/impl-closure-147146.stderr
@@ -0,0 +1,15 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/impl-closure-147146.rs:1:6
+   |
+LL | impl typeof(|| {}) {}
+   |      ^^^^^^^^^^^^^ reserved keyword
+
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/impl-closure-147146.rs:4:22
+   |
+LL | unsafe impl Send for typeof(|| {}) {}
+   |                      ^^^^^^^^^^^^^ reserved keyword
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0516`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs
new file mode 100644
index 00000000000..0a0dca804ef
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs
@@ -0,0 +1,21 @@
+//@ add-core-stubs
+//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
+//@ incremental (required to trigger the bug)
+//@ needs-llvm-components: arm
+#![feature(abi_cmse_nonsecure_call, no_core)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+// A regression test for https://github.com/rust-lang/rust/issues/131639.
+// NOTE: `-Cincremental` was required for triggering the bug.
+
+fn foo() {
+    id::<extern "cmse-nonsecure-call" fn(&'a ())>(PhantomData);
+    //~^ ERROR use of undeclared lifetime name `'a`
+}
+
+fn id<T>(x: PhantomData<T>) -> PhantomData<T> {
+    x
+}
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr
new file mode 100644
index 00000000000..7300bdb72cd
--- /dev/null
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr
@@ -0,0 +1,19 @@
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/undeclared-lifetime.rs:15:43
+   |
+LL |     id::<extern "cmse-nonsecure-call" fn(&'a ())>(PhantomData);
+   |                                           ^^ undeclared lifetime
+   |
+   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the type lifetime-generic with a new `'a` lifetime
+   |
+LL |     id::<for<'a> extern "cmse-nonsecure-call" fn(&'a ())>(PhantomData);
+   |          +++++++
+help: consider introducing lifetime `'a` here
+   |
+LL | fn foo<'a>() {
+   |       ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
index b6f2662a939..d7a7ab52c83 100644
--- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
@@ -2,29 +2,39 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/in-signature.rs:6:21
    |
 LL | fn arr_fn() -> [u8; _] {
-   |                -----^-
-   |                |    |
-   |                |    not allowed in type signatures
-   |                help: replace with the correct return type: `[u8; 3]`
+   |                     ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn arr_fn() -> [u8; _] {
+LL + fn arr_fn() -> [u8; 3] {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/in-signature.rs:11:24
    |
 LL | fn ty_fn() -> Bar<i32, _> {
-   |               ---------^-
-   |               |        |
-   |               |        not allowed in type signatures
-   |               help: replace with the correct return type: `Bar<i32, 3>`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn ty_fn() -> Bar<i32, _> {
+LL + fn ty_fn() -> Bar<i32, 3> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/in-signature.rs:16:25
    |
 LL | fn ty_fn_mixed() -> Bar<_, _> {
-   |                     ----^--^-
-   |                     |   |  |
-   |                     |   |  not allowed in type signatures
-   |                     |   not allowed in type signatures
-   |                     help: replace with the correct return type: `Bar<i32, 3>`
+   |                         ^  ^ not allowed in type signatures
+   |                         |
+   |                         not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn ty_fn_mixed() -> Bar<_, _> {
+LL + fn ty_fn_mixed() -> Bar<i32, 3> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/in-signature.rs:21:20
diff --git a/tests/ui/coroutine/handle_opaques_before_coroutines.rs b/tests/ui/coroutine/handle_opaques_before_coroutines.rs
new file mode 100644
index 00000000000..2771c77429c
--- /dev/null
+++ b/tests/ui/coroutine/handle_opaques_before_coroutines.rs
@@ -0,0 +1,15 @@
+// test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/239
+//@edition: 2024
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+fn foo<'a>() -> impl Send {
+    if false {
+        foo();
+    }
+    async {}
+}
+
+fn main() {}
diff --git a/tests/ui/empty/empty-attributes.stderr b/tests/ui/empty/empty-attributes.stderr
index f0be56ddc6a..41dc790737d 100644
--- a/tests/ui/empty/empty-attributes.stderr
+++ b/tests/ui/empty/empty-attributes.stderr
@@ -56,12 +56,16 @@ error: unused attribute
    |
 LL | #[repr()]
    | ^^^^^^^^^ help: remove this attribute
+   |
+   = note: using `repr` with an empty list has no effect
 
 error: unused attribute
   --> $DIR/empty-attributes.rs:12:1
    |
 LL | #[target_feature()]
    | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: using `target_feature` with an empty list has no effect
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/error-codes/E0121.stderr b/tests/ui/error-codes/E0121.stderr
index b169373f643..074929c4e74 100644
--- a/tests/ui/error-codes/E0121.stderr
+++ b/tests/ui/error-codes/E0121.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/E0121.rs:1:13
    |
 LL | fn foo() -> _ { 5 }
-   |             ^
-   |             |
-   |             not allowed in type signatures
-   |             help: replace with the correct return type: `i32`
+   |             ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn foo() -> _ { 5 }
+LL + fn foo() -> i32 { 5 }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
   --> $DIR/E0121.rs:3:13
diff --git a/tests/ui/error-codes/E0719.rs b/tests/ui/error-codes/E0719.rs
index 0ea6d19000b..d7b4b876d1b 100644
--- a/tests/ui/error-codes/E0719.rs
+++ b/tests/ui/error-codes/E0719.rs
@@ -1,8 +1,3 @@
-trait Foo: Iterator<Item = i32, Item = i32> {}
-//~^ ERROR is already specified
-//~| ERROR is already specified
-//~| ERROR is already specified
-
 type Unit = ();
 
 fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr
index 7e8329db1f4..f4817568924 100644
--- a/tests/ui/error-codes/E0719.stderr
+++ b/tests/ui/error-codes/E0719.stderr
@@ -1,33 +1,5 @@
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:1:33
-   |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
-   |                     ----------  ^^^^^^^^^^ re-bound here
-   |                     |
-   |                     `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:1:33
-   |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
-   |                     ----------  ^^^^^^^^^^ re-bound here
-   |                     |
-   |                     `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:1:33
-   |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
-   |                     ----------  ^^^^^^^^^^ re-bound here
-   |                     |
-   |                     `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:8:42
+  --> $DIR/E0719.rs:3:42
    |
 LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
    |                               ---------  ^^^^^^^^^^^ re-bound here
@@ -35,13 +7,13 @@ LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
    |                               `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:14:38
+  --> $DIR/E0719.rs:9:38
    |
 LL |     let _: &dyn Iterator<Item = i32, Item = i32>;
    |                          ----------  ^^^^^^^^^^ re-bound here
    |                          |
    |                          `Item` bound here first
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0719`.
diff --git a/tests/ui/errors/auxiliary/remapped_dep.rs b/tests/ui/errors/auxiliary/remapped_dep.rs
index 36d4699a306..997118f822c 100644
--- a/tests/ui/errors/auxiliary/remapped_dep.rs
+++ b/tests/ui/errors/auxiliary/remapped_dep.rs
@@ -1,4 +1,4 @@
 //@ compile-flags: --remap-path-prefix={{src-base}}/errors/auxiliary=remapped-aux
-// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file.
+// Manually remap, so the remapped path remains in .stderr file.
 
 pub struct SomeStruct {} // This line should be show as part of the error.
diff --git a/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr b/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
index b4f83f6bfc0..b2651f3e03a 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
+++ b/tests/ui/errors/remap-path-prefix-reverse.local-self.stderr
@@ -1,5 +1,5 @@
 error[E0423]: expected value, found struct `remapped_dep::SomeStruct`
-  --> $DIR/remap-path-prefix-reverse.rs:16:13
+  --> $DIR/remap-path-prefix-reverse.rs:15:13
    |
 LL |     let _ = remapped_dep::SomeStruct;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `remapped_dep::SomeStruct {}`
diff --git a/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr b/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
index b4f83f6bfc0..b2651f3e03a 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
+++ b/tests/ui/errors/remap-path-prefix-reverse.remapped-self.stderr
@@ -1,5 +1,5 @@
 error[E0423]: expected value, found struct `remapped_dep::SomeStruct`
-  --> $DIR/remap-path-prefix-reverse.rs:16:13
+  --> $DIR/remap-path-prefix-reverse.rs:15:13
    |
 LL |     let _ = remapped_dep::SomeStruct;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `remapped_dep::SomeStruct {}`
diff --git a/tests/ui/errors/remap-path-prefix-reverse.rs b/tests/ui/errors/remap-path-prefix-reverse.rs
index 28fdabb8f4d..562e44690f7 100644
--- a/tests/ui/errors/remap-path-prefix-reverse.rs
+++ b/tests/ui/errors/remap-path-prefix-reverse.rs
@@ -2,7 +2,6 @@
 //@ compile-flags: --remap-path-prefix={{src-base}}/errors/auxiliary=remapped-aux
 
 //@ revisions: local-self remapped-self
-// [local-self] no-remap-src-base: The hack should work regardless of remapping.
 //@ [remapped-self] remap-src-base
 
 // Verify that the expected source code is shown.
diff --git a/tests/ui/errors/remap-path-prefix.rs b/tests/ui/errors/remap-path-prefix.rs
index 7e38e16280f..de18aa8cc20 100644
--- a/tests/ui/errors/remap-path-prefix.rs
+++ b/tests/ui/errors/remap-path-prefix.rs
@@ -2,7 +2,7 @@
 //@ compile-flags: --remap-path-prefix={{src-base}}=remapped
 //@ [with-diagnostic-scope]compile-flags: -Zremap-path-scope=diagnostics
 //@ [without-diagnostic-scope]compile-flags: -Zremap-path-scope=object
-// no-remap-src-base: Manually remap, so the remapped path remains in .stderr file.
+// Manually remap, so the remapped path remains in .stderr file.
 
 // The remapped paths are not normalized by compiletest.
 //@ normalize-stderr: "\\(errors)" -> "/$1"
diff --git a/tests/ui/errors/span-format_args-issue-140578.rs b/tests/ui/errors/span-format_args-issue-140578.rs
new file mode 100644
index 00000000000..8c91ded8337
--- /dev/null
+++ b/tests/ui/errors/span-format_args-issue-140578.rs
@@ -0,0 +1,32 @@
+fn check_format_args() {
+  print!("{:?} {a} {a:?}", [], a = 1 + 1);
+  //~^ ERROR type annotations needed
+}
+
+fn check_format_args_nl() {
+  println!("{:?} {a} {a:?}", [], a = 1 + 1);
+  //~^ ERROR type annotations needed
+}
+
+fn check_multi1() {
+  println!("{:?} {:?} {a} {a:?}", [], [], a = 1 + 1);
+  //~^ ERROR type annotations needed
+}
+
+fn check_multi2() {
+  println!("{:?} {:?} {a} {a:?} {b:?}", [], [], a = 1 + 1, b = []);
+  //~^ ERROR type annotations needed
+}
+
+fn check_unformatted() {
+  println!("
+  {:?} {:?}
+{a}
+{a:?}",
+        [],
+        //~^ ERROR type annotations needed
+ [],
+a = 1 + 1);
+}
+
+fn main() {}
diff --git a/tests/ui/errors/span-format_args-issue-140578.stderr b/tests/ui/errors/span-format_args-issue-140578.stderr
new file mode 100644
index 00000000000..6a273e5cd51
--- /dev/null
+++ b/tests/ui/errors/span-format_args-issue-140578.stderr
@@ -0,0 +1,43 @@
+error[E0282]: type annotations needed
+  --> $DIR/span-format_args-issue-140578.rs:2:28
+   |
+LL |   print!("{:?} {a} {a:?}", [], a = 1 + 1);
+   |                            ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args` which comes from the expansion of the macro `print` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0282]: type annotations needed
+  --> $DIR/span-format_args-issue-140578.rs:7:30
+   |
+LL |   println!("{:?} {a} {a:?}", [], a = 1 + 1);
+   |                              ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0282]: type annotations needed
+  --> $DIR/span-format_args-issue-140578.rs:12:35
+   |
+LL |   println!("{:?} {:?} {a} {a:?}", [], [], a = 1 + 1);
+   |                                   ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0282]: type annotations needed
+  --> $DIR/span-format_args-issue-140578.rs:17:41
+   |
+LL |   println!("{:?} {:?} {a} {a:?} {b:?}", [], [], a = 1 + 1, b = []);
+   |                                         ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0282]: type annotations needed
+  --> $DIR/span-format_args-issue-140578.rs:26:9
+   |
+LL |         [],
+   |         ^^ cannot infer type
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/fn/issue-80179.stderr b/tests/ui/fn/issue-80179.stderr
index f5d6c44db75..95158da3cff 100644
--- a/tests/ui/fn/issue-80179.stderr
+++ b/tests/ui/fn/issue-80179.stderr
@@ -2,21 +2,26 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/issue-80179.rs:10:24
    |
 LL | fn returns_fn_ptr() -> _ {
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `fn() -> i32`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn returns_fn_ptr() -> _ {
+LL + fn returns_fn_ptr() -> fn() -> i32 {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/issue-80179.rs:18:25
    |
 LL | fn returns_closure() -> _ {
-   |                         ^
-   |                         |
-   |                         not allowed in type signatures
-   |                         help: replace with an appropriate return type: `impl Fn() -> i32`
+   |                         ^ not allowed in type signatures
    |
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+help: replace with an appropriate return type
+   |
+LL - fn returns_closure() -> _ {
+LL + fn returns_closure() -> impl Fn() -> i32 {
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/fn/suggest-return-closure.stderr b/tests/ui/fn/suggest-return-closure.stderr
index 1860d1ca5d9..0639c23c75a 100644
--- a/tests/ui/fn/suggest-return-closure.stderr
+++ b/tests/ui/fn/suggest-return-closure.stderr
@@ -2,34 +2,40 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/suggest-return-closure.rs:1:17
    |
 LL | fn fn_once() -> _ {
-   |                 ^
-   |                 |
-   |                 not allowed in type signatures
-   |                 help: replace with an appropriate return type: `impl FnOnce()`
+   |                 ^ not allowed in type signatures
    |
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+help: replace with an appropriate return type
+   |
+LL - fn fn_once() -> _ {
+LL + fn fn_once() -> impl FnOnce() {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/suggest-return-closure.rs:13:16
    |
 LL | fn fn_mut() -> _ {
-   |                ^
-   |                |
-   |                not allowed in type signatures
-   |                help: replace with an appropriate return type: `impl FnMut(char)`
+   |                ^ not allowed in type signatures
    |
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+help: replace with an appropriate return type
+   |
+LL - fn fn_mut() -> _ {
+LL + fn fn_mut() -> impl FnMut(char) {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/suggest-return-closure.rs:33:13
    |
 LL | fn fun() -> _ {
-   |             ^
-   |             |
-   |             not allowed in type signatures
-   |             help: replace with an appropriate return type: `impl Fn() -> i32`
+   |             ^ not allowed in type signatures
    |
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+help: replace with an appropriate return type
+   |
+LL - fn fun() -> _ {
+LL + fn fun() -> impl Fn() -> i32 {
+   |
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/suggest-return-closure.rs:24:9
diff --git a/tests/ui/fn/suggest-return-future.stderr b/tests/ui/fn/suggest-return-future.stderr
index a4c8b5d8c4b..7c097e50671 100644
--- a/tests/ui/fn/suggest-return-future.stderr
+++ b/tests/ui/fn/suggest-return-future.stderr
@@ -2,19 +2,25 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/suggest-return-future.rs:7:13
    |
 LL | fn foo() -> _ {
-   |             ^
-   |             |
-   |             not allowed in type signatures
-   |             help: replace with an appropriate return type: `impl Future<Output = i32>`
+   |             ^ not allowed in type signatures
+   |
+help: replace with an appropriate return type
+   |
+LL - fn foo() -> _ {
+LL + fn foo() -> impl Future<Output = i32> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/suggest-return-future.rs:15:13
    |
 LL | fn bar() -> _ {
-   |             ^
-   |             |
-   |             not allowed in type signatures
-   |             help: replace with an appropriate return type: `impl Future<Output = i32>`
+   |             ^ not allowed in type signatures
+   |
+help: replace with an appropriate return type
+   |
+LL - fn bar() -> _ {
+LL + fn bar() -> impl Future<Output = i32> {
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
index 8bb72833e30..77a637c470c 100644
--- a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
@@ -14,6 +14,11 @@ note: due to a current limitation of the type system, this implies a `'static` l
    |
 LL |     for<'a> I::Item<'a>: Debug,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/hrtb-implied-1.rs:26:26
+   |
+LL |     for<'a> I::Item<'a>: Debug,
+   |                          ^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs
index 7587e89409a..412d8af9884 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.rs
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs
@@ -32,6 +32,7 @@ fn needs_static() {
     //~| NOTE borrowed value does not live long enoug
 
     fn needs_static(_: impl Sized + 'static) {}
+    //~^ NOTE requirement that the value outlives `'static` introduced here
     needs_static(a);
     //~^ NOTE argument requires that `x` is borrowed for `'static`
 }
@@ -79,6 +80,7 @@ fn needs_static_mut() {
     //~| NOTE borrowed value does not live long enough
 
     fn needs_static(_: impl Sized + 'static) {}
+    //~^ NOTE requirement that the value outlives `'static` introduced here
     needs_static(a);
     //~^ NOTE argument requires that `x` is borrowed for `'static`
 }
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
index aa0f6400091..880e7878477 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `x` does not live long enough
-  --> $DIR/migration-note.rs:182:17
+  --> $DIR/migration-note.rs:184:17
    |
 LL |     let x = vec![0];
    |         - binding `x` declared here
@@ -50,6 +50,11 @@ LL |
 LL | }
    | - `x` dropped here while still borrowed
    |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/migration-note.rs:34:37
+   |
+LL |     fn needs_static(_: impl Sized + 'static) {}
+   |                                     ^^^^^^^
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
   --> $DIR/migration-note.rs:29:13
    |
@@ -61,7 +66,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:48:8
+  --> $DIR/migration-note.rs:49:8
    |
 LL |     let x = vec![1];
    |         - binding `x` declared here
@@ -76,7 +81,7 @@ LL | }
    | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:43:13
+  --> $DIR/migration-note.rs:44:13
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
@@ -90,7 +95,7 @@ LL |     let a = display_len(&x.clone());
    |                           ++++++++
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/migration-note.rs:66:5
+  --> $DIR/migration-note.rs:67:5
    |
 LL |     let a = display_len_mut(&mut x);
    |                             ------ first mutable borrow occurs here
@@ -102,7 +107,7 @@ LL |     println!("{a}");
    |                - first borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:63:13
+  --> $DIR/migration-note.rs:64:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +117,7 @@ LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
 
 error[E0597]: `x` does not live long enough
-  --> $DIR/migration-note.rs:76:29
+  --> $DIR/migration-note.rs:77:29
    |
 LL |     let mut x = vec![1];
    |         ----- binding `x` declared here
@@ -126,8 +131,13 @@ LL |
 LL | }
    | - `x` dropped here while still borrowed
    |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/migration-note.rs:82:37
+   |
+LL |     fn needs_static(_: impl Sized + 'static) {}
+   |                                     ^^^^^^^
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:76:13
+  --> $DIR/migration-note.rs:77:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -137,7 +147,7 @@ LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:95:8
+  --> $DIR/migration-note.rs:97:8
    |
 LL |     let mut x = vec![1];
    |         ----- binding `x` declared here
@@ -152,7 +162,7 @@ LL | }
    | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:90:13
+  --> $DIR/migration-note.rs:92:13
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -166,7 +176,7 @@ LL |     let a = display_len_mut(&mut x.clone());
    |                                   ++++++++
 
 error[E0506]: cannot assign to `s.f` because it is borrowed
-  --> $DIR/migration-note.rs:115:5
+  --> $DIR/migration-note.rs:117:5
    |
 LL |     let a = display_field(&s.f);
    |                           ---- `s.f` is borrowed here
@@ -178,7 +188,7 @@ LL |     println!("{a}");
    |                - borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:112:13
+  --> $DIR/migration-note.rs:114:13
    |
 LL |     let a = display_field(&s.f);
    |             ^^^^^^^^^^^^^^^^^^^
@@ -188,7 +198,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0506]: cannot assign to `s.f` because it is borrowed
-  --> $DIR/migration-note.rs:131:5
+  --> $DIR/migration-note.rs:133:5
    |
 LL |     let a = display_field(&mut s.f);
    |                           -------- `s.f` is borrowed here
@@ -200,7 +210,7 @@ LL |     println!("{a}");
    |                - borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:128:13
+  --> $DIR/migration-note.rs:130:13
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,7 +220,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0503]: cannot use `s.f` because it was mutably borrowed
-  --> $DIR/migration-note.rs:143:5
+  --> $DIR/migration-note.rs:145:5
    |
 LL |     let a = display_field(&mut s.f);
    |                           -------- `s.f` is borrowed here
@@ -222,7 +232,7 @@ LL |     println!("{a}");
    |                - borrow later used here
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:140:13
+  --> $DIR/migration-note.rs:142:13
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,7 +242,7 @@ LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
 
 error[E0597]: `z.f` does not live long enough
-  --> $DIR/migration-note.rs:159:25
+  --> $DIR/migration-note.rs:161:25
    |
 LL |         let z = Z { f: vec![1] };
    |             - binding `z` declared here
@@ -248,7 +258,7 @@ LL | }
    |
    = note: values in a scope are dropped in the opposite order they are defined
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:159:13
+  --> $DIR/migration-note.rs:161:13
    |
 LL |         x = display_len(&z.f);
    |             ^^^^^^^^^^^^^^^^^
@@ -258,7 +268,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/migration-note.rs:170:40
+  --> $DIR/migration-note.rs:172:40
    |
 LL |     let x = { let x = display_len(&mut vec![0]); x };
    |                                        ^^^^^^^ - - borrow later used here
@@ -268,7 +278,7 @@ LL |     let x = { let x = display_len(&mut vec![0]); x };
    |
    = note: consider using a `let` binding to create a longer lived value
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:170:23
+  --> $DIR/migration-note.rs:172:23
    |
 LL |     let x = { let x = display_len(&mut vec![0]); x };
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +289,7 @@ LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/migration-note.rs:198:10
+  --> $DIR/migration-note.rs:200:10
    |
 LL |     let x = String::new();
    |         - binding `x` declared here
@@ -294,12 +304,12 @@ LL | }
    | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized`
    |
 note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
-  --> $DIR/migration-note.rs:195:13
+  --> $DIR/migration-note.rs:197:13
    |
 LL |     let y = capture_apit(&x);
    |             ^^^^^^^^^^^^^^^^
 note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
-  --> $DIR/migration-note.rs:189:21
+  --> $DIR/migration-note.rs:191:21
    |
 LL | fn capture_apit(x: &impl Sized) -> impl Sized {}
    |                     ^^^^^^^^^^
diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs
index 6548c03d1b0..e2750bcf957 100644
--- a/tests/ui/implied-bounds/bevy_world_query.rs
+++ b/tests/ui/implied-bounds/bevy_world_query.rs
@@ -1,6 +1,8 @@
-#![crate_name = "bevy_ecs"]
-
 //@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+#![crate_name = "bevy_ecs"]
 
 // We currently special case bevy from erroring on incorrect implied bounds
 // from normalization (issue #109628).
diff --git a/tests/ui/indexing/ambiguity-after-deref-step.rs b/tests/ui/indexing/ambiguity-after-deref-step.rs
new file mode 100644
index 00000000000..2dd95eed097
--- /dev/null
+++ b/tests/ui/indexing/ambiguity-after-deref-step.rs
@@ -0,0 +1,9 @@
+// Regression test making sure that indexing fails with an ambiguity
+// error if one of the deref-steps encounters an inference variable.
+
+fn main() {
+    let x = &Default::default();
+    //~^ ERROR type annotations needed for `&_`
+    x[1];
+    let _: &Vec<()> = x;
+}
diff --git a/tests/ui/indexing/ambiguity-after-deref-step.stderr b/tests/ui/indexing/ambiguity-after-deref-step.stderr
new file mode 100644
index 00000000000..c7ddd4731c7
--- /dev/null
+++ b/tests/ui/indexing/ambiguity-after-deref-step.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed for `&_`
+  --> $DIR/ambiguity-after-deref-step.rs:5:9
+   |
+LL |     let x = &Default::default();
+   |         ^
+LL |
+LL |     x[1];
+   |     - type must be known at this point
+   |
+help: consider giving `x` an explicit type, where the placeholders `_` are specified
+   |
+LL |     let x: &_ = &Default::default();
+   |          ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr
index a78941f9e11..3de317d2af6 100644
--- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr
+++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr
@@ -1,10 +1,10 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:5
+  --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:22
    |
 LL |     println!("{:?}", []);
-   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type
+   |                      ^^ cannot infer type
    |
-   = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/keyword/soup.rs b/tests/ui/keyword/soup.rs
new file mode 100644
index 00000000000..c4dbe3fb483
--- /dev/null
+++ b/tests/ui/keyword/soup.rs
@@ -0,0 +1,30 @@
+//@ edition:2024
+//@ check-pass
+
+#![allow(unused_imports)]
+#![allow(missing_abi)]
+#![allow(unused_macros)]
+#![allow(non_camel_case_types)]
+#![allow(unreachable_code)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(unused_must_use)]
+
+// all 48 keywords in 300 characters
+mod x {
+    pub(super) struct X;
+    use Ok;
+    impl X {
+        pub(in crate) async fn x(self: Self, x: &'static &'_ dyn for<> Fn()) where {
+            unsafe extern { safe fn x(); }
+            macro_rules! x { () => {}; }
+            if 'x: loop {
+                return match while let true = break 'x false { continue } {
+                    ref x => { &raw mut x; async { const { enum A {} } }.await as () },
+                };
+            } { type x = X; } else { move || { trait x { } union B { x: () } }; }
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/macros/macro-use-all-and-none.stderr b/tests/ui/macros/macro-use-all-and-none.stderr
index a5efb065a21..b4c05adcb33 100644
--- a/tests/ui/macros/macro-use-all-and-none.stderr
+++ b/tests/ui/macros/macro-use-all-and-none.stderr
@@ -2,8 +2,9 @@ warning: unused attribute
   --> $DIR/macro-use-all-and-none.rs:7:12
    |
 LL | #[macro_use()]
-   |            ^^ help: remove this attribute
+   |            ^^ help: remove these parentheses
    |
+   = note: using `macro_use` with an empty list is equivalent to not using a list at all
 note: the lint level is defined here
   --> $DIR/macro-use-all-and-none.rs:4:9
    |
diff --git a/tests/ui/methods/overflow-if-subtyping.rs b/tests/ui/methods/overflow-if-subtyping.rs
new file mode 100644
index 00000000000..a97f29f1f6d
--- /dev/null
+++ b/tests/ui/methods/overflow-if-subtyping.rs
@@ -0,0 +1,30 @@
+//@ check-pass
+
+// Regression test for #128887.
+#![allow(unconditional_recursion)]
+trait Mappable<T> {
+    type Output;
+}
+
+trait Bound<T> {}
+// Deleting this impl made it compile on beta
+impl<T> Bound<T> for T {}
+
+trait Generic<M> {}
+
+// Deleting the `: Mappable<T>` already made it error on stable.
+struct IndexWithIter<I, M: Mappable<T>, T>(I, M, T);
+
+impl<I, M, T> IndexWithIter<I, M, T>
+where
+    <M as Mappable<T>>::Output: Bound<T>,
+    // Flipping these where bounds causes this to succeed, even when removing
+    // the where-clause on the struct definition.
+    M: Mappable<T>,
+    I: Generic<M>,
+{
+    fn new(x: I) {
+        IndexWithIter::<_, _, _>::new(x);
+    }
+}
+fn main() {}
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index e13653f3423..af07745a00a 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -69,6 +69,12 @@ LL |         cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static ->
 LL |     })
 LL | }
    | - `a` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:13:8
+   |
+LL |     F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>),
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr
index 15f48d88c37..4136ac418de 100644
--- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr
@@ -13,6 +13,12 @@ LL |         z = &local_arr;
 ...
 LL | }
    | - `local_arr` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/propagate-multiple-requirements.rs:4:21
+   |
+LL | fn once<S, T, U, F: FnOnce(S, T) -> U>(f: F, s: S, t: T) -> U {
+   |                     ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr
index a98f11ce513..263d271b6b3 100644
--- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr
+++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr
@@ -17,6 +17,11 @@ note: due to a current limitation of the type system, this implies a `'static` l
    |
 LL | fn assert_static_via_hrtb<G>(_: G) where for<'a> G: Outlives<'a> {}
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/local-outlives-static-via-hrtb.rs:15:53
+   |
+LL | fn assert_static_via_hrtb<G>(_: G) where for<'a> G: Outlives<'a> {}
+   |                                                     ^^^^^^^^^^^^
 
 error[E0597]: `local` does not live long enough
   --> $DIR/local-outlives-static-via-hrtb.rs:25:45
@@ -37,6 +42,11 @@ note: due to a current limitation of the type system, this implies a `'static` l
    |
 LL |     for<'a> &'a T: Reference<AssociatedType = &'a ()>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/local-outlives-static-via-hrtb.rs:19:30
+   |
+LL |     for<'a> &'a T: Reference<AssociatedType = &'a ()>,
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr
index 6e47b8e59f5..804b3f00a26 100644
--- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr
+++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr
@@ -18,6 +18,11 @@ note: due to a current limitation of the type system, this implies a `'static` l
    |
 LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
    |           ^^^^^^^^^^^^^^
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22
+   |
+LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
+   |                      ^^^
 
 error: implementation of `Fn` is not general enough
   --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr
index 6e47b8e59f5..804b3f00a26 100644
--- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr
+++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr
@@ -18,6 +18,11 @@ note: due to a current limitation of the type system, this implies a `'static` l
    |
 LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
    |           ^^^^^^^^^^^^^^
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22
+   |
+LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
+   |                      ^^^
 
 error: implementation of `Fn` is not general enough
   --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed
new file mode 100644
index 00000000000..63cc3333b6b
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed
@@ -0,0 +1,20 @@
+#![allow(dead_code, unused_variables)]
+//@ run-rustfix
+pub use my_mod::Foo;
+//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+
+mod my_mod {
+    pub struct Foo(u32);
+
+    mod my_sub_mod {
+        fn my_func() {
+            let crate::my_mod::Foo(x) = crate::my_mod::Foo(42);
+            //~^ ERROR cannot initialize a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+            //~| ERROR cannot match against a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+        }
+    }
+}
+fn main() {}
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs
new file mode 100644
index 00000000000..0b695f90654
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs
@@ -0,0 +1,20 @@
+#![allow(dead_code, unused_variables)]
+//@ run-rustfix
+pub use my_mod::Foo;
+//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+
+mod my_mod {
+    pub struct Foo(u32);
+
+    mod my_sub_mod {
+        fn my_func() {
+            let crate::Foo(x) = crate::Foo(42);
+            //~^ ERROR cannot initialize a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+            //~| ERROR cannot match against a tuple struct which contains private fields
+            //~| HELP the type can be constructed directly, because its fields are available from the current scope
+        }
+    }
+}
+fn main() {}
diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr
new file mode 100644
index 00000000000..6ab324cb32f
--- /dev/null
+++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr
@@ -0,0 +1,36 @@
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:33
+   |
+LL |             let crate::Foo(x) = crate::Foo(42);
+   |                                 ^^^^^^^^^^
+   |
+note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9
+   |
+LL | pub use my_mod::Foo;
+   |         ^^^^^^^^^^^
+help: the type can be constructed directly, because its fields are available from the current scope
+   |
+LL |             let crate::Foo(x) = crate::my_mod::Foo(42);
+   |                                        ++++++++
+
+error[E0532]: cannot match against a tuple struct which contains private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:17
+   |
+LL |             let crate::Foo(x) = crate::Foo(42);
+   |                 ^^^^^^^^^^
+   |
+note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields
+  --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9
+   |
+LL | pub use my_mod::Foo;
+   |         ^^^^^^^^^^^
+help: the type can be constructed directly, because its fields are available from the current scope
+   |
+LL |             let crate::my_mod::Foo(x) = crate::Foo(42);
+   |                        ++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0532.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/proc-macro/expand-expr.rs b/tests/ui/proc-macro/expand-expr.rs
index 1e058abe3bc..c3dddd8e459 100644
--- a/tests/ui/proc-macro/expand-expr.rs
+++ b/tests/ui/proc-macro/expand-expr.rs
@@ -1,6 +1,6 @@
 //@ proc-macro: expand-expr.rs
 //@ ignore-backends: gcc
-// no-remap-src-base: check_expand_expr_file!() fails when enabled.
+// No `remap-src-base`, since `check_expand_expr_file!()` fails when enabled.
 
 #![feature(concat_bytes)]
 extern crate expand_expr;
diff --git a/tests/ui/proc-macro/pretty-print-hack-show.rs b/tests/ui/proc-macro/pretty-print-hack-show.rs
index 70f0d5f6ea9..08e26c81142 100644
--- a/tests/ui/proc-macro/pretty-print-hack-show.rs
+++ b/tests/ui/proc-macro/pretty-print-hack-show.rs
@@ -1,7 +1,6 @@
 //@ proc-macro: test-macros.rs
 //@ compile-flags: -Z span-debug
 //@ revisions: local remapped
-// [local] no-remap-src-base: The hack should work regardless of remapping.
 //@ [remapped] remap-src-base
 
 #![no_std] // Don't load unnecessary hygiene information from std
diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr
index d1c3d06f2b6..62a02638e54 100644
--- a/tests/ui/proc-macro/quote/not-quotable.stderr
+++ b/tests/ui/proc-macro/quote/not-quotable.stderr
@@ -15,8 +15,8 @@ LL |     let _ = quote! { $ip };
              Cow<'_, T>
              Option<T>
              Rc<T>
-             RepInterp<T>
-           and 25 others
+             bool
+           and 24 others
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.rs b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs
new file mode 100644
index 00000000000..720cd1cf6ee
--- /dev/null
+++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs
@@ -0,0 +1,11 @@
+fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {}
+//~^ NOTE: requirements that the value outlives `'b` introduced here
+
+fn foo<'b>() { //~ NOTE: lifetime `'b` defined here
+    outlives_indir::<'_, 'b, _>(&mut 1u32); //~ ERROR: temporary value dropped while borrowed
+    //~^ NOTE: argument requires that borrow lasts for `'b`
+    //~| NOTE: creates a temporary value which is freed while still in use
+    //~| NOTE: temporary value is freed at the end of this statement
+}
+
+fn main() {}
diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr
new file mode 100644
index 00000000000..4cdaf950e15
--- /dev/null
+++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr
@@ -0,0 +1,20 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/multiple-sources-for-outlives-requirement.rs:5:38
+   |
+LL | fn foo<'b>() {
+   |        -- lifetime `'b` defined here
+LL |     outlives_indir::<'_, 'b, _>(&mut 1u32);
+   |     ---------------------------------^^^^-- temporary value is freed at the end of this statement
+   |     |                                |
+   |     |                                creates a temporary value which is freed while still in use
+   |     argument requires that borrow lasts for `'b`
+   |
+note: requirements that the value outlives `'b` introduced here
+  --> $DIR/multiple-sources-for-outlives-requirement.rs:1:23
+   |
+LL | fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {}
+   |                       ^^         ^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr
index 919fcffdc53..158d74ed06d 100644
--- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr
+++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr
@@ -11,6 +11,12 @@ LL | |     });
    | |______- argument requires that `x` is borrowed for `'static`
 LL |   }
    |   - `x` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/regions-infer-proc-static-upvar.rs:4:19
+   |
+LL | fn foo<F:FnOnce()+'static>(_p: F) { }
+   |                   ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
index 1d3d5e831c3..a8fd827bc69 100644
--- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
+++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
@@ -10,6 +10,12 @@ LL |         [ word ] => { assert_static(word); }
 LL |     }
 LL | }
    | - `line` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/regions-pattern-typing-issue-19552.rs:1:21
+   |
+LL | fn assert_static<T: 'static>(_t: T) {}
+   |                     ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/repr/repr-empty-packed.stderr b/tests/ui/repr/repr-empty-packed.stderr
index 6565b2e8c1d..adf32c95529 100644
--- a/tests/ui/repr/repr-empty-packed.stderr
+++ b/tests/ui/repr/repr-empty-packed.stderr
@@ -15,6 +15,7 @@ error: unused attribute
 LL | #[repr()]
    | ^^^^^^^^^ help: remove this attribute
    |
+   = note: using `repr` with an empty list has no effect
 note: the lint level is defined here
   --> $DIR/repr-empty-packed.rs:2:9
    |
diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr
index 8b7c5e1681a..839e4265e03 100644
--- a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr
+++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr
@@ -2,37 +2,49 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:8:24
    |
 LL |     fn f1(s: S<'_>) -> _ {
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `S<'_>`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn f1(s: S<'_>) -> _ {
+LL +     fn f1(s: S<'_>) -> S<'_> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:13:24
    |
 LL |     fn f2(s: S<'_>) -> _ {
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `S<'_>`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn f2(s: S<'_>) -> _ {
+LL +     fn f2(s: S<'_>) -> S<'_> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:23:24
    |
 LL |     fn f3(s: S<'_>) -> _ {
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `S<'_>`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn f3(s: S<'_>) -> _ {
+LL +     fn f3(s: S<'_>) -> S<'_> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:28:24
    |
 LL |     fn f4(s: S<'_>) -> _ {
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `S<'_>`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn f4(s: S<'_>) -> _ {
+LL +     fn f4(s: S<'_>) -> S<'_> {
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr
index 8b0d3a0bf4c..51be79be5db 100644
--- a/tests/ui/static/static-lifetime-bound.stderr
+++ b/tests/ui/static/static-lifetime-bound.stderr
@@ -10,6 +10,12 @@ LL |     f(&x);
    |     argument requires that `x` is borrowed for `'static`
 LL | }
    | - `x` dropped here while still borrowed
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/static-lifetime-bound.rs:1:10
+   |
+LL | fn f<'a: 'static>(_: &'a i32) {}
+   |          ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/static/static-region-bound.stderr b/tests/ui/static/static-region-bound.stderr
index a47c9457102..8472738daa4 100644
--- a/tests/ui/static/static-region-bound.stderr
+++ b/tests/ui/static/static-region-bound.stderr
@@ -7,6 +7,12 @@ LL |     f(x);
    |     ---- argument requires that borrow lasts for `'static`
 LL | }
    | - temporary value is freed at the end of this statement
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/static-region-bound.rs:3:8
+   |
+LL | fn f<T:'static>(_: T) {}
+   |        ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/auxiliary/hidden-struct.rs b/tests/ui/suggestions/auxiliary/hidden-struct.rs
index 30d69acac20..1f495a9f222 100644
--- a/tests/ui/suggestions/auxiliary/hidden-struct.rs
+++ b/tests/ui/suggestions/auxiliary/hidden-struct.rs
@@ -1,3 +1,5 @@
+// `Foo` and `Bar` should not be suggested in diagnostics of dependents
+
 #[doc(hidden)]
 pub mod hidden {
     pub struct Foo;
@@ -5,13 +7,29 @@ pub mod hidden {
 
 pub mod hidden1 {
     #[doc(hidden)]
-    pub struct Foo;
+    pub struct Bar;
 }
 
+// `Baz` and `Quux` *should* be suggested in diagnostics of dependents
 
 #[doc(hidden)]
-pub(crate) mod hidden2 {
-    pub struct Bar;
+pub mod hidden2 {
+    pub struct Baz;
+}
+
+pub use hidden2::Baz;
+
+#[doc(hidden)]
+pub(crate) mod hidden3 {
+    pub struct Quux;
 }
 
-pub use hidden2::Bar;
+pub use hidden3::Quux;
+
+pub trait Marker {}
+
+impl Marker for Option<u32> {}
+impl Marker for hidden::Foo {}
+impl Marker for hidden1::Bar {}
+impl Marker for Baz {}
+impl Marker for Quux {}
diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
index 281975dcc2f..a83e496f270 100644
--- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
+++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
@@ -1,5 +1,4 @@
 //@ aux-build:hidden-struct.rs
-//@ compile-flags: --crate-type lib
 
 extern crate hidden_struct;
 
@@ -9,7 +8,20 @@ mod local {
 }
 
 pub fn test(_: Foo) {}
-//~^ ERROR cannot find type `Foo` in this scope
+//~^ ERROR [E0412]
 
 pub fn test2(_: Bar) {}
-//~^ ERROR cannot find type `Bar` in this scope
+//~^ ERROR [E0412]
+
+pub fn test3(_: Baz) {}
+//~^ ERROR [E0412]
+
+pub fn test4(_: Quux) {}
+//~^ ERROR [E0412]
+
+fn test5<T: hidden_struct::Marker>() {}
+
+fn main() {
+    test5::<i32>();
+    //~^ ERROR [E0277]
+}
diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
index 7fb4d95ff9b..7036708756d 100644
--- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
+++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Foo` in this scope
-  --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:10:16
    |
 LL | pub fn test(_: Foo) {}
    |                ^^^ not found in this scope
@@ -10,16 +10,50 @@ LL + use local::Foo;
    |
 
 error[E0412]: cannot find type `Bar` in this scope
-  --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:13:17
    |
 LL | pub fn test2(_: Bar) {}
    |                 ^^^ not found in this scope
+
+error[E0412]: cannot find type `Baz` in this scope
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:16:17
+   |
+LL | pub fn test3(_: Baz) {}
+   |                 ^^^ not found in this scope
    |
 help: consider importing this struct
    |
-LL + use hidden_struct::Bar;
+LL + use hidden_struct::Baz;
+   |
+
+error[E0412]: cannot find type `Quux` in this scope
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:19:17
+   |
+LL | pub fn test4(_: Quux) {}
+   |                 ^^^^ not found in this scope
+   |
+help: consider importing this struct
+   |
+LL + use hidden_struct::Quux;
+   |
+
+error[E0277]: the trait bound `i32: Marker` is not satisfied
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13
+   |
+LL |     test5::<i32>();
+   |             ^^^ the trait `Marker` is not implemented for `i32`
+   |
+   = help: the following other types implement trait `Marker`:
+             Baz
+             Option<u32>
+             Quux
+note: required by a bound in `test5`
+  --> $DIR/dont-suggest-foreign-doc-hidden.rs:22:13
    |
+LL | fn test5<T: hidden_struct::Marker>() {}
+   |             ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5`
 
-error: aborting due to 2 previous errors
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/suggestions/return-cycle-2.stderr b/tests/ui/suggestions/return-cycle-2.stderr
index 23de2309e87..e852cd34a72 100644
--- a/tests/ui/suggestions/return-cycle-2.stderr
+++ b/tests/ui/suggestions/return-cycle-2.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/return-cycle-2.rs:6:34
    |
 LL |     fn as_ref(_: i32, _: i32) -> _ {
-   |                                  ^
-   |                                  |
-   |                                  not allowed in type signatures
-   |                                  help: replace with the correct return type: `Token<&'static T>`
+   |                                  ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn as_ref(_: i32, _: i32) -> _ {
+LL +     fn as_ref(_: i32, _: i32) -> Token<&'static T> {
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/return-cycle.stderr b/tests/ui/suggestions/return-cycle.stderr
index 60470490441..cd46c2daa40 100644
--- a/tests/ui/suggestions/return-cycle.stderr
+++ b/tests/ui/suggestions/return-cycle.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/return-cycle.rs:6:17
    |
 LL |     fn new() -> _ {
-   |                 ^
-   |                 |
-   |                 not allowed in type signatures
-   |                 help: replace with the correct return type: `Token<()>`
+   |                 ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn new() -> _ {
+LL +     fn new() -> Token<()> {
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/suggest-fn-ptr-for-fn-item-in-fn-ret.stderr b/tests/ui/suggestions/suggest-fn-ptr-for-fn-item-in-fn-ret.stderr
index bf7790e2307..9880dd95d86 100644
--- a/tests/ui/suggestions/suggest-fn-ptr-for-fn-item-in-fn-ret.stderr
+++ b/tests/ui/suggestions/suggest-fn-ptr-for-fn-item-in-fn-ret.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/suggest-fn-ptr-for-fn-item-in-fn-ret.rs:7:13
    |
 LL | fn bar() -> _ { Wrapper(foo) }
-   |             ^
-   |             |
-   |             not allowed in type signatures
-   |             help: replace with the correct return type: `Wrapper<fn()>`
+   |             ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn bar() -> _ { Wrapper(foo) }
+LL + fn bar() -> Wrapper<fn()> { Wrapper(foo) }
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
index 6a1025ea087..7c78d432fa0 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
@@ -6,7 +6,6 @@
 //@ exec-env:RUST_BACKTRACE=0
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
 
-//@ ignore-android #120567
 //@ needs-subprocess
 
 #![cfg(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index 8d7c62f8ec7..d8f65a78261 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
@@ -1,11 +1,11 @@
 
-thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:32:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:31:5:
 assertion `left == right` failed
   left: 2
  right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:26:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:25:5:
 assertion `left == right` failed
   left: 2
  right: 4
diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs
index 6c9b641fb6f..13a30223399 100644
--- a/tests/ui/test-attrs/test-panic-abort.rs
+++ b/tests/ui/test-attrs/test-panic-abort.rs
@@ -6,7 +6,6 @@
 //@ exec-env:RUST_BACKTRACE=0
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
 
-//@ ignore-android #120567
 //@ needs-subprocess
 
 #![cfg(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout
index 4d65c05b944..ca247f7da41 100644
--- a/tests/ui/test-attrs/test-panic-abort.run.stdout
+++ b/tests/ui/test-attrs/test-panic-abort.run.stdout
@@ -18,7 +18,7 @@ testing123
 ---- it_fails stderr ----
 testing321
 
-thread 'main' ($TID) panicked at $DIR/test-panic-abort.rs:37:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort.rs:36:5:
 assertion `left == right` failed
   left: 2
  right: 5
diff --git a/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs b/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs
new file mode 100644
index 00000000000..679d6b1fb16
--- /dev/null
+++ b/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs
@@ -0,0 +1,60 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#105. We previously encountered
+// an ICE in typenum as `forced_ambiguity` failed. While this test no longer causes
+// `forced_ambiguity` to error, we still want to use it as a regression test.
+
+pub struct UInt<U, B> {
+    _msb: U,
+    _lsb: B,
+}
+pub struct B1;
+pub trait Sub<Rhs> {
+    type Output;
+}
+impl<U, B> Sub<B1> for UInt<UInt<U, B>, B1> {
+    type Output = ();
+}
+impl<U> Sub<B1> for UInt<U, ()>
+where
+    U: Sub<B1>,
+    U::Output: Send,
+{
+    type Output = ();
+}
+
+pub trait Op<N, R, I> {
+    fn op(&self) {
+        unimplemented!()
+    }
+}
+trait OpIf<N, R, I> {}
+
+impl<N, Ur, Br, I> Op<N, UInt<Ur, Br>, I> for ()
+where
+    N: Sub<I>,
+    (): OpIf<N, UInt<UInt<Ur, Br>, N::Output>, I>,
+{
+}
+impl<N, R, Ui, Bi> OpIf<N, R, UInt<Ui, Bi>> for ()
+where
+    UInt<Ui, Bi>: Sub<B1>,
+    (): Op<N, R, <UInt<Ui, Bi> as Sub<B1>>::Output>,
+{
+}
+impl<N, R> OpIf<N, R, ()> for () where R: Sub<N> {}
+
+pub trait Compute {
+    type Output;
+}
+
+pub fn repro<Ul, Bl>()
+where
+    UInt<Ul, Bl>: Compute,
+    <UInt<Ul, Bl> as Compute>::Output: Sub<B1>,
+    (): Op<UInt<(), Bl>, (), ()>,
+{
+    ().op();
+}
+fn main() {}
diff --git a/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs
new file mode 100644
index 00000000000..e35e48dfcec
--- /dev/null
+++ b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs
@@ -0,0 +1,25 @@
+//@ ignore-compare-mode-next-solver
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#220. Builtin `Fn`-trait
+// candidates required `for<'latebound> Output<'latebound>: Sized` which ended
+// up resulting in overflow if the return type is an opaque in the defining scope.
+//
+// We now eagerly instantiate the binder of the function definition which avoids
+// that overflow by relating the lifetime of the opaque to something from the
+// input.
+fn flat_map<T, F, I, G>(_: F, _: G)
+where
+    F: FnOnce(T) -> I,
+    I: Iterator,
+    G: Fn(<I as Iterator>::Item) -> usize,
+{
+}
+
+fn rarw<'a>(_: &'a ()) -> impl Iterator<Item = &'a str> {
+    flat_map(rarw, |x| x.len());
+    std::iter::empty()
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs
new file mode 100644
index 00000000000..1d64e422d89
--- /dev/null
+++ b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs
@@ -0,0 +1,14 @@
+//@ ignore-compare-mode-next-solver
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#204, see
+// the sibling test for more details.
+
+fn constrain<'a, F: FnOnce(&'a ())>(_: F) {}
+fn foo<'a>(_: &'a ()) -> impl Sized + use<'a> {
+    constrain(foo);
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
index 2760c1696b5..f603ff1ec80 100644
--- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
@@ -1,12 +1,5 @@
 //@ revisions: current next
 //@[next] compile-flags: -Znext-solver
-//@[next] failure-status: 101
-//@[next] known-bug: unknown
-//@[next] normalize-stderr: "note: .*\n\n" -> ""
-//@[next] normalize-stderr: "thread 'rustc' panicked.*\n.*\n" -> ""
-//@[next] normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
-//@[next] normalize-stderr: "delayed at .*" -> ""
-//@[next] rustc-env:RUST_BACKTRACE=0
 //@ check-pass
 
 trait Super {
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr
index c0f197ec48c..222edfb90a7 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr
@@ -11,10 +11,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/issue-77179.rs:8:22
    |
 LL | fn test() -> Pointer<_> {
-   |              --------^-
-   |              |       |
-   |              |       not allowed in type signatures
-   |              help: replace with the correct return type: `Pointer<i32>`
+   |                      ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn test() -> Pointer<_> {
+LL + fn test() -> Pointer<i32> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/issue-77179.rs:19:25
diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs
index 79d46c010d7..f5eb90e94d4 100644
--- a/tests/ui/type/pattern_types/const_generics.rs
+++ b/tests/ui/type/pattern_types/const_generics.rs
@@ -1,4 +1,7 @@
 //@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 
 #![feature(pattern_types, generic_pattern_types, pattern_type_macro)]
 #![expect(incomplete_features)]
diff --git a/tests/ui/type/pattern_types/transmute.stderr b/tests/ui/type/pattern_types/transmute.current.stderr
index 578549b515c..edec542e5e1 100644
--- a/tests/ui/type/pattern_types/transmute.stderr
+++ b/tests/ui/type/pattern_types/transmute.current.stderr
@@ -1,5 +1,5 @@
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute.rs:20:14
+  --> $DIR/transmute.rs:23:14
    |
 LL |     unsafe { std::mem::transmute(x) }
    |              ^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     unsafe { std::mem::transmute(x) }
    = note: target type: `u32` (32 bits)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute.rs:28:14
+  --> $DIR/transmute.rs:31:14
    |
 LL |     unsafe { std::mem::transmute(x) }
    |              ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type/pattern_types/transmute.next.stderr b/tests/ui/type/pattern_types/transmute.next.stderr
new file mode 100644
index 00000000000..edec542e5e1
--- /dev/null
+++ b/tests/ui/type/pattern_types/transmute.next.stderr
@@ -0,0 +1,21 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/transmute.rs:23:14
+   |
+LL |     unsafe { std::mem::transmute(x) }
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32)
+   = note: target type: `u32` (32 bits)
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/transmute.rs:31:14
+   |
+LL |     unsafe { std::mem::transmute(x) }
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32)
+   = note: target type: `Option<u32>` (64 bits)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/type/pattern_types/transmute.rs b/tests/ui/type/pattern_types/transmute.rs
index 43dd62a19e7..4e686245f93 100644
--- a/tests/ui/type/pattern_types/transmute.rs
+++ b/tests/ui/type/pattern_types/transmute.rs
@@ -1,3 +1,6 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 #![feature(pattern_types, pattern_type_macro, generic_pattern_types)]
 #![expect(incomplete_features)]
 
diff --git a/tests/ui/typeck/issue-80779.stderr b/tests/ui/typeck/issue-80779.stderr
index 2261ba61654..90c80fa2ea6 100644
--- a/tests/ui/typeck/issue-80779.stderr
+++ b/tests/ui/typeck/issue-80779.stderr
@@ -2,19 +2,25 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/issue-80779.rs:10:28
    |
 LL | pub fn g(_: T<'static>) -> _ {}
-   |                            ^
-   |                            |
-   |                            not allowed in type signatures
-   |                            help: replace with the correct return type: `()`
+   |                            ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - pub fn g(_: T<'static>) -> _ {}
+LL + pub fn g(_: T<'static>) -> () {}
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/issue-80779.rs:5:29
    |
 LL | pub fn f<'a>(val: T<'a>) -> _ {
-   |                             ^
-   |                             |
-   |                             not allowed in type signatures
-   |                             help: replace with the correct return type: `()`
+   |                             ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - pub fn f<'a>(val: T<'a>) -> _ {
+LL + pub fn f<'a>(val: T<'a>) -> () {
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/typeck/issue-98260.stderr b/tests/ui/typeck/issue-98260.stderr
index b7debd335b0..f380db55cdf 100644
--- a/tests/ui/typeck/issue-98260.stderr
+++ b/tests/ui/typeck/issue-98260.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/issue-98260.rs:3:27
    |
 LL |     fn a(aa: B) -> Result<_, B> {
-   |                    -------^----
-   |                    |      |
-   |                    |      not allowed in type signatures
-   |                    help: replace with the correct return type: `Result<(), B>`
+   |                           ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn a(aa: B) -> Result<_, B> {
+LL +     fn a(aa: B) -> Result<(), B> {
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index 87750ee6dc1..240dc1ae8ab 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -48,20 +48,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:7:14
    |
 LL | fn test() -> _ { 5 }
-   |              ^
-   |              |
-   |              not allowed in type signatures
-   |              help: replace with the correct return type: `i32`
+   |              ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn test() -> _ { 5 }
+LL + fn test() -> i32 { 5 }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:10:16
    |
 LL | fn test2() -> (_, _) { (5, 5) }
-   |               -^--^-
-   |               ||  |
-   |               ||  not allowed in type signatures
-   |               |not allowed in type signatures
-   |               help: replace with the correct return type: `(i32, i32)`
+   |                ^  ^ not allowed in type signatures
+   |                |
+   |                not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn test2() -> (_, _) { (5, 5) }
+LL + fn test2() -> (i32, i32) { (5, 5) }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
   --> $DIR/typeck_type_placeholder_item.rs:13:15
@@ -189,19 +196,25 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:47:26
    |
 LL | fn test11(x: &usize) -> &_ {
-   |                         -^
-   |                         ||
-   |                         |not allowed in type signatures
-   |                         help: replace with the correct return type: `&&usize`
+   |                          ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn test11(x: &usize) -> &_ {
+LL + fn test11(x: &usize) -> &&usize {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:52:52
    |
 LL | unsafe fn test12(x: *const usize) -> *const *const _ {
-   |                                      --------------^
-   |                                      |             |
-   |                                      |             not allowed in type signatures
-   |                                      help: replace with the correct return type: `*const *const usize`
+   |                                                    ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - unsafe fn test12(x: *const usize) -> *const *const _ {
+LL + unsafe fn test12(x: *const usize) -> *const *const usize {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods
   --> $DIR/typeck_type_placeholder_item.rs:58:24
@@ -261,20 +274,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:80:21
    |
 LL |     fn fn_test() -> _ { 5 }
-   |                     ^
-   |                     |
-   |                     not allowed in type signatures
-   |                     help: replace with the correct return type: `i32`
+   |                     ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn fn_test() -> _ { 5 }
+LL +     fn fn_test() -> i32 { 5 }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:83:23
    |
 LL |     fn fn_test2() -> (_, _) { (5, 5) }
-   |                      -^--^-
-   |                      ||  |
-   |                      ||  not allowed in type signatures
-   |                      |not allowed in type signatures
-   |                      help: replace with the correct return type: `(i32, i32)`
+   |                       ^  ^ not allowed in type signatures
+   |                       |
+   |                       not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn fn_test2() -> (_, _) { (5, 5) }
+LL +     fn fn_test2() -> (i32, i32) { (5, 5) }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
   --> $DIR/typeck_type_placeholder_item.rs:86:22
@@ -374,20 +394,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:134:30
    |
 LL |     fn fn_test12(x: i32) -> (_, _) { (x, x) }
-   |                             -^--^-
-   |                             ||  |
-   |                             ||  not allowed in type signatures
-   |                             |not allowed in type signatures
-   |                             help: replace with the correct return type: `(i32, i32)`
+   |                              ^  ^ not allowed in type signatures
+   |                              |
+   |                              not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn fn_test12(x: i32) -> (_, _) { (x, x) }
+LL +     fn fn_test12(x: i32) -> (i32, i32) { (x, x) }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:137:33
    |
 LL |     fn fn_test13(x: _) -> (i32, _) { (x, x) }
-   |                           ------^-
-   |                           |     |
-   |                           |     not allowed in type signatures
-   |                           help: replace with the correct return type: `(i32, i32)`
+   |                                 ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn fn_test13(x: _) -> (i32, _) { (x, x) }
+LL +     fn fn_test13(x: _) -> (i32, i32) { (x, x) }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods
   --> $DIR/typeck_type_placeholder_item.rs:142:31
@@ -528,10 +555,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:226:31
    |
 LL | fn value() -> Option<&'static _> {
-   |               ----------------^-
-   |               |               |
-   |               |               not allowed in type signatures
-   |               help: replace with the correct return type: `Option<&'static u8>`
+   |                               ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn value() -> Option<&'static _> {
+LL + fn value() -> Option<&'static u8> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/typeck_type_placeholder_item.rs:231:17
@@ -549,10 +579,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:235:31
    |
 LL | fn evens_squared(n: usize) -> _ {
-   |                               ^
-   |                               |
-   |                               not allowed in type signatures
-   |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
+   |                               ^ not allowed in type signatures
+   |
+help: replace with an appropriate return type
+   |
+LL - fn evens_squared(n: usize) -> _ {
+LL + fn evens_squared(n: usize) -> impl Iterator<Item = usize> {
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/typeck_type_placeholder_item.rs:240:10
@@ -570,10 +603,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:40:24
    |
 LL |     fn test9(&self) -> _ { () }
-   |                        ^
-   |                        |
-   |                        not allowed in type signatures
-   |                        help: replace with the correct return type: `()`
+   |                        ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -     fn test9(&self) -> _ { () }
+LL +     fn test9(&self) -> () { () }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods
   --> $DIR/typeck_type_placeholder_item.rs:43:27
@@ -585,10 +621,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item.rs:107:31
    |
 LL |         fn fn_test9(&self) -> _ { () }
-   |                               ^
-   |                               |
-   |                               not allowed in type signatures
-   |                               help: replace with the correct return type: `()`
+   |                               ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL -         fn fn_test9(&self) -> _ { () }
+LL +         fn fn_test9(&self) -> () { () }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods
   --> $DIR/typeck_type_placeholder_item.rs:110:34
diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
index 2fce00e7a8e..3f21ff6d4ec 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/typeck_type_placeholder_item_help.rs:4:15
    |
 LL | fn test1() -> _ { Some(42) }
-   |               ^
-   |               |
-   |               not allowed in type signatures
-   |               help: replace with the correct return type: `Option<i32>`
+   |               ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - fn test1() -> _ { Some(42) }
+LL + fn test1() -> Option<i32> { Some(42) }
+   |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/typeck_type_placeholder_item_help.rs:7:14
diff --git a/tests/ui/variance/leaking-unnameables.stderr b/tests/ui/variance/leaking-unnameables.stderr
index 92afe952801..59bdc33040d 100644
--- a/tests/ui/variance/leaking-unnameables.stderr
+++ b/tests/ui/variance/leaking-unnameables.stderr
@@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/leaking-unnameables.rs:8:18
    |
 LL | pub fn f<T>() -> _ {
-   |                  ^
-   |                  |
-   |                  not allowed in type signatures
-   |                  help: replace with the correct return type: `fn()`
+   |                  ^ not allowed in type signatures
+   |
+help: replace with the correct return type
+   |
+LL - pub fn f<T>() -> _ {
+LL + pub fn f<T>() -> fn() {
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/wf/wf-in-where-clause-static.current.stderr b/tests/ui/wf/wf-in-where-clause-static.current.stderr
index d0bb89884c6..788fe2c3faa 100644
--- a/tests/ui/wf/wf-in-where-clause-static.current.stderr
+++ b/tests/ui/wf/wf-in-where-clause-static.current.stderr
@@ -6,6 +6,12 @@ LL |     let s = foo(&String::from("blah blah blah"));
    |             |    |
    |             |    creates a temporary value which is freed while still in use
    |             argument requires that borrow lasts for `'static`
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/wf-in-where-clause-static.rs:12:17
+   |
+LL |     &'static S: Static,
+   |                 ^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/wf/wf-in-where-clause-static.next.stderr b/tests/ui/wf/wf-in-where-clause-static.next.stderr
index d0bb89884c6..788fe2c3faa 100644
--- a/tests/ui/wf/wf-in-where-clause-static.next.stderr
+++ b/tests/ui/wf/wf-in-where-clause-static.next.stderr
@@ -6,6 +6,12 @@ LL |     let s = foo(&String::from("blah blah blah"));
    |             |    |
    |             |    creates a temporary value which is freed while still in use
    |             argument requires that borrow lasts for `'static`
+   |
+note: requirement that the value outlives `'static` introduced here
+  --> $DIR/wf-in-where-clause-static.rs:12:17
+   |
+LL |     &'static S: Static,
+   |                 ^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/triagebot.toml b/triagebot.toml
index 2d58c616bc2..a04f8d28072 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1382,6 +1382,7 @@ libs = [
     "@tgross35",
     "@thomcc",
     "@ibraheemdev",
+    "@joboet",
 ]
 infra-ci = [
     "@Mark-Simulacrum",