about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-06 06:42:23 +0000
committerbors <bors@rust-lang.org>2024-09-06 06:42:23 +0000
commit0903724a9b839bb642ce537ababe6625e8887c4f (patch)
treea327c16521758286ea353293be72e4104cba2442
parent18d358c63c7ae8ff9d921f3464707bedb23254d2 (diff)
parent2fccb4b358e06c9c33d1ed18b280aa1a776c2f36 (diff)
downloadrust-0903724a9b839bb642ce537ababe6625e8887c4f.tar.gz
rust-0903724a9b839bb642ce537ababe6625e8887c4f.zip
Auto merge of #3862 - rust-lang:rustup-2024-09-06, r=RalfJung
Automatic Rustup
-rw-r--r--.mailmap2
-rw-r--r--Cargo.lock38
-rw-r--r--RELEASES.md8
-rw-r--r--compiler/rustc/Cargo.toml1
-rw-r--r--compiler/rustc_abi/src/layout.rs11
-rw-r--r--compiler/rustc_abi/src/lib.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs7
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs40
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/stack.rs2
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/base_n.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/hashes.rs4
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs8
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml5
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs13
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0582.md2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_errors/src/markdown/parse.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs84
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs21
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs39
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs67
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_index/Cargo.toml1
-rw-r--r--compiler/rustc_index/src/lib.rs11
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl3
-rw-r--r--compiler/rustc_lint/src/context/diagnostics/check_cfg.rs2
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs375
-rw-r--r--compiler/rustc_lint/src/internal.rs30
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs5
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs2
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs12
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs27
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs6
-rw-r--r--compiler/rustc_middle/Cargo.toml1
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs6
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs62
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_middle/src/util/common.rs16
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs75
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs4
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_subtyping_projections.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_alignment.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs4
-rw-r--r--compiler/rustc_mir_transform/src/check_packed_ref.rs33
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs4
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs257
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs5
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ctfe_limit.rs4
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs4
-rw-r--r--compiler/rustc_mir_transform/src/deduplicate_blocks.rs2
-rw-r--r--compiler/rustc_mir_transform/src/deref_separator.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs119
-rw-r--r--compiler/rustc_mir_transform/src/dump_mir.rs4
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs4
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs2
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs2
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs5
-rw-r--r--compiler/rustc_mir_transform/src/large_enums.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs22
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs2
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs22
-rw-r--r--compiler/rustc_mir_transform/src/mentioned_items.rs4
-rw-r--r--compiler/rustc_mir_transform/src/multiple_return_terminators.rs2
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs4
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs104
-rw-r--r--compiler/rustc_mir_transform/src/prettify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs4
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs4
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs2
-rw-r--r--compiler/rustc_mir_transform/src/remove_place_mention.rs2
-rw-r--r--compiler/rustc_mir_transform/src/remove_storage_markers.rs2
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs4
-rw-r--r--compiler/rustc_mir_transform/src/remove_unneeded_drops.rs2
-rw-r--r--compiler/rustc_mir_transform/src/remove_zsts.rs2
-rw-r--r--compiler/rustc_mir_transform/src/reveal_all.rs2
-rw-r--r--compiler/rustc_mir_transform/src/sanity_check.rs11
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/simplify_branches.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs4
-rw-r--r--compiler/rustc_mir_transform/src/single_use_consts.rs2
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs2
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_enum_branching.rs4
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs2
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/lib.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs66
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs2
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs4
-rw-r--r--compiler/rustc_passes/src/loops.rs40
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs8
-rw-r--r--compiler/rustc_pattern_analysis/tests/exhaustiveness.rs2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs2
-rw-r--r--compiler/rustc_resolve/messages.ftl2
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs2
-rw-r--r--compiler/rustc_resolve/src/errors.rs2
-rw-r--r--compiler/rustc_resolve/src/ident.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs4
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs2
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs6
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs12
-rw-r--r--compiler/rustc_sanitizers/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/src/opaque.rs2
-rw-r--r--compiler/rustc_session/src/config.rs10
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/options.rs142
-rw-r--r--compiler/rustc_smir/src/lib.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mod.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs2
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs2
-rw-r--r--compiler/rustc_span/src/lib.rs5
-rw-r--r--compiler/rustc_span/src/span_encoding.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/hashed.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/abi/call/aarch64.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/amdgpu.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/arm.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/avr.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/bpf.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/csky.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/hexagon.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/loongarch.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/m68k.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mips.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mips64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/msp430.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/nvptx64.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/riscv.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/s390x.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/sparc.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/wasm.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/x86.rs4
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/x86_win64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/xtensa.rs4
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/aix.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/android.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs30
-rw-r--r--compiler/rustc_target/src/spec/base/avr_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/bpf.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/dragonfly.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/haiku.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/hermit.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/hurd.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/hurd_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/illumos.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/l4re.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux_ohos.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/linux_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/nto_qnx.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/redox.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/solid.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/teeos.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/thumb.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/uefi_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/wasm.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_msvc.rs4
-rw-r--r--compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/base/xtensa.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs35
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i386_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/msp430_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs18
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs140
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/_match.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs14
-rw-r--r--compiler/rustc_traits/src/codegen.rs2
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs2
-rw-r--r--compiler/rustc_transmute/src/layout/tree/tests.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs1
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/mod.rs6
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs20
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs1
-rw-r--r--compiler/rustc_type_ir/src/binder.rs2
-rw-r--r--compiler/rustc_type_ir/src/fold.rs2
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/relate.rs2
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs4
-rw-r--r--compiler/stable_mir/src/abi.rs2
-rw-r--r--compiler/stable_mir/src/ty.rs2
-rw-r--r--config.example.toml10
-rw-r--r--library/alloc/Cargo.toml1
-rw-r--r--library/alloc/src/boxed.rs28
-rw-r--r--library/alloc/src/collections/btree/map.rs4
-rw-r--r--library/alloc/src/collections/btree/node/tests.rs2
-rw-r--r--library/alloc/src/collections/btree/set.rs4
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/array/mod.rs2
-rw-r--r--library/core/src/ffi/mod.rs2
-rw-r--r--library/core/src/future/async_drop.rs4
-rw-r--r--library/core/src/hint.rs1
-rw-r--r--library/core/src/intrinsics/mir.rs2
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/marker.rs15
-rw-r--r--library/core/src/mem/transmutability.rs2
-rw-r--r--library/core/src/primitive_docs.rs5
-rw-r--r--library/core/src/slice/raw.rs16
-rw-r--r--library/core/src/sync/atomic.rs58
-rw-r--r--library/core/src/task/wake.rs103
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/waker.rs11
-rw-r--r--library/panic_unwind/Cargo.toml7
-rw-r--r--library/panic_unwind/src/lib.rs2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/build.rs3
-rw-r--r--library/std/src/io/tests.rs2
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/rtems/fs.rs374
-rw-r--r--library/std/src/os/rtems/mod.rs4
-rw-r--r--library/std/src/os/rtems/raw.rs33
-rw-r--r--library/std/src/os/unix/mod.rs2
-rw-r--r--library/std/src/process.rs36
-rw-r--r--library/std/src/rt.rs2
-rw-r--r--library/std/src/sync/mpmc/list.rs2
-rw-r--r--library/std/src/sync/once_lock.rs2
-rw-r--r--library/std/src/sync/reentrant_lock.rs2
-rw-r--r--library/std/src/sys/pal/solid/fs.rs2
-rw-r--r--library/std/src/sys/pal/uefi/process.rs2
-rw-r--r--library/std/src/sys/pal/unix/args.rs1
-rw-r--r--library/std/src/sys/pal/unix/env.rs11
-rw-r--r--library/std/src/sys/pal/unix/fs.rs18
-rw-r--r--library/std/src/sys/pal/unix/l4re.rs4
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/net.rs2
-rw-r--r--library/std/src/sys/pal/unix/os.rs19
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs6
-rw-r--r--library/std/src/sys/pal/windows/api.rs5
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt5
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs5
-rw-r--r--library/std/src/sys/pal/windows/fs.rs211
-rw-r--r--library/std/src/sys/pal/windows/fs/remove_dir_all.rs196
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/process.rs23
-rw-r--r--library/std/src/sys/path/windows.rs5
-rw-r--r--library/std/src/sys/personality/mod.rs2
-rw-r--r--library/unwind/Cargo.toml7
-rw-r--r--library/unwind/src/lib.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs12
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs3
-rw-r--r--src/bootstrap/src/core/builder.rs20
-rw-r--r--src/bootstrap/src/core/config/config.rs37
-rw-r--r--src/bootstrap/src/core/sanity.rs13
-rw-r--r--src/bootstrap/src/lib.rs4
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs10
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile1
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh50
-rw-r--r--src/doc/not_found.md2
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md52
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md117
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/html/markdown.rs73
-rw-r--r--src/librustdoc/html/render/context.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs103
-rw-r--r--src/librustdoc/html/render/print_item.rs32
-rw-r--r--src/librustdoc/html/render/sidebar.rs323
-rw-r--r--src/librustdoc/html/sources.rs57
-rw-r--r--src/librustdoc/html/static/css/noscript.css4
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css174
-rw-r--r--src/librustdoc/html/static/js/main.js13
-rw-r--r--src/librustdoc/html/static/js/scrape-examples.js7
-rw-r--r--src/librustdoc/html/static/js/settings.js29
-rw-r--r--src/librustdoc/html/static/js/storage.js13
-rw-r--r--src/librustdoc/html/templates/scraped_source.html33
-rw-r--r--src/librustdoc/html/templates/sidebar.html49
-rw-r--r--src/librustdoc/html/templates/source.html14
-rw-r--r--src/librustdoc/html/toc.rs26
-rw-r--r--src/librustdoc/html/toc/tests.rs6
-rw-r--r--src/librustdoc/markdown.rs1
-rw-r--r--src/tools/build_helper/src/git.rs34
m---------src/tools/cargo0
-rw-r--r--src/tools/compiletest/src/command-list.rs1
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header/needs.rs5
-rw-r--r--src/tools/compiletest/src/lib.rs6
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/pass/dyn-arbitrary-self.rs2
-rw-r--r--src/tools/run-make-support/src/command.rs85
-rw-r--r--src/tools/run-make-support/src/external_deps/llvm.rs7
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs6
-rw-r--r--src/tools/run-make-support/src/external_deps/rustdoc.rs6
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--tests/assembly/targets/targets-elf.rs3
-rw-r--r--tests/codegen/intrinsics/likely.rs2
-rw-r--r--tests/codegen/issues/issue-86106.rs1
-rw-r--r--tests/codegen/mem-replace-big-type.rs1
-rw-r--r--tests/codegen/slice-iter-nonnull.rs1
-rw-r--r--tests/codegen/vecdeque-drain.rs1
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir)8
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir)4
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir)6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir10
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir)4
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir)4
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir)6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir10
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir (renamed from tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir)6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir10
-rw-r--r--tests/mir-opt/async_closure_shims.rs11
-rw-r--r--tests/mir-opt/building/receiver_ptr_mutability.rs2
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs1
-rw-r--r--tests/run-make/clear-error-blank-output/rmake.rs2
-rw-r--r--tests/run-make/comment-section/rmake.rs2
-rw-r--r--tests/run-make/compile-stdin/rmake.rs2
-rw-r--r--tests/run-make/libtest-junit/rmake.rs2
-rw-r--r--tests/run-make/llvm-ident/rmake.rs2
-rw-r--r--tests/run-make/llvm-outputs/rmake.rs4
-rw-r--r--tests/run-make/no-builtins-attribute/rmake.rs2
-rw-r--r--tests/run-make/pgo-branch-weights/rmake.rs5
-rw-r--r--tests/run-make/pgo-indirect-call-promotion/rmake.rs5
-rw-r--r--tests/run-make/pgo-use/rmake.rs2
-rw-r--r--tests/run-make/rustdoc-output-stdout/rmake.rs19
-rw-r--r--tests/run-make/separate-link/rmake.rs2
-rw-r--r--tests/run-make/static-pie/rmake.rs2
-rw-r--r--tests/run-make/stdin-rustc/rmake.rs4
-rw-r--r--tests/run-make/stdin-rustdoc/rmake.rs4
-rw-r--r--tests/run-make/sysroot-crates-are-unstable/rmake.rs2
-rw-r--r--tests/run-make/unknown-mod-stdin/rmake.rs2
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs12
-rw-r--r--tests/rustdoc-gui/code-example-buttons.goml21
-rw-r--r--tests/rustdoc-gui/deref-block.goml30
-rw-r--r--tests/rustdoc-gui/docblock-code-block-line-number.goml73
-rw-r--r--tests/rustdoc-gui/scrape-examples-button-focus.goml38
-rw-r--r--tests/rustdoc-gui/scrape-examples-color.goml8
-rw-r--r--tests/rustdoc-gui/scrape-examples-layout.goml87
-rw-r--r--tests/rustdoc-gui/sidebar-modnav-position.goml44
-rw-r--r--tests/rustdoc-gui/sidebar.goml45
-rw-r--r--tests/rustdoc-gui/src/lib2/lib.rs10
-rw-r--r--tests/rustdoc-gui/src/theme_css/custom-theme.css2
-rw-r--r--tests/rustdoc/impl-associated-items-order.rs42
-rw-r--r--tests/rustdoc/impl-associated-items-sidebar.rs42
-rw-r--r--tests/rustdoc/sidebar/module.rs16
-rw-r--r--tests/rustdoc/sidebar/sidebar-all-page.rs (renamed from tests/rustdoc/sidebar-all-page.rs)0
-rw-r--r--tests/rustdoc/sidebar/sidebar-items.rs (renamed from tests/rustdoc/sidebar-items.rs)0
-rw-r--r--tests/rustdoc/sidebar/sidebar-link-generation.rs (renamed from tests/rustdoc/sidebar-link-generation.rs)0
-rw-r--r--tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs (renamed from tests/rustdoc/sidebar-links-to-foreign-impl.rs)0
-rw-r--r--tests/rustdoc/sidebar/top-toc-html.rs23
-rw-r--r--tests/rustdoc/sidebar/top-toc-idmap.rs44
-rw-r--r--tests/rustdoc/sidebar/top-toc-nil.rs7
-rw-r--r--tests/rustdoc/strip-enum-variant.no-not-shown.html2
-rw-r--r--tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs18
-rw-r--r--tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr31
-rw-r--r--tests/ui/async-await/async-closures/mac-body.rs12
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr4
-rw-r--r--tests/ui/coercion/constrain-expectation-in-arg.rs24
-rw-r--r--tests/ui/coherence/normalize-for-errors.next.stderr2
-rw-r--r--tests/ui/coherence/normalize-for-errors.rs2
-rw-r--r--tests/ui/dyn-keyword/dyn-2021-edition-error.stderr10
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr36
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr12
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024-but-fine.rs15
-rw-r--r--tests/ui/inference/auxiliary/inference_unstable_iterator.rs2
-rw-r--r--tests/ui/inference/auxiliary/inference_unstable_itertools.rs2
-rw-r--r--tests/ui/inline-const/break-inside-inline-const-issue-128604.rs25
-rw-r--r--tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr39
-rw-r--r--tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs142
-rw-r--r--tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr673
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs10
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs9
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr19
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs21
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.stderr66
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs26
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr65
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs21
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs23
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr39
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs5
-rw-r--r--tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr10
-rw-r--r--tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs2
-rw-r--r--tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs2
-rw-r--r--tests/ui/stats/hir-stats.rs3
-rw-r--r--tests/ui/std/windows-bat-args.rs4
-rw-r--r--tests/ui/structs-enums/type-sizes.rs1
-rw-r--r--tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs34
-rw-r--r--tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr42
-rw-r--r--triagebot.toml8
740 files changed, 5685 insertions, 2556 deletions
diff --git a/.mailmap b/.mailmap
index 4d93792422c..9ac7f1a9b49 100644
--- a/.mailmap
+++ b/.mailmap
@@ -81,6 +81,7 @@ boolean_coercion <booleancoercion@gmail.com>
 Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
 bors <bors@rust-lang.org> bors[bot] <26634292+bors[bot]@users.noreply.github.com>
 bors <bors@rust-lang.org> bors[bot] <bors[bot]@users.noreply.github.com>
+Boxy <rust@boxyuwu.dev> <supbscripter@gmail.com>
 Braden Nelson <moonheart08@users.noreply.github.com>
 Brandon Sanderson <singingboyo@gmail.com> Brandon Sanderson <singingboyo@hotmail.com>
 Brett Cannon <brett@python.org> Brett Cannon <brettcannon@users.noreply.github.com>
@@ -146,6 +147,7 @@ David Klein <david.klein@baesystemsdetica.com>
 David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au>
 David Ross <daboross@daboross.net>
 David Wood <david@davidtw.co> <david.wood@huawei.com>
+David Wood <david@davidtw.co> <david.wood2@arm.com>
 Deadbeef <ent3rm4n@gmail.com>
 Deadbeef <ent3rm4n@gmail.com> <fee1-dead-beef@protonmail.com>
 dependabot[bot] <dependabot[bot]@users.noreply.github.com> <27856297+dependabot-preview[bot]@users.noreply.github.com>
diff --git a/Cargo.lock b/Cargo.lock
index 7244ae14fb8..d6714199682 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -199,7 +199,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
 dependencies = [
- "object 0.36.3",
+ "object 0.36.4",
 ]
 
 [[package]]
@@ -2453,9 +2453,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.3"
+version = "0.36.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
+checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
 dependencies = [
  "crc32fast",
  "flate2",
@@ -2463,7 +2463,7 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd 0.7.0",
- "wasmparser 0.215.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -3129,11 +3129,11 @@ dependencies = [
  "build_helper",
  "gimli 0.31.0",
  "libc",
- "object 0.36.3",
+ "object 0.36.4",
  "regex",
  "serde_json",
  "similar",
- "wasmparser 0.216.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -3408,7 +3408,7 @@ dependencies = [
  "itertools",
  "libc",
  "measureme",
- "object 0.36.3",
+ "object 0.36.4",
  "rustc-demangle",
  "rustc_ast",
  "rustc_attr",
@@ -3447,7 +3447,7 @@ dependencies = [
  "itertools",
  "jobserver",
  "libc",
- "object 0.36.3",
+ "object 0.36.4",
  "pathdiff",
  "regex",
  "rustc_arena",
@@ -3569,6 +3569,7 @@ dependencies = [
  "rustc_hir_pretty",
  "rustc_hir_typeck",
  "rustc_incremental",
+ "rustc_index",
  "rustc_infer",
  "rustc_interface",
  "rustc_lint",
@@ -4431,7 +4432,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 2.6.0",
- "object 0.36.3",
+ "object 0.36.4",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_feature",
@@ -5849,7 +5850,7 @@ dependencies = [
  "lexopt",
  "tempfile",
  "wasi-preview1-component-adapter-provider",
- "wasmparser 0.216.0",
+ "wasmparser",
  "wat",
  "wit-component",
  "wit-parser",
@@ -5869,7 +5870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "04c23aebea22c8a75833ae08ed31ccc020835b12a41999e58c31464271b94a88"
 dependencies = [
  "leb128",
- "wasmparser 0.216.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -5885,16 +5886,7 @@ dependencies = [
  "serde_json",
  "spdx",
  "wasm-encoder",
- "wasmparser 0.216.0",
-]
-
-[[package]]
-name = "wasmparser"
-version = "0.215.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53fbde0881f24199b81cf49b6ff8f9c145ac8eb1b7fc439adb5c099734f7d90e"
-dependencies = [
- "bitflags 2.6.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -6228,7 +6220,7 @@ dependencies = [
  "serde_json",
  "wasm-encoder",
  "wasm-metadata",
- "wasmparser 0.216.0",
+ "wasmparser",
  "wit-parser",
 ]
 
@@ -6247,7 +6239,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.216.0",
+ "wasmparser",
 ]
 
 [[package]]
diff --git a/RELEASES.md b/RELEASES.md
index 6aba476103e..29c872eb448 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -112,6 +112,14 @@ tools.
 
 - [Add a Rust-for Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/)
 
+Version 1.80.1 (2024-08-08)
+===========================
+
+<a id="1.80.1"></a>
+
+- [Fix miscompilation in the jump threading MIR optimization when comparing floats](https://github.com/rust-lang/rust/pull/128271)
+- [Revert changes to the `dead_code` lint from 1.80.0](https://github.com/rust-lang/rust/pull/128618)
+
 Version 1.80.0 (2024-07-25)
 ==========================
 
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 5008069542f..a2fc9d5c408 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -30,5 +30,6 @@ features = ['unprefixed_malloc_on_supported_platforms']
 jemalloc = ['dep:jemalloc-sys']
 llvm = ['rustc_driver_impl/llvm']
 max_level_info = ['rustc_driver_impl/max_level_info']
+rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
 rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
 # tidy-alphabetical-end
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 5160b4ed0a2..7432768be4a 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -968,8 +968,8 @@ fn univariant<
     let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
     let mut max_repr_align = repr.align;
     let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
-    let optimize = !repr.inhibit_struct_field_reordering();
-    if optimize && fields.len() > 1 {
+    let optimize_field_order = !repr.inhibit_struct_field_reordering();
+    if optimize_field_order && fields.len() > 1 {
         let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
         let optimizing = &mut inverse_memory_index.raw[..end];
         let fields_excluding_tail = &fields.raw[..end];
@@ -1176,7 +1176,7 @@ fn univariant<
     // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
     // Field 5 would be the first element, so memory_index is i:
     // Note: if we didn't optimize, it's already right.
-    let memory_index = if optimize {
+    let memory_index = if optimize_field_order {
         inverse_memory_index.invert_bijective_mapping()
     } else {
         debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices()));
@@ -1189,6 +1189,9 @@ fn univariant<
     }
     let mut layout_of_single_non_zst_field = None;
     let mut abi = Abi::Aggregate { sized };
+
+    let optimize_abi = !repr.inhibit_newtype_abi_optimization();
+
     // Try to make this a Scalar/ScalarPair.
     if sized && size.bytes() > 0 {
         // We skip *all* ZST here and later check if we are good in terms of alignment.
@@ -1205,7 +1208,7 @@ fn univariant<
                     match field.abi {
                         // For plain scalars, or vectors of them, we can't unpack
                         // newtypes for `#[repr(C)]`, as that affects C ABIs.
-                        Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
+                        Abi::Scalar(_) | Abi::Vector { .. } if optimize_abi => {
                             abi = field.abi;
                         }
                         // But scalar pairs are Rust-specific and get
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index df29b3d54f0..be42bc84932 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -43,14 +43,17 @@ bitflags! {
         const IS_SIMD            = 1 << 1;
         const IS_TRANSPARENT     = 1 << 2;
         // Internal only for now. If true, don't reorder fields.
+        // On its own it does not prevent ABI optimizations.
         const IS_LINEAR          = 1 << 3;
-        // If true, the type's layout can be randomized using
-        // the seed stored in `ReprOptions.field_shuffle_seed`
+        // If true, the type's crate has opted into layout randomization.
+        // Other flags can still inhibit reordering and thus randomization.
+        // The seed stored in `ReprOptions.field_shuffle_seed`.
         const RANDOMIZE_LAYOUT   = 1 << 4;
         // Any of these flags being set prevent field reordering optimisation.
-        const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits()
+        const FIELD_ORDER_UNOPTIMIZABLE   = ReprFlags::IS_C.bits()
                                  | ReprFlags::IS_SIMD.bits()
                                  | ReprFlags::IS_LINEAR.bits();
+        const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
     }
 }
 
@@ -139,10 +142,14 @@ impl ReprOptions {
         self.c() || self.int.is_some()
     }
 
+    pub fn inhibit_newtype_abi_optimization(&self) -> bool {
+        self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
+    }
+
     /// Returns `true` if this `#[repr()]` guarantees a fixed field order,
     /// e.g. `repr(C)` or `repr(<int>)`.
     pub fn inhibit_struct_field_reordering(&self) -> bool {
-        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
+        self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
     }
 
     /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 80077348204..ac527df474a 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -72,7 +72,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn has_self(&self, def_id: DefId, span: Span) -> bool {
         if let Some(local_sig_id) = def_id.as_local() {
             // The value may be missing due to recursive delegation.
-            // Error will be emmited later during HIR ty lowering.
+            // Error will be emitted later during HIR ty lowering.
             self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self)
         } else {
             match self.tcx.def_kind(def_id) {
@@ -139,7 +139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) {
         if let Some(local_sig_id) = sig_id.as_local() {
             // Map may be filled incorrectly due to recursive delegation.
-            // Error will be emmited later during HIR ty lowering.
+            // Error will be emitted later during HIR ty lowering.
             match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
                 Some(sig) => (sig.param_count, sig.c_variadic),
                 None => (0, false),
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 9951f9fcda6..c817b6fac71 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1179,7 +1179,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         for field in &variant.fields {
             // In practice unless there are more than one field with the same type, we'll be
             // suggesting a single field at a type, because we don't aggregate multiple borrow
-            // checker errors involving the functional record update sytnax into a single one.
+            // checker errors involving the functional record update syntax into a single one.
             let field_ty = field.ty(self.infcx.tcx, args);
             let ident = field.ident(self.infcx.tcx);
             if field_ty == ty && fields.iter().all(|field| field.ident.name != ident.name) {
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index de3ff8378bc..6186904e5fb 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -218,7 +218,7 @@ impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tc
         // This collect is more necessary than immediately apparent
         // because these facts go into `add_drop_live_facts_for()`,
         // which also writes to `all_facts`, and so this is genuinely
-        // a simulatneous overlapping mutable borrow.
+        // a simultaneous overlapping mutable borrow.
         // FIXME for future hackers: investigate whether this is
         // actually necessary; these facts come from Polonius
         // and probably maybe plausibly does not need to go back in.
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index b143e28c5f9..d60122fccee 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -390,7 +390,7 @@ impl<'ll> CodegenCx<'ll, '_> {
             let val_llty = self.val_ty(v);
 
             let g = self.get_static_inner(def_id, val_llty);
-            let llty = self.val_ty(g);
+            let llty = llvm::LLVMGlobalGetValueType(g);
 
             let g = if val_llty == llty {
                 g
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 069b62af5e7..b5acfabfde2 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -422,7 +422,7 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
             (instance.def_id(), body)
         });
 
-    // Functions whose coverage statments were found inlined into other functions.
+    // Functions whose coverage statements were found inlined into other functions.
     let mut used_via_inlining = FxHashSet::default();
     // Functions that were instrumented, but had all of their coverage statements
     // removed by later MIR transforms (e.g. UnreachablePropagation).
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index a300f5f707a..05fb77a193a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -187,9 +187,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     Some(instance),
                 )
             }
-            sym::likely => {
-                self.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(true)])
-            }
+            sym::likely => self.expect(args[0].immediate(), true),
             sym::is_val_statically_known => {
                 let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
                 let kind = self.type_kind(intrinsic_type);
@@ -210,8 +208,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self.const_bool(false)
                 }
             }
-            sym::unlikely => self
-                .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
+            sym::unlikely => self.expect(args[0].immediate(), false),
             sym::select_unpredictable => {
                 let cond = args[0].immediate();
                 assert_eq!(args[1].layout, args[2].layout);
@@ -604,11 +601,17 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 
     fn assume(&mut self, val: Self::Value) {
-        self.call_intrinsic("llvm.assume", &[val]);
+        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
+            self.call_intrinsic("llvm.assume", &[val]);
+        }
     }
 
     fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value {
-        self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
+        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
+            self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
+        } else {
+            cond
+        }
     }
 
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 138cc3219aa..3bf4d496408 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -974,6 +974,7 @@ unsafe extern "C" {
     pub fn LLVMGetAlignment(Global: &Value) -> c_uint;
     pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint);
     pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass);
+    pub fn LLVMGlobalGetValueType(Global: &Value) -> &Type;
 
     // Operations on global variables
     pub fn LLVMIsAGlobalVariable(GlobalVar: &Value) -> Option<&Value>;
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index f0bc4354f9a..5103b2f3158 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -701,7 +701,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
             match ty.kind() {
                 ty::Int(ity) => {
                     // FIXME: directly extract the bits from a valtree instead of evaluating an
-                    // alreay evaluated `Const` in order to get the bits.
+                    // already evaluated `Const` in order to get the bits.
                     let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
                     write!(output, "{val}")
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d94c6f8ddce..91fd9905f63 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -382,7 +382,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         scalar: abi::Scalar,
         backend_ty: Bx::Type,
     ) {
-        if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less)
+        if matches!(self.cx.sess().opts.optimize, OptLevel::No)
             // For now, the critical niches are all over `Int`eger values.
             // Should floating-point values or pointers ever get more complex
             // niches, then this code will probably want to handle them too.
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 2ef860fc336..73283cafb49 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,6 +1,5 @@
 use rustc_middle::mir::{self, NonDivergingIntrinsic};
 use rustc_middle::span_bug;
-use rustc_session::config::OptLevel;
 use tracing::instrument;
 
 use super::{FunctionCx, LocalRef};
@@ -68,10 +67,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_coverage(bx, kind, statement.source_info.scope);
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
-                if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
-                    let op_val = self.codegen_operand(bx, op);
-                    bx.assume(op_val.immediate());
-                }
+                let op_val = self.codegen_operand(bx, op);
+                bx.assume(op_val.immediate());
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
                 mir::CopyNonOverlapping { ref count, ref src, ref dst },
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 7cfb101399d..8be327a8b56 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -46,7 +46,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
     /// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
     ///
     /// Only updates the cursor if absolutely necessary
-    pub fn needs_drop(
+    fn needs_drop(
         &mut self,
         ccx: &'mir ConstCx<'mir, 'tcx>,
         local: Local,
@@ -76,7 +76,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
     /// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
     ///
     /// Only updates the cursor if absolutely necessary
-    pub fn needs_non_const_drop(
+    pub(crate) fn needs_non_const_drop(
         &mut self,
         ccx: &'mir ConstCx<'mir, 'tcx>,
         local: Local,
@@ -106,7 +106,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
     /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
     ///
     /// Only updates the cursor if absolutely necessary.
-    pub fn has_mut_interior(
+    fn has_mut_interior(
         &mut self,
         ccx: &'mir ConstCx<'mir, 'tcx>,
         local: Local,
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 93fafa60557..e8f10c88408 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -57,7 +57,7 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug {
 
 /// A function call where the callee is a pointer.
 #[derive(Debug)]
-pub struct FnCallIndirect;
+pub(crate) struct FnCallIndirect;
 impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::UnallowedFnPointerCall { span, kind: ccx.const_kind() })
@@ -66,7 +66,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
 
 /// A function call where the callee is not marked as `const`.
 #[derive(Debug, Clone, Copy)]
-pub struct FnCallNonConst<'tcx> {
+pub(crate) struct FnCallNonConst<'tcx> {
     pub caller: LocalDefId,
     pub callee: DefId,
     pub args: GenericArgsRef<'tcx>,
@@ -299,7 +299,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
 ///
 /// Contains the name of the feature that would allow the use of this function.
 #[derive(Debug)]
-pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
+pub(crate) struct FnCallUnstable(pub DefId, pub Option<Symbol>);
 
 impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
@@ -324,7 +324,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
 }
 
 #[derive(Debug)]
-pub struct Coroutine(pub hir::CoroutineKind);
+pub(crate) struct Coroutine(pub hir::CoroutineKind);
 impl<'tcx> NonConstOp<'tcx> for Coroutine {
     fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
         if let hir::CoroutineKind::Desugared(
@@ -356,7 +356,7 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
 }
 
 #[derive(Debug)]
-pub struct HeapAllocation;
+pub(crate) struct HeapAllocation;
 impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::UnallowedHeapAllocations {
@@ -368,7 +368,7 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
 }
 
 #[derive(Debug)]
-pub struct InlineAsm;
+pub(crate) struct InlineAsm;
 impl<'tcx> NonConstOp<'tcx> for InlineAsm {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::UnallowedInlineAsm { span, kind: ccx.const_kind() })
@@ -376,7 +376,7 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm {
 }
 
 #[derive(Debug)]
-pub struct LiveDrop<'tcx> {
+pub(crate) struct LiveDrop<'tcx> {
     pub dropped_at: Option<Span>,
     pub dropped_ty: Ty<'tcx>,
 }
@@ -394,7 +394,7 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
 #[derive(Debug)]
 /// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow never escapes to
 /// the final value of the constant.
-pub struct TransientCellBorrow;
+pub(crate) struct TransientCellBorrow;
 impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
     fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
         Status::Unstable(sym::const_refs_to_cell)
@@ -410,7 +410,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
 /// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow might escape to
 /// the final value of the constant, and thus we cannot allow this (for now). We may allow
 /// it in the future for static items.
-pub struct CellBorrow;
+pub(crate) struct CellBorrow;
 impl<'tcx> NonConstOp<'tcx> for CellBorrow {
     fn importance(&self) -> DiagImportance {
         // Most likely the code will try to do mutation with these borrows, which
@@ -431,7 +431,7 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
 /// This op is for `&mut` borrows in the trailing expression of a constant
 /// which uses the "enclosing scopes rule" to leak its locals into anonymous
 /// static or const items.
-pub struct MutBorrow(pub hir::BorrowKind);
+pub(crate) struct MutBorrow(pub hir::BorrowKind);
 
 impl<'tcx> NonConstOp<'tcx> for MutBorrow {
     fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
@@ -461,7 +461,7 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
 }
 
 #[derive(Debug)]
-pub struct TransientMutBorrow(pub hir::BorrowKind);
+pub(crate) struct TransientMutBorrow(pub hir::BorrowKind);
 
 impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
     fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
@@ -484,7 +484,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
 }
 
 #[derive(Debug)]
-pub struct MutDeref;
+pub(crate) struct MutDeref;
 impl<'tcx> NonConstOp<'tcx> for MutDeref {
     fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
         Status::Unstable(sym::const_mut_refs)
@@ -505,7 +505,7 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
 
 /// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
 #[derive(Debug)]
-pub struct PanicNonStr;
+pub(crate) struct PanicNonStr;
 impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::PanicNonStrErr { span })
@@ -516,7 +516,7 @@ impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
 /// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
 /// allocation base addresses that are not known at compile-time.
 #[derive(Debug)]
-pub struct RawPtrComparison;
+pub(crate) struct RawPtrComparison;
 impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         // FIXME(const_trait_impl): revert to span_bug?
@@ -525,7 +525,7 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
 }
 
 #[derive(Debug)]
-pub struct RawMutPtrDeref;
+pub(crate) struct RawMutPtrDeref;
 impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
     fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
         Status::Unstable(sym::const_mut_refs)
@@ -546,7 +546,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
 /// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
 /// allocation base addresses that are not known at compile-time.
 #[derive(Debug)]
-pub struct RawPtrToIntCast;
+pub(crate) struct RawPtrToIntCast;
 impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::RawPtrToIntErr { span })
@@ -555,7 +555,7 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast {
 
 /// An access to a (non-thread-local) `static`.
 #[derive(Debug)]
-pub struct StaticAccess;
+pub(crate) struct StaticAccess;
 impl<'tcx> NonConstOp<'tcx> for StaticAccess {
     fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
         if let hir::ConstContext::Static(_) = ccx.const_kind() {
@@ -582,7 +582,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
 
 /// An access to a thread-local `static`.
 #[derive(Debug)]
-pub struct ThreadLocalAccess;
+pub(crate) struct ThreadLocalAccess;
 impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
         ccx.dcx().create_err(errors::ThreadLocalAccessErr { span })
@@ -590,11 +590,11 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
 }
 
 /// Types that cannot appear in the signature or locals of a `const fn`.
-pub mod mut_ref {
+pub(crate) mod mut_ref {
     use super::*;
 
     #[derive(Debug)]
-    pub struct MutRef(pub mir::LocalKind);
+    pub(crate) struct MutRef(pub mir::LocalKind);
     impl<'tcx> NonConstOp<'tcx> for MutRef {
         fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
             Status::Unstable(sym::const_mut_refs)
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 61e8007e10e..82438eb5e78 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -20,7 +20,7 @@ use super::{
 };
 use crate::fluent_generated as fluent;
 
-/// An argment passed to a function.
+/// An argument passed to a function.
 #[derive(Clone, Debug)]
 pub enum FnArg<'tcx, Prov: Provenance = CtfeProvenance> {
     /// Pass a copy of the given operand.
@@ -123,7 +123,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             self.tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed)
         };
         let inner = self.unfold_transparent(inner, /* may_unfold */ |def| {
-            // Stop at NPO tpyes so that we don't miss that attribute in the check below!
+            // Stop at NPO types so that we don't miss that attribute in the check below!
             def.is_struct() && !is_npo(def)
         });
         Ok(match inner.ty.kind() {
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 7a6bbdfdcb5..dd744c51f23 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -574,7 +574,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                                 // be computed as the type references non-existing names.
                                 // See <https://github.com/rust-lang/rust/issues/124348>.
                             } else {
-                                // Looks like the const is not captued by `required_consts`, that's bad.
+                                // Looks like the const is not captured by `required_consts`, that's bad.
                                 span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
                             }
                         }
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 97326fe99a2..45a5eb9bd52 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -827,7 +827,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
                 let (size, align) = if nested {
                     // Nested anonymous statics are untyped, so let's get their
-                    // size and alignment from the allocaiton itself. This always
+                    // size and alignment from the allocation itself. This always
                     // succeeds, as the query is fed at DefId creation time, so no
                     // evaluation actually occurs.
                     let alloc = self.tcx.eval_static_initializer(def_id).unwrap();
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index ede6a51c712..840f7986c6e 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -61,13 +61,13 @@ pub(super) struct MemPlace<Prov: Provenance = CtfeProvenance> {
 
 impl<Prov: Provenance> MemPlace<Prov> {
     /// Adjust the provenance of the main pointer (metadata is unaffected).
-    pub fn map_provenance(self, f: impl FnOnce(Prov) -> Prov) -> Self {
+    fn map_provenance(self, f: impl FnOnce(Prov) -> Prov) -> Self {
         MemPlace { ptr: self.ptr.map_provenance(|p| p.map(f)), ..self }
     }
 
     /// Turn a mplace into a (thin or wide) pointer, as a reference, pointing to the same space.
     #[inline]
-    pub fn to_ref(self, cx: &impl HasDataLayout) -> Immediate<Prov> {
+    fn to_ref(self, cx: &impl HasDataLayout) -> Immediate<Prov> {
         Immediate::new_pointer_with_meta(self.ptr, self.meta, cx)
     }
 
@@ -186,7 +186,7 @@ pub(super) enum Place<Prov: Provenance = CtfeProvenance> {
     /// `Local` places always refer to the current stack frame, so they are unstable under
     /// function calls/returns and switching betweens stacks of different threads!
     /// We carry around the address of the `locals` buffer of the correct stack frame as a sanity
-    /// chec to be able to catch some cases of using a dangling `Place`.
+    /// check to be able to catch some cases of using a dangling `Place`.
     ///
     /// This variant shall not be used for unsized types -- those must always live in memory.
     Local { local: mir::Local, offset: Option<Size>, locals_addr: usize },
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs
index 0f6bf5c0336..b6e83715e39 100644
--- a/compiler/rustc_const_eval/src/interpret/stack.rs
+++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -1,5 +1,5 @@
 //! Manages the low-level pushing and popping of stack frames and the (de)allocation of local variables.
-//! For hadling of argument passing and return values, see the `call` module.
+//! For handling of argument passing and return values, see the `call` module.
 use std::cell::Cell;
 use std::{fmt, mem};
 
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index d825a47bfdf..73dda81bd29 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -14,6 +14,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod check_consts;
diff --git a/compiler/rustc_data_structures/src/base_n.rs b/compiler/rustc_data_structures/src/base_n.rs
index 1c2321623e4..0c3d7613d4f 100644
--- a/compiler/rustc_data_structures/src/base_n.rs
+++ b/compiler/rustc_data_structures/src/base_n.rs
@@ -42,7 +42,7 @@ impl fmt::Display for BaseNString {
 }
 
 // This trait just lets us reserve the exact right amount of space when doing fixed-length
-// case-insensitve encoding. Add any impls you need.
+// case-insensitive encoding. Add any impls you need.
 pub trait ToBaseN: Into<u128> {
     fn encoded_len(base: usize) -> usize;
 
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index 2a457ffb70b..06fedef00fc 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -477,7 +477,7 @@ where
         // will know when we hit the state where previous_node == node.
         loop {
             // Back at the beginning, we can return. Note that we return the root state.
-            // This is becuse for components being explored, we would otherwise get a
+            // This is because for components being explored, we would otherwise get a
             // `node_state[n] = InCycleWith{ parent: n }` and that's wrong.
             if previous_node == node {
                 return root_state;
diff --git a/compiler/rustc_data_structures/src/hashes.rs b/compiler/rustc_data_structures/src/hashes.rs
index f98c8de1eb0..8f4639fc2e6 100644
--- a/compiler/rustc_data_structures/src/hashes.rs
+++ b/compiler/rustc_data_structures/src/hashes.rs
@@ -3,11 +3,11 @@
 //! or 16 bytes of the hash.
 //!
 //! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`.
-//! `Hash64` and `Hash128` expose some utilty functions to encourage users to not extract the inner
+//! `Hash64` and `Hash128` expose some utility functions to encourage users to not extract the inner
 //! hash value as an integer type and accidentally apply varint encoding to it.
 //!
 //! In contrast with `Fingerprint`, users of these types cannot and should not attempt to construct
-//! and decompose these types into constitutent pieces. The point of these types is only to
+//! and decompose these types into constituent pieces. The point of these types is only to
 //! connect the fact that they can only be produced by a `StableHasher` to their
 //! `Encode`/`Decode` impls.
 
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index 4950481d311..b6efcada10b 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -19,7 +19,7 @@ impl RegistryId {
     /// index within the registry. This panics if the current thread is not associated with this
     /// registry.
     ///
-    /// Note that there's a race possible where the identifer in `THREAD_DATA` could be reused
+    /// Note that there's a race possible where the identifier in `THREAD_DATA` could be reused
     /// so this can succeed from a different registry.
     #[cfg(parallel_compiler)]
     fn verify(self) -> usize {
@@ -50,7 +50,7 @@ struct ThreadData {
 }
 
 thread_local! {
-    /// A thread local which contains the identifer of `REGISTRY` but allows for faster access.
+    /// A thread local which contains the identifier of `REGISTRY` but allows for faster access.
     /// It also holds the index of the current thread.
     static THREAD_DATA: ThreadData = const { ThreadData {
         registry_id: Cell::new(RegistryId(ptr::null())),
@@ -66,7 +66,7 @@ impl Registry {
 
     /// Gets the registry associated with the current thread. Panics if there's no such registry.
     pub fn current() -> Self {
-        REGISTRY.with(|registry| registry.get().cloned().expect("No assocated registry"))
+        REGISTRY.with(|registry| registry.get().cloned().expect("No associated registry"))
     }
 
     /// Registers the current thread with the registry so worker locals can be used on it.
@@ -92,7 +92,7 @@ impl Registry {
         }
     }
 
-    /// Gets the identifer of this registry.
+    /// Gets the identifier of this registry.
     fn id(&self) -> RegistryId {
         RegistryId(&*self.0)
     }
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 91cbffcd707..6d6d3f35a4b 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -23,6 +23,7 @@ rustc_hir_analysis = { path = "../rustc_hir_analysis" }
 rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_hir_typeck = { path = "../rustc_hir_typeck" }
 rustc_incremental = { path = "../rustc_incremental" }
+rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
 rustc_interface = { path = "../rustc_interface" }
 rustc_lint = { path = "../rustc_lint" }
@@ -72,6 +73,10 @@ ctrlc = "3.4.4"
 # tidy-alphabetical-start
 llvm = ['rustc_interface/llvm']
 max_level_info = ['rustc_log/max_level_info']
+rustc_randomized_layouts = [
+    'rustc_index/rustc_randomized_layouts',
+    'rustc_middle/rustc_randomized_layouts'
+]
 rustc_use_parallel_compiler = [
     'rustc_data_structures/rustc_use_parallel_compiler',
     'rustc_interface/rustc_use_parallel_compiler',
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index e49ae60e890..cb2fa6e9d74 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -61,7 +61,6 @@ use rustc_session::lint::{Lint, LintId};
 use rustc_session::output::collect_crate_types;
 use rustc_session::{config, filesearch, EarlyDiagCtxt, Session};
 use rustc_span::source_map::FileLoader;
-use rustc_span::symbol::sym;
 use rustc_span::FileName;
 use rustc_target::json::ToJson;
 use rustc_target::spec::{Target, TargetTriple};
@@ -777,16 +776,8 @@ fn print_crate_info(
                     .config
                     .iter()
                     .filter_map(|&(name, value)| {
-                        // Note that crt-static is a specially recognized cfg
-                        // directive that's printed out here as part of
-                        // rust-lang/rust#37406, but in general the
-                        // `target_feature` cfg is gated under
-                        // rust-lang/rust#29717. For now this is just
-                        // specifically allowing the crt-static cfg and that's
-                        // it, this is intended to get into Cargo and then go
-                        // through to build scripts.
-                        if (name != sym::target_feature || value != Some(sym::crt_dash_static))
-                            && !sess.is_nightly_build()
+                        // On stable, exclude unstable flags.
+                        if !sess.is_nightly_build()
                             && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some()
                         {
                             return None;
diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md
index b2cdb509c95..c4aaa17706a 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0582.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0582.md
@@ -44,7 +44,7 @@ where
 ```
 The latter scenario encounters this error because `Foo::Assoc<'a>` could be
 implemented by a type that does not use the `'a` parameter, so there is no
-guarentee that `X::Assoc<'a>` actually uses `'a`.
+guarantee that `X::Assoc<'a>` actually uses `'a`.
 
 To fix this we can pass a dummy parameter:
 ```
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 34aebadfdad..1c39840207c 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -479,7 +479,7 @@ pub struct Subdiag {
 /// - The `EmissionGuarantee`, which determines the type returned from `emit`.
 ///
 /// Each constructed `Diag` must be consumed by a function such as `emit`,
-/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurrs if a `Diag`
+/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurs if a `Diag`
 /// is dropped without being consumed by one of these functions.
 ///
 /// If there is some state in a downstream crate you would like to access in
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 2bc29dabd18..2b135df91a4 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2300,7 +2300,7 @@ impl HumanEmitter {
                     // For example, for the following:
                     //   |
                     // 2 -     .await
-                    // 2 +     (note the left over whitepsace)
+                    // 2 +     (note the left over whitespace)
                     //   |
                     // We really want
                     //   |
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index e08d28a156c..02ead41fc68 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -817,7 +817,7 @@ impl<'a> DiagCtxtHandle<'a> {
                 );
             }
             // We delay a bug here so that `-Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs`
-            // can be used to create a backtrace at the stashing site insted of whenever the
+            // can be used to create a backtrace at the stashing site instead of whenever the
             // diagnostic context is dropped and thus delayed bugs are emitted.
             Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))),
             DelayedBug => {
diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs
index b1db44dd215..8dd146c1c33 100644
--- a/compiler/rustc_errors/src/markdown/parse.rs
+++ b/compiler/rustc_errors/src/markdown/parse.rs
@@ -487,7 +487,7 @@ fn is_break_ty(val: &MdTree<'_>) -> bool {
         || matches!(val, MdTree::PlainText(txt) if txt.trim().is_empty())
 }
 
-/// Perform tranformations to text. This splits paragraphs, replaces patterns,
+/// Perform transformations to text. This splits paragraphs, replaces patterns,
 /// and corrects newlines.
 ///
 /// To avoid allocating strings (and using a different heavier tt type), our
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index ffeaa861220..fba65883550 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -349,8 +349,10 @@ declare_features! (
     (unstable, adt_const_params, "1.56.0", Some(95174)),
     /// Allows defining an `#[alloc_error_handler]`.
     (unstable, alloc_error_handler, "1.29.0", Some(51540)),
-    /// Allows trait methods with arbitrary self types.
+    /// Allows inherent and trait methods with arbitrary self types.
     (unstable, arbitrary_self_types, "1.23.0", Some(44874)),
+    /// Allows inherent and trait methods with arbitrary self types that are raw pointers.
+    (unstable, arbitrary_self_types_pointers, "CURRENT_RUSTC_VERSION", Some(44874)),
     /// Enables experimental inline assembly support for additional architectures.
     (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
     /// Allows using `label` operands in inline assembly.
@@ -585,7 +587,7 @@ declare_features! (
     (unstable, rust_cold_cc, "1.63.0", Some(97544)),
     /// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics
     (unstable, sha512_sm_x86, "CURRENT_RUSTC_VERSION", Some(126624)),
-    /// Shortern the tail expression lifetime
+    /// Shorten the tail expression lifetime
     (unstable, shorter_tail_lifetimes, "1.79.0", Some(123739)),
     /// Allows the use of SIMD types in functions declared in `extern` blocks.
     (unstable, simd_ffi, "1.0.0", Some(27731)),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 359b4729e50..3627faf8dfc 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1016,7 +1016,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                             sym::adt_const_params,
                         )])
                     }
-                    // Implments `ConstParamTy`, suggest adding the feature to enable.
+                    // Implements `ConstParamTy`, suggest adding the feature to enable.
                     Ok(..) => Some(vec![(adt_const_params_feature_string, sym::adt_const_params)]),
                 };
                 if let Some(features) = may_suggest_feature {
@@ -1652,6 +1652,13 @@ fn check_fn_or_method<'tcx>(
     }
 }
 
+/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
+#[derive(Clone, Copy, PartialEq)]
+enum ArbitrarySelfTypesLevel {
+    Basic,        // just arbitrary_self_types
+    WithPointers, // both arbitrary_self_types and arbitrary_self_types_pointers
+}
+
 #[instrument(level = "debug", skip(wfcx))]
 fn check_method_receiver<'tcx>(
     wfcx: &WfCheckingCtxt<'_, 'tcx>,
@@ -1684,14 +1691,27 @@ fn check_method_receiver<'tcx>(
         return Ok(());
     }
 
-    if tcx.features().arbitrary_self_types {
-        if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
-            // Report error; `arbitrary_self_types` was enabled.
-            return Err(tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }));
-        }
+    let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers {
+        Some(ArbitrarySelfTypesLevel::WithPointers)
+    } else if tcx.features().arbitrary_self_types {
+        Some(ArbitrarySelfTypesLevel::Basic)
     } else {
-        if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
-            return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
+        None
+    };
+
+    if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) {
+        return Err(match arbitrary_self_types_level {
+            // Wherever possible, emit a message advising folks that the features
+            // `arbitrary_self_types` or `arbitrary_self_types_pointers` might
+            // have helped.
+            None if receiver_is_valid(
+                wfcx,
+                span,
+                receiver_ty,
+                self_ty,
+                Some(ArbitrarySelfTypesLevel::Basic),
+            ) =>
+            {
                 // Report error; would have worked with `arbitrary_self_types`.
                 feature_err(
                     &tcx.sess,
@@ -1699,25 +1719,49 @@ fn check_method_receiver<'tcx>(
                     span,
                     format!(
                         "`{receiver_ty}` cannot be used as the type of `self` without \
-                         the `arbitrary_self_types` feature",
+                            the `arbitrary_self_types` feature",
                     ),
                 )
                 .with_help(fluent::hir_analysis_invalid_receiver_ty_help)
                 .emit()
-            } else {
-                // Report error; would not have worked with `arbitrary_self_types`.
+            }
+            None | Some(ArbitrarySelfTypesLevel::Basic)
+                if receiver_is_valid(
+                    wfcx,
+                    span,
+                    receiver_ty,
+                    self_ty,
+                    Some(ArbitrarySelfTypesLevel::WithPointers),
+                ) =>
+            {
+                // Report error; would have worked with `arbitrary_self_types_pointers`.
+                feature_err(
+                    &tcx.sess,
+                    sym::arbitrary_self_types_pointers,
+                    span,
+                    format!(
+                        "`{receiver_ty}` cannot be used as the type of `self` without \
+                            the `arbitrary_self_types_pointers` feature",
+                    ),
+                )
+                .with_help(fluent::hir_analysis_invalid_receiver_ty_help)
+                .emit()
+            }
+            _ =>
+            // Report error; would not have worked with `arbitrary_self_types[_pointers]`.
+            {
                 tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
-            });
-        }
+            }
+        });
     }
     Ok(())
 }
 
 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
-/// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
-/// strict: `receiver_ty` must implement `Receiver` and directly implement
-/// `Deref<Target = self_ty>`.
+/// through a `*const/mut T` raw pointer if  `arbitrary_self_types_pointers` is also enabled.
+/// If neither feature is enabled, the requirements are more strict: `receiver_ty` must implement
+/// `Receiver` and directly implement `Deref<Target = self_ty>`.
 ///
 /// N.B., there are cases this function returns `true` but causes an error to be emitted,
 /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
@@ -1727,7 +1771,7 @@ fn receiver_is_valid<'tcx>(
     span: Span,
     receiver_ty: Ty<'tcx>,
     self_ty: Ty<'tcx>,
-    arbitrary_self_types_enabled: bool,
+    arbitrary_self_types_enabled: Option<ArbitrarySelfTypesLevel>,
 ) -> bool {
     let infcx = wfcx.infcx;
     let tcx = wfcx.tcx();
@@ -1745,8 +1789,8 @@ fn receiver_is_valid<'tcx>(
 
     let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
 
-    // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
-    if arbitrary_self_types_enabled {
+    // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
+    if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) {
         autoderef = autoderef.include_raw_pointers();
     }
 
@@ -1772,7 +1816,7 @@ fn receiver_is_valid<'tcx>(
 
         // Without `feature(arbitrary_self_types)`, we require that each step in the
         // deref chain implement `receiver`.
-        if !arbitrary_self_types_enabled {
+        if arbitrary_self_types_enabled.is_none() {
             if !receiver_is_implemented(
                 wfcx,
                 receiver_trait_def_id,
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 9f01f7be80a..30fc06829ed 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -219,7 +219,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
     // Later parts of the compiler rely on all DispatchFromDyn types to be ABI-compatible with raw
     // pointers. This is enforced here: we only allow impls for references, raw pointers, and things
     // that are effectively repr(transparent) newtypes around types that already hav a
-    // DispatchedFromDyn impl. We cannot literally use repr(transparent) on those tpyes since some
+    // DispatchedFromDyn impl. We cannot literally use repr(transparent) on those types since some
     // of them support an allocator, but we ensure that for the cases where the type implements this
     // trait, they *do* satisfy the repr(transparent) rules, and then we assume that everything else
     // in the compiler (in particular, all the call ABI logic) will treat them as repr(transparent)
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 53105f337c4..92111805ab4 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1037,7 +1037,7 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> {
 
     /// Check the uniqueness of fields in a struct variant, and recursively
     /// check the nested fields if it is an unnamed field with type of an
-    /// annoymous adt.
+    /// anonymous adt.
     fn check_field(&mut self, field: &hir::FieldDef<'_>) {
         if field.ident.name != kw::Underscore {
             self.check_field_decl(field.ident, field.span.into());
@@ -1491,7 +1491,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
         Some(ty) => {
             let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
             // Typeck doesn't expect erased regions to be returned from `type_of`.
-            // This is a heuristic approach. If the scope has region paramters,
+            // This is a heuristic approach. If the scope has region parameters,
             // we should change fn_sig's lifetime from `ReErased` to `ReError`,
             // otherwise to `ReStatic`.
             let has_region_params = generics.params.iter().any(|param| match param.kind {
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 70a3c744c78..bffe68f9b74 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -529,7 +529,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
 /// Detect and reject early-bound & escaping late-bound generic params in the type of assoc const bindings.
 ///
-/// FIXME(const_generics): This is a temporary and semi-artifical restriction until the
+/// FIXME(const_generics): This is a temporary and semi-artificial restriction until the
 /// arrival of *generic const generics*[^1].
 ///
 /// It might actually be possible that we can already support early-bound generic params
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 7be45463f15..149bc6d2698 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -133,9 +133,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 return;
             };
             let sugg = self.add_generic_param_suggestion(generics, self_ty.span, &impl_trait_name);
-            if sugg.is_empty() {
-                return;
-            };
             diag.multipart_suggestion(
                 format!(
                     "alternatively use a blanket implementation to implement `{of_trait_name}` for \
@@ -170,6 +167,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
         // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>`
         //        and suggest `Trait0<Ty = impl Trait1>`.
+        // Functions are found in three different contexts.
+        // 1. Independent functions
+        // 2. Functions inside trait blocks
+        // 3. Functions inside impl blocks
         let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
             hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
                 (sig, generics, None)
@@ -180,6 +181,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 owner_id,
                 ..
             }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
+            hir::Node::ImplItem(hir::ImplItem {
+                kind: hir::ImplItemKind::Fn(sig, _),
+                generics,
+                owner_id,
+                ..
+            }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
             _ => return false,
         };
         let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
@@ -187,6 +194,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         };
         let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
         let mut is_downgradable = true;
+
+        // Check if trait object is safe for suggesting dynamic dispatch.
         let is_object_safe = match self_ty.kind {
             hir::TyKind::TraitObject(objects, ..) => {
                 objects.iter().all(|(o, _)| match o.trait_ref.path.res {
@@ -202,8 +211,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
             _ => false,
         };
+
+        let borrowed = matches!(
+            tcx.parent_hir_node(self_ty.hir_id),
+            hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. })
+        );
+
+        // Suggestions for function return type.
         if let hir::FnRetTy::Return(ty) = sig.decl.output
-            && ty.hir_id == self_ty.hir_id
+            && ty.peel_refs().hir_id == self_ty.hir_id
         {
             let pre = if !is_object_safe {
                 format!("`{trait_name}` is not object safe, ")
@@ -214,14 +230,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 "{pre}use `impl {trait_name}` to return an opaque type, as long as you return a \
                  single underlying type",
             );
+
             diag.multipart_suggestion_verbose(msg, impl_sugg, Applicability::MachineApplicable);
+
+            // Suggest `Box<dyn Trait>` for return type
             if is_object_safe {
-                diag.multipart_suggestion_verbose(
-                    "alternatively, you can return an owned trait object",
+                // If the return type is `&Trait`, we don't want
+                // the ampersand to be displayed in the `Box<dyn Trait>`
+                // suggestion.
+                let suggestion = if borrowed {
+                    vec![(ty.span, format!("Box<dyn {trait_name}>"))]
+                } else {
                     vec![
                         (ty.span.shrink_to_lo(), "Box<dyn ".to_string()),
                         (ty.span.shrink_to_hi(), ">".to_string()),
-                    ],
+                    ]
+                };
+
+                diag.multipart_suggestion_verbose(
+                    "alternatively, you can return an owned trait object",
+                    suggestion,
                     Applicability::MachineApplicable,
                 );
             } else if is_downgradable {
@@ -230,24 +258,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
             return true;
         }
+
+        // Suggestions for function parameters.
         for ty in sig.decl.inputs {
-            if ty.hir_id != self_ty.hir_id {
+            if ty.peel_refs().hir_id != self_ty.hir_id {
                 continue;
             }
             let sugg = self.add_generic_param_suggestion(generics, self_ty.span, &trait_name);
-            if !sugg.is_empty() {
-                diag.multipart_suggestion_verbose(
-                    format!("use a new generic type parameter, constrained by `{trait_name}`"),
-                    sugg,
-                    Applicability::MachineApplicable,
-                );
-                diag.multipart_suggestion_verbose(
-                    "you can also use an opaque type, but users won't be able to specify the type \
-                     parameter when calling the `fn`, having to rely exclusively on type inference",
-                    impl_sugg,
-                    Applicability::MachineApplicable,
-                );
-            }
+            diag.multipart_suggestion_verbose(
+                format!("use a new generic type parameter, constrained by `{trait_name}`"),
+                sugg,
+                Applicability::MachineApplicable,
+            );
+            diag.multipart_suggestion_verbose(
+                "you can also use an opaque type, but users won't be able to specify the type \
+                 parameter when calling the `fn`, having to rely exclusively on type inference",
+                impl_sugg,
+                Applicability::MachineApplicable,
+            );
             if !is_object_safe {
                 diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`"));
                 if is_downgradable {
@@ -255,14 +283,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     diag.downgrade_to_delayed_bug();
                 }
             } else {
+                // No ampersand in suggestion if it's borrowed already
+                let (dyn_str, paren_dyn_str) =
+                    if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") };
+
                 let sugg = if let hir::TyKind::TraitObject([_, _, ..], _, _) = self_ty.kind {
                     // There are more than one trait bound, we need surrounding parentheses.
                     vec![
-                        (self_ty.span.shrink_to_lo(), "&(dyn ".to_string()),
+                        (self_ty.span.shrink_to_lo(), paren_dyn_str.to_string()),
                         (self_ty.span.shrink_to_hi(), ")".to_string()),
                     ]
                 } else {
-                    vec![(self_ty.span.shrink_to_lo(), "&dyn ".to_string())]
+                    vec![(self_ty.span.shrink_to_lo(), dyn_str.to_string())]
                 };
                 diag.multipart_suggestion_verbose(
                     format!(
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 36c26f91089..ac5bd825b18 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -986,7 +986,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
     /// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
     /// For the latter case, we report ambiguity.
-    /// While desirable to support, the implemention would be non-trivial. Tracked in [#22519].
+    /// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
     ///
     /// At the time of writing, *inherent associated types* are also resolved here. This however
     /// is [problematic][iat]. A proper implementation would be as non-trivial as the one
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index a4eec5f05a8..9863d036449 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -503,18 +503,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let fn_sig = self.instantiate_binder_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig);
         let fn_sig = self.normalize(call_expr.span, fn_sig);
 
-        // Call the generic checker.
-        let expected_arg_tys = self.expected_inputs_for_expected_output(
-            call_expr.span,
-            expected,
-            fn_sig.output(),
-            fn_sig.inputs(),
-        );
         self.check_argument_types(
             call_expr.span,
             call_expr,
             fn_sig.inputs(),
-            expected_arg_tys,
+            fn_sig.output(),
+            expected,
             arg_exprs,
             fn_sig.c_variadic,
             TupleArgumentsFlag::DontTupleArguments,
@@ -866,19 +860,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // don't know the full details yet (`Fn` vs `FnMut` etc), but we
         // do know the types expected for each argument and the return
         // type.
-
-        let expected_arg_tys = self.expected_inputs_for_expected_output(
-            call_expr.span,
-            expected,
-            fn_sig.output(),
-            fn_sig.inputs(),
-        );
-
         self.check_argument_types(
             call_expr.span,
             call_expr,
             fn_sig.inputs(),
-            expected_arg_tys,
+            fn_sig.output(),
+            expected,
             arg_exprs,
             fn_sig.c_variadic,
             TupleArgumentsFlag::TupleArguments,
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 1db2c865b40..1e1e007862e 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -650,7 +650,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         // cannot distinguish. This would cause us to erroneously discard a cast which will
                         // lead to a borrowck error like #113257.
                         // We still did a coercion above to unify inference variables for `ptr as _` casts.
-                        // This does cause us to miss some trivial casts in the trival cast lint.
+                        // This does cause us to miss some trivial casts in the trivial cast lint.
                         debug!(" -> PointerCast");
                     } else {
                         self.trivial_cast_lint(fcx);
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 1362d3626ef..f0d47e584ac 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1673,15 +1673,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        let expected_inputs =
-            self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]);
-        let adt_ty_hint = if let Some(expected_inputs) = expected_inputs {
-            expected_inputs.get(0).cloned().unwrap_or(adt_ty)
-        } else {
-            adt_ty
-        };
-        // re-link the regions that EIfEO can erase.
-        self.demand_eqtype(span, adt_ty_hint, adt_ty);
+        let adt_ty = self.resolve_vars_with_obligations(adt_ty);
+        let adt_ty_hint = expected.only_has_type(self).and_then(|expected| {
+            self.fudge_inference_if_ok(|| {
+                let ocx = ObligationCtxt::new(self);
+                ocx.sup(&self.misc(span), self.param_env, expected, adt_ty)?;
+                if !ocx.select_where_possible().is_empty() {
+                    return Err(TypeError::Mismatch);
+                }
+                Ok(self.resolve_vars_if_possible(adt_ty))
+            })
+            .ok()
+        });
+        if let Some(adt_ty_hint) = adt_ty_hint {
+            // re-link the variables that the fudging above can create.
+            self.demand_eqtype(span, adt_ty_hint, adt_ty);
+        }
 
         let ty::Adt(adt, args) = adt_ty.kind() else {
             span_bug!(span, "non-ADT passed to check_expr_struct_fields");
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 97c27680959..19f7950287f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -20,7 +20,6 @@ use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryRespons
 use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
 use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{
@@ -36,7 +35,7 @@ use rustc_span::Span;
 use rustc_target::abi::FieldIdx;
 use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_trait_selection::traits::{
-    self, NormalizeExt, ObligationCauseCode, ObligationCtxt, StructurallyNormalizeExt,
+    self, NormalizeExt, ObligationCauseCode, StructurallyNormalizeExt,
 };
 use tracing::{debug, instrument};
 
@@ -689,42 +688,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         vec![ty_error; len]
     }
 
-    /// Unifies the output type with the expected type early, for more coercions
-    /// and forward type information on the input expressions.
-    #[instrument(skip(self, call_span), level = "debug")]
-    pub(crate) fn expected_inputs_for_expected_output(
-        &self,
-        call_span: Span,
-        expected_ret: Expectation<'tcx>,
-        formal_ret: Ty<'tcx>,
-        formal_args: &[Ty<'tcx>],
-    ) -> Option<Vec<Ty<'tcx>>> {
-        let formal_ret = self.resolve_vars_with_obligations(formal_ret);
-        let ret_ty = expected_ret.only_has_type(self)?;
-
-        let expect_args = self
-            .fudge_inference_if_ok(|| {
-                let ocx = ObligationCtxt::new(self);
-
-                // Attempt to apply a subtyping relationship between the formal
-                // return type (likely containing type variables if the function
-                // is polymorphic) and the expected return type.
-                // No argument expectations are produced if unification fails.
-                let origin = self.misc(call_span);
-                ocx.sup(&origin, self.param_env, ret_ty, formal_ret)?;
-                if !ocx.select_where_possible().is_empty() {
-                    return Err(TypeError::Mismatch);
-                }
-
-                // Record all the argument types, with the args
-                // produced from the above subtyping unification.
-                Ok(Some(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect()))
-            })
-            .unwrap_or_default();
-        debug!(?formal_args, ?formal_ret, ?expect_args, ?expected_ret);
-        expect_args
-    }
-
     pub(crate) fn resolve_lang_item_path(
         &self,
         lang_item: hir::LangItem,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index eebb0217990..bdf84f33216 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -17,6 +17,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_index::IndexVec;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TypeTrace};
 use rustc_middle::ty::adjustment::AllowTwoPhase;
+use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
@@ -25,7 +26,7 @@ use rustc_span::symbol::{kw, Ident};
 use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
 use rustc_trait_selection::infer::InferCtxtExt;
-use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
+use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
 use tracing::debug;
 use {rustc_ast as ast, rustc_hir as hir};
 
@@ -124,6 +125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         if let Err(guar) = has_error {
             let err_inputs = self.err_args(args_no_rcvr.len(), guar);
+            let err_output = Ty::new_error(self.tcx, guar);
 
             let err_inputs = match tuple_arguments {
                 DontTupleArguments => err_inputs,
@@ -134,28 +136,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 sp,
                 expr,
                 &err_inputs,
-                None,
+                err_output,
+                NoExpectation,
                 args_no_rcvr,
                 false,
                 tuple_arguments,
                 method.ok().map(|method| method.def_id),
             );
-            return Ty::new_error(self.tcx, guar);
+            return err_output;
         }
 
         let method = method.unwrap();
-        // HACK(eddyb) ignore self in the definition (see above).
-        let expected_input_tys = self.expected_inputs_for_expected_output(
-            sp,
-            expected,
-            method.sig.output(),
-            &method.sig.inputs()[1..],
-        );
         self.check_argument_types(
             sp,
             expr,
             &method.sig.inputs()[1..],
-            expected_input_tys,
+            method.sig.output(),
+            expected,
             args_no_rcvr,
             method.sig.c_variadic,
             tuple_arguments,
@@ -175,8 +172,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         call_expr: &'tcx hir::Expr<'tcx>,
         // Types (as defined in the *signature* of the target function)
         formal_input_tys: &[Ty<'tcx>],
-        // More specific expected types, after unifying with caller output types
-        expected_input_tys: Option<Vec<Ty<'tcx>>>,
+        formal_output: Ty<'tcx>,
+        // Expected output from the parent expression or statement
+        expectation: Expectation<'tcx>,
         // The expressions for each provided argument
         provided_args: &'tcx [hir::Expr<'tcx>],
         // Whether the function is variadic, for example when imported from C
@@ -210,6 +208,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
+        // First, let's unify the formal method signature with the expectation eagerly.
+        // We use this to guide coercion inference; it's output is "fudged" which means
+        // any remaining type variables are assigned to new, unrelated variables. This
+        // is because the inference guidance here is only speculative.
+        let formal_output = self.resolve_vars_with_obligations(formal_output);
+        let expected_input_tys: Option<Vec<_>> = expectation
+            .only_has_type(self)
+            .and_then(|expected_output| {
+                self.fudge_inference_if_ok(|| {
+                    let ocx = ObligationCtxt::new(self);
+
+                    // Attempt to apply a subtyping relationship between the formal
+                    // return type (likely containing type variables if the function
+                    // is polymorphic) and the expected return type.
+                    // No argument expectations are produced if unification fails.
+                    let origin = self.misc(call_span);
+                    ocx.sup(&origin, self.param_env, expected_output, formal_output)?;
+                    if !ocx.select_where_possible().is_empty() {
+                        return Err(TypeError::Mismatch);
+                    }
+
+                    // Record all the argument types, with the args
+                    // produced from the above subtyping unification.
+                    Ok(Some(
+                        formal_input_tys
+                            .iter()
+                            .map(|&ty| self.resolve_vars_if_possible(ty))
+                            .collect(),
+                    ))
+                })
+                .ok()
+            })
+            .unwrap_or_default();
+
         let mut err_code = E0061;
 
         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
@@ -292,21 +324,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let coerce_error =
                 self.coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None).err();
-
             if coerce_error.is_some() {
                 return Compatibility::Incompatible(coerce_error);
             }
 
-            // 3. Check if the formal type is a supertype of the checked one
-            //    and register any such obligations for future type checks
-            let supertype_error = self.at(&self.misc(provided_arg.span), self.param_env).sup(
+            // 3. Check if the formal type is actually equal to the checked one
+            //    and register any such obligations for future type checks.
+            let formal_ty_error = self.at(&self.misc(provided_arg.span), self.param_env).eq(
                 DefineOpaqueTypes::Yes,
                 formal_input_ty,
                 coerced_ty,
             );
 
             // If neither check failed, the types are compatible
-            match supertype_error {
+            match formal_ty_error {
                 Ok(InferOk { obligations, value: () }) => {
                     self.register_predicates(obligations);
                     Compatibility::Compatible
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index faeabdc0821..10a22eee7b7 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -249,7 +249,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     }
 
     /// Returns a set of generic parameters for the method *receiver* where all type and region
-    /// parameters are instantiated with fresh variables. This generic paramters does not include any
+    /// parameters are instantiated with fresh variables. This generic parameters does not include any
     /// parameters declared on the method itself.
     ///
     /// Note that this generic parameters may include late-bound regions from the impl level. If so,
@@ -375,7 +375,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             IsMethodCall::Yes,
         );
 
-        // Create generic paramters for early-bound lifetime parameters,
+        // Create generic parameters for early-bound lifetime parameters,
         // combining parameters from the type and those from the method.
         assert_eq!(generics.parent_count, parent_args.len());
 
@@ -546,7 +546,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         debug!("instantiate_method_sig(pick={:?}, all_args={:?})", pick, all_args);
 
         // Instantiate the bounds on the method with the
-        // type/early-bound-regions instatiations performed. There can
+        // type/early-bound-regions instantiations performed. There can
         // be no late-bound regions appearing here.
         let def_id = pick.item.def_id;
         let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args);
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 0cf5403b3c0..2fdba8446bd 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -403,7 +403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     mode,
                 }));
             } else if bad_ty.reached_raw_pointer
-                && !self.tcx.features().arbitrary_self_types
+                && !self.tcx.features().arbitrary_self_types_pointers
                 && !self.tcx.sess.at_least_rust_2018()
             {
                 // this case used to be allowed by the compiler,
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 986453397ff..5789e60ebbe 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -228,7 +228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // coroutine bodies can't borrow from their parent closure. To fix this,
         // we force the inner coroutine to also be `move`. This only matters for
         // coroutine-closures that are `move` since otherwise they themselves will
-        // be borrowing from the outer environment, so there's no self-borrows occuring.
+        // be borrowing from the outer environment, so there's no self-borrows occurring.
         if let UpvarArgs::Coroutine(..) = args
             && let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
                 self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml
index 92ea3f278dc..f7d18f84e34 100644
--- a/compiler/rustc_index/Cargo.toml
+++ b/compiler/rustc_index/Cargo.toml
@@ -20,4 +20,5 @@ nightly = [
     "dep:rustc_macros",
     "rustc_index_macros/nightly",
 ]
+rustc_randomized_layouts = []
 # tidy-alphabetical-end
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index f773b5b46ad..52f354b8eca 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -33,8 +33,19 @@ pub use vec::IndexVec;
 ///
 /// </div>
 #[macro_export]
+#[cfg(not(feature = "rustc_randomized_layouts"))]
 macro_rules! static_assert_size {
     ($ty:ty, $size:expr) => {
         const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
     };
 }
+
+#[macro_export]
+#[cfg(feature = "rustc_randomized_layouts")]
+macro_rules! static_assert_size {
+    ($ty:ty, $size:expr) => {
+        // no effect other than using the statements.
+        // struct sizes are not deterministic under randomized layouts
+        const _: (usize, usize) = ($size, ::std::mem::size_of::<$ty>());
+    };
+}
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 9d77afa5d2f..1930e357fc9 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -51,7 +51,7 @@ impl<'tcx> InferCtxt<'tcx> {
             query_state,
             |tcx, param_env, query_state| {
                 // FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
-                // `param_env` beacause they are treated differently by trait selection.
+                // `param_env` because they are treated differently by trait selection.
                 Canonicalizer::canonicalize(
                     param_env,
                     None,
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 88db7237647..5ceaaf1a3c4 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -213,7 +213,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// ```
     ///
     /// As indicating in the comments above, each of those references
-    /// is (in the compiler) basically generic paramters (`args`)
+    /// is (in the compiler) basically generic parameters (`args`)
     /// applied to the type of a suitable `def_id` (which identifies
     /// `Foo1` or `Foo2`).
     ///
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 70b59322f5b..f2ec1dd3df7 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -153,7 +153,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
             // During coherence, opaque types should be treated as *possibly*
             // equal to any other type (except for possibly itself). This is an
-            // extremely heavy hammer, but can be relaxed in a fowards-compatible
+            // extremely heavy hammer, but can be relaxed in a forwards-compatible
             // way later.
             (&ty::Alias(ty::Opaque, _), _) | (_, &ty::Alias(ty::Opaque, _)) if self.intercrate => {
                 relation.register_predicates([ty::Binder::dummy(ty::PredicateKind::Ambiguous)]);
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index f257141ea65..f2a511d7a88 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -120,7 +120,7 @@ impl<'tcx> InferCtxt<'tcx> {
         } else {
             // NOTE: The `instantiation_variance` is not the same variance as
             // used by the relation. When instantiating `b`, `target_is_expected`
-            // is flipped and the `instantion_variance` is also flipped. To
+            // is flipped and the `instantiation_variance` is also flipped. To
             // constrain the `generalized_ty` while using the original relation,
             // we therefore only have to flip the arguments.
             //
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 779b98d073d..c4a38047b5e 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -435,7 +435,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
             escape_dep_filename(&file.prefer_local().to_string())
         };
 
-        // The entries will be used to declare dependencies beween files in a
+        // The entries will be used to declare dependencies between files in a
         // Makefile-like output, so the iteration order does not matter.
         #[allow(rustc::potential_query_instability)]
         let extra_tracked_files =
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 31b7eb5ee7d..35334595833 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -783,6 +783,9 @@ lint_tykind = usage of `ty::TyKind`
 lint_tykind_kind = usage of `ty::TyKind::<kind>`
     .suggestion = try using `ty::<kind>` directly
 
+lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+    .note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
 lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
     .label = argument has type `{$arg_ty}`
     .suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
index fb3f40aa271..ddaa819df14 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
@@ -267,7 +267,7 @@ pub(super) fn unexpected_cfg_value(
     // encouraged to do so.
     let can_suggest_adding_value = !sess.psess.check_config.well_known_names.contains(&name)
         // Except when working on rustc or the standard library itself, in which case we want to
-        // suggest adding these cfgs to the "normal" place because of bootstraping reasons. As a
+        // suggest adding these cfgs to the "normal" place because of bootstrapping reasons. As a
         // basic heuristic, we use the "cheat" unstable feature enable method and the
         // non-ui-testing enabled option.
         || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat)
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 8824e1dfe50..c43c650a9f9 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -1,19 +1,29 @@
-use rustc_data_structures::fx::FxIndexSet;
+use std::assert_matches::debug_assert_matches;
+use std::cell::LazyCell;
+
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{Applicability, LintDiagnostic};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_macros::LintDiagnostic;
-use rustc_middle::bug;
 use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
+use rustc_middle::ty::relate::{
+    structurally_relate_consts, structurally_relate_tys, Relate, RelateResult, TypeRelation,
+};
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::FutureIncompatibilityReason;
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
+use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt;
+use rustc_trait_selection::traits::ObligationCtxt;
 
 use crate::{fluent_generated as fluent, LateContext, LateLintPass};
 
@@ -119,20 +129,41 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
     }
 }
 
+#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
+enum ParamKind {
+    // Early-bound var.
+    Early(Symbol, u32),
+    // Late-bound var on function, not within a binder. We can capture these.
+    Free(DefId, Symbol),
+    // Late-bound var in a binder. We can't capture these yet.
+    Late,
+}
+
 fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) {
     let sig = tcx.fn_sig(parent_def_id).instantiate_identity();
 
-    let mut in_scope_parameters = FxIndexSet::default();
+    let mut in_scope_parameters = FxIndexMap::default();
     // Populate the in_scope_parameters list first with all of the generics in scope
     let mut current_def_id = Some(parent_def_id.to_def_id());
     while let Some(def_id) = current_def_id {
         let generics = tcx.generics_of(def_id);
         for param in &generics.own_params {
-            in_scope_parameters.insert(param.def_id);
+            in_scope_parameters.insert(param.def_id, ParamKind::Early(param.name, param.index));
         }
         current_def_id = generics.parent;
     }
 
+    for bound_var in sig.bound_vars() {
+        let ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, name)) = bound_var
+        else {
+            span_bug!(tcx.def_span(parent_def_id), "unexpected non-lifetime binder on fn sig");
+        };
+
+        in_scope_parameters.insert(def_id, ParamKind::Free(def_id, name));
+    }
+
+    let sig = tcx.liberate_late_bound_regions(parent_def_id.to_def_id(), sig);
+
     // Then visit the signature to walk through all the binders (incl. the late-bound
     // vars on the function itself, which we need to count too).
     sig.visit_with(&mut VisitOpaqueTypes {
@@ -140,21 +171,45 @@ fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) {
         parent_def_id,
         in_scope_parameters,
         seen: Default::default(),
+        // Lazily compute these two, since they're likely a bit expensive.
+        variances: LazyCell::new(|| {
+            let mut functional_variances = FunctionalVariances {
+                tcx: tcx,
+                variances: FxHashMap::default(),
+                ambient_variance: ty::Covariant,
+                generics: tcx.generics_of(parent_def_id),
+            };
+            functional_variances.relate(sig, sig).unwrap();
+            functional_variances.variances
+        }),
+        outlives_env: LazyCell::new(|| {
+            let param_env = tcx.param_env(parent_def_id);
+            let infcx = tcx.infer_ctxt().build();
+            let ocx = ObligationCtxt::new(&infcx);
+            let assumed_wf_tys = ocx.assumed_wf_types(param_env, parent_def_id).unwrap_or_default();
+            let implied_bounds =
+                infcx.implied_bounds_tys_compat(param_env, parent_def_id, &assumed_wf_tys, false);
+            OutlivesEnvironment::with_bounds(param_env, implied_bounds)
+        }),
     });
 }
 
-struct VisitOpaqueTypes<'tcx> {
+struct VisitOpaqueTypes<'tcx, VarFn, OutlivesFn> {
     tcx: TyCtxt<'tcx>,
     parent_def_id: LocalDefId,
-    in_scope_parameters: FxIndexSet<DefId>,
+    in_scope_parameters: FxIndexMap<DefId, ParamKind>,
+    variances: LazyCell<FxHashMap<DefId, ty::Variance>, VarFn>,
+    outlives_env: LazyCell<OutlivesEnvironment<'tcx>, OutlivesFn>,
     seen: FxIndexSet<LocalDefId>,
 }
 
-impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> Self::Result {
+impl<'tcx, VarFn, OutlivesFn> TypeVisitor<TyCtxt<'tcx>>
+    for VisitOpaqueTypes<'tcx, VarFn, OutlivesFn>
+where
+    VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>,
+    OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>,
+{
+    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
         // When we get into a binder, we need to add its own bound vars to the scope.
         let mut added = vec![];
         for arg in t.bound_vars() {
@@ -163,8 +218,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
                 ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..))
                 | ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, _)) => {
                     added.push(def_id);
-                    let unique = self.in_scope_parameters.insert(def_id);
-                    assert!(unique);
+                    let unique = self.in_scope_parameters.insert(def_id, ParamKind::Late);
+                    assert_eq!(unique, None);
                 }
                 _ => {
                     self.tcx.dcx().span_delayed_bug(
@@ -184,7 +239,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
         }
     }
 
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
+    fn visit_ty(&mut self, t: Ty<'tcx>) {
         if !t.has_aliases() {
             return;
         }
@@ -207,89 +262,126 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
             && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin
             && parent_def_id == self.parent_def_id
         {
-            // Compute the set of args that are captured by the opaque...
-            let mut captured = FxIndexSet::default();
-            let variances = self.tcx.variances_of(opaque_def_id);
-            let mut current_def_id = Some(opaque_def_id.to_def_id());
-            while let Some(def_id) = current_def_id {
-                let generics = self.tcx.generics_of(def_id);
-                for param in &generics.own_params {
-                    // A param is captured if it's invariant.
-                    if variances[param.index as usize] != ty::Invariant {
-                        continue;
-                    }
-                    // We need to turn all `ty::Param`/`ConstKind::Param` and
-                    // `ReEarlyParam`/`ReBound` into def ids.
-                    captured.insert(extract_def_id_from_arg(
-                        self.tcx,
-                        generics,
-                        opaque_ty.args[param.index as usize],
-                    ));
-                }
-                current_def_id = generics.parent;
-            }
-
-            // Compute the set of in scope params that are not captured. Get their spans,
-            // since that's all we really care about them for emitting the diagnostic.
-            let uncaptured_spans: Vec<_> = self
-                .in_scope_parameters
-                .iter()
-                .filter(|def_id| !captured.contains(*def_id))
-                .map(|def_id| self.tcx.def_span(def_id))
-                .collect();
-
             let opaque_span = self.tcx.def_span(opaque_def_id);
             let new_capture_rules =
                 opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024;
-
-            // If we have uncaptured args, and if the opaque doesn't already have
-            // `use<>` syntax on it, and we're < edition 2024, then warn the user.
             if !new_capture_rules
                 && !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..)))
-                && !uncaptured_spans.is_empty()
             {
-                let suggestion = if let Ok(snippet) =
-                    self.tcx.sess.source_map().span_to_snippet(opaque_span)
-                    && snippet.starts_with("impl ")
-                {
-                    let (lifetimes, others): (Vec<_>, Vec<_>) = captured
-                        .into_iter()
-                        .partition(|def_id| self.tcx.def_kind(*def_id) == DefKind::LifetimeParam);
-                    // Take all lifetime params first, then all others (ty/ct).
-                    let generics: Vec<_> = lifetimes
-                        .into_iter()
-                        .chain(others)
-                        .map(|def_id| self.tcx.item_name(def_id).to_string())
-                        .collect();
-                    // Make sure that we're not trying to name any APITs
-                    if generics.iter().all(|name| !name.starts_with("impl ")) {
-                        Some((
-                            format!(" + use<{}>", generics.join(", ")),
-                            opaque_span.shrink_to_hi(),
-                        ))
+                // Compute the set of args that are captured by the opaque...
+                let mut captured = FxIndexSet::default();
+                let mut captured_regions = FxIndexSet::default();
+                let variances = self.tcx.variances_of(opaque_def_id);
+                let mut current_def_id = Some(opaque_def_id.to_def_id());
+                while let Some(def_id) = current_def_id {
+                    let generics = self.tcx.generics_of(def_id);
+                    for param in &generics.own_params {
+                        // A param is captured if it's invariant.
+                        if variances[param.index as usize] != ty::Invariant {
+                            continue;
+                        }
+
+                        let arg = opaque_ty.args[param.index as usize];
+                        // We need to turn all `ty::Param`/`ConstKind::Param` and
+                        // `ReEarlyParam`/`ReBound` into def ids.
+                        captured.insert(extract_def_id_from_arg(self.tcx, generics, arg));
+
+                        captured_regions.extend(arg.as_region());
+                    }
+                    current_def_id = generics.parent;
+                }
+
+                // Compute the set of in scope params that are not captured.
+                let mut uncaptured_args: FxIndexSet<_> = self
+                    .in_scope_parameters
+                    .iter()
+                    .filter(|&(def_id, _)| !captured.contains(def_id))
+                    .collect();
+                // Remove the set of lifetimes that are in-scope that outlive some other captured
+                // lifetime and are contravariant (i.e. covariant in argument position).
+                uncaptured_args.retain(|&(def_id, kind)| {
+                    let Some(ty::Bivariant | ty::Contravariant) = self.variances.get(def_id) else {
+                        // Keep all covariant/invariant args. Also if variance is `None`,
+                        // then that means it's either not a lifetime, or it didn't show up
+                        // anywhere in the signature.
+                        return true;
+                    };
+                    // We only computed variance of lifetimes...
+                    debug_assert_matches!(self.tcx.def_kind(def_id), DefKind::LifetimeParam);
+                    let uncaptured = match *kind {
+                        ParamKind::Early(name, index) => ty::Region::new_early_param(
+                            self.tcx,
+                            ty::EarlyParamRegion { name, index },
+                        ),
+                        ParamKind::Free(def_id, name) => ty::Region::new_late_param(
+                            self.tcx,
+                            self.parent_def_id.to_def_id(),
+                            ty::BoundRegionKind::BrNamed(def_id, name),
+                        ),
+                        // Totally ignore late bound args from binders.
+                        ParamKind::Late => return true,
+                    };
+                    // Does this region outlive any captured region?
+                    !captured_regions.iter().any(|r| {
+                        self.outlives_env
+                            .free_region_map()
+                            .sub_free_regions(self.tcx, *r, uncaptured)
+                    })
+                });
+
+                // If we have uncaptured args, and if the opaque doesn't already have
+                // `use<>` syntax on it, and we're < edition 2024, then warn the user.
+                if !uncaptured_args.is_empty() {
+                    let suggestion = if let Ok(snippet) =
+                        self.tcx.sess.source_map().span_to_snippet(opaque_span)
+                        && snippet.starts_with("impl ")
+                    {
+                        let (lifetimes, others): (Vec<_>, Vec<_>) =
+                            captured.into_iter().partition(|def_id| {
+                                self.tcx.def_kind(*def_id) == DefKind::LifetimeParam
+                            });
+                        // Take all lifetime params first, then all others (ty/ct).
+                        let generics: Vec<_> = lifetimes
+                            .into_iter()
+                            .chain(others)
+                            .map(|def_id| self.tcx.item_name(def_id).to_string())
+                            .collect();
+                        // Make sure that we're not trying to name any APITs
+                        if generics.iter().all(|name| !name.starts_with("impl ")) {
+                            Some((
+                                format!(" + use<{}>", generics.join(", ")),
+                                opaque_span.shrink_to_hi(),
+                            ))
+                        } else {
+                            None
+                        }
                     } else {
                         None
-                    }
-                } else {
-                    None
-                };
-
-                self.tcx.emit_node_span_lint(
-                    IMPL_TRAIT_OVERCAPTURES,
-                    self.tcx.local_def_id_to_hir_id(opaque_def_id),
-                    opaque_span,
-                    ImplTraitOvercapturesLint {
-                        self_ty: t,
-                        num_captured: uncaptured_spans.len(),
-                        uncaptured_spans,
-                        suggestion,
-                    },
-                );
+                    };
+
+                    let uncaptured_spans: Vec<_> = uncaptured_args
+                        .into_iter()
+                        .map(|(def_id, _)| self.tcx.def_span(def_id))
+                        .collect();
+
+                    self.tcx.emit_node_span_lint(
+                        IMPL_TRAIT_OVERCAPTURES,
+                        self.tcx.local_def_id_to_hir_id(opaque_def_id),
+                        opaque_span,
+                        ImplTraitOvercapturesLint {
+                            self_ty: t,
+                            num_captured: uncaptured_spans.len(),
+                            uncaptured_spans,
+                            suggestion,
+                        },
+                    );
+                }
             }
+
             // Otherwise, if we are edition 2024, have `use<>` syntax, and
             // have no uncaptured args, then we should warn to the user that
             // it's redundant to capture all args explicitly.
-            else if new_capture_rules
+            if new_capture_rules
                 && let Some((captured_args, capturing_span)) =
                     opaque.bounds.iter().find_map(|bound| match *bound {
                         hir::GenericBound::Use(a, s) => Some((a, s)),
@@ -327,7 +419,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
                 if self
                     .in_scope_parameters
                     .iter()
-                    .all(|def_id| explicitly_captured.contains(def_id))
+                    .all(|(def_id, _)| explicitly_captured.contains(def_id))
                 {
                     self.tcx.emit_node_span_lint(
                         IMPL_TRAIT_REDUNDANT_CAPTURES,
@@ -396,7 +488,11 @@ fn extract_def_id_from_arg<'tcx>(
             ty::ReBound(
                 _,
                 ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, ..), .. },
-            ) => def_id,
+            )
+            | ty::ReLateParam(ty::LateParamRegion {
+                scope: _,
+                bound_region: ty::BoundRegionKind::BrNamed(def_id, ..),
+            }) => def_id,
             _ => unreachable!(),
         },
         ty::GenericArgKind::Type(ty) => {
@@ -413,3 +509,106 @@ fn extract_def_id_from_arg<'tcx>(
         }
     }
 }
+
+/// Computes the variances of regions that appear in the type, but considering
+/// late-bound regions too, which don't have their variance computed usually.
+///
+/// Like generalization, this is a unary operation implemented on top of the binary
+/// relation infrastructure, mostly because it's much easier to have the relation
+/// track the variance for you, rather than having to do it yourself.
+struct FunctionalVariances<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    variances: FxHashMap<DefId, ty::Variance>,
+    ambient_variance: ty::Variance,
+    generics: &'tcx ty::Generics,
+}
+
+impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
+    fn cx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn relate_with_variance<T: ty::relate::Relate<TyCtxt<'tcx>>>(
+        &mut self,
+        variance: rustc_type_ir::Variance,
+        _: ty::VarianceDiagInfo<TyCtxt<'tcx>>,
+        a: T,
+        b: T,
+    ) -> RelateResult<'tcx, T> {
+        let old_variance = self.ambient_variance;
+        self.ambient_variance = self.ambient_variance.xform(variance);
+        self.relate(a, b).unwrap();
+        self.ambient_variance = old_variance;
+        Ok(a)
+    }
+
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        structurally_relate_tys(self, a, b).unwrap();
+        Ok(a)
+    }
+
+    fn regions(
+        &mut self,
+        a: ty::Region<'tcx>,
+        _: ty::Region<'tcx>,
+    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+        let def_id = match *a {
+            ty::ReEarlyParam(ebr) => self.generics.region_param(ebr, self.tcx).def_id,
+            ty::ReBound(
+                _,
+                ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, ..), .. },
+            )
+            | ty::ReLateParam(ty::LateParamRegion {
+                scope: _,
+                bound_region: ty::BoundRegionKind::BrNamed(def_id, ..),
+            }) => def_id,
+            _ => {
+                return Ok(a);
+            }
+        };
+
+        if let Some(variance) = self.variances.get_mut(&def_id) {
+            *variance = unify(*variance, self.ambient_variance);
+        } else {
+            self.variances.insert(def_id, self.ambient_variance);
+        }
+
+        Ok(a)
+    }
+
+    fn consts(
+        &mut self,
+        a: ty::Const<'tcx>,
+        b: ty::Const<'tcx>,
+    ) -> RelateResult<'tcx, ty::Const<'tcx>> {
+        structurally_relate_consts(self, a, b).unwrap();
+        Ok(a)
+    }
+
+    fn binders<T>(
+        &mut self,
+        a: ty::Binder<'tcx, T>,
+        b: ty::Binder<'tcx, T>,
+    ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
+    where
+        T: Relate<TyCtxt<'tcx>>,
+    {
+        self.relate(a.skip_binder(), b.skip_binder()).unwrap();
+        Ok(a)
+    }
+}
+
+/// What is the variance that satisfies the two variances?
+fn unify(a: ty::Variance, b: ty::Variance) -> ty::Variance {
+    match (a, b) {
+        // Bivariance is lattice bottom.
+        (ty::Bivariant, other) | (other, ty::Bivariant) => other,
+        // Invariant is lattice top.
+        (ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
+        // If type is required to be covariant and contravariant, then it's invariant.
+        (ty::Contravariant, ty::Covariant) | (ty::Covariant, ty::Contravariant) => ty::Invariant,
+        // Otherwise, co + co = co, contra + contra = contra.
+        (ty::Contravariant, ty::Contravariant) => ty::Contravariant,
+        (ty::Covariant, ty::Covariant) => ty::Covariant,
+    }
+}
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 65571815019..2e8116b8ba8 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -18,7 +18,7 @@ use tracing::debug;
 use crate::lints::{
     BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
     NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
-    TykindKind, UntranslatableDiag,
+    TykindKind, TypeIrInherentUsage, UntranslatableDiag,
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
@@ -277,13 +277,39 @@ declare_tool_lint! {
     report_in_external_macro: true
 }
 
-declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]);
+declare_tool_lint! {
+    /// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
+    ///
+    /// This module should only be used within the trait solver.
+    pub rustc::USAGE_OF_TYPE_IR_INHERENT,
+    Allow,
+    "usage `rustc_type_ir::inherent` outside of trait system",
+    report_in_external_macro: true
+}
+
+declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT]);
 
 impl<'tcx> LateLintPass<'tcx> for TypeIr {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
 
         let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
+
+        // Path segments except for the final.
+        if let Some(seg) =
+            path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent))
+        {
+            cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage);
+        }
+        // Final path resolutions, like `use rustc_type_ir::inherent`
+        else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) {
+            cx.emit_span_lint(
+                USAGE_OF_TYPE_IR_INHERENT,
+                path.segments.last().unwrap().ident.span,
+                TypeIrInherentUsage,
+            );
+        }
+
         let (lo, hi, snippet) = match path.segments {
             [.., penultimate, segment]
                 if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index c5a5c5b30af..bb7de4739fb 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -30,6 +30,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(array_windows)]
+#![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(extract_if)]
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 2712e25668a..7ca282b7c85 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -919,6 +919,11 @@ pub(crate) struct TyQualified {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_type_ir_inherent_usage)]
+#[note]
+pub(crate) struct TypeIrInherentUsage;
+
+#[derive(LintDiagnostic)]
 #[diag(lint_non_glob_import_type_ir_inherent)]
 pub(crate) struct NonGlobImportTypeIrInherent {
     #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 13a3c741fe3..1546d79e4fd 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 // > same expression-containing item.
                 //
                 // To achieve this we get try to get the paths of the _Trait_ and
-                // _Type_, and we look inside thoses paths to try a find in one
+                // _Type_, and we look inside those paths to try a find in one
                 // of them a type whose parent is the same as the impl definition.
                 //
                 // If that's the case this means that this impl block declaration
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index c3b80e01c36..761d30bac71 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -734,7 +734,7 @@ trait UnusedDelimLint {
             return false;
         }
 
-        // Check if we need parens for `match &( Struct { feild:  }) {}`.
+        // Check if we need parens for `match &( Struct { field:  }) {}`.
         {
             let mut innermost = inner;
             loop {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 7063f488209..25d33126754 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3706,7 +3706,7 @@ declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
 
 declare_lint! {
     /// The `missing_abi` lint detects cases where the ABI is omitted from
-    /// extern declarations.
+    /// `extern` declarations.
     ///
     /// ### Example
     ///
@@ -3720,10 +3720,12 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// Historically, Rust implicitly selected C as the ABI for extern
-    /// declarations. We expect to add new ABIs, like `C-unwind`, in the future,
-    /// though this has not yet happened, and especially with their addition
-    /// seeing the ABI easily will make code review easier.
+    /// For historic reasons, Rust implicitly selects `C` as the default ABI for
+    /// `extern` declarations. [Other ABIs] like `C-unwind` and `system` have
+    /// been added since then, and especially with their addition seeing the ABI
+    /// easily makes code review easier.
+    ///
+    /// [Other ABIs]: https://doc.rust-lang.org/reference/items/external-blocks.html#abi
     pub MISSING_ABI,
     Allow,
     "No declared ABI for extern declaration"
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 0f46cacc27a..53da07aeaa6 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -71,8 +71,8 @@ impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'
     for Option<DecodeIterator<'a, 'tcx, T>>
 {
     #[inline(always)]
-    fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> &'tcx [T] {
-        if let Some(iter) = self { tcx.arena.alloc_from_iter(iter) } else { &[] }
+    fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] {
+        if let Some(iter) = self { tcx.arena.alloc_from_iter(iter) } else { err() }
     }
 }
 
@@ -84,12 +84,12 @@ impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
     fn process_decoded(
         self,
         tcx: TyCtxt<'tcx>,
-        _err: impl Fn() -> !,
+        err: impl Fn() -> !,
     ) -> ty::EarlyBinder<'tcx, &'tcx [T]> {
         ty::EarlyBinder::bind(if let Some(iter) = self {
             tcx.arena.alloc_from_iter(iter)
         } else {
-            &[]
+            err()
         })
     }
 }
@@ -247,8 +247,8 @@ provide! { tcx, def_id, other, cdata,
     explicit_predicates_of => { table }
     generics_of => { table }
     inferred_outlives_of => { table_defaulted_array }
-    explicit_super_predicates_of => { table }
-    explicit_implied_predicates_of => { table }
+    explicit_super_predicates_of => { table_defaulted_array }
+    explicit_implied_predicates_of => { table_defaulted_array }
     type_of => { table }
     type_alias_is_lazy => { table_direct }
     variances_of => { table }
@@ -300,7 +300,20 @@ provide! { tcx, def_id, other, cdata,
             .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer")))
     }
     trait_def => { table }
-    deduced_param_attrs => { table }
+    deduced_param_attrs => {
+        // FIXME: `deduced_param_attrs` has some sketchy encoding settings,
+        // where we don't encode unless we're optimizing, doing codegen,
+        // and not incremental (see `encoder.rs`). I don't think this is right!
+        cdata
+            .root
+            .tables
+            .deduced_param_attrs
+            .get(cdata, def_id.index)
+            .map(|lazy| {
+                &*tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx)))
+            })
+            .unwrap_or_default()
+    }
     is_type_alias_impl_trait => {
         debug_assert_eq!(tcx.def_kind(def_id), DefKind::OpaqueTy);
         cdata.root.tables.is_type_alias_impl_trait.get(cdata, def_id.index)
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 88256c4db04..c55583b39a6 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1443,9 +1443,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             if let DefKind::Trait = def_kind {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
-                record_array!(self.tables.explicit_super_predicates_of[def_id] <-
+                record_defaulted_array!(self.tables.explicit_super_predicates_of[def_id] <-
                     self.tcx.explicit_super_predicates_of(def_id).skip_binder());
-                record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
+                record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
                     self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
 
                 let module_children = self.tcx.module_children_local(local_id);
@@ -1454,9 +1454,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             if let DefKind::TraitAlias = def_kind {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
-                record_array!(self.tables.explicit_super_predicates_of[def_id] <-
+                record_defaulted_array!(self.tables.explicit_super_predicates_of[def_id] <-
                     self.tcx.explicit_super_predicates_of(def_id).skip_binder());
-                record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
+                record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
                     self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
             }
             if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index a84923130c3..8180a507a51 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -390,6 +390,8 @@ define_tables! {
     explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     explicit_item_super_predicates: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
+    explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
+    explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
     associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
     associated_type_for_effects: Table<DefIndex, Option<LazyValue<DefId>>>,
@@ -419,10 +421,6 @@ define_tables! {
     lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
     explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
     generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
-    explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
-    // As an optimization, we only store this for trait aliases,
-    // since it's identical to explicit_super_predicates_of for traits.
-    explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 69e3b703cce..b23589afb58 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -40,5 +40,6 @@ tracing = "0.1"
 
 [features]
 # tidy-alphabetical-start
+rustc_randomized_layouts = []
 rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
 # tidy-alphabetical-end
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 563647ad4e6..c6105d1f383 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -240,7 +240,7 @@ impl<'tcx> Const<'tcx> {
         match self {
             Const::Ty(ty, ct) => {
                 match ct.kind() {
-                    // Dont use the outter ty as on invalid code we can wind up with them not being the same.
+                    // Dont use the outer ty as on invalid code we can wind up with them not being the same.
                     // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
                     // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
                     ty::ConstKind::Value(ty, _) => ty,
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 69ce3e08735..8c89c15f961 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -91,9 +91,9 @@ pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled
 pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>;
 pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
 /// `Ok(Err(ty))` indicates the constant was fine, but the valtree couldn't be constructed
-/// because the value containts something of type `ty` that is not valtree-compatible.
+/// because the value contains something of type `ty` that is not valtree-compatible.
 /// The caller can then show an appropriate error; the query does not have the
-/// necssary context to give good user-facing errors for this case.
+/// necessary context to give good user-facing errors for this case.
 pub type EvalToValTreeResult<'tcx> = Result<Result<ValTree<'tcx>, Ty<'tcx>>, ErrorHandled>;
 
 #[cfg(target_pointer_width = "64")]
@@ -231,7 +231,7 @@ pub enum CheckInAllocMsg {
 pub enum CheckAlignMsg {
     /// The accessed pointer did not have proper alignment.
     AccessedPtr,
-    /// The access ocurred with a place that was based on a misaligned pointer.
+    /// The access occurred with a place that was based on a misaligned pointer.
     BasedOn,
 }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7b901915037..081a23b6ff3 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -3,8 +3,6 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
 
 use std::borrow::Cow;
-use std::cell::RefCell;
-use std::collections::hash_map::Entry;
 use std::fmt::{self, Debug, Formatter};
 use std::ops::{Index, IndexMut};
 use std::{iter, mem};
@@ -26,7 +24,6 @@ use rustc_index::bit_set::BitSet;
 use rustc_index::{Idx, IndexSlice, IndexVec};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_serialize::{Decodable, Encodable};
-use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
@@ -106,65 +103,6 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
     }
 }
 
-thread_local! {
-    static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
-        RefCell::new(FxHashMap::default())
-    };
-}
-
-/// Converts a MIR pass name into a snake case form to match the profiling naming style.
-fn to_profiler_name(type_name: &'static str) -> &'static str {
-    PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
-        Entry::Occupied(e) => *e.get(),
-        Entry::Vacant(e) => {
-            let snake_case: String = type_name
-                .chars()
-                .flat_map(|c| {
-                    if c.is_ascii_uppercase() {
-                        vec!['_', c.to_ascii_lowercase()]
-                    } else if c == '-' {
-                        vec!['_']
-                    } else {
-                        vec![c]
-                    }
-                })
-                .collect();
-            let result = &*String::leak(format!("mir_pass{}", snake_case));
-            e.insert(result);
-            result
-        }
-    })
-}
-
-/// A streamlined trait that you can implement to create a pass; the
-/// pass will be named after the type, and it will consist of a main
-/// loop that goes over each available MIR and applies `run_pass`.
-pub trait MirPass<'tcx> {
-    fn name(&self) -> &'static str {
-        // FIXME Simplify the implementation once more `str` methods get const-stable.
-        // See copypaste in `MirLint`
-        const {
-            let name = std::any::type_name::<Self>();
-            crate::util::common::c_name(name)
-        }
-    }
-
-    fn profiler_name(&self) -> &'static str {
-        to_profiler_name(self.name())
-    }
-
-    /// Returns `true` if this pass is enabled with the current combination of compiler flags.
-    fn is_enabled(&self, _sess: &Session) -> bool {
-        true
-    }
-
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);
-
-    fn is_mir_dump_enabled(&self) -> bool {
-        true
-    }
-}
-
 impl MirPhase {
     /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
     ///
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 9906be60e3e..a98e6943d68 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -612,7 +612,9 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io:
     let def_id = body.source.def_id();
     let kind = tcx.def_kind(def_id);
     let is_function = match kind {
-        DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) => true,
+        DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::SyntheticCoroutineBody => {
+            true
+        }
         _ => tcx.is_closure_like(def_id),
     };
     match (kind, body.source.promoted) {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index d6bdc1af0d2..969374cb0e5 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -327,7 +327,7 @@ rustc_queries! {
         }
     }
 
-    /// Returns the list of bounds that are required to be satsified
+    /// Returns the list of bounds that are required to be satisfied
     /// by a implementation or definition. For associated types, these
     /// must be satisfied for an implementation to be well-formed,
     /// and for opaque types, these are required to be satisfied by
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index c9bd702cce3..0320a91d142 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -337,6 +337,7 @@ macro_rules! define_callbacks {
                 // Ensure that values grow no larger than 64 bytes by accident.
                 // Increase this limit if necessary, but do try to keep the size low if possible
                 #[cfg(target_pointer_width = "64")]
+                #[cfg(not(feature = "rustc_randomized_layouts"))]
                 const _: () = {
                     if mem::size_of::<Value<'static>>() > 64 {
                         panic!("{}", concat!(
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 43dda252f83..20828067c46 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1475,7 +1475,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// provides a `TyCtxt`.
     ///
     /// By only providing the `TyCtxt` inside of the closure we enforce that the type
-    /// context and any interned alue (types, args, etc.) can only be used while `ty::tls`
+    /// context and any interned value (types, args, etc.) can only be used while `ty::tls`
     /// has a valid reference to the context, to allow formatting values that need it.
     pub fn create_global_ctxt(
         s: &'tcx Session,
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 698104b0462..dd00db8635f 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -81,10 +81,6 @@ impl<'tcx> VariantDef {
         adt: ty::AdtDef<'_>,
     ) -> InhabitedPredicate<'tcx> {
         debug_assert!(!adt.is_union());
-        if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
-            // Non-exhaustive variants from other crates are always considered inhabited.
-            return InhabitedPredicate::True;
-        }
         InhabitedPredicate::all(
             tcx,
             self.fields.iter().map(|field| {
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 7d5f0f1e9c4..072951d1319 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -38,7 +38,7 @@ pub struct Instance<'tcx> {
     pub args: GenericArgsRef<'tcx>,
 }
 
-/// Describes why a `ReifyShim` was created. This is needed to distingish a ReifyShim created to
+/// Describes why a `ReifyShim` was created. This is needed to distinguish a ReifyShim created to
 /// adjust for things like `#[track_caller]` in a vtable from a `ReifyShim` created to produce a
 /// function pointer from a vtable entry.
 /// Currently, this is only used when KCFI is enabled, as only KCFI needs to treat those two
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e41ea7507ef..ee70a6346d9 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -35,6 +35,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
 use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
+use rustc_hir::LangItem;
 use rustc_index::IndexVec;
 use rustc_macros::{
     extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
@@ -1570,8 +1571,15 @@ impl<'tcx> TyCtxt<'tcx> {
             flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
         }
 
+        // box is special, on the one hand the compiler assumes an ordered layout, with the pointer
+        // always at offset zero. On the other hand we want scalar abi optimizations.
+        let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
+
         // This is here instead of layout because the choice must make it into metadata.
-        if !self.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did))) {
+        if is_box
+            || !self
+                .consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
+        {
             flags.insert(ReprFlags::IS_LINEAR);
         }
 
@@ -1819,7 +1827,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self.get_attrs(did, attr).next().is_some()
     }
 
-    /// Determines whether an item is annotated with a multi-segement attribute
+    /// Determines whether an item is annotated with a multi-segment attribute
     pub fn has_attrs_with_path(self, did: impl Into<DefId>, attrs: &[Symbol]) -> bool {
         self.get_attrs_by_path(did.into(), attrs).next().is_some()
     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index b144fd0feb0..89ef30fa768 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1930,7 +1930,7 @@ impl<'tcx> Ty<'tcx> {
 
     /// Returns `true` when the outermost type cannot be further normalized,
     /// resolved, or instantiated. This includes all primitive types, but also
-    /// things like ADTs and trait objects, sice even if their arguments or
+    /// things like ADTs and trait objects, since even if their arguments or
     /// nested types may be further simplified, the outermost [`TyKind`] or
     /// type constructor remains the same.
     pub fn is_known_rigid(self) -> bool {
diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs
index 2038d3f8448..223b2b3bfe4 100644
--- a/compiler/rustc_middle/src/util/common.rs
+++ b/compiler/rustc_middle/src/util/common.rs
@@ -20,19 +20,3 @@ pub fn to_readable_str(mut val: usize) -> String {
 
     groups.join("_")
 }
-
-// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
-pub const fn c_name(name: &'static str) -> &'static str {
-    // FIXME Simplify the implementation once more `str` methods get const-stable.
-    // and inline into call site
-    let bytes = name.as_bytes();
-    let mut i = bytes.len();
-    while i > 0 && bytes[i - 1] != b':' {
-        i = i - 1;
-    }
-    let (_, bytes) = bytes.split_at(i);
-    match std::str::from_utf8(bytes) {
-        Ok(name) => name,
-        Err(_) => name,
-    }
-}
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 0171cc85918..8c3e6f49b16 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -1,7 +1,7 @@
 use rustc_ast::MetaItem;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
-use rustc_middle::mir::{self, Body, Local, Location, MirPass};
+use rustc_middle::mir::{self, Body, Local, Location};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
@@ -18,8 +18,6 @@ use crate::impls::{
 use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
 use crate::{Analysis, JoinSemiLattice, ResultsCursor};
 
-pub struct SanityCheck;
-
 fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> {
     for attr in tcx.get_attrs(def_id, sym::rustc_mir) {
         let items = attr.meta_item_list();
@@ -33,53 +31,50 @@ fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<Me
     None
 }
 
-// FIXME: This should be a `MirLint`, but it needs to be moved back to `rustc_mir_transform` first.
-impl<'tcx> MirPass<'tcx> for SanityCheck {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let def_id = body.source.def_id();
-        if !tcx.has_attr(def_id, sym::rustc_mir) {
-            debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
-            return;
-        } else {
-            debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
-        }
+pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+    let def_id = body.source.def_id();
+    if !tcx.has_attr(def_id, sym::rustc_mir) {
+        debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
+        return;
+    } else {
+        debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
+    }
 
-        let param_env = tcx.param_env(def_id);
-        let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
+    let param_env = tcx.param_env(def_id);
+    let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
 
-        if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
-            let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
-                .into_engine(tcx, body)
-                .iterate_to_fixpoint();
+    if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
+        let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
+            .into_engine(tcx, body)
+            .iterate_to_fixpoint();
 
-            sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body));
-        }
+        sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body));
+    }
 
-        if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
-            let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
-                .into_engine(tcx, body)
-                .iterate_to_fixpoint();
+    if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
+        let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
+            .into_engine(tcx, body)
+            .iterate_to_fixpoint();
 
-            sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
-        }
+        sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
+    }
 
-        if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() {
-            let flow_def_inits = DefinitelyInitializedPlaces::new(body, &move_data)
-                .into_engine(tcx, body)
-                .iterate_to_fixpoint();
+    if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() {
+        let flow_def_inits = DefinitelyInitializedPlaces::new(body, &move_data)
+            .into_engine(tcx, body)
+            .iterate_to_fixpoint();
 
-            sanity_check_via_rustc_peek(tcx, flow_def_inits.into_results_cursor(body));
-        }
+        sanity_check_via_rustc_peek(tcx, flow_def_inits.into_results_cursor(body));
+    }
 
-        if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
-            let flow_liveness = MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint();
+    if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
+        let flow_liveness = MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint();
 
-            sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body));
-        }
+        sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body));
+    }
 
-        if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
-            tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation);
-        }
+    if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
+        tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation);
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index edb6bc4fbea..e4bc6b3efe4 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -22,7 +22,7 @@ use rustc_target::spec::PanicStrategy;
 #[derive(PartialEq)]
 pub struct AbortUnwindingCalls;
 
-impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
+impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let def_id = body.source.def_id();
         let kind = tcx.def_kind(def_id);
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index df5312d155c..78e850de3c7 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -30,7 +30,7 @@ pub use self::AddCallGuards::*;
  *
  */
 
-impl<'tcx> MirPass<'tcx> for AddCallGuards {
+impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         self.add_call_guards(body);
     }
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 61a1d8cc902..4a8196aeff5 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -37,7 +37,7 @@ use crate::util;
 /// blowup.
 pub struct AddMovesForPackedDrops;
 
-impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
+impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
         add_moves_for_packed_drops(tcx, body);
@@ -86,7 +86,7 @@ fn add_move_for_packed_drop<'tcx>(
 
     let source_info = terminator.source_info;
     let ty = place.ty(body, tcx).ty;
-    let temp = patch.new_temp(ty, terminator.source_info.span);
+    let temp = patch.new_temp(ty, source_info.span);
 
     let storage_dead_block = patch.new_block(BasicBlockData {
         statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }],
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index 79bc21cab14..2e12064fe73 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -48,7 +48,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
     }
 }
 
-impl<'tcx> MirPass<'tcx> for AddRetag {
+impl<'tcx> crate::MirPass<'tcx> for AddRetag {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.opts.unstable_opts.mir_emit_retag
     }
diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
index 04204c68f7b..369f6c60084 100644
--- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
+++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
@@ -62,7 +62,7 @@ pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     checker.patcher.apply(body);
 }
 
-impl<'tcx> MirPass<'tcx> for Subtyper {
+impl<'tcx> crate::MirPass<'tcx> for Subtyper {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         subtype_finder(tcx, body);
     }
diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
index ad362f22ce1..2e072aa262a 100644
--- a/compiler/rustc_mir_transform/src/check_alignment.rs
+++ b/compiler/rustc_mir_transform/src/check_alignment.rs
@@ -9,7 +9,7 @@ use tracing::{debug, trace};
 
 pub struct CheckAlignment;
 
-impl<'tcx> MirPass<'tcx> for CheckAlignment {
+impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
     fn is_enabled(&self, sess: &Session) -> bool {
         // FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
         if sess.target.llvm_target == "i686-pc-windows-msvc" {
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 1f615c9d8d1..fb03323e37e 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -6,11 +6,11 @@ use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 
-use crate::{errors, MirLint};
+use crate::errors;
 
 pub struct CheckConstItemMutation;
 
-impl<'tcx> MirLint<'tcx> for CheckConstItemMutation {
+impl<'tcx> crate::MirLint<'tcx> for CheckConstItemMutation {
     fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         let mut checker = ConstMutationChecker { body, tcx, target_local: None };
         checker.visit_body(body);
diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs
index 9902002580a..2f957de7e78 100644
--- a/compiler/rustc_mir_transform/src/check_packed_ref.rs
+++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs
@@ -3,11 +3,11 @@ use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, TyCtxt};
 
-use crate::{errors, util, MirLint};
+use crate::{errors, util};
 
 pub struct CheckPackedRef;
 
-impl<'tcx> MirLint<'tcx> for CheckPackedRef {
+impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef {
     fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         let param_env = tcx.param_env(body.source.def_id());
         let source_info = SourceInfo::outermost(body.span);
@@ -37,24 +37,17 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
     }
 
     fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
-        if context.is_borrow() {
-            if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
-                let def_id = self.body.source.instance.def_id();
-                if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
-                    && self.tcx.is_builtin_derived(impl_def_id)
-                {
-                    // If we ever reach here it means that the generated derive
-                    // code is somehow doing an unaligned reference, which it
-                    // shouldn't do.
-                    span_bug!(
-                        self.source_info.span,
-                        "builtin derive created an unaligned reference"
-                    );
-                } else {
-                    self.tcx
-                        .dcx()
-                        .emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
-                }
+        if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
+            let def_id = self.body.source.instance.def_id();
+            if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
+                && self.tcx.is_builtin_derived(impl_def_id)
+            {
+                // If we ever reach here it means that the generated derive
+                // code is somehow doing an unaligned reference, which it
+                // shouldn't do.
+                span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
+            } else {
+                self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
             }
         }
     }
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index 08c9f9f08e6..2f3be1e425d 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -21,11 +21,9 @@ use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, Termi
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::TyCtxt;
 
-use crate::MirPass;
-
 pub struct CleanupPostBorrowck;
 
-impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
+impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         for basic_block in body.basic_blocks.as_mut() {
             for statement in basic_block.statements.iter_mut() {
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index 5c267f85378..85d25ca2231 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -19,7 +19,7 @@ use crate::ssa::SsaLocals;
 /// We want to replace all those locals by `_a`, either copied or moved.
 pub struct CopyProp;
 
-impl<'tcx> MirPass<'tcx> for CopyProp {
+impl<'tcx> crate::MirPass<'tcx> for CopyProp {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 1
     }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 8051fca9e7c..eefb748e49d 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -63,7 +63,9 @@ use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, InstanceKind, Ty, TyCtxt};
+use rustc_middle::ty::{
+    self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
@@ -113,47 +115,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
     }
 }
 
-struct DerefArgVisitor<'tcx> {
+struct SelfArgVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
+    new_base: Place<'tcx>,
 }
 
-impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
-        assert_ne!(*local, SELF_ARG);
-    }
-
-    fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
-        if place.local == SELF_ARG {
-            replace_base(
-                place,
-                Place {
-                    local: SELF_ARG,
-                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
-                },
-                self.tcx,
-            );
-        } else {
-            self.visit_local(&mut place.local, context, location);
-
-            for elem in place.projection.iter() {
-                if let PlaceElem::Index(local) = elem {
-                    assert_ne!(local, SELF_ARG);
-                }
-            }
-        }
+impl<'tcx> SelfArgVisitor<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>) -> Self {
+        Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } }
     }
 }
 
-struct PinArgVisitor<'tcx> {
-    ref_coroutine_ty: Ty<'tcx>,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
+impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -164,17 +137,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
 
     fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
         if place.local == SELF_ARG {
-            replace_base(
-                place,
-                Place {
-                    local: SELF_ARG,
-                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
-                        FieldIdx::ZERO,
-                        self.ref_coroutine_ty,
-                    )]),
-                },
-                self.tcx,
-            );
+            replace_base(place, self.new_base, self.tcx);
         } else {
             self.visit_local(&mut place.local, context, location);
 
@@ -198,15 +161,6 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx
 
 const SELF_ARG: Local = Local::from_u32(1);
 
-/// Coroutine has not been resumed yet.
-const UNRESUMED: usize = CoroutineArgs::UNRESUMED;
-/// Coroutine has returned / is completed.
-const RETURNED: usize = CoroutineArgs::RETURNED;
-/// Coroutine has panicked and is poisoned.
-const POISONED: usize = CoroutineArgs::POISONED;
-/// Number of reserved variants of coroutine state.
-const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS;
-
 /// A `yield` point in the coroutine.
 struct SuspensionPoint<'tcx> {
     /// State discriminant used when suspending or resuming at this point.
@@ -261,14 +215,10 @@ impl<'tcx> TransformVisitor<'tcx> {
             // `gen` continues return `None`
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
-                Rvalue::Aggregate(
-                    Box::new(AggregateKind::Adt(
-                        option_def_id,
-                        VariantIdx::ZERO,
-                        self.tcx.mk_args(&[self.old_yield_ty.into()]),
-                        None,
-                        None,
-                    )),
+                make_aggregate_adt(
+                    option_def_id,
+                    VariantIdx::ZERO,
+                    self.tcx.mk_args(&[self.old_yield_ty.into()]),
                     IndexVec::new(),
                 )
             }
@@ -317,64 +267,28 @@ impl<'tcx> TransformVisitor<'tcx> {
         is_return: bool,
         statements: &mut Vec<Statement<'tcx>>,
     ) {
+        const ZERO: VariantIdx = VariantIdx::ZERO;
+        const ONE: VariantIdx = VariantIdx::from_usize(1);
         let rvalue = match self.coroutine_kind {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
                 let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
                 let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
-                if is_return {
-                    // Poll::Ready(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            poll_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
+                let (variant_idx, operands) = if is_return {
+                    (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
                 } else {
-                    // Poll::Pending
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            poll_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::new(),
-                    )
-                }
+                    (ONE, IndexVec::new()) // Poll::Pending
+                };
+                make_aggregate_adt(poll_def_id, variant_idx, args, operands)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
-                if is_return {
-                    // None
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            option_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::new(),
-                    )
+                let (variant_idx, operands) = if is_return {
+                    (ZERO, IndexVec::new()) // None
                 } else {
-                    // Some(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            option_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
-                }
+                    (ONE, IndexVec::from_raw(vec![val])) // Some(val)
+                };
+                make_aggregate_adt(option_def_id, variant_idx, args, operands)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => {
                 if is_return {
@@ -400,31 +314,17 @@ impl<'tcx> TransformVisitor<'tcx> {
                 let coroutine_state_def_id =
                     self.tcx.require_lang_item(LangItem::CoroutineState, None);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
-                if is_return {
-                    // CoroutineState::Complete(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            coroutine_state_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
+                let variant_idx = if is_return {
+                    ONE // CoroutineState::Complete(val)
                 } else {
-                    // CoroutineState::Yielded(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            coroutine_state_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
-                }
+                    ZERO // CoroutineState::Yielded(val)
+                };
+                make_aggregate_adt(
+                    coroutine_state_def_id,
+                    variant_idx,
+                    args,
+                    IndexVec::from_raw(vec![val]),
+                )
             }
         };
 
@@ -517,7 +417,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
             self.make_state(v, source_info, is_return, &mut data.statements);
             let state = if let Some((resume, mut resume_arg)) = resume {
                 // Yield
-                let state = RESERVED_VARIANTS + self.suspension_points.len();
+                let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len();
 
                 // The resume arg target location might itself be remapped if its base local is
                 // live across a yield.
@@ -550,7 +450,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
                 VariantIdx::new(state)
             } else {
                 // Return
-                VariantIdx::new(RETURNED) // state for returned
+                VariantIdx::new(CoroutineArgs::RETURNED) // state for returned
             };
             data.statements.push(self.set_discr(state, source_info));
             data.terminator_mut().kind = TerminatorKind::Return;
@@ -560,6 +460,15 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
     }
 }
 
+fn make_aggregate_adt<'tcx>(
+    def_id: DefId,
+    variant_idx: VariantIdx,
+    args: GenericArgsRef<'tcx>,
+    operands: IndexVec<FieldIdx, Operand<'tcx>>,
+) -> Rvalue<'tcx> {
+    Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands)
+}
+
 fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let coroutine_ty = body.local_decls.raw[1].ty;
 
@@ -569,7 +478,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
     body.local_decls.raw[1].ty = ref_coroutine_ty;
 
     // Add a deref to accesses of the coroutine state
-    DerefArgVisitor { tcx }.visit_body(body);
+    SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body);
 }
 
 fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -584,7 +493,8 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
     body.local_decls.raw[1].ty = pin_ref_coroutine_ty;
 
     // Add the Pin field access to accesses of the coroutine state
-    PinArgVisitor { ref_coroutine_ty, tcx }.visit_body(body);
+    SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty))
+        .visit_body(body);
 }
 
 /// Allocates a new local and replaces all references of `local` with it. Returns the new local.
@@ -651,8 +561,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                         let local = eliminate_get_context_call(&mut body[bb]);
                         replace_resume_ty_local(tcx, body, local, context_mut_ref);
                     }
-                } else {
-                    continue;
                 }
             }
             TerminatorKind::Yield { resume_arg, .. } => {
@@ -665,24 +573,23 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
 fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
     let terminator = bb_data.terminator.take().unwrap();
-    if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind {
-        let [arg] = *Box::try_from(args).unwrap();
-        let local = arg.node.place().unwrap().local;
-
-        let arg = Rvalue::Use(arg.node);
-        let assign = Statement {
-            source_info: terminator.source_info,
-            kind: StatementKind::Assign(Box::new((destination, arg))),
-        };
-        bb_data.statements.push(assign);
-        bb_data.terminator = Some(Terminator {
-            source_info: terminator.source_info,
-            kind: TerminatorKind::Goto { target: target.unwrap() },
-        });
-        local
-    } else {
+    let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else {
         bug!();
-    }
+    };
+    let [arg] = *Box::try_from(args).unwrap();
+    let local = arg.node.place().unwrap().local;
+
+    let arg = Rvalue::Use(arg.node);
+    let assign = Statement {
+        source_info: terminator.source_info,
+        kind: StatementKind::Assign(Box::new((destination, arg))),
+    };
+    bb_data.statements.push(assign);
+    bb_data.terminator = Some(Terminator {
+        source_info: terminator.source_info,
+        kind: TerminatorKind::Goto { target: target.unwrap() },
+    });
+    local
 }
 
 #[cfg_attr(not(debug_assertions), allow(unused))]
@@ -1085,10 +992,11 @@ fn compute_layout<'tcx>(
     // Build the coroutine variant field list.
     // Create a map from local indices to coroutine struct indices.
     let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
-        iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
+        iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
     let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
     for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
-        let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx);
+        let variant_index =
+            VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx);
         let mut fields = IndexVec::new();
         for (idx, saved_local) in live_locals.iter().enumerate() {
             fields.push(saved_local);
@@ -1183,12 +1091,10 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                 source_info,
                 kind: TerminatorKind::Drop { place, target, unwind, replace: _ },
             } => {
-                if let Some(local) = place.as_local() {
-                    if local == SELF_ARG {
-                        (target, unwind, source_info)
-                    } else {
-                        continue;
-                    }
+                if let Some(local) = place.as_local()
+                    && local == SELF_ARG
+                {
+                    (target, unwind, source_info)
                 } else {
                     continue;
                 }
@@ -1237,7 +1143,7 @@ fn create_coroutine_drop_shim<'tcx>(
 
     let mut cases = create_cases(&mut body, transform, Operation::Drop);
 
-    cases.insert(0, (UNRESUMED, drop_clean));
+    cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean));
 
     // The returned state and the poisoned state fall through to the default
     // case which is just to return
@@ -1387,7 +1293,9 @@ fn create_coroutine_resume_function<'tcx>(
     if can_unwind {
         let source_info = SourceInfo::outermost(body.span);
         let poison_block = body.basic_blocks_mut().push(BasicBlockData {
-            statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)],
+            statements: vec![
+                transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info),
+            ],
             terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
             is_cleanup: true,
         });
@@ -1419,13 +1327,16 @@ fn create_coroutine_resume_function<'tcx>(
     use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
 
     // Jump to the entry point on the unresumed
-    cases.insert(0, (UNRESUMED, START_BLOCK));
+    cases.insert(0, (CoroutineArgs::UNRESUMED, START_BLOCK));
 
     // Panic when resumed on the returned or poisoned state
     if can_unwind {
         cases.insert(
             1,
-            (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind))),
+            (
+                CoroutineArgs::POISONED,
+                insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind)),
+            ),
         );
     }
 
@@ -1440,7 +1351,7 @@ fn create_coroutine_resume_function<'tcx>(
                 transform.insert_none_ret_block(body)
             }
         };
-        cases.insert(1, (RETURNED, block));
+        cases.insert(1, (CoroutineArgs::RETURNED, block));
     }
 
     insert_switch(body, cases, &transform, TerminatorKind::Unreachable);
@@ -1624,7 +1535,7 @@ fn check_field_tys_sized<'tcx>(
     }
 }
 
-impl<'tcx> MirPass<'tcx> for StateTransform {
+impl<'tcx> crate::MirPass<'tcx> for StateTransform {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let Some(old_yield_ty) = body.yield_ty() else {
             // This only applies to coroutines
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index ebe8d2eff4f..cf39c136b01 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -207,11 +207,12 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
 
     let mut by_move_body = body.clone();
     MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
-    dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(()));
 
-    let body_def = tcx.create_def(coroutine_def_id, kw::Empty, DefKind::SyntheticCoroutineBody);
+    // This will always be `{closure#1}`, since the original coroutine is `{closure#0}`.
+    let body_def = tcx.create_def(parent_def_id, kw::Empty, DefKind::SyntheticCoroutineBody);
     by_move_body.source =
         mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
+    dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(()));
 
     // Inherited from the by-ref coroutine.
     body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index bba354d2936..4edba61fdec 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -28,14 +28,13 @@ use tracing::{debug, debug_span, instrument, trace};
 use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
 use crate::coverage::graph::CoverageGraph;
 use crate::coverage::mappings::ExtractedMappings;
-use crate::MirPass;
 
 /// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
 /// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
 /// to construct the coverage map.
 pub struct InstrumentCoverage;
 
-impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
+impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.instrument_coverage()
     }
diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs
index bf522fd5ef4..ea473b64ce5 100644
--- a/compiler/rustc_mir_transform/src/ctfe_limit.rs
+++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs
@@ -8,11 +8,9 @@ use rustc_middle::mir::{
 use rustc_middle::ty::TyCtxt;
 use tracing::instrument;
 
-use crate::MirPass;
-
 pub struct CtfeLimit;
 
-impl<'tcx> MirPass<'tcx> for CtfeLimit {
+impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
     #[instrument(skip(self, _tcx, body))]
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let doms = body.basic_blocks.dominators();
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index b16d25c93bb..46f7408ef80 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -28,7 +28,7 @@ const PLACE_LIMIT: usize = 100;
 
 pub struct DataflowConstProp;
 
-impl<'tcx> MirPass<'tcx> for DataflowConstProp {
+impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 3
     }
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index f473073083a..9081a2e2e30 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -32,7 +32,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let borrowed_locals = borrowed_locals(body);
 
     // If the user requests complete debuginfo, mark the locals that appear in it as live, so
-    // we don't remove assignements to them.
+    // we don't remove assignments to them.
     let mut always_live = debuginfo_locals(body);
     always_live.union(&borrowed_locals);
 
@@ -132,7 +132,7 @@ pub enum DeadStoreElimination {
     Final,
 }
 
-impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
+impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
     fn name(&self) -> &'static str {
         match self {
             DeadStoreElimination::Initial => "DeadStoreElimination-initial",
diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
index b38f4a4a823..be50c1da8a4 100644
--- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
+++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
@@ -15,7 +15,7 @@ use super::simplify::simplify_cfg;
 
 pub struct DeduplicateBlocks;
 
-impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
+impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 4
     }
diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs
index 0e2fccc85da..a878f777448 100644
--- a/compiler/rustc_mir_transform/src/deref_separator.rs
+++ b/compiler/rustc_mir_transform/src/deref_separator.rs
@@ -78,7 +78,7 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     checker.patcher.apply(body);
 }
 
-impl<'tcx> MirPass<'tcx> for Derefer {
+impl<'tcx> crate::MirPass<'tcx> for Derefer {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         deref_finder(tcx, body);
     }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index a530dccf96b..67bee36b8a5 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -38,7 +38,7 @@
 //!   not contain any indirection through a pointer or any indexing projections.
 //!
 //! * `p` and `q` must have the **same type**. If we replace a local with a subtype or supertype,
-//!   we may end up with a differnet vtable for that local. See the `subtyping-impacts-selection`
+//!   we may end up with a different vtable for that local. See the `subtyping-impacts-selection`
 //!   tests for an example where that causes issues.
 //!
 //! * We need to make sure that the goal of "merging the memory" is actually structurally possible
@@ -146,11 +146,9 @@ use rustc_mir_dataflow::points::{save_as_intervals, DenseLocationMap, PointIndex
 use rustc_mir_dataflow::Analysis;
 use tracing::{debug, trace};
 
-use crate::MirPass;
-
 pub struct DestinationPropagation;
 
-impl<'tcx> MirPass<'tcx> for DestinationPropagation {
+impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // For now, only run at MIR opt level 3. Two things need to be changed before this can be
         // turned on by default:
@@ -165,7 +163,8 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let def_id = body.source.def_id();
-        let mut allocations = Allocations::default();
+        let mut candidates = Candidates::default();
+        let mut write_info = WriteInfo::default();
         trace!(func = ?tcx.def_path_str(def_id));
 
         let borrowed = rustc_mir_dataflow::impls::borrowed_locals(body);
@@ -193,12 +192,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
         loop {
             // PERF: Can we do something smarter than recalculating the candidates and liveness
             // results?
-            let mut candidates = find_candidates(
-                body,
-                &borrowed,
-                &mut allocations.candidates,
-                &mut allocations.candidates_reverse,
-            );
+            candidates.reset_and_find(body, &borrowed);
             trace!(?candidates);
             dest_prop_mir_dump(tcx, body, &points, &live, round_count);
 
@@ -206,7 +200,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
                 &mut candidates,
                 &points,
                 &live,
-                &mut allocations.write_info,
+                &mut write_info,
                 body,
             );
 
@@ -255,20 +249,8 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
     }
 }
 
-/// Container for the various allocations that we need.
-///
-/// We store these here and hand out `&mut` access to them, instead of dropping and recreating them
-/// frequently. Everything with a `&'alloc` lifetime points into here.
-#[derive(Default)]
-struct Allocations {
-    candidates: FxIndexMap<Local, Vec<Local>>,
-    candidates_reverse: FxIndexMap<Local, Vec<Local>>,
-    write_info: WriteInfo,
-    // PERF: Do this for `MaybeLiveLocals` allocations too.
-}
-
-#[derive(Debug)]
-struct Candidates<'alloc> {
+#[derive(Debug, Default)]
+struct Candidates {
     /// The set of candidates we are considering in this optimization.
     ///
     /// We will always merge the key into at most one of its values.
@@ -283,11 +265,12 @@ struct Candidates<'alloc> {
     ///
     /// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
     /// remove that assignment.
-    c: &'alloc mut FxIndexMap<Local, Vec<Local>>,
+    c: FxIndexMap<Local, Vec<Local>>,
+
     /// A reverse index of the `c` set; if the `c` set contains `a => Place { local: b, proj }`,
     /// then this contains `b => a`.
     // PERF: Possibly these should be `SmallVec`s?
-    reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
+    reverse: FxIndexMap<Local, Vec<Local>>,
 }
 
 //////////////////////////////////////////////////////////
@@ -360,19 +343,40 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
 //
 // This section enforces bullet point 2
 
-struct FilterInformation<'a, 'body, 'alloc, 'tcx> {
-    body: &'body Body<'tcx>,
+struct FilterInformation<'a, 'tcx> {
+    body: &'a Body<'tcx>,
     points: &'a DenseLocationMap,
     live: &'a SparseIntervalMatrix<Local, PointIndex>,
-    candidates: &'a mut Candidates<'alloc>,
-    write_info: &'alloc mut WriteInfo,
+    candidates: &'a mut Candidates,
+    write_info: &'a mut WriteInfo,
     at: Location,
 }
 
 // We first implement some utility functions which we will expose removing candidates according to
 // different needs. Throughout the liveness filtering, the `candidates` are only ever accessed
 // through these methods, and not directly.
-impl<'alloc> Candidates<'alloc> {
+impl Candidates {
+    /// Collects the candidates for merging.
+    ///
+    /// This is responsible for enforcing the first and third bullet point.
+    fn reset_and_find<'tcx>(&mut self, body: &Body<'tcx>, borrowed: &BitSet<Local>) {
+        self.c.clear();
+        self.reverse.clear();
+        let mut visitor = FindAssignments { body, candidates: &mut self.c, borrowed };
+        visitor.visit_body(body);
+        // Deduplicate candidates.
+        for (_, cands) in self.c.iter_mut() {
+            cands.sort();
+            cands.dedup();
+        }
+        // Generate the reverse map.
+        for (src, cands) in self.c.iter() {
+            for dest in cands.iter().copied() {
+                self.reverse.entry(dest).or_default().push(*src);
+            }
+        }
+    }
+
     /// Just `Vec::retain`, but the condition is inverted and we add debugging output
     fn vec_filter_candidates(
         src: Local,
@@ -447,7 +451,7 @@ enum CandidateFilter {
     Remove,
 }
 
-impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
+impl<'a, 'tcx> FilterInformation<'a, 'tcx> {
     /// Filters the set of candidates to remove those that conflict.
     ///
     /// The steps we take are exactly those that are outlined at the top of the file. For each
@@ -465,12 +469,12 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
     /// before the statement/terminator will correctly report locals that are read in the
     /// statement/terminator to be live. We are additionally conservative by treating all written to
     /// locals as also being read from.
-    fn filter_liveness<'b>(
-        candidates: &mut Candidates<'alloc>,
+    fn filter_liveness(
+        candidates: &mut Candidates,
         points: &DenseLocationMap,
         live: &SparseIntervalMatrix<Local, PointIndex>,
-        write_info_alloc: &'alloc mut WriteInfo,
-        body: &'b Body<'tcx>,
+        write_info: &mut WriteInfo,
+        body: &Body<'tcx>,
     ) {
         let mut this = FilterInformation {
             body,
@@ -479,7 +483,7 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> {
             candidates,
             // We don't actually store anything at this scope, we just keep things here to be able
             // to reuse the allocation.
-            write_info: write_info_alloc,
+            write_info,
             // Doesn't matter what we put here, will be overwritten before being used
             at: Location::START,
         };
@@ -736,40 +740,13 @@ fn places_to_candidate_pair<'tcx>(
     Some((a, b))
 }
 
-/// Collects the candidates for merging
-///
-/// This is responsible for enforcing the first and third bullet point.
-fn find_candidates<'alloc, 'tcx>(
-    body: &Body<'tcx>,
-    borrowed: &BitSet<Local>,
-    candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
-    candidates_reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
-) -> Candidates<'alloc> {
-    candidates.clear();
-    candidates_reverse.clear();
-    let mut visitor = FindAssignments { body, candidates, borrowed };
-    visitor.visit_body(body);
-    // Deduplicate candidates
-    for (_, cands) in candidates.iter_mut() {
-        cands.sort();
-        cands.dedup();
-    }
-    // Generate the reverse map
-    for (src, cands) in candidates.iter() {
-        for dest in cands.iter().copied() {
-            candidates_reverse.entry(dest).or_default().push(*src);
-        }
-    }
-    Candidates { c: candidates, reverse: candidates_reverse }
-}
-
-struct FindAssignments<'a, 'alloc, 'tcx> {
+struct FindAssignments<'a, 'tcx> {
     body: &'a Body<'tcx>,
-    candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
+    candidates: &'a mut FxIndexMap<Local, Vec<Local>>,
     borrowed: &'a BitSet<Local>,
 }
 
-impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> {
+impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
         if let StatementKind::Assign(box (
             lhs,
@@ -821,9 +798,9 @@ fn is_local_required(local: Local, body: &Body<'_>) -> bool {
 /////////////////////////////////////////////////////////
 // MIR Dump
 
-fn dest_prop_mir_dump<'body, 'tcx>(
+fn dest_prop_mir_dump<'tcx>(
     tcx: TyCtxt<'tcx>,
-    body: &'body Body<'tcx>,
+    body: &Body<'tcx>,
     points: &DenseLocationMap,
     live: &SparseIntervalMatrix<Local, PointIndex>,
     round: usize,
diff --git a/compiler/rustc_mir_transform/src/dump_mir.rs b/compiler/rustc_mir_transform/src/dump_mir.rs
index 29db45f9450..06ae1b490d7 100644
--- a/compiler/rustc_mir_transform/src/dump_mir.rs
+++ b/compiler/rustc_mir_transform/src/dump_mir.rs
@@ -7,11 +7,9 @@ use rustc_middle::mir::{write_mir_pretty, Body};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{OutFileName, OutputType};
 
-use crate::MirPass;
-
 pub struct Marker(pub &'static str);
 
-impl<'tcx> MirPass<'tcx> for Marker {
+impl<'tcx> crate::MirPass<'tcx> for Marker {
     fn name(&self) -> &'static str {
         self.0
     }
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index 67b81efd614..1c54cd70023 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -92,7 +92,7 @@ use super::simplify::simplify_cfg;
 /// ```
 pub struct EarlyOtherwiseBranch;
 
-impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
+impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 2
     }
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index e5778f8a05d..5dd82f40163 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -88,7 +88,7 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
 
 pub struct ElaborateBoxDerefs;
 
-impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
+impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         if let Some(def_id) = tcx.lang_items().owned_box() {
             let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index d0809d9388d..f4a951ebde6 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -49,7 +49,7 @@ use crate::deref_separator::deref_finder;
 /// ```
 pub struct ElaborateDrops;
 
-impl<'tcx> MirPass<'tcx> for ElaborateDrops {
+impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
     #[instrument(level = "trace", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index b7873e73c18..199fd0f10ee 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -9,11 +9,11 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
-use crate::{errors, MirLint};
+use crate::errors;
 
 pub struct FunctionItemReferences;
 
-impl<'tcx> MirLint<'tcx> for FunctionItemReferences {
+impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences {
     fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         let mut checker = FunctionItemRefChecker { tcx, body };
         checker.visit_body(body);
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index fb9baeeb3ed..df0fcc42e59 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -111,7 +111,7 @@ use crate::ssa::{AssignedValue, SsaLocals};
 
 pub struct GVN;
 
-impl<'tcx> MirPass<'tcx> for GVN {
+impl<'tcx> crate::MirPass<'tcx> for GVN {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 2
     }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 4482801826a..6cc7e0ee1e4 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -42,7 +42,7 @@ struct CallSite<'tcx> {
     source_info: SourceInfo,
 }
 
-impl<'tcx> MirPass<'tcx> for Inline {
+impl<'tcx> crate::MirPass<'tcx> for Inline {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined
         // MIR correctly when Modified Condition/Decision Coverage is enabled.
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 3ec553d0ba0..4fbfa744e67 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -27,7 +27,7 @@ impl InstSimplify {
     }
 }
 
-impl<'tcx> MirPass<'tcx> for InstSimplify {
+impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
     fn name(&self) -> &'static str {
         self.name()
     }
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 435b6a01163..02dd56e1b4f 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -61,7 +61,7 @@ const MAX_BACKTRACK: usize = 5;
 const MAX_COST: usize = 100;
 const MAX_PLACES: usize = 100;
 
-impl<'tcx> MirPass<'tcx> for JumpThreading {
+impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 2
     }
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 443d97d004e..61405fb25c6 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -25,11 +25,10 @@ use rustc_target::abi::{Abi, FieldIdx, HasDataLayout, Size, TargetDataLayout, Va
 use tracing::{debug, instrument, trace};
 
 use crate::errors::{AssertLint, AssertLintKind};
-use crate::MirLint;
 
 pub struct KnownPanicsLint;
 
-impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
+impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint {
     fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
         if body.tainted_by_errors.is_some() {
             return;
@@ -914,7 +913,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
     fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) {
         use rustc_middle::mir::visit::PlaceContext::*;
 
-        // Dereferencing just read the addess of `place.local`.
+        // Dereferencing just read the address of `place.local`.
         if place.projection.first() == Some(&PlaceElem::Deref) {
             context = NonMutatingUse(NonMutatingUseContext::Copy);
         }
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
index cbc3169f2f1..f02ba71ddc6 100644
--- a/compiler/rustc_mir_transform/src/large_enums.rs
+++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -27,7 +27,7 @@ pub struct EnumSizeOpt {
     pub(crate) discrepancy: u64,
 }
 
-impl<'tcx> MirPass<'tcx> for EnumSizeOpt {
+impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
     fn is_enabled(&self, sess: &Session) -> bool {
         // There are some differences in behavior on wasm and ARM that are not properly
         // understood, so we conservatively treat this optimization as unsound:
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 7a531977267..62e73ba2c8e 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -3,13 +3,11 @@
 #![feature(box_patterns)]
 #![feature(const_type_name)]
 #![feature(cow_is_borrowed)]
-#![feature(decl_macro)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
-#![feature(option_get_or_insert_default)]
 #![feature(round_char_boundary)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
@@ -17,6 +15,7 @@
 
 use hir::ConstContext;
 use required_consts::RequiredConstsVisitor;
+use rustc_const_eval::check_consts::{self, ConstCx};
 use rustc_const_eval::util;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::steal::Steal;
@@ -27,7 +26,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_index::IndexVec;
 use rustc_middle::mir::{
     AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
-    MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
+    MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
     Statement, StatementKind, TerminatorKind, START_BLOCK,
 };
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@@ -41,7 +40,7 @@ use tracing::{debug, trace};
 #[macro_use]
 mod pass_manager;
 
-use pass_manager::{self as pm, Lint, MirLint, WithMinOptLevel};
+use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
 
 mod abort_unwinding_calls;
 mod add_call_guards;
@@ -96,6 +95,7 @@ mod remove_unneeded_drops;
 mod remove_zsts;
 mod required_consts;
 mod reveal_all;
+mod sanity_check;
 mod shim;
 mod ssa;
 // This pass is public to allow external drivers to perform MIR cleanup
@@ -108,9 +108,6 @@ mod unreachable_enum_branching;
 mod unreachable_prop;
 mod validate;
 
-use rustc_const_eval::check_consts::{self, ConstCx};
-use rustc_mir_dataflow::rustc_peek;
-
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 pub fn provide(providers: &mut Providers) {
@@ -128,7 +125,7 @@ pub fn provide(providers: &mut Providers) {
         mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses,
         optimized_mir,
         is_mir_available,
-        is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
+        is_ctfe_mir_available: is_mir_available,
         mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
         mir_inliner_callees: inline::cycle::mir_inliner_callees,
         promoted_mir,
@@ -221,10 +218,8 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// Finds the full set of `DefId`s within the current crate that have
 /// MIR associated with them.
 fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
-    let mut set = FxIndexSet::default();
-
     // All body-owners have MIR associated with them.
-    set.extend(tcx.hir().body_owners());
+    let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
 
     // Additionally, tuple struct/variant constructors have MIR, but
     // they don't have a BodyId, so we need to build them separately.
@@ -249,8 +244,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
 
     // No need to const-check a non-const `fn`.
     match const_kind {
-        Some(ConstContext::Const { .. } | ConstContext::Static(_))
-        | Some(ConstContext::ConstFn) => {}
+        Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {}
         None => span_bug!(
             tcx.def_span(def),
             "`mir_const_qualif` should only be called on const fns and const items"
@@ -294,7 +288,7 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
             &Lint(function_item_references::FunctionItemReferences),
             // What we need to do constant evaluation.
             &simplify::SimplifyCfg::Initial,
-            &rustc_peek::SanityCheck, // Just a lint
+            &Lint(sanity_check::SanityCheck),
         ],
         None,
     );
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index a9bdff95fe5..55eec332306 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -9,7 +9,7 @@ use crate::take_array;
 
 pub struct LowerIntrinsics;
 
-impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
+impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let local_decls = &body.local_decls;
         for block in body.basic_blocks.as_mut() {
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index 77a7f4f47dd..555309a7750 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt;
 
 pub struct LowerSliceLenCalls;
 
-impl<'tcx> MirPass<'tcx> for LowerSliceLenCalls {
+impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index 47758b56f8c..233b39fb47a 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -12,7 +12,7 @@ use super::simplify::simplify_cfg;
 
 pub struct MatchBranchSimplification;
 
-impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
+impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 1
     }
@@ -289,7 +289,7 @@ fn can_cast(
 
 #[derive(Default)]
 struct SimplifyToExp {
-    transfrom_kinds: Vec<TransfromKind>,
+    transform_kinds: Vec<TransformKind>,
 }
 
 #[derive(Clone, Copy)]
@@ -302,17 +302,17 @@ enum ExpectedTransformKind<'tcx, 'a> {
     Cast { place: &'a Place<'tcx>, ty: Ty<'tcx> },
 }
 
-enum TransfromKind {
+enum TransformKind {
     Same,
     Cast,
 }
 
-impl From<ExpectedTransformKind<'_, '_>> for TransfromKind {
+impl From<ExpectedTransformKind<'_, '_>> for TransformKind {
     fn from(compare_type: ExpectedTransformKind<'_, '_>) -> Self {
         match compare_type {
-            ExpectedTransformKind::Same(_) => TransfromKind::Same,
-            ExpectedTransformKind::SameByEq { .. } => TransfromKind::Same,
-            ExpectedTransformKind::Cast { .. } => TransfromKind::Cast,
+            ExpectedTransformKind::Same(_) => TransformKind::Same,
+            ExpectedTransformKind::SameByEq { .. } => TransformKind::Same,
+            ExpectedTransformKind::Cast { .. } => TransformKind::Cast,
         }
     }
 }
@@ -475,7 +475,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
                 }
             }
         }
-        self.transfrom_kinds = expected_transform_kinds.into_iter().map(|c| c.into()).collect();
+        self.transform_kinds = expected_transform_kinds.into_iter().map(|c| c.into()).collect();
         Some(())
     }
 
@@ -493,13 +493,13 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
         let (_, first) = targets.iter().next().unwrap();
         let first = &bbs[first];
 
-        for (t, s) in iter::zip(&self.transfrom_kinds, &first.statements) {
+        for (t, s) in iter::zip(&self.transform_kinds, &first.statements) {
             match (t, &s.kind) {
-                (TransfromKind::Same, _) => {
+                (TransformKind::Same, _) => {
                     patch.add_statement(parent_end, s.kind.clone());
                 }
                 (
-                    TransfromKind::Cast,
+                    TransformKind::Cast,
                     StatementKind::Assign(box (lhs, Rvalue::Use(Operand::Constant(f_c)))),
                 ) => {
                     let operand = Operand::Copy(Place::from(discr_local));
diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs
index 32c8064ebca..41ce03caf08 100644
--- a/compiler/rustc_mir_transform/src/mentioned_items.rs
+++ b/compiler/rustc_mir_transform/src/mentioned_items.rs
@@ -1,5 +1,5 @@
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{self, Location, MentionedItem, MirPass};
+use rustc_middle::mir::{self, Location, MentionedItem};
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::Session;
@@ -13,7 +13,7 @@ struct MentionedItemsVisitor<'a, 'tcx> {
     mentioned_items: &'a mut Vec<Spanned<MentionedItem<'tcx>>>,
 }
 
-impl<'tcx> MirPass<'tcx> for MentionedItems {
+impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
     fn is_enabled(&self, _sess: &Session) -> bool {
         // If this pass is skipped the collector assume that nothing got mentioned! We could
         // potentially skip it in opt-level 0 if we are sure that opt-level will never *remove* uses
diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
index 1e87a0e01d9..1b4972d487e 100644
--- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
+++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs
@@ -9,7 +9,7 @@ use crate::simplify;
 
 pub struct MultipleReturnTerminators;
 
-impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
+impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 4
     }
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index dd1875f2a78..94573a9d89b 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -8,8 +8,6 @@ use rustc_middle::mir::{self, BasicBlock, Local, Location};
 use rustc_middle::ty::TyCtxt;
 use tracing::{debug, trace};
 
-use crate::MirPass;
-
 /// This pass looks for MIR that always copies the same local into the return place and eliminates
 /// the copy by renaming all uses of that local to `_0`.
 ///
@@ -34,7 +32,7 @@ use crate::MirPass;
 /// [#71003]: https://github.com/rust-lang/rust/pull/71003
 pub struct RenameReturnPlace;
 
-impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
+impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // unsound: #111005
         sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 51e27600404..28d4e1a1c91 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -1,19 +1,99 @@
+use std::cell::RefCell;
+use std::collections::hash_map::Entry;
+
+use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use tracing::trace;
 
 use crate::lint::lint_body;
-use crate::{validate, MirPass};
+use crate::validate;
+
+thread_local! {
+    static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
+        RefCell::new(FxHashMap::default())
+    };
+}
+
+/// Converts a MIR pass name into a snake case form to match the profiling naming style.
+fn to_profiler_name(type_name: &'static str) -> &'static str {
+    PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
+        Entry::Occupied(e) => *e.get(),
+        Entry::Vacant(e) => {
+            let snake_case: String = type_name
+                .chars()
+                .flat_map(|c| {
+                    if c.is_ascii_uppercase() {
+                        vec!['_', c.to_ascii_lowercase()]
+                    } else if c == '-' {
+                        vec!['_']
+                    } else {
+                        vec![c]
+                    }
+                })
+                .collect();
+            let result = &*String::leak(format!("mir_pass{}", snake_case));
+            e.insert(result);
+            result
+        }
+    })
+}
+
+// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
+const fn c_name(name: &'static str) -> &'static str {
+    // FIXME Simplify the implementation once more `str` methods get const-stable.
+    // and inline into call site
+    let bytes = name.as_bytes();
+    let mut i = bytes.len();
+    while i > 0 && bytes[i - 1] != b':' {
+        i = i - 1;
+    }
+    let (_, bytes) = bytes.split_at(i);
+    match std::str::from_utf8(bytes) {
+        Ok(name) => name,
+        Err(_) => name,
+    }
+}
+
+/// A streamlined trait that you can implement to create a pass; the
+/// pass will be named after the type, and it will consist of a main
+/// loop that goes over each available MIR and applies `run_pass`.
+pub(super) trait MirPass<'tcx> {
+    fn name(&self) -> &'static str {
+        // FIXME Simplify the implementation once more `str` methods get const-stable.
+        // See copypaste in `MirLint`
+        const {
+            let name = std::any::type_name::<Self>();
+            c_name(name)
+        }
+    }
+
+    fn profiler_name(&self) -> &'static str {
+        to_profiler_name(self.name())
+    }
+
+    /// Returns `true` if this pass is enabled with the current combination of compiler flags.
+    fn is_enabled(&self, _sess: &Session) -> bool {
+        true
+    }
+
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);
+
+    fn is_mir_dump_enabled(&self) -> bool {
+        true
+    }
+}
 
-/// Just like `MirPass`, except it cannot mutate `Body`.
-pub trait MirLint<'tcx> {
+/// Just like `MirPass`, except it cannot mutate `Body`, and MIR dumping is
+/// disabled (via the `Lint` adapter).
+pub(super) trait MirLint<'tcx> {
     fn name(&self) -> &'static str {
         // FIXME Simplify the implementation once more `str` methods get const-stable.
         // See copypaste in `MirPass`
         const {
             let name = std::any::type_name::<Self>();
-            rustc_middle::util::common::c_name(name)
+            c_name(name)
         }
     }
 
@@ -26,7 +106,7 @@ pub trait MirLint<'tcx> {
 
 /// An adapter for `MirLint`s that implements `MirPass`.
 #[derive(Debug, Clone)]
-pub struct Lint<T>(pub T);
+pub(super) struct Lint<T>(pub T);
 
 impl<'tcx, T> MirPass<'tcx> for Lint<T>
 where
@@ -49,7 +129,7 @@ where
     }
 }
 
-pub struct WithMinOptLevel<T>(pub u32, pub T);
+pub(super) struct WithMinOptLevel<T>(pub u32, pub T);
 
 impl<'tcx, T> MirPass<'tcx> for WithMinOptLevel<T>
 where
@@ -70,7 +150,7 @@ where
 
 /// Run the sequence of passes without validating the MIR after each pass. The MIR is still
 /// validated at the end.
-pub fn run_passes_no_validate<'tcx>(
+pub(super) fn run_passes_no_validate<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
     passes: &[&dyn MirPass<'tcx>],
@@ -80,7 +160,7 @@ pub fn run_passes_no_validate<'tcx>(
 }
 
 /// The optional `phase_change` is applied after executing all the passes, if present
-pub fn run_passes<'tcx>(
+pub(super) fn run_passes<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
     passes: &[&dyn MirPass<'tcx>],
@@ -89,7 +169,7 @@ pub fn run_passes<'tcx>(
     run_passes_inner(tcx, body, passes, phase_change, true);
 }
 
-pub fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
+pub(super) fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
 where
     P: MirPass<'tcx> + ?Sized,
 {
@@ -185,11 +265,11 @@ fn run_passes_inner<'tcx>(
     }
 }
 
-pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
+pub(super) fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
     validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body);
 }
 
-pub fn dump_mir_for_pass<'tcx>(
+pub(super) fn dump_mir_for_pass<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     pass_name: &str,
@@ -205,7 +285,7 @@ pub fn dump_mir_for_pass<'tcx>(
     );
 }
 
-pub fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+pub(super) fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
     assert_eq!(body.pass_count, 0);
     mir::dump_mir(tcx, true, body.phase.name(), &"after", body, |_, _| Ok(()))
 }
diff --git a/compiler/rustc_mir_transform/src/prettify.rs b/compiler/rustc_mir_transform/src/prettify.rs
index 14dd0c6f61e..ad71c622660 100644
--- a/compiler/rustc_mir_transform/src/prettify.rs
+++ b/compiler/rustc_mir_transform/src/prettify.rs
@@ -17,7 +17,7 @@ use rustc_session::Session;
 /// `IndexVec`, unless that successor is a back-edge (such as from a loop).
 pub struct ReorderBasicBlocks;
 
-impl<'tcx> MirPass<'tcx> for ReorderBasicBlocks {
+impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
     fn is_enabled(&self, _session: &Session) -> bool {
         false
     }
@@ -45,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for ReorderBasicBlocks {
 /// (Does not reorder arguments nor the [`RETURN_PLACE`].)
 pub struct ReorderLocals;
 
-impl<'tcx> MirPass<'tcx> for ReorderLocals {
+impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
     fn is_enabled(&self, _session: &Session) -> bool {
         false
     }
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index f2610fd52bc..cf0a569ffa4 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -41,7 +41,7 @@ pub struct PromoteTemps<'tcx> {
     pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
 }
 
-impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
+impl<'tcx> crate::MirPass<'tcx> for PromoteTemps<'tcx> {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // There's not really any point in promoting errorful MIR.
         //
@@ -498,7 +498,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                                 Some(x) if x != 0 => {}        // okay
                                 _ => return Err(Unpromotable), // value not known or 0 -- not okay
                             }
-                            // Furthermore, for signed divison, we also have to exclude `int::MIN / -1`.
+                            // Furthermore, for signed division, we also have to exclude `int::MIN / -1`.
                             if lhs_ty.is_signed() {
                                 match rhs_val.map(|x| x.to_int(sz)) {
                                     Some(-1) | None => {
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index 2b07c04a121..4a447d24cce 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -72,7 +72,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
 /// so we perform all the possible instantiations without removing the `_1 = &_2` statement.
 pub struct ReferencePropagation;
 
-impl<'tcx> MirPass<'tcx> for ReferencePropagation {
+impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 2
     }
@@ -345,7 +345,7 @@ fn fully_replacable_locals(ssa: &SsaLocals) -> BitSet<Local> {
     replacable
 }
 
-/// Utility to help performing subtitution of `*pattern` by `target`.
+/// Utility to help performing substitution of `*pattern` by `target`.
 struct Replacer<'tcx> {
     tcx: TyCtxt<'tcx>,
     targets: IndexVec<Local, Value<'tcx>>,
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 33c7d1695c0..ccba8d015e3 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -10,7 +10,7 @@ use tracing::debug;
 /// terrible code for these.
 pub struct RemoveNoopLandingPads;
 
-impl<'tcx> MirPass<'tcx> for RemoveNoopLandingPads {
+impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.panic_strategy() != PanicStrategy::Abort
     }
diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs
index 6c0b50fafdb..5801fdedceb 100644
--- a/compiler/rustc_mir_transform/src/remove_place_mention.rs
+++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs
@@ -6,7 +6,7 @@ use tracing::trace;
 
 pub struct RemovePlaceMention;
 
-impl<'tcx> MirPass<'tcx> for RemovePlaceMention {
+impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         !sess.opts.unstable_opts.mir_keep_place_mention
     }
diff --git a/compiler/rustc_mir_transform/src/remove_storage_markers.rs b/compiler/rustc_mir_transform/src/remove_storage_markers.rs
index af89395dddd..329b30d3890 100644
--- a/compiler/rustc_mir_transform/src/remove_storage_markers.rs
+++ b/compiler/rustc_mir_transform/src/remove_storage_markers.rs
@@ -6,7 +6,7 @@ use tracing::trace;
 
 pub struct RemoveStorageMarkers;
 
-impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
+impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0 && !sess.emit_lifetime_markers()
     }
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index fae1cb5f7d8..aafe971311d 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -6,8 +6,6 @@ use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
 use rustc_mir_dataflow::{move_path_children_matching, Analysis, MaybeReachable};
 use rustc_target::abi::FieldIdx;
 
-use crate::MirPass;
-
 /// Removes `Drop` terminators whose target is known to be uninitialized at
 /// that point.
 ///
@@ -18,7 +16,7 @@ use crate::MirPass;
 /// [#90770]: https://github.com/rust-lang/rust/issues/90770
 pub struct RemoveUninitDrops;
 
-impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
+impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let param_env = tcx.param_env(body.source.def_id());
         let move_data =
diff --git a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
index 9adcb5a38fd..43109aae0fb 100644
--- a/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
@@ -12,7 +12,7 @@ use super::simplify::simplify_cfg;
 
 pub struct RemoveUnneededDrops;
 
-impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
+impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("Running RemoveUnneededDrops on {:?}", body.source);
 
diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs
index 9a94cae3382..9aa46bd4fba 100644
--- a/compiler/rustc_mir_transform/src/remove_zsts.rs
+++ b/compiler/rustc_mir_transform/src/remove_zsts.rs
@@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 
 pub struct RemoveZsts;
 
-impl<'tcx> MirPass<'tcx> for RemoveZsts {
+impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index 5eaa024f846..29312a99cbc 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 
 pub struct RevealAll;
 
-impl<'tcx> MirPass<'tcx> for RevealAll {
+impl<'tcx> crate::MirPass<'tcx> for RevealAll {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
         RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
diff --git a/compiler/rustc_mir_transform/src/sanity_check.rs b/compiler/rustc_mir_transform/src/sanity_check.rs
new file mode 100644
index 00000000000..c9445d18162
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/sanity_check.rs
@@ -0,0 +1,11 @@
+use rustc_middle::mir::Body;
+use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::rustc_peek::sanity_check;
+
+pub(super) struct SanityCheck;
+
+impl<'tcx> crate::MirLint<'tcx> for SanityCheck {
+    fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+        sanity_check(tcx, body);
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index d1c2c91e00f..1478b86d3c7 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -74,7 +74,7 @@ pub(crate) fn simplify_cfg(body: &mut Body<'_>) {
     body.basic_blocks_mut().raw.shrink_to_fit();
 }
 
-impl<'tcx> MirPass<'tcx> for SimplifyCfg {
+impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg {
     fn name(&self) -> &'static str {
         self.name()
     }
@@ -366,7 +366,7 @@ pub enum SimplifyLocals {
     Final,
 }
 
-impl<'tcx> MirPass<'tcx> for SimplifyLocals {
+impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
     fn name(&self) -> &'static str {
         match &self {
             SimplifyLocals::BeforeConstProp => "SimplifyLocals-before-const-prop",
diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs
index 7c8a686d007..5a014bb7346 100644
--- a/compiler/rustc_mir_transform/src/simplify_branches.rs
+++ b/compiler/rustc_mir_transform/src/simplify_branches.rs
@@ -7,7 +7,7 @@ pub enum SimplifyConstCondition {
     Final,
 }
 /// A pass that replaces a branch with a goto when its condition is known.
-impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
+impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
     fn name(&self) -> &'static str {
         match self {
             SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index ac892adebec..bd30ecc59b3 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -9,8 +9,6 @@ use rustc_middle::mir::{
 use rustc_middle::ty::{Ty, TyCtxt};
 use tracing::trace;
 
-use super::MirPass;
-
 /// Pass to convert `if` conditions on integrals into switches on the integral.
 /// For an example, it turns something like
 ///
@@ -27,7 +25,7 @@ use super::MirPass;
 /// ```
 pub struct SimplifyComparisonIntegral;
 
-impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
+impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs
index 35cb6872fe9..64a92872830 100644
--- a/compiler/rustc_mir_transform/src/single_use_consts.rs
+++ b/compiler/rustc_mir_transform/src/single_use_consts.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::TyCtxt;
 /// needed to do that too, including updating the debug info.
 pub struct SingleUseConsts;
 
-impl<'tcx> MirPass<'tcx> for SingleUseConsts {
+impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 906e2c23f3b..3c5ccc0c99a 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -13,7 +13,7 @@ use tracing::{debug, instrument};
 
 pub struct ScalarReplacementOfAggregates;
 
-impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
+impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() >= 2
     }
diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
index 2427fbac5ee..51a322628ee 100644
--- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
@@ -12,8 +12,6 @@ use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_target::abi::{Abi, Variants};
 use tracing::trace;
 
-use crate::MirPass;
-
 pub struct UnreachableEnumBranching;
 
 fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
@@ -74,7 +72,7 @@ fn variant_discriminants<'tcx>(
     }
 }
 
-impl<'tcx> MirPass<'tcx> for UnreachableEnumBranching {
+impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index a6c3c3b189e..b8da86f1a8d 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -12,7 +12,7 @@ use rustc_target::abi::Size;
 
 pub struct UnreachablePropagation;
 
-impl MirPass<'_> for UnreachablePropagation {
+impl crate::MirPass<'_> for UnreachablePropagation {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
         sess.mir_opt_level() >= 2
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 99e06f59dd0..69e2592e82c 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -36,7 +36,7 @@ pub struct Validator {
     pub mir_phase: MirPhase,
 }
 
-impl<'tcx> MirPass<'tcx> for Validator {
+impl<'tcx> crate::MirPass<'tcx> for Validator {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // FIXME(JakobDegen): These bodies never instantiated in codegend anyway, so it's not
         // terribly important that they pass the validator. However, I think other passes might
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 9c820b888d9..8515ab45de2 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -397,7 +397,7 @@ fn collect_items_rec<'tcx>(
         MonoItem::Static(def_id) => {
             recursion_depth_reset = None;
 
-            // Statics always get evaluted (which is possible because they can't be generic), so for
+            // Statics always get evaluated (which is possible because they can't be generic), so for
             // `MentionedItems` collection there's nothing to do here.
             if mode == CollectionMode::UsedItems {
                 let instance = Instance::mono(tcx, def_id);
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index ea244b5107a..ca140500e2c 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -5,6 +5,7 @@
 //! So if you got to this crate from the old solver, it's totally normal.
 
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
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 bb05eb4c256..6c9a6011144 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -304,6 +304,11 @@ where
 
         let mut candidates = vec![];
 
+        if self.solver_mode() == SolverMode::Coherence {
+            if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
+                return vec![candidate];
+            }
+        }
         self.assemble_impl_candidates(goal, &mut candidates);
 
         self.assemble_builtin_impl_candidates(goal, &mut candidates);
@@ -314,11 +319,8 @@ where
 
         self.assemble_param_env_candidates(goal, &mut candidates);
 
-        match self.solver_mode() {
-            SolverMode::Normal => self.discard_impls_shadowed_by_env(goal, &mut candidates),
-            SolverMode::Coherence => {
-                self.assemble_coherence_unknowable_candidates(goal, &mut candidates)
-            }
+        if self.solver_mode() == SolverMode::Normal {
+            self.discard_impls_shadowed_by_env(goal, &mut candidates);
         }
 
         candidates
@@ -682,38 +684,34 @@ where
     /// also consider impls which may get added in a downstream or sibling crate
     /// or which an upstream impl may add in a minor release.
     ///
-    /// To do so we add an ambiguous candidate in case such an unknown impl could
-    /// apply to the current goal.
+    /// To do so we return a single ambiguous candidate in case such an unknown
+    /// impl could apply to the current goal.
     #[instrument(level = "trace", skip_all)]
-    fn assemble_coherence_unknowable_candidates<G: GoalKind<D>>(
+    fn consider_coherence_unknowable_candidate<G: GoalKind<D>>(
         &mut self,
         goal: Goal<I, G>,
-        candidates: &mut Vec<Candidate<I>>,
-    ) {
-        let cx = self.cx();
-
-        candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
-            |ecx| {
-                let trait_ref = goal.predicate.trait_ref(cx);
-                if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? {
-                    Err(NoSolution)
-                } else {
-                    // While the trait bound itself may be unknowable, we may be able to
-                    // prove that a super trait is not implemented. For this, we recursively
-                    // prove the super trait bounds of the current goal.
-                    //
-                    // We skip the goal itself as that one would cycle.
-                    let predicate: I::Predicate = trait_ref.upcast(cx);
-                    ecx.add_goals(
-                        GoalSource::Misc,
-                        elaborate::elaborate(cx, [predicate])
-                            .skip(1)
-                            .map(|predicate| goal.with(cx, predicate)),
-                    );
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
-                }
-            },
-        ))
+    ) -> Result<Candidate<I>, NoSolution> {
+        self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(|ecx| {
+            let cx = ecx.cx();
+            let trait_ref = goal.predicate.trait_ref(cx);
+            if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? {
+                Err(NoSolution)
+            } else {
+                // While the trait bound itself may be unknowable, we may be able to
+                // prove that a super trait is not implemented. For this, we recursively
+                // prove the super trait bounds of the current goal.
+                //
+                // We skip the goal itself as that one would cycle.
+                let predicate: I::Predicate = trait_ref.upcast(cx);
+                ecx.add_goals(
+                    GoalSource::Misc,
+                    elaborate::elaborate(cx, [predicate])
+                        .skip(1)
+                        .map(|predicate| goal.with(cx, predicate)),
+                );
+                ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+            }
+        })
     }
 
     /// If there's a where-bound for the current goal, do not use any impl candidates
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 2e521ddcec3..1c00f5f8b41 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -238,7 +238,7 @@ where
         (normalization_nested_goals.clone(), certainty)
     }
 
-    /// This returns the canoncial variable values to instantiate the bound variables of
+    /// This returns the canonical variable values to instantiate the bound variables of
     /// the canonical response. This depends on the `original_values` for the
     /// bound variables.
     fn compute_query_response_instantiation_values<T: ResponseT<I>>(
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index c65c5851e9b..536b502136a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -164,7 +164,7 @@ where
             // - `Bound` cannot exist as we don't have a binder around the self Type
             // - `Expr` is part of `feature(generic_const_exprs)` and is not implemented yet
             ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Expr(_) => {
-                panic!("unexpect const kind: {:?}", ct)
+                panic!("unexpected const kind: {:?}", ct)
             }
         }
     }
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 1314b7eb6ff..67b001d0cce 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -628,7 +628,7 @@ where
         }
 
         // FIXME: This actually should destructure the `Result` we get from transmutability and
-        // register candiates. We probably need to register >1 since we may have an OR of ANDs.
+        // register candidates. We probably need to register >1 since we may have an OR of ANDs.
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let certainty = ecx.is_transmutable(
                 goal.param_env,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 8233f9a7943..f87b5649654 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -402,7 +402,7 @@ impl<'a> Parser<'a> {
             let non_assoc_span = expr.span;
 
             // Parse an associative expression such as `+ expr`, `% expr`, ...
-            // Assignements, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
+            // Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
             if let Ok((expr, _)) =
                 snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
             {
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 7ae5c904004..7f1e906ffd7 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -439,7 +439,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 _ => intravisit::walk_item(self, item),
             },
             Node::TraitItem(trait_item) => {
-                // mark corresponing ImplTerm live
+                // mark corresponding ImplTerm live
                 let trait_item_id = trait_item.owner_id.to_def_id();
                 if let Some(trait_id) = self.tcx.trait_of_item(trait_item_id) {
                     // mark the trait live
@@ -1035,7 +1035,7 @@ impl<'tcx> DeadVisitor<'tcx> {
         };
 
         let encl_def_id = parent_item.unwrap_or(first_item.def_id);
-        // If parent of encl_def_id is an enum, use the parent ID intead.
+        // If parent of encl_def_id is an enum, use the parent ID instead.
         let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id);
 
         let ignored_derived_impls =
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 25115c5cafd..c11562ae39e 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -19,17 +19,25 @@ use crate::errors::{
     OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
 };
 
+/// The context in which a block is encountered.
 #[derive(Clone, Copy, Debug, PartialEq)]
 enum Context {
     Normal,
     Fn,
     Loop(hir::LoopSource),
     Closure(Span),
-    Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
+    Coroutine {
+        coroutine_span: Span,
+        kind: hir::CoroutineDesugaring,
+        source: hir::CoroutineSource,
+    },
     UnlabeledBlock(Span),
     UnlabeledIfBlock(Span),
     LabeledBlock,
-    Constant,
+    /// E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`.
+    AnonConst,
+    /// E.g. `const { ... }`.
+    ConstBlock,
 }
 
 #[derive(Clone)]
@@ -90,11 +98,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
     }
 
     fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
-        self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
+        self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
     }
 
     fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
-        self.with_context(Constant, |v| intravisit::walk_inline_const(v, c));
+        self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c));
     }
 
     fn visit_fn(
@@ -128,7 +136,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                         && matches!(
                             ck_loop.cx_stack.last(),
                             Some(&Normal)
-                                | Some(&Constant)
+                                | Some(&AnonConst)
                                 | Some(&UnlabeledBlock(_))
                                 | Some(&UnlabeledIfBlock(_))
                         )
@@ -175,14 +183,18 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             hir::ExprKind::Block(ref b, Some(_label)) => {
                 self.with_context(LabeledBlock, |v| v.visit_block(b));
             }
-            hir::ExprKind::Block(ref b, None) if matches!(self.cx_stack.last(), Some(&Fn)) => {
+            hir::ExprKind::Block(ref b, None)
+                if matches!(self.cx_stack.last(), Some(&Fn) | Some(&ConstBlock)) =>
+            {
                 self.with_context(Normal, |v| v.visit_block(b));
             }
-            hir::ExprKind::Block(ref b, None)
-                if matches!(
-                    self.cx_stack.last(),
-                    Some(&Normal) | Some(&Constant) | Some(&UnlabeledBlock(_))
-                ) =>
+            hir::ExprKind::Block(
+                ref b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. },
+                None,
+            ) if matches!(
+                self.cx_stack.last(),
+                Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock(_))
+            ) =>
             {
                 self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
             }
@@ -353,7 +365,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
             UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => {
                 self.require_break_cx(br_cx_kind, span, break_span, cx_pos - 1);
             }
-            Normal | Constant | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) => {
+            Normal | AnonConst | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) | ConstBlock => {
                 self.sess.dcx().emit_err(OutsideLoop {
                     spans: vec![span],
                     name: &br_cx_kind.to_string(),
@@ -365,7 +377,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
     }
 
     fn require_label_in_labeled_block(
-        &mut self,
+        &self,
         span: Span,
         label: &Destination,
         cf_type: &str,
@@ -380,7 +392,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
         false
     }
 
-    fn report_outside_loop_error(&mut self) {
+    fn report_outside_loop_error(&self) {
         for (s, block) in &self.block_breaks {
             self.sess.dcx().emit_err(OutsideLoop {
                 spans: block.spans.clone(),
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 3a2a75a638f..e4edd7befb7 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -288,7 +288,7 @@ impl IntRange {
     /// Best effort; will not know that e.g. `255u8..` is a singleton.
     pub fn is_singleton(&self) -> bool {
         // Since `lo` and `hi` can't be the same `Infinity` and `plus_one` never changes from finite
-        // to infinite, this correctly only detects ranges that contain exacly one `Finite(x)`.
+        // to infinite, this correctly only detects ranges that contain exactly one `Finite(x)`.
         self.lo.plus_one() == Some(self.hi)
     }
 
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index d7885e05a2f..6c09f97bfe7 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -229,17 +229,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                     } else {
                         let variant =
                             &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
-
-                        // In the cases of either a `#[non_exhaustive]` field list or a non-public
-                        // field, we skip uninhabited fields in order not to reveal the
-                        // uninhabitedness of the whole variant.
-                        let is_non_exhaustive =
-                            variant.is_field_list_non_exhaustive() && !adt.did().is_local();
                         let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
                             let is_visible =
                                 adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
                             let is_uninhabited = cx.is_uninhabited(*ty);
-                            let skip = is_uninhabited && (!is_visible || is_non_exhaustive);
+                            let skip = is_uninhabited && !is_visible;
                             (ty, PrivateUninhabitedField(skip))
                         });
                         cx.dropless_arena.alloc_from_iter(tys)
diff --git a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
index 2192940d4d7..af093db782c 100644
--- a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
+++ b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
@@ -22,7 +22,7 @@ fn check(patterns: Vec<DeconstructedPat<Cx>>) -> Vec<WitnessPat<Cx>> {
 fn assert_exhaustive(patterns: Vec<DeconstructedPat<Cx>>) {
     let witnesses = check(patterns);
     if !witnesses.is_empty() {
-        panic!("non-exaustive match: missing {witnesses:?}");
+        panic!("non-exhaustive match: missing {witnesses:?}");
     }
 }
 
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index b6aa1d5a43b..eb3eddf34aa 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -1405,7 +1405,7 @@ fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepN
         "Error: trying to record dependency on DepNode {dep_node} in a \
          context that does not allow it (e.g. during query deserialization). \
          The most common case of recording a dependency on a DepNode `foo` is \
-         when the correspondng query `foo` is invoked. Invoking queries is not \
+         when the corresponding query `foo` is invoked. Invoking queries is not \
          allowed as part of loading something from the incremental on-disk cache. \
          See <https://github.com/rust-lang/rust/pull/91919>."
     )
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 73d1a2ea49a..6602c788969 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -11,7 +11,7 @@ resolve_added_macro_use =
 resolve_ancestor_only =
     visibilities can only be restricted to ancestor modules
 
-resolve_anonymous_livetime_non_gat_report_error =
+resolve_anonymous_lifetime_non_gat_report_error =
     in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
     .label = this lifetime must come from the implemented type
 
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index a70d51606f7..0fedb998463 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -223,7 +223,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                 // we must create two defs.
                 let coroutine_def =
                     self.create_def(coroutine_kind.closure_id(), kw::Empty, DefKind::Closure, span);
-                self.with_parent(coroutine_def, |this| visit::walk_expr(this, body));
+                self.with_parent(coroutine_def, |this| this.visit_expr(body));
             }
             _ => visit::walk_fn(self, fn_kind),
         }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 662b772413b..58834d0a2b3 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -894,7 +894,7 @@ pub(crate) struct LendingIteratorReportError {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_anonymous_livetime_non_gat_report_error)]
+#[diag(resolve_anonymous_lifetime_non_gat_report_error)]
 pub(crate) struct AnonymousLivetimeNonGatReportError {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 149c639efab..87f8e51f282 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -445,7 +445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
                     }
                     Scope::DeriveHelpersCompat => {
-                        // FIXME: Try running this logic eariler, to allocate name bindings for
+                        // FIXME: Try running this logic earlier, to allocate name bindings for
                         // legacy derive helpers when creating an attribute invocation with
                         // following derives. Legacy derive helpers are not common, so it shouldn't
                         // affect performance. It should also allow to remove the `derives`
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index a0386ddcbb3..79c42456cf8 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -133,7 +133,7 @@ pub(crate) enum NoConstantGenericsReason {
     /// Const arguments are only allowed to use generic parameters when:
     /// - `feature(generic_const_exprs)` is enabled
     /// or
-    /// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()`
+    /// - the const argument is a sole const generic parameter, i.e. `foo::<{ N }>()`
     ///
     /// If neither of the above are true then this is used as the cause.
     NonTrivialConstArg,
@@ -4486,7 +4486,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
     /// There are a few places that we need to resolve an anon const but we did not parse an
     /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
-    /// const arguments that were parsed as type arguments, and `legact_const_generics` which
+    /// const arguments that were parsed as type arguments, and `legacy_const_generics` which
     /// parse as normal function argument expressions. To avoid duplicating the code for resolving
     /// an anon const we have this function which lets the caller manually call `resolve_expr` or
     /// `smart_resolve_path`.
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index de4fc5c27d4..976c4acb212 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -417,7 +417,7 @@ pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Box<s
     parse_links(&doc)
 }
 
-/// Similiar version of `markdown_links` from rustdoc.
+/// Similar version of `markdown_links` from rustdoc.
 /// This will collect destination links and display text if exists.
 fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
     let mut broken_link_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index a4e4f50e8f2..45057a3530c 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -26,11 +26,11 @@ use crate::cfi::typeid::itanium_cxx_abi::transform::{TransformTy, TransformTyOpt
 use crate::cfi::typeid::TypeIdOptions;
 
 /// Options for encode_ty.
-pub type EncodeTyOptions = TypeIdOptions;
+pub(crate) type EncodeTyOptions = TypeIdOptions;
 
 /// Substitution dictionary key.
 #[derive(Eq, Hash, PartialEq)]
-pub enum DictKey<'tcx> {
+pub(crate) enum DictKey<'tcx> {
     Ty(Ty<'tcx>, TyQ),
     Region(Region<'tcx>),
     Const(Const<'tcx>),
@@ -39,7 +39,7 @@ pub enum DictKey<'tcx> {
 
 /// Type and extended type qualifiers.
 #[derive(Eq, Hash, PartialEq)]
-pub enum TyQ {
+pub(crate) enum TyQ {
     None,
     Const,
     Mut,
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 2f43199796c..34763adde4f 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -23,16 +23,16 @@ use crate::cfi::typeid::itanium_cxx_abi::encode::EncodeTyOptions;
 use crate::cfi::typeid::TypeIdOptions;
 
 /// Options for transform_ty.
-pub type TransformTyOptions = TypeIdOptions;
+pub(crate) type TransformTyOptions = TypeIdOptions;
 
-pub struct TransformTy<'tcx> {
+pub(crate) struct TransformTy<'tcx> {
     tcx: TyCtxt<'tcx>,
     options: TransformTyOptions,
     parents: Vec<Ty<'tcx>>,
 }
 
 impl<'tcx> TransformTy<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, options: TransformTyOptions) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, options: TransformTyOptions) -> Self {
         TransformTy { tcx, options, parents: Vec::new() }
     }
 }
@@ -262,7 +262,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
 /// mangling.
 ///
 /// typeid_for_instance is called at two locations, initially when declaring/defining functions and
-/// methods, and later during code generation at call sites, after type erasure might have ocurred.
+/// methods, and later during code generation at call sites, after type erasure might have occurred.
 ///
 /// In the first call (i.e., when declaring/defining functions and methods), it encodes type ids for
 /// an FnAbi or Instance, and these type ids are attached to functions and methods. (These type ids
@@ -270,7 +270,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
 /// these type ids.)
 ///
 /// In the second call (i.e., during code generation at call sites), it encodes a type id for an
-/// FnAbi or Instance, after type erasure might have occured, and this type id is used for testing
+/// FnAbi or Instance, after type erasure might have occurred, and this type id is used for testing
 /// if a function is member of the group derived from this type id. Therefore, in the first call to
 /// typeid_for_fnabi (when type ids are attached to functions and methods), it can only include at
 /// most as much information that would be available in the second call (i.e., during code
@@ -365,7 +365,7 @@ pub fn transform_instance<'tcx>(
         // of the trait that defines the method.
         if let Some((trait_ref, method_id, ancestor)) = implemented_method(tcx, instance) {
             // Trait methods will have a Self polymorphic parameter, where the concreteized
-            // implementatation will not. We need to walk back to the more general trait method
+            // implementation will not. We need to walk back to the more general trait method
             let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
                 instance.args,
                 ty::ParamEnv::reveal_all(),
diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs
index e4792563e71..55be931bcd6 100644
--- a/compiler/rustc_sanitizers/src/lib.rs
+++ b/compiler/rustc_sanitizers/src/lib.rs
@@ -5,6 +5,7 @@
 
 // tidy-alphabetical-start
 #![feature(let_chains)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod cfi;
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index f0e1630c650..b7977a848ce 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -16,6 +16,7 @@
 #![feature(never_type)]
 #![feature(ptr_sub_ptr)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index d8609ccfe42..c7c561156e3 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -159,7 +159,7 @@ impl FileEncoder {
         // We produce a post-mono error if N > BUF_SIZE.
         let buf = unsafe { self.buffer_empty().first_chunk_mut::<N>().unwrap_unchecked() };
         let written = visitor(buf);
-        // We have to ensure that an errant visitor cannot cause self.buffered to exeed BUF_SIZE.
+        // We have to ensure that an errant visitor cannot cause self.buffered to exceed BUF_SIZE.
         if written > N {
             Self::panic_invalid_write::<N>(written);
         }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 945bab6887e..908d50a041e 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -251,7 +251,7 @@ pub struct LinkSelfContained {
     pub explicitly_set: Option<bool>,
 
     /// The components that are enabled on the CLI, using the `+component` syntax or one of the
-    /// `true` shorcuts.
+    /// `true` shortcuts.
     enabled_components: LinkSelfContainedComponents,
 
     /// The components that are disabled on the CLI, using the `-component` syntax or one of the
@@ -313,13 +313,13 @@ impl LinkSelfContained {
     }
 
     /// Returns whether the self-contained linker component was enabled on the CLI, using the
-    /// `-C link-self-contained=+linker` syntax, or one of the `true` shorcuts.
+    /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts.
     pub fn is_linker_enabled(&self) -> bool {
         self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
     }
 
     /// Returns whether the self-contained linker component was disabled on the CLI, using the
-    /// `-C link-self-contained=-linker` syntax, or one of the `false` shorcuts.
+    /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts.
     pub fn is_linker_disabled(&self) -> bool {
         self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
     }
@@ -360,7 +360,7 @@ impl LinkerFeaturesCli {
         // Duplicate flags are reduced as we go, the last occurrence wins:
         // `+feature,-feature,+feature` only enables the feature, and does not record it as both
         // enabled and disabled on the CLI.
-        // We also only expose `+/-lld` at the moment, as it's currenty the only implemented linker
+        // We also only expose `+/-lld` at the moment, as it's currently the only implemented linker
         // feature and toggling `LinkerFeatures::CC` would be a noop.
         match feature {
             "+lld" => {
@@ -1102,7 +1102,7 @@ bitflags::bitflags! {
         const MACRO = 1 << 0;
         /// Apply remappings to printed compiler diagnostics
         const DIAGNOSTICS = 1 << 1;
-        /// Apply remappings to debug informations
+        /// Apply remappings to debug information
         const DEBUGINFO = 1 << 3;
 
         /// An alias for `macro` and `debuginfo`. This ensures all paths in compiled
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index d93b3eac080..7e059a88c27 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -5,6 +5,7 @@
 #![feature(map_many_mut)]
 #![feature(option_get_or_insert_default)]
 #![feature(rustc_attrs)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod errors;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 37077901e0c..45339c23ea3 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -358,94 +358,98 @@ fn build_options<O: Default>(
 
 #[allow(non_upper_case_globals)]
 mod desc {
-    pub const parse_no_flag: &str = "no value";
-    pub const parse_bool: &str = "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`";
-    pub const parse_opt_bool: &str = parse_bool;
-    pub const parse_string: &str = "a string";
-    pub const parse_opt_string: &str = parse_string;
-    pub const parse_string_push: &str = parse_string;
-    pub const parse_opt_langid: &str = "a language identifier";
-    pub const parse_opt_pathbuf: &str = "a path";
-    pub const parse_list: &str = "a space-separated list of strings";
-    pub const parse_list_with_polarity: &str =
+    pub(crate) const parse_no_flag: &str = "no value";
+    pub(crate) const parse_bool: &str =
+        "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`";
+    pub(crate) const parse_opt_bool: &str = parse_bool;
+    pub(crate) const parse_string: &str = "a string";
+    pub(crate) const parse_opt_string: &str = parse_string;
+    pub(crate) const parse_string_push: &str = parse_string;
+    pub(crate) const parse_opt_langid: &str = "a language identifier";
+    pub(crate) const parse_opt_pathbuf: &str = "a path";
+    pub(crate) const parse_list: &str = "a space-separated list of strings";
+    pub(crate) const parse_list_with_polarity: &str =
         "a comma-separated list of strings, with elements beginning with + or -";
-    pub const parse_comma_list: &str = "a comma-separated list of strings";
-    pub const parse_opt_comma_list: &str = parse_comma_list;
-    pub const parse_number: &str = "a number";
-    pub const parse_opt_number: &str = parse_number;
-    pub const parse_frame_pointer: &str = "one of `true`/`yes`/`on`, `false`/`no`/`off`, or (with -Zunstable-options) `non-leaf` or `always`";
-    pub const parse_threads: &str = parse_number;
-    pub const parse_time_passes_format: &str = "`text` (default) or `json`";
-    pub const parse_passes: &str = "a space-separated list of passes, or `all`";
-    pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
-    pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
-    pub const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)";
-    pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
-    pub const parse_oom_strategy: &str = "either `panic` or `abort`";
-    pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
-    pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`";
-    pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
-    pub const parse_cfguard: &str =
+    pub(crate) const parse_comma_list: &str = "a comma-separated list of strings";
+    pub(crate) const parse_opt_comma_list: &str = parse_comma_list;
+    pub(crate) const parse_number: &str = "a number";
+    pub(crate) const parse_opt_number: &str = parse_number;
+    pub(crate) const parse_frame_pointer: &str = "one of `true`/`yes`/`on`, `false`/`no`/`off`, or (with -Zunstable-options) `non-leaf` or `always`";
+    pub(crate) const parse_threads: &str = parse_number;
+    pub(crate) const parse_time_passes_format: &str = "`text` (default) or `json`";
+    pub(crate) const parse_passes: &str = "a space-separated list of passes, or `all`";
+    pub(crate) const parse_panic_strategy: &str = "either `unwind` or `abort`";
+    pub(crate) const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
+    pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)";
+    pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
+    pub(crate) const parse_oom_strategy: &str = "either `panic` or `abort`";
+    pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
+    pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`";
+    pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
+    pub(crate) const parse_cfguard: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
-    pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
-    pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
-    pub const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`";
-    pub const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
-    pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
-    pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
-    pub const parse_optimization_fuel: &str = "crate=integer";
-    pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
-    pub const parse_instrument_coverage: &str = parse_bool;
-    pub const parse_coverage_options: &str =
+    pub(crate) const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
+    pub(crate) const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
+    pub(crate) const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`";
+    pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
+    pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
+    pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
+    pub(crate) const parse_optimization_fuel: &str = "crate=integer";
+    pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
+    pub(crate) const parse_instrument_coverage: &str = parse_bool;
+    pub(crate) const parse_coverage_options: &str =
         "`block` | `branch` | `condition` | `mcdc` | `no-mir-spans`";
-    pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
-    pub const parse_unpretty: &str = "`string` or `string=string`";
-    pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
-    pub const parse_next_solver_config: &str =
+    pub(crate) const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
+    pub(crate) const parse_unpretty: &str = "`string` or `string=string`";
+    pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
+    pub(crate) const parse_next_solver_config: &str =
         "a comma separated list of solver configurations: `globally` (default), and `coherence`";
-    pub const parse_lto: &str =
+    pub(crate) const parse_lto: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
-    pub const parse_linker_plugin_lto: &str =
+    pub(crate) const parse_linker_plugin_lto: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin";
-    pub const parse_location_detail: &str = "either `none`, or a comma separated list of location details to track: `file`, `line`, or `column`";
-    pub const parse_fmt_debug: &str = "either `full`, `shallow`, or `none`";
-    pub const parse_switch_with_opt_path: &str =
+    pub(crate) const parse_location_detail: &str = "either `none`, or a comma separated list of location details to track: `file`, `line`, or `column`";
+    pub(crate) const parse_fmt_debug: &str = "either `full`, `shallow`, or `none`";
+    pub(crate) const parse_switch_with_opt_path: &str =
         "an optional path to the profiling data output directory";
-    pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
-    pub const parse_symbol_mangling_version: &str =
+    pub(crate) const parse_merge_functions: &str =
+        "one of: `disabled`, `trampolines`, or `aliases`";
+    pub(crate) const parse_symbol_mangling_version: &str =
         "one of: `legacy`, `v0` (RFC 2603), or `hashed`";
-    pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
-    pub const parse_relocation_model: &str =
+    pub(crate) const parse_src_file_hash: &str = "either `md5` or `sha1`";
+    pub(crate) const parse_relocation_model: &str =
         "one of supported relocation models (`rustc --print relocation-models`)";
-    pub const parse_code_model: &str = "one of supported code models (`rustc --print code-models`)";
-    pub const parse_tls_model: &str = "one of supported TLS models (`rustc --print tls-models`)";
-    pub const parse_target_feature: &str = parse_string;
-    pub const parse_terminal_url: &str =
+    pub(crate) const parse_code_model: &str =
+        "one of supported code models (`rustc --print code-models`)";
+    pub(crate) const parse_tls_model: &str =
+        "one of supported TLS models (`rustc --print tls-models`)";
+    pub(crate) const parse_target_feature: &str = parse_string;
+    pub(crate) const parse_terminal_url: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), or `auto`";
-    pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
-    pub const parse_split_debuginfo: &str =
+    pub(crate) const parse_wasi_exec_model: &str = "either `command` or `reactor`";
+    pub(crate) const parse_split_debuginfo: &str =
         "one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
-    pub const parse_split_dwarf_kind: &str =
+    pub(crate) const parse_split_dwarf_kind: &str =
         "one of supported split dwarf modes (`split` or `single`)";
-    pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
+    pub(crate) const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
         components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
-    pub const parse_linker_features: &str =
+    pub(crate) const parse_linker_features: &str =
         "a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
-    pub const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
-    pub const parse_stack_protector: &str =
+    pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
+    pub(crate) const parse_stack_protector: &str =
         "one of (`none` (default), `basic`, `strong`, or `all`)";
-    pub const parse_branch_protection: &str =
+    pub(crate) const parse_branch_protection: &str =
         "a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
-    pub const parse_proc_macro_execution_strategy: &str =
+    pub(crate) const parse_proc_macro_execution_strategy: &str =
         "one of supported execution strategies (`same-thread`, or `cross-thread`)";
-    pub const parse_remap_path_scope: &str =
+    pub(crate) const parse_remap_path_scope: &str =
         "comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`";
-    pub const parse_inlining_threshold: &str =
+    pub(crate) const parse_inlining_threshold: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
-    pub const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
-    pub const parse_function_return: &str = "`keep` or `thunk-extern`";
-    pub const parse_wasm_c_abi: &str = "`legacy` or `spec`";
-    pub const parse_mir_include_spans: &str =
+    pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
+    pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`";
+    pub(crate) const parse_wasm_c_abi: &str = "`legacy` or `spec`";
+    pub(crate) const parse_mir_include_spans: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
 }
 
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 9f888875306..2215e2f01ad 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -15,6 +15,7 @@
 )]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod rustc_internal;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index e997ea25ec8..a3aa589cb64 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -397,7 +397,7 @@ macro_rules! run_driver {
     }};
 }
 
-/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
+/// Similar to rustc's `FxIndexMap`, `IndexMap` with extra
 /// safety features added.
 pub struct IndexMap<K, V> {
     index_map: fx::FxIndexMap<K, V>,
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
index 677b4c7a9c0..11fbc005e37 100644
--- a/compiler/rustc_smir/src/rustc_smir/alloc.rs
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -20,7 +20,7 @@ fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
 // because we need to get `Ty` of the const we are trying to create, to do that
 // we need to have access to `ConstantKind` but we can't access that inside Stable impl.
 #[allow(rustc::usage_of_qualified_ty)]
-pub fn new_allocation<'tcx>(
+pub(crate) fn new_allocation<'tcx>(
     ty: rustc_middle::ty::Ty<'tcx>,
     const_value: ConstValue<'tcx>,
     tables: &mut Tables<'tcx>,
@@ -30,7 +30,7 @@ pub fn new_allocation<'tcx>(
 }
 
 #[allow(rustc::usage_of_qualified_ty)]
-pub fn try_new_allocation<'tcx>(
+pub(crate) fn try_new_allocation<'tcx>(
     ty: rustc_middle::ty::Ty<'tcx>,
     const_value: ConstValue<'tcx>,
     tables: &mut Tables<'tcx>,
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 883ab7c18b4..cd91fc26c10 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -12,13 +12,13 @@ use rustc_middle::ty::{self, TyCtxt};
 use crate::rustc_smir::{Stable, Tables};
 
 /// Builds a monomorphic body for a given instance.
-pub struct BodyBuilder<'tcx> {
+pub(crate) struct BodyBuilder<'tcx> {
     tcx: TyCtxt<'tcx>,
     instance: ty::Instance<'tcx>,
 }
 
 impl<'tcx> BodyBuilder<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
         let instance = match instance.def {
             // To get the fallback body of an intrinsic, we need to convert it to an item.
             ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
@@ -30,7 +30,7 @@ impl<'tcx> BodyBuilder<'tcx> {
     /// Build a stable monomorphic body for a given instance based on the MIR body.
     ///
     /// All constants are also evaluated.
-    pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
+    pub(crate) fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
         let body = tables.tcx.instance_mir(self.instance.def).clone();
         let mono_body = if !self.instance.args.is_empty()
             // Without the `generic_const_exprs` feature gate, anon consts in signatures do not
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index f9663f2dd30..a4ede374a19 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -784,7 +784,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     }
 }
 
-pub struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
+pub(crate) struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
 
 /// Implement error handling for extracting function ABI information.
 impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
index 50687935473..c9795fca399 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs
@@ -9,7 +9,7 @@ mod error;
 mod mir;
 mod ty;
 
-pub use ty::mir_const_from_ty_const;
+pub(crate) use ty::mir_const_from_ty_const;
 
 impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
     type T = stable_mir::mir::Safety;
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 9afd732486c..efbb0f244fc 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -411,7 +411,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
     }
 }
 
-pub fn mir_const_from_ty_const<'tcx>(
+pub(crate) fn mir_const_from_ty_const<'tcx>(
     tables: &mut Tables<'tcx>,
     ty_const: ty::Const<'tcx>,
     ty: Ty<'tcx>,
diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index ba7e0cec5bd..28ce883daee 100644
--- a/compiler/rustc_span/src/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
@@ -8,7 +8,7 @@ mod tests;
 ///
 /// This function will use an SSE2 enhanced implementation if hardware support
 /// is detected at runtime.
-pub fn analyze_source_file(src: &str) -> (Vec<RelativeBytePos>, Vec<MultiByteChar>) {
+pub(crate) fn analyze_source_file(src: &str) -> (Vec<RelativeBytePos>, Vec<MultiByteChar>) {
     let mut lines = vec![RelativeBytePos::from_u32(0)];
     let mut multi_byte_chars = vec![];
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 5e1b1b44bc2..463e0dbc30c 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1358,7 +1358,7 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
         let mut inner = context.inner.lock();
 
         if let Some(ctxt) = inner.remapped_ctxts.get(raw_id as usize).copied().flatten() {
-            // This has already beeen decoded.
+            // This has already been decoded.
             return ctxt;
         }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 7b020f11cdd..c7bd7321f0c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -30,6 +30,7 @@
 #![feature(round_char_boundary)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // The code produced by the `Encodable`/`Decodable` derive macros refer to
@@ -271,7 +272,7 @@ impl RealFileName {
         }
     }
 
-    /// Return the path remmapped or not depending on the [`FileNameDisplayPreference`].
+    /// Return the path remapped or not depending on the [`FileNameDisplayPreference`].
     ///
     /// For the purpose of this function, local and short preference are equal.
     pub fn to_path(&self, display_pref: FileNameDisplayPreference) -> &Path {
@@ -1683,7 +1684,7 @@ impl fmt::Debug for SourceFile {
 /// is because SourceFiles for the local crate are allocated very early in the
 /// compilation process when the `StableCrateId` is not yet known. If, due to
 /// some refactoring of the compiler, the `StableCrateId` of the local crate
-/// were to become available, it would be better to uniformely make this a
+/// were to become available, it would be better to uniformly make this a
 /// hash of `(filename, stable_crate_id)`.
 ///
 /// When `SourceFile`s are exported in crate metadata, the `StableSourceFileId`
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index 8988becb171..3047abfbb5c 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -424,7 +424,7 @@ impl Span {
 }
 
 #[derive(Default)]
-pub struct SpanInterner {
+pub(crate) struct SpanInterner {
     spans: FxIndexSet<SpanData>,
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 34765209605..36b31d10c4d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -407,6 +407,7 @@ symbols! {
         append_const_msg,
         arbitrary_enum_discriminant,
         arbitrary_self_types,
+        arbitrary_self_types_pointers,
         args,
         arith_offset,
         arm,
diff --git a/compiler/rustc_symbol_mangling/src/hashed.rs b/compiler/rustc_symbol_mangling/src/hashed.rs
index 8e2f94991cf..07c5f544792 100644
--- a/compiler/rustc_symbol_mangling/src/hashed.rs
+++ b/compiler/rustc_symbol_mangling/src/hashed.rs
@@ -14,7 +14,7 @@ pub(super) fn mangle<'tcx>(
 ) -> String {
     // The symbol of a generic function may be scattered in multiple downstream dylibs.
     // If the symbol of a generic function still contains `crate name`, hash conflicts between the
-    // generic funcion and other symbols of the same `crate` cannot be detected in time during
+    // generic function and other symbols of the same `crate` cannot be detected in time during
     // construction. This symbol conflict is left over until it occurs during run time.
     // In this case, `instantiating-crate name` is used to replace `crate name` can completely
     // eliminate the risk of the preceding potential hash conflict.
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index dea4eb08c76..0c97cda81c8 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -93,6 +93,7 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_hir::def::DefKind;
diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs
index 04020d13f22..55b65fb1caa 100644
--- a/compiler/rustc_target/src/abi/call/aarch64.rs
+++ b/compiler/rustc_target/src/abi/call/aarch64.rs
@@ -6,7 +6,7 @@ use crate::abi::{HasDataLayout, TyAbiInterface};
 ///
 /// Corresponds to Clang's `AArch64ABIInfo::ABIKind`.
 #[derive(Copy, Clone, PartialEq)]
-pub enum AbiKind {
+pub(crate) enum AbiKind {
     AAPCS,
     DarwinPCS,
     Win64,
@@ -109,7 +109,7 @@ where
     arg.make_indirect();
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, kind: AbiKind)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, kind: AbiKind)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
diff --git a/compiler/rustc_target/src/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs
index e30dead63cb..3007a729a8b 100644
--- a/compiler/rustc_target/src/abi/call/amdgpu.rs
+++ b/compiler/rustc_target/src/abi/call/amdgpu.rs
@@ -17,7 +17,7 @@ where
     arg.extend_integer_width_to(32);
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs
index 9371e1b3958..bd6f781fb81 100644
--- a/compiler/rustc_target/src/abi/call/arm.rs
+++ b/compiler/rustc_target/src/abi/call/arm.rs
@@ -81,7 +81,7 @@ where
     arg.cast_to(Uniform::consecutive(if align <= 4 { Reg::i32() } else { Reg::i64() }, total));
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/avr.rs b/compiler/rustc_target/src/abi/call/avr.rs
index b01dac8c70d..dfc991e0954 100644
--- a/compiler/rustc_target/src/abi/call/avr.rs
+++ b/compiler/rustc_target/src/abi/call/avr.rs
@@ -44,7 +44,7 @@ fn classify_arg_ty<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fty: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fty: &mut FnAbi<'_, Ty>) {
     if !fty.ret.is_ignore() {
         classify_ret_ty(&mut fty.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/bpf.rs b/compiler/rustc_target/src/abi/call/bpf.rs
index 780e7df4383..f19772ac709 100644
--- a/compiler/rustc_target/src/abi/call/bpf.rs
+++ b/compiler/rustc_target/src/abi/call/bpf.rs
@@ -17,7 +17,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs
index 7951f28beea..b1c1ae814a7 100644
--- a/compiler/rustc_target/src/abi/call/csky.rs
+++ b/compiler/rustc_target/src/abi/call/csky.rs
@@ -47,7 +47,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/hexagon.rs b/compiler/rustc_target/src/abi/call/hexagon.rs
index 80a442048d5..0a0688880c0 100644
--- a/compiler/rustc_target/src/abi/call/hexagon.rs
+++ b/compiler/rustc_target/src/abi/call/hexagon.rs
@@ -16,7 +16,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs
index 893818af77c..4a21935623b 100644
--- a/compiler/rustc_target/src/abi/call/loongarch.rs
+++ b/compiler/rustc_target/src/abi/call/loongarch.rs
@@ -325,7 +325,7 @@ fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
     arg.extend_integer_width_to(xlen);
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/m68k.rs b/compiler/rustc_target/src/abi/call/m68k.rs
index 06697bdd83e..b6bd68b66fc 100644
--- a/compiler/rustc_target/src/abi/call/m68k.rs
+++ b/compiler/rustc_target/src/abi/call/m68k.rs
@@ -20,7 +20,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs
index 0e5a7f37a09..37980a91c76 100644
--- a/compiler/rustc_target/src/abi/call/mips.rs
+++ b/compiler/rustc_target/src/abi/call/mips.rs
@@ -35,7 +35,7 @@ where
     *offset = offset.align_to(align) + size.align_to(align);
 }
 
-pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
+pub(crate) fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
 where
     C: HasDataLayout,
 {
diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs
index 5b52ebbdedd..2c3258c8d42 100644
--- a/compiler/rustc_target/src/abi/call/mips64.rs
+++ b/compiler/rustc_target/src/abi/call/mips64.rs
@@ -149,7 +149,7 @@ where
     });
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
diff --git a/compiler/rustc_target/src/abi/call/msp430.rs b/compiler/rustc_target/src/abi/call/msp430.rs
index 33ef47be009..4f613aa6c15 100644
--- a/compiler/rustc_target/src/abi/call/msp430.rs
+++ b/compiler/rustc_target/src/abi/call/msp430.rs
@@ -25,7 +25,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs
index 27d197af792..2e8b16d3a93 100644
--- a/compiler/rustc_target/src/abi/call/nvptx64.rs
+++ b/compiler/rustc_target/src/abi/call/nvptx64.rs
@@ -71,7 +71,7 @@ where
     }
 }
 
-pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
@@ -84,7 +84,7 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
diff --git a/compiler/rustc_target/src/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs
index 8f67f57cd2b..f3b05c48173 100644
--- a/compiler/rustc_target/src/abi/call/powerpc.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc.rs
@@ -27,7 +27,7 @@ fn classify_arg<Ty>(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) {
     }
 }
 
-pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs
index 749eea0ef63..b9767bf906b 100644
--- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -86,7 +86,7 @@ where
     };
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index 84f13f8cc5d..be6bc701b49 100644
--- a/compiler/rustc_target/src/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
@@ -331,7 +331,7 @@ fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
     arg.extend_integer_width_to(xlen);
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs
index 901ce139c7b..502e7331267 100644
--- a/compiler/rustc_target/src/abi/call/s390x.rs
+++ b/compiler/rustc_target/src/abi/call/s390x.rs
@@ -54,7 +54,7 @@ where
     }
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs
index 0e5a7f37a09..37980a91c76 100644
--- a/compiler/rustc_target/src/abi/call/sparc.rs
+++ b/compiler/rustc_target/src/abi/call/sparc.rs
@@ -35,7 +35,7 @@ where
     *offset = offset.align_to(align) + size.align_to(align);
 }
 
-pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
+pub(crate) fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
 where
     C: HasDataLayout,
 {
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index 311691d8efb..2954d9642df 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -7,7 +7,7 @@ use crate::abi::{self, HasDataLayout, Scalar, Size, TyAbiInterface, TyAndLayout}
 use crate::spec::HasTargetSpec;
 
 #[derive(Clone, Debug)]
-pub struct Sdata {
+struct Sdata {
     pub prefix: [Option<Reg>; 8],
     pub prefix_index: usize,
     pub last_offset: Size,
@@ -209,7 +209,7 @@ where
     arg.cast_to(Uniform::new(Reg::i64(), total));
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs
index a773fb1e814..4ae8b9490dd 100644
--- a/compiler/rustc_target/src/abi/call/wasm.rs
+++ b/compiler/rustc_target/src/abi/call/wasm.rs
@@ -45,7 +45,7 @@ where
 }
 
 /// The purpose of this ABI is to match the C ABI (aka clang) exactly.
-pub fn compute_c_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_c_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
@@ -69,7 +69,7 @@ where
 /// This ABI is *bad*! It uses `PassMode::Direct` for `abi::Aggregate` types, which leaks LLVM
 /// implementation details into the ABI. It's just hard to fix because ABIs are hard to change.
 /// Also see <https://github.com/rust-lang/rust/issues/115666>.
-pub fn compute_wasm_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_wasm_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
         classify_ret_wasm_abi(&mut fn_abi.ret);
     }
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index e9aedc3d28a..bdb14350ded 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -3,12 +3,12 @@ use crate::abi::{Abi, Align, HasDataLayout, TyAbiInterface, TyAndLayout};
 use crate::spec::HasTargetSpec;
 
 #[derive(PartialEq)]
-pub enum Flavor {
+pub(crate) enum Flavor {
     General,
     FastcallOrVectorcall,
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index fcd712489fa..1209204debf 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -170,7 +170,7 @@ fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
 const MAX_INT_REGS: usize = 6; // RDI, RSI, RDX, RCX, R8, R9
 const MAX_SSE_REGS: usize = 8; // XMM0-7
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout,
diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs
index 720707ef53f..e5a20b248e4 100644
--- a/compiler/rustc_target/src/abi/call/x86_win64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_win64.rs
@@ -4,7 +4,7 @@ use crate::spec::HasTargetSpec;
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
 
-pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     let fixup = |a: &mut ArgAbi<'_, Ty>| {
         match a.layout.abi {
             Abi::Uninhabited | Abi::Aggregate { sized: false } => {}
diff --git a/compiler/rustc_target/src/abi/call/xtensa.rs b/compiler/rustc_target/src/abi/call/xtensa.rs
index addbe698925..cb61bf2c56b 100644
--- a/compiler/rustc_target/src/abi/call/xtensa.rs
+++ b/compiler/rustc_target/src/abi/call/xtensa.rs
@@ -26,7 +26,7 @@ where
     // so defer to `classify_arg_ty`.
     let mut arg_gprs_left = NUM_RET_GPRS;
     classify_arg_ty(arg, &mut arg_gprs_left, MAX_RET_IN_REGS_SIZE);
-    // Ret args cannot be passed via stack, we lower to indirect and let the backend handle the invisble reference
+    // Ret args cannot be passed via stack, we lower to indirect and let the backend handle the invisible reference
     match arg.mode {
         super::PassMode::Indirect { attrs: _, meta_attrs: _, ref mut on_stack } => {
             *on_stack = false;
@@ -96,7 +96,7 @@ where
     }
 }
 
-pub fn compute_abi_info<'a, Ty, C>(_cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
+pub(crate) fn compute_abi_info<'a, Ty, C>(_cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
 where
     Ty: TyAbiInterface<'a, C> + Copy,
     C: HasDataLayout + HasTargetSpec,
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index daf5162e8ac..74970a26b23 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -70,7 +70,7 @@ impl AArch64InlineAsmRegClass {
     }
 }
 
-pub fn target_reserves_x18(target: &Target) -> bool {
+pub(crate) fn target_reserves_x18(target: &Target) -> bool {
     target.os == "android" || target.os == "fuchsia" || target.is_like_osx || target.is_like_windows
 }
 
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index b2116c51216..d7c66d6f5e3 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -17,6 +17,7 @@
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs
index c71c4ba2cc9..e7e9ec663c4 100644
--- a/compiler/rustc_target/src/spec/base/aix.rs
+++ b/compiler/rustc_target/src/spec/base/aix.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{crt_objects, cvs, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         abi: "vec-extabi".into(),
         code_model: Some(CodeModel::Small),
diff --git a/compiler/rustc_target/src/spec/base/android.rs b/compiler/rustc_target/src/spec/base/android.rs
index 5320f1b4bbb..dfa0e3fe989 100644
--- a/compiler/rustc_target/src/spec/base/android.rs
+++ b/compiler/rustc_target/src/spec/base/android.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, TargetOptions, TlsModel};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut base = base::linux::opts();
     base.os = "android".into();
     base.is_like_android = true;
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index 39d7cf7d097..b752a344395 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -12,7 +12,7 @@ mod tests;
 use Arch::*;
 #[allow(non_camel_case_types)]
 #[derive(Copy, Clone, PartialEq)]
-pub enum Arch {
+pub(crate) enum Arch {
     Armv7k,
     Armv7s,
     Arm64,
@@ -25,7 +25,7 @@ pub enum Arch {
 }
 
 impl Arch {
-    pub fn target_name(self) -> &'static str {
+    fn target_name(self) -> &'static str {
         match self {
             Armv7k => "armv7k",
             Armv7s => "armv7s",
@@ -39,7 +39,7 @@ impl Arch {
         }
     }
 
-    pub fn target_arch(self) -> Cow<'static, str> {
+    pub(crate) fn target_arch(self) -> Cow<'static, str> {
         Cow::Borrowed(match self {
             Armv7k | Armv7s => "arm",
             Arm64 | Arm64e | Arm64_32 => "aarch64",
@@ -80,7 +80,7 @@ impl Arch {
 }
 
 #[derive(Copy, Clone, PartialEq)]
-pub enum TargetAbi {
+pub(crate) enum TargetAbi {
     Normal,
     Simulator,
     MacCatalyst,
@@ -142,7 +142,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
     args
 }
 
-pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
+pub(crate) fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
     TargetOptions {
         abi: abi.target_abi().into(),
         os: os.into(),
@@ -279,7 +279,7 @@ fn macos_deployment_target(arch: Arch) -> (u32, u32) {
         .unwrap_or_else(|| macos_default_deployment_target(arch))
 }
 
-pub fn macos_llvm_target(arch: Arch) -> String {
+pub(crate) fn macos_llvm_target(arch: Arch) -> String {
     let (major, minor) = macos_deployment_target(arch);
     format!("{}-apple-macosx{}.{}.0", arch.target_name(), major, minor)
 }
@@ -333,7 +333,7 @@ fn ios_deployment_target(arch: Arch, abi: &str) -> (u32, u32) {
     from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((major, minor))
 }
 
-pub fn ios_llvm_target(arch: Arch) -> String {
+pub(crate) fn ios_llvm_target(arch: Arch) -> String {
     // Modern iOS tooling extracts information about deployment target
     // from LC_BUILD_VERSION. This load command will only be emitted when
     // we build with a version specific `llvm_target`, with the version
@@ -344,12 +344,12 @@ pub fn ios_llvm_target(arch: Arch) -> String {
     format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor)
 }
 
-pub fn mac_catalyst_llvm_target(arch: Arch) -> String {
+pub(crate) fn mac_catalyst_llvm_target(arch: Arch) -> String {
     let (major, minor) = ios_deployment_target(arch, "macabi");
     format!("{}-apple-ios{}.{}.0-macabi", arch.target_name(), major, minor)
 }
 
-pub fn ios_sim_llvm_target(arch: Arch) -> String {
+pub(crate) fn ios_sim_llvm_target(arch: Arch) -> String {
     let (major, minor) = ios_deployment_target(arch, "sim");
     format!("{}-apple-ios{}.{}.0-simulator", arch.target_name(), major, minor)
 }
@@ -360,12 +360,12 @@ fn tvos_deployment_target() -> (u32, u32) {
     from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
 }
 
-pub fn tvos_llvm_target(arch: Arch) -> String {
+pub(crate) fn tvos_llvm_target(arch: Arch) -> String {
     let (major, minor) = tvos_deployment_target();
     format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor)
 }
 
-pub fn tvos_sim_llvm_target(arch: Arch) -> String {
+pub(crate) fn tvos_sim_llvm_target(arch: Arch) -> String {
     let (major, minor) = tvos_deployment_target();
     format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor)
 }
@@ -376,12 +376,12 @@ fn watchos_deployment_target() -> (u32, u32) {
     from_set_deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
 }
 
-pub fn watchos_llvm_target(arch: Arch) -> String {
+pub(crate) fn watchos_llvm_target(arch: Arch) -> String {
     let (major, minor) = watchos_deployment_target();
     format!("{}-apple-watchos{}.{}.0", arch.target_name(), major, minor)
 }
 
-pub fn watchos_sim_llvm_target(arch: Arch) -> String {
+pub(crate) fn watchos_sim_llvm_target(arch: Arch) -> String {
     let (major, minor) = watchos_deployment_target();
     format!("{}-apple-watchos{}.{}.0-simulator", arch.target_name(), major, minor)
 }
@@ -392,12 +392,12 @@ fn visionos_deployment_target() -> (u32, u32) {
     from_set_deployment_target("XROS_DEPLOYMENT_TARGET").unwrap_or((1, 0))
 }
 
-pub fn visionos_llvm_target(arch: Arch) -> String {
+pub(crate) fn visionos_llvm_target(arch: Arch) -> String {
     let (major, minor) = visionos_deployment_target();
     format!("{}-apple-visionos{}.{}.0", arch.target_name(), major, minor)
 }
 
-pub fn visionos_sim_llvm_target(arch: Arch) -> String {
+pub(crate) fn visionos_sim_llvm_target(arch: Arch) -> String {
     let (major, minor) = visionos_deployment_target();
     format!("{}-apple-visionos{}.{}.0-simulator", arch.target_name(), major, minor)
 }
diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr_gnu.rs
index c3d0344ea6c..dd9fc32b69e 100644
--- a/compiler/rustc_target/src/spec/base/avr_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/avr_gnu.rs
@@ -6,7 +6,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
 ///
 /// Requires GNU avr-gcc and avr-binutils on the host system.
 /// FIXME: Remove the second parameter when const string concatenation is possible.
-pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
+pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target {
     Target {
         arch: "avr".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/base/bpf.rs b/compiler/rustc_target/src/spec/base/bpf.rs
index 4d03747d016..17d5e75ef6d 100644
--- a/compiler/rustc_target/src/spec/base/bpf.rs
+++ b/compiler/rustc_target/src/spec/base/bpf.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, TargetOptions};
 
-pub fn opts(endian: Endian) -> TargetOptions {
+pub(crate) fn opts(endian: Endian) -> TargetOptions {
     TargetOptions {
         allow_asm: true,
         endian,
diff --git a/compiler/rustc_target/src/spec/base/dragonfly.rs b/compiler/rustc_target/src/spec/base/dragonfly.rs
index 3c1846696f7..5da23f2b8fd 100644
--- a/compiler/rustc_target/src/spec/base/dragonfly.rs
+++ b/compiler/rustc_target/src/spec/base/dragonfly.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "dragonfly".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/freebsd.rs b/compiler/rustc_target/src/spec/base/freebsd.rs
index c772754aa8d..a016489e52d 100644
--- a/compiler/rustc_target/src/spec/base/freebsd.rs
+++ b/compiler/rustc_target/src/spec/base/freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "freebsd".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/fuchsia.rs b/compiler/rustc_target/src/spec/base/fuchsia.rs
index d1ac22f3a09..fc3d9f6fb9f 100644
--- a/compiler/rustc_target/src/spec/base/fuchsia.rs
+++ b/compiler/rustc_target/src/spec/base/fuchsia.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     crt_objects, cvs, Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, TargetOptions,
 };
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     // This mirrors the linker options provided by clang. We presume lld for
     // now. When using clang as the linker it will supply these options for us,
     // so we only list them for ld/lld.
diff --git a/compiler/rustc_target/src/spec/base/haiku.rs b/compiler/rustc_target/src/spec/base/haiku.rs
index 8ab874410aa..d90e4c99f93 100644
--- a/compiler/rustc_target/src/spec/base/haiku.rs
+++ b/compiler/rustc_target/src/spec/base/haiku.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "haiku".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/hermit.rs b/compiler/rustc_target/src/spec/base/hermit.rs
index c6e98fc1a11..971abef80d9 100644
--- a/compiler/rustc_target/src/spec/base/hermit.rs
+++ b/compiler/rustc_target/src/spec/base/hermit.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, TargetOptions, TlsModel};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "hermit".into(),
         linker: Some("rust-lld".into()),
diff --git a/compiler/rustc_target/src/spec/base/hurd.rs b/compiler/rustc_target/src/spec/base/hurd.rs
index 76f8223c0e4..d464d50ecc2 100644
--- a/compiler/rustc_target/src/spec/base/hurd.rs
+++ b/compiler/rustc_target/src/spec/base/hurd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "hurd".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/hurd_gnu.rs b/compiler/rustc_target/src/spec/base/hurd_gnu.rs
index 3501dbdea1b..70d423217a6 100644
--- a/compiler/rustc_target/src/spec/base/hurd_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/hurd_gnu.rs
@@ -1,5 +1,5 @@
 use crate::spec::{base, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions { env: "gnu".into(), ..base::hurd::opts() }
 }
diff --git a/compiler/rustc_target/src/spec/base/illumos.rs b/compiler/rustc_target/src/spec/base/illumos.rs
index f0a648b93ad..fa743a0c66d 100644
--- a/compiler/rustc_target/src/spec/base/illumos.rs
+++ b/compiler/rustc_target/src/spec/base/illumos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let late_link_args = TargetOptions::link_args(
         LinkerFlavor::Unix(Cc::Yes),
         &[
diff --git a/compiler/rustc_target/src/spec/base/l4re.rs b/compiler/rustc_target/src/spec/base/l4re.rs
index 3a4d83fad17..dbe9e78a193 100644
--- a/compiler/rustc_target/src/spec/base/l4re.rs
+++ b/compiler/rustc_target/src/spec/base/l4re.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "l4re".into(),
         env: "uclibc".into(),
diff --git a/compiler/rustc_target/src/spec/base/linux.rs b/compiler/rustc_target/src/spec/base/linux.rs
index 34b2eb0f641..2e30364525e 100644
--- a/compiler/rustc_target/src/spec/base/linux.rs
+++ b/compiler/rustc_target/src/spec/base/linux.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{cvs, RelroLevel, SplitDebuginfo, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "linux".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/linux_gnu.rs b/compiler/rustc_target/src/spec/base/linux_gnu.rs
index 3491277c440..1200add4fe1 100644
--- a/compiler/rustc_target/src/spec/base/linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/linux_gnu.rs
@@ -1,5 +1,5 @@
 use crate::spec::{base, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions { env: "gnu".into(), ..base::linux::opts() }
 }
diff --git a/compiler/rustc_target/src/spec/base/linux_musl.rs b/compiler/rustc_target/src/spec/base/linux_musl.rs
index 42aa1e1a6da..a29635112ff 100644
--- a/compiler/rustc_target/src/spec/base/linux_musl.rs
+++ b/compiler/rustc_target/src/spec/base/linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, crt_objects, LinkSelfContainedDefault, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut base = base::linux::opts();
 
     base.env = "musl".into();
diff --git a/compiler/rustc_target/src/spec/base/linux_ohos.rs b/compiler/rustc_target/src/spec/base/linux_ohos.rs
index 8272cda05e7..2372bc2c718 100644
--- a/compiler/rustc_target/src/spec/base/linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/base/linux_ohos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, TargetOptions, TlsModel};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut base = base::linux::opts();
 
     base.env = "ohos".into();
diff --git a/compiler/rustc_target/src/spec/base/linux_uclibc.rs b/compiler/rustc_target/src/spec/base/linux_uclibc.rs
index 540344e9e94..80a6479bb5f 100644
--- a/compiler/rustc_target/src/spec/base/linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/base/linux_uclibc.rs
@@ -1,5 +1,5 @@
 use crate::spec::{base, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions { env: "uclibc".into(), ..base::linux::opts() }
 }
diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs
index 720cf03005a..b0fb2ef4b27 100644
--- a/compiler/rustc_target/src/spec/base/msvc.rs
+++ b/compiler/rustc_target/src/spec/base/msvc.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     // Suppress the verbose logo and authorship debugging output, which would needlessly
     // clog any log files.
     let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]);
diff --git a/compiler/rustc_target/src/spec/base/netbsd.rs b/compiler/rustc_target/src/spec/base/netbsd.rs
index 495e3d10fbc..1ae81eb0633 100644
--- a/compiler/rustc_target/src/spec/base/netbsd.rs
+++ b/compiler/rustc_target/src/spec/base/netbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "netbsd".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/nto_qnx.rs
index f1405e9b446..47177415b39 100644
--- a/compiler/rustc_target/src/spec/base/nto_qnx.rs
+++ b/compiler/rustc_target/src/spec/base/nto_qnx.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         crt_static_respected: true,
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/openbsd.rs b/compiler/rustc_target/src/spec/base/openbsd.rs
index bc3aecb5c1e..942ac4a393c 100644
--- a/compiler/rustc_target/src/spec/base/openbsd.rs
+++ b/compiler/rustc_target/src/spec/base/openbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, FramePointer, RelroLevel, TargetOptions, TlsModel};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "openbsd".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/redox.rs b/compiler/rustc_target/src/spec/base/redox.rs
index 9070791e9df..3f13f1f8841 100644
--- a/compiler/rustc_target/src/spec/base/redox.rs
+++ b/compiler/rustc_target/src/spec/base/redox.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "redox".into(),
         env: "relibc".into(),
diff --git a/compiler/rustc_target/src/spec/base/solaris.rs b/compiler/rustc_target/src/spec/base/solaris.rs
index f97cdb4fb28..1529cd65b28 100644
--- a/compiler/rustc_target/src/spec/base/solaris.rs
+++ b/compiler/rustc_target/src/spec/base/solaris.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "solaris".into(),
         dynamic_linking: true,
diff --git a/compiler/rustc_target/src/spec/base/solid.rs b/compiler/rustc_target/src/spec/base/solid.rs
index ce4a8869001..fd55e1d1501 100644
--- a/compiler/rustc_target/src/spec/base/solid.rs
+++ b/compiler/rustc_target/src/spec/base/solid.rs
@@ -1,6 +1,6 @@
 use crate::spec::{FramePointer, TargetOptions};
 
-pub fn opts(kernel: &str) -> TargetOptions {
+pub(crate) fn opts(kernel: &str) -> TargetOptions {
     TargetOptions {
         os: format!("solid_{kernel}").into(),
         vendor: "kmc".into(),
diff --git a/compiler/rustc_target/src/spec/base/teeos.rs b/compiler/rustc_target/src/spec/base/teeos.rs
index 38d0a6d7314..94eb946dda4 100644
--- a/compiler/rustc_target/src/spec/base/teeos.rs
+++ b/compiler/rustc_target/src/spec/base/teeos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{add_link_args, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
     let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
 
diff --git a/compiler/rustc_target/src/spec/base/thumb.rs b/compiler/rustc_target/src/spec/base/thumb.rs
index 0decfecb4cd..03ec679038c 100644
--- a/compiler/rustc_target/src/spec/base/thumb.rs
+++ b/compiler/rustc_target/src/spec/base/thumb.rs
@@ -29,7 +29,7 @@
 
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     // See rust-lang/rfcs#1645 for a discussion about these defaults
     TargetOptions {
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/base/uefi_msvc.rs b/compiler/rustc_target/src/spec/base/uefi_msvc.rs
index e8acd6078e2..0020106f40e 100644
--- a/compiler/rustc_target/src/spec/base/uefi_msvc.rs
+++ b/compiler/rustc_target/src/spec/base/uefi_msvc.rs
@@ -11,7 +11,7 @@
 
 use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut base = base::msvc::opts();
 
     base.add_pre_link_args(
diff --git a/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs b/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs
index 9ccd0a1e7ca..fd813815724 100644
--- a/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, PanicStrategy, RelocModel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "linux".into(),
         env: "musl".into(),
diff --git a/compiler/rustc_target/src/spec/base/vxworks.rs b/compiler/rustc_target/src/spec/base/vxworks.rs
index aa4784b63e7..425dd3c8cc2 100644
--- a/compiler/rustc_target/src/spec/base/vxworks.rs
+++ b/compiler/rustc_target/src/spec/base/vxworks.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "vxworks".into(),
         env: "gnu".into(),
diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs
index f237391016e..e417137ced1 100644
--- a/compiler/rustc_target/src/spec/base/wasm.rs
+++ b/compiler/rustc_target/src/spec/base/wasm.rs
@@ -3,7 +3,7 @@ use crate::spec::{
     TargetOptions, TlsModel,
 };
 
-pub fn options() -> TargetOptions {
+pub(crate) fn options() -> TargetOptions {
     macro_rules! args {
         ($prefix:literal) => {
             &[
diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs
index 7346e42dd91..1393b159184 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs
@@ -5,7 +5,7 @@ use crate::spec::{
     Lld, SplitDebuginfo, TargetOptions,
 };
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::No, Lld::No),
         &[
diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
index 88c3b8a81ad..9e89a3c75fe 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     // We cannot use `-nodefaultlibs` because compiler-rt has to be passed
     // as a path since it's not added to linker search path by the default.
     // There were attempts to make it behave like libgcc (so one can just use -l<name>)
diff --git a/compiler/rustc_target/src/spec/base/windows_msvc.rs b/compiler/rustc_target/src/spec/base/windows_msvc.rs
index bd0318f3183..e68043ca2ee 100644
--- a/compiler/rustc_target/src/spec/base/windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/base/windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, cvs, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let base = base::msvc::opts();
 
     TargetOptions {
@@ -29,7 +29,7 @@ pub fn opts() -> TargetOptions {
         // they bring in.
         //
         // See also https://learn.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=msvc-170#lib
-        // for documention on including library dependencies in C/C++ code.
+        // for documentation on including library dependencies in C/C++ code.
         no_default_libraries: false,
         has_thread_local: true,
 
diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs
index 17256e18e24..8134b5feade 100644
--- a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs
+++ b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let base = base::windows_gnu::opts();
 
     // FIXME: This should be updated for the exception machinery changes from #67502
diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs
index 59a76167125..f4f71214504 100644
--- a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs
+++ b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, LinkerFlavor, Lld, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     let mut opts = base::windows_msvc::opts();
 
     opts.abi = "uwp".into();
diff --git a/compiler/rustc_target/src/spec/base/xtensa.rs b/compiler/rustc_target/src/spec/base/xtensa.rs
index 31ad09c52e4..280dd16e264 100644
--- a/compiler/rustc_target/src/spec/base/xtensa.rs
+++ b/compiler/rustc_target/src/spec/base/xtensa.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions};
 
-pub fn opts() -> TargetOptions {
+pub(crate) fn opts() -> TargetOptions {
     TargetOptions {
         os: "none".into(),
         endian: Endian::Little,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 37665018219..6abd8a0d6b7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1695,6 +1695,8 @@ supported_targets! {
     ("armv7r-none-eabihf", armv7r_none_eabihf),
     ("armv8r-none-eabihf", armv8r_none_eabihf),
 
+    ("armv7-rtems-eabihf", armv7_rtems_eabihf),
+
     ("x86_64-pc-solaris", x86_64_pc_solaris),
     ("sparcv9-sun-solaris", sparcv9_sun_solaris),
 
@@ -2097,9 +2099,10 @@ pub struct TargetOptions {
     /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults
     /// to "generic".
     pub cpu: StaticCow<str>,
-    /// Default target features to pass to LLVM. These features will *always* be
-    /// passed, and cannot be disabled even via `-C`. Corresponds to `llc
-    /// -mattr=$features`.
+    /// Default target features to pass to LLVM. These features overwrite
+    /// `-Ctarget-cpu` but can be overwritten with `-Ctarget-features`.
+    /// Corresponds to `llc -mattr=$features`.
+    /// Note that these are LLVM feature names, not Rust feature names!
     pub features: StaticCow<str>,
     /// Direct or use GOT indirect to reference external data symbols
     pub direct_access_external_data: Option<bool>,
@@ -2149,7 +2152,7 @@ pub struct TargetOptions {
     pub is_like_aix: bool,
     /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
     /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
-    /// Also indiates whether to use Apple-specific ABI changes, such as extending function
+    /// Also indicates whether to use Apple-specific ABI changes, such as extending function
     /// parameters to 32-bits.
     pub is_like_osx: bool,
     /// Whether the target toolchain is like Solaris's.
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
index 65f2a1e3069..912392c9fef 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("macos", arch, TargetAbi::Normal);
     base.cpu = "apple-m1".into();
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
index 11a39c26e9d..7f3a86f3256 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("ios", arch, TargetAbi::Normal);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
index 32c2367d5bf..e60eeda4295 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
index 703b886cc19..d605e22701a 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("ios", arch, TargetAbi::Simulator);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
index e97ad11cdf6..fc774ab94c8 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     Target {
         llvm_target: tvos_llvm_target(arch).into(),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
index 8bfa9c8e8b7..8e8bb1efc9d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     Target {
         llvm_target: tvos_sim_llvm_target(arch).into(),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
index b0798e5e4f5..16c7d72daed 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("visionos", arch, TargetAbi::Normal);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
index 7b2d2b6a8e4..42973e0268e 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     let mut base = opts("visionos", arch, TargetAbi::Simulator);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
index 6d66299d6d9..03fc2518d1d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = opts("watchos", Arch::Arm64, TargetAbi::Normal);
     Target {
         llvm_target: "aarch64-apple-watchos".into(),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
index 9675a950d5d..13e2b961794 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64;
     Target {
         // Clang automatically chooses a more specific target based on
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
index df389fe34bd..5b8efd66262 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64_be-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
index 10a8e3e4df8..c14fa20b697 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.max_atomic_width = Some(128);
 
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
index ba646cd6065..fe4dadfe838 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64_be-unknown-netbsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs
index 3668db912bb..144ac85622e 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_fuchsia.rs
@@ -1 +1 @@
-pub use crate::spec::targets::aarch64_unknown_fuchsia::target;
+pub(crate) use crate::spec::targets::aarch64_unknown_fuchsia::target;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
index 1c2273bb3a1..1d054dad568 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, RelocModel, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = base::solid::opts("asp3");
     Target {
         llvm_target: "aarch64-unknown-none".into(),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
index 3f0072c00c1..ff0a0762e3c 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a
 // for target ABI requirements.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-linux-android".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
index 1ba4fbb3d25..d6d49a4a070 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs
@@ -5,7 +5,7 @@ use crate::spec::{
 const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld");
 
 /// A base target for Nintendo Switch devices using a pure LLVM toolchain.
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-none".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs
index 070460538c7..9d10358a49f 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_gnullvm::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index f4e2ee44805..c3bd2ea6c33 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
index b10f1c7592e..b993275ff83 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-freebsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
index f84853fbb19..b462739e561 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-fuchsia".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
index 55cb0b8f2ee..e9da6a8f3ce 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-hermit".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs
index 7f05358e016..bed9c88fd67 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::illumos::opts();
     base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-std=c99"]);
     base.max_atomic_width = Some(128);
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
index 1a45c2c5c05..56709f788d3 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
index 851366b7647..71b331972cc 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-linux-gnu_ilp32".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
index 6b4a422a474..1cf71b65040 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.max_atomic_width = Some(128);
     base.supports_xray = true;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
index 726a85c81f3..0dbf4cb7a70 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_ohos::opts();
     base.max_atomic_width = Some(128);
 
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
index 0069d5431f8..e25beec0a13 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-netbsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
index 169468f2e24..54a08853c28 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs
@@ -11,7 +11,7 @@ use crate::spec::{
     TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let opts = TargetOptions {
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
         linker: Some("rust-lld".into()),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
index 222d5651b52..7933041b584 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
@@ -10,7 +10,7 @@ use crate::spec::{
     Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let opts = TargetOptions {
         abi: "softfloat".into(),
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs
index ac1bec02ec8..47a9b91663f 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     // In QNX, libc does not provide a compatible ABI between versions.
     // To distinguish between QNX versions, we needed a stable conditional compilation switch,
     // which is why we needed to implement different targets in the compiler.
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
index 65a1863eb39..5b5a21fca95 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs
@@ -1,6 +1,6 @@
 use crate::spec::Target;
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = super::aarch64_unknown_nto_qnx700::target();
     base.metadata.description = Some("ARM64 QNX Neutrino 7.1 RTOS".into());
     base.options.env = "nto71".into();
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
index e16991af4e6..8f6215df71a 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-openbsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
index e59b38a3e41..26c1a671095 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::redox::opts();
     base.max_atomic_width = Some(128);
     base.stack_probes = StackProbeType::Inline;
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
index 5ae2d68332c..4e3d5ce34bc 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::teeos::opts();
     base.features = "+strict-align,+neon,+fp-armv8".into();
     base.max_atomic_width = Some(128);
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs
index 9fd7c246498..69ab992e12c 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-unknown-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs
index 429303170b6..bb580af7c47 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs
@@ -3,7 +3,7 @@
 
 use crate::spec::{base, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
 
     base.max_atomic_width = Some(128);
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs
index df1b75272b1..630658efd06 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_uwp_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a".into();
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
index 41f7532ecdb..3c0f92fa31f 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "aarch64-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
index 2c76f4736de..f292ee7f563 100644
--- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64_32;
     let base = opts("watchos", arch, TargetAbi::Normal);
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
index 6f28f5d0543..e86b8358a9c 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64e;
     let mut base = opts("macos", arch, TargetAbi::Normal);
     base.cpu = "apple-m1".into();
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
index 1590ae9679d..fcb850f44bc 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Arm64e;
     let mut base = opts("ios", arch, TargetAbi::Normal);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
index 21cb38868fb..50c399bf4a8 100644
--- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{add_link_args, base, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.max_atomic_width = Some(128);
     base.features = "+v8a,+neon,+fp-armv8".into();
diff --git a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs
index a22bcef4757..350a01b1967 100644
--- a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "arm-linux-androideabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs
index 8ff272e786d..296f9d0b423 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "arm-unknown-linux-gnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs
index e3e2f4cd05c..5d58055f1af 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "arm-unknown-linux-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
index f958b89358b..89a80ae8bed 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
         // to determine the calling convention and float ABI, and it doesn't
diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
index 98093fdc003..200bb917964 100644
--- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and it
diff --git a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
index b56f311793a..a6ea48817c0 100644
--- a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armeb-unknown-linux-gnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
index df32b74f6d9..d09624e0e73 100644
--- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs
@@ -3,7 +3,7 @@
 use crate::abi::Endian;
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armebv7r-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
index 063038c8012..10669dcf09d 100644
--- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
@@ -3,7 +3,7 @@
 use crate::abi::Endian;
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armebv7r-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs
index f873fb0d349..2236e02d006 100644
--- a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs
@@ -11,7 +11,7 @@
 
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv4t-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs
index 18f327bc87f..d88022ac10a 100644
--- a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv4t-unknown-linux-gnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs
index 1fbe4b89ea1..3d8e75d3ee9 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, cvs, FramePointer, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv5te-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs
index 12368644837..a73d8298dde 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv5te-unknown-linux-gnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
index ccbc1e36dde..91b0e2039c7 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // FIXME: this comment below does not seem applicable?
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
index d88b88333b5..65658ab45fc 100644
--- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv5te-unknown-linux-uclibcgnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs
index 24e9d1e0394..52617237f20 100644
--- a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv6-unknown-freebsd-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs
index 62e328b9cbd..eda1c028aad 100644
--- a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv6-unknown-netbsdelf-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
index bcdad0a55b3..b29ee2dd793 100644
--- a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
+++ b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs
@@ -4,7 +4,7 @@ use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}
 ///
 /// Requires the devkitARM toolchain for 3DS targets on the host system.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::Yes, Lld::No),
         &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs
index 8f6a58a1b49..3bba22f8a1f 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs
@@ -8,7 +8,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptio
 // See https://developer.android.com/ndk/guides/abis.html#v7a
 // for target ABI requirements.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::android::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]);
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs
new file mode 100644
index 00000000000..1edecac095f
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs
@@ -0,0 +1,35 @@
+use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    Target {
+        llvm_target: "armv7-unknown-none-eabihf".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Armv7 RTEMS (Requires RTEMS toolchain and kernel".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(true),
+        },
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
+        arch: "arm".into(),
+
+        options: TargetOptions {
+            os: "rtems".into(),
+            families: cvs!["unix"],
+            abi: "eabihf".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+            linker: None,
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            features: "+thumb2,+neon,+vfp3".into(),
+            max_atomic_width: Some(64),
+            emit_debug_gdb_scripts: false,
+            // GCC defaults to 8 for arm-none here.
+            c_enum_min_bits: Some(8),
+            eh_frame_header: false,
+            no_default_libraries: false,
+            env: "newlib".into(),
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
index a9b5172385b..5f71d325efb 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
@@ -5,7 +5,7 @@ use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}
 ///
 /// Requires the VITASDK toolchain on the host system.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::Yes, Lld::No),
         &["-Wl,-q", "-Wl,--pic-veneer"],
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs
index 3a16bbe95db..b955acd0dca 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-freebsd-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs
index 8a4ba271456..703a9b132b2 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for glibc Linux on ARMv7 without thumb-mode, NEON or
 // hardfloat.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-linux-gnueabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs
index a217a2daeb3..db79810b5dd 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for glibc Linux on ARMv7 without NEON or
 // thumb-mode. See the thumbv7neon variant for enabling both.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
index 96459a5137f..e4e99eab853 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for musl Linux on ARMv7 without thumb-mode, NEON or
 // hardfloat.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     // Most of these settings are copied from the armv7_unknown_linux_gnueabi
     // target.
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
index 6c878141fd4..5fc3f703175 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs
@@ -2,7 +2,7 @@ use crate::spec::{base, Target, TargetOptions};
 
 // This target is for musl Linux on ARMv7 without thumb-mode or NEON.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
index bffc51d9b7b..040a953b12e 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or
 // hardfloat.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     // Most of these settings are copied from the armv7_unknown_linux_musleabi
     // target.
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs
index 9dc1221287d..af10d2d9012 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for uclibc Linux on ARMv7 without NEON,
 // thumb-mode or hardfloat.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = base::linux_uclibc::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabi".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs
index 01a1468d3a8..53673daa812 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, Target, TargetOptions};
 // This target is for uclibc Linux on ARMv7 without NEON or
 // thumb-mode. See the thumbv7neon variant for enabling both.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = base::linux_uclibc::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs
index a2391503ff8..164acd17f21 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-netbsdelf-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
index 889cc201569..1ad91b8f080 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
@@ -1,6 +1,6 @@
 use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
         // to determine the calling convention and float ABI, and it doesn't
diff --git a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs
index 7d60ec1b64d..f8faec918e4 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs
index 76d4653931b..aea897f56b8 100644
--- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = base::solid::opts("asp3");
     Target {
         llvm_target: "armv7a-none-eabi".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs
index d2b4d46adac..be526d63250 100644
--- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let base = base::solid::opts("asp3");
     Target {
         llvm_target: "armv7a-none-eabihf".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs
index b544c404f3f..1e4798abfff 100644
--- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs
@@ -16,7 +16,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let opts = TargetOptions {
         abi: "eabi".into(),
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs
index aebb7e667bc..ab8b870c628 100644
--- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs
@@ -7,7 +7,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let opts = TargetOptions {
         abi: "eabihf".into(),
         linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
index e876c567b09..35de6b35eaf 100644
--- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Armv7k;
     Target {
         llvm_target: "armv7k-apple-watchos".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs
index b3246dc7928..aba55f533a7 100644
--- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7r-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
index 9ac500d7ffe..5a8519dcc49 100644
--- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7r-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
index 11608794932..41eaa79d3eb 100644
--- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::Armv7s;
     Target {
         llvm_target: ios_llvm_target(arch).into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
index ee940c3a76a..042a9a14071 100644
--- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv8r-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs
index bf01413a80a..020322b2739 100644
--- a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs
+++ b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs
@@ -1,5 +1,5 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     base::avr_gnu::target("atmega328", "-mmcu=atmega328")
 }
diff --git a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
index eb223af8cf4..f4c3a35ced5 100644
--- a/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/bpfeb_unknown_none.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "bpfeb".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
index 12164adc00f..6ef72c40210 100644
--- a/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/bpfel_unknown_none.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "bpfel".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs
index e8a0b465e15..61c246fc4cb 100644
--- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs
+++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs
@@ -2,7 +2,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
 // This target is for glibc Linux on Csky
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         //https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h
         llvm_target: "csky-unknown-linux-gnuabiv2".into(),
diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs
index 99330ddc318..91c33caae3e 100644
--- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs
+++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs
@@ -2,7 +2,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
 // This target is for glibc Linux on Csky
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         //https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h
         llvm_target: "csky-unknown-linux-gnuabiv2".into(),
diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
index bd539799029..cddc3a33f9f 100644
--- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "hexagonv60".into();
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs
index cefd0bf6d67..730b19abd2b 100644
--- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{PanicStrategy, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "hexagon-unknown-none-elf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
index b1b2b6cdffa..263393fd536 100644
--- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::I386;
     // i386-apple-ios is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs
index 6c80ab6994d..cf0577d8cb0 100644
--- a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "i586-pc-unknown".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs
index befb0f89f3b..dd38f86bced 100644
--- a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::Target;
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = super::i686_pc_windows_msvc::target();
     base.cpu = "pentium".into();
     base.llvm_target = "i586-pc-windows-msvc".into();
diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs
index b699a7af177..e481e967ebf 100644
--- a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::Target;
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = super::i686_unknown_linux_gnu::target();
     base.cpu = "pentium".into();
     base.llvm_target = "i586-unknown-linux-gnu".into();
diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
index 55a26eb004a..623422a89ea 100644
--- a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::Target;
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = super::i686_unknown_linux_musl::target();
     base.cpu = "pentium".into();
     base.llvm_target = "i586-unknown-linux-musl".into();
diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs
index de42549b7f8..3c5ba157c1e 100644
--- a/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/i586_unknown_netbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.cpu = "pentium".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
index 02f6bec4692..f173e8b7e4a 100644
--- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     // ld64 only understands i386 and not i686
     let arch = Arch::I386;
     let mut base = opts("macos", arch, TargetAbi::Normal);
diff --git a/compiler/rustc_target/src/spec/targets/i686_linux_android.rs b/compiler/rustc_target/src/spec/targets/i686_linux_android.rs
index fc313e575be..bce41976a96 100644
--- a/compiler/rustc_target/src/spec/targets/i686_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_linux_android.rs
@@ -3,7 +3,7 @@ use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions};
 // See https://developer.android.com/ndk/guides/abis.html#x86
 // for target ABI requirements.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::android::opts();
 
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
index 4b0f4bf3ecd..7288359f564 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_gnu::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
index 5bb08201429..a38e67b96f0 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_gnullvm::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
index 970b43ad109..a8e1ad45014 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, LinkerFlavor, Lld, SanitizerSet, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs
index cce21fcacb1..8ba58dfd705 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs
index 84ef00f06c8..b2316fd3bf4 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::haiku::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
index ad8c0f7f582..2e303ff402f 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::hurd_gnu::opts();
     base.cpu = "pentiumpro".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs
index 5584435a0ad..15bc4da1775 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
index d1ab1f73b51..8dd08a9567b 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs
index 255148fca9a..02a95ee6626 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs
index d6df801234c..b8c9efc7c47 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::openbsd::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
index 83252fadb78..0e00249d66c 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::redox::opts();
     base.cpu = "pentiumpro".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
index b92fc2e759a..3cda78003ed 100644
--- a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs
@@ -7,7 +7,7 @@
 
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
index 851bea80fb8..901c9fc378d 100644
--- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_uwp_gnu::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs
index 28bd2aae8e7..c7703666ae0 100644
--- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_uwp_msvc::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
index cd488d0532c..79302cdc0a1 100644
--- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
index 973c75eeca6..ba669334e7f 100644
--- a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::vxworks::opts();
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
index 6f0bb449c16..d33c7af92c6 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "loongarch64-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
index f7a6e0bd857..5540e71ad4f 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "loongarch64-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
index c7f47da6972..56285190268 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "loongarch64-unknown-none".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
index 21e4f4a2b05..7e57715ce7a 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "loongarch64-unknown-none".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
index 7cff0efd112..9d9f6145e2f 100644
--- a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "M68020".into();
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
index c3235bf994f..72577749ac6 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs
@@ -3,7 +3,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2,+soft-float".into();
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
index cdf4ffb7f9e..1fad6be2f8d 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mips64-unknown-linux-gnuabi64".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
index 463f7dc47f7..7627131bc2f 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2".into();
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
index ad77a02c063..f93e5676b05 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mips64el-unknown-linux-gnuabi64".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
index 83f5c7ea37d..6fbb4f40024 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2".into();
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
index 0bdfd6ee6b0..778b0041214 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mips-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
index 8e27c9936c5..2cce3271c57 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "mips32r2".into();
     base.features = "+mips32r2,+soft-float".into();
diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
index 852e1d9376d..ef7d6bf82e3 100644
--- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_uclibc.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mips-unknown-linux-uclibc".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
index 9d3f4d9f795..850808b4c7b 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs
@@ -3,7 +3,7 @@ use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}
 // The PSP has custom linker requirements.
 const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::No, Lld::No),
         &["--emit-relocs", "--nmagic"],
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
index c0b99a68b0d..761495b2a29 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsel-sony-psx".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs
index 8fe4548a3ad..2784b371469 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsel-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
index 43914a23308..1b2d8e9a105 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "mips32r2".into();
     base.features = "+mips32r2,+soft-float".into();
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
index 6150654c081..21f03a40ec2 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_uclibc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsel-unknown-linux-uclibc".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
index 03501aa76a8..ea2fb2e7f3a 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_netbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.max_atomic_width = Some(32);
     base.cpu = "mips32".into();
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs
index 81aac3ce0b8..bb8eb24908c 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_none.rs
@@ -4,7 +4,7 @@
 
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsel-unknown-none".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
index 2ed520e9f48..5c07e9ea6dd 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsisa32r6-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs
index de30c5b35b7..63b3cc47ffc 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa32r6el_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsisa32r6el-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
index 4178a991e14..7f5e2edb036 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
index 8e50373bd12..a2d807bcfe1 100644
--- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
index de476741def..5bc5f79d1b6 100644
--- a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "msp430-none-elf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
index ec5edfb6e42..289251e906a 100644
--- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
+++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, PanicStrategy, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         arch: "nvptx64".into(),
         data_layout: "e-i64:64-i128:128-v16:16-v32:32-n16:32:64".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
index bda43e7a2b0..0f90efb4bb3 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::aix::opts();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
index 6eb5bba0fcd..89afe234376 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
index 53b84479a49..e39849c9b18 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
index 0d0484dd174..24a56f917e5 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
index 2922c921e17..1dab74e9376 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::openbsd::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
index dd2ec274207..1029a135e4a 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::vxworks::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs
index ea295cf169e..3c9d01e2d18 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs
index dc70bd238a7..df8f9f07c2f 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
index dbfbd69b95b..909a25304f4 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
index 2f7acccfae8..e8f09d70cc8 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     // Extra hint to linker that we are generating secure-PLT code.
     base.add_pre_link_args(
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
index 2ecafbb08bc..9e5cea6eff5 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
index 04b2309fdc8..dbea70168a5 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
index 108e468eb66..86840f16d90 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
index d19015729ec..51cd3c186fa 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
index 3ee6cd46c85..7129fe42876 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
index f00ee960413..6e98ecce45b 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_openbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::openbsd::opts();
     base.endian = Endian::Big;
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
index 5d107d6e60e..b19513bf1d7 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::vxworks::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "--secure-plt"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
index aea525a6912..8484c160a99 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::vxworks::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe", "--secure-plt"]);
     base.max_atomic_width = Some(32);
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
index e425d6a3f3f..8913df3b954 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_gnu.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{base, CodeModel, SplitDebuginfo, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv32-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
index 409b6b22f1c..5717e7a3907 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{base, CodeModel, SplitDebuginfo, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv32-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
index 631a31edeb5..1995de9dd2d 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32i_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
index 8aa5e098890..bd37cf80b48 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
index 5fa3858e857..32df30ddb5e 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32im_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
index 2022873d05c..61c887031bc 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32ima_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
index 386e3a38f97..0d453901efa 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
index 7ced37e1535..cc28198e3ff 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
index aa51b8957fc..5ee6b3cbfa6 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
index cd50a9e60c3..0eaabc60cbc 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs
index 3661e38e7b1..c2882151d3d 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs
index 95466090891..7395e1a6aad 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs
index fe49951ebfd..dcd4fcd9b48 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
index d52dc8f96ca..50d36e724a2 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
index ff993197846..0ae49debc3a 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_none_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
index baee03e6833..eab18064334 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs
@@ -1,6 +1,6 @@
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
         llvm_target: "riscv32".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
index 2dfaf8a2033..00059a2691d 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{base, CodeModel, SanitizerSet, SplitDebuginfo, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-linux-android".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
index 1fd6a4b38dc..8d2b16c4501 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, CodeModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-freebsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
index 5c3f525966e..f5e6b1cbd78 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, CodeModel, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-fuchsia".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
index f11128cfcb6..3033479358e 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_hermit.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, CodeModel, RelocModel, Target, TargetOptions, TlsModel};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-hermit".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
index 308c995297b..07253803f5c 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_gnu.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{base, CodeModel, SplitDebuginfo, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
index 8b401329868..9b0b14cb108 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{base, CodeModel, SplitDebuginfo, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
index 65781f5af5c..3eb9366c850 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_netbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, CodeModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-netbsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
index 61226809e52..c32c57d92f7 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs
@@ -3,7 +3,7 @@ use crate::spec::{
     TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
index 5bea708e0dd..27b8ae99753 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs
@@ -3,7 +3,7 @@ use crate::spec::{
     TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
index 5bdbda773b1..dca8a524b10 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_openbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, CodeModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "riscv64-unknown-openbsd".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
index b7444df04cd..d514f8efcd0 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs
@@ -3,7 +3,7 @@ use crate::spec::{
     TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         llvm_target: "riscv64".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
index 215c0724f91..5fbc2a86fa9 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
@@ -3,7 +3,7 @@ use crate::spec::{
     TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         metadata: crate::spec::TargetMetadata {
@@ -21,7 +21,6 @@ pub fn target() -> Target {
             os: "nuttx".into(),
             linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
             linker: Some("rust-lld".into()),
-            llvm_abiname: "lp64d".into(),
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
             features: "+m,+a,+c".into(),
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index b0dd0eb612e..e0a6c230fd6 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index 3976233819c..6aabe9ca519 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
index eeb7eebfe50..7c37fa0d632 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.endian = Endian::Big;
     base.cpu = "v9".into();
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
index 69bb6e1fb60..842e35392dc 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.cpu = "v9".into();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
index 08f6eaf8361..a8767fa9d3c 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::openbsd::opts();
     base.endian = Endian::Big;
     base.cpu = "v9".into();
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
index 8b7ff5d8011..7089fc51124 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "sparc-unknown-linux-gnu".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
index c977fe608a7..0cd4faefd6b 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let options = TargetOptions {
         linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
         linker: Some("sparc-elf-gcc".into()),
diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
index 1c0adadece0..a932632b857 100644
--- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
@@ -1,7 +1,7 @@
 use crate::abi::Endian;
 use crate::spec::{base, Cc, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::solaris::opts();
     base.endian = Endian::Big;
     base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]);
diff --git a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs
index 8806f3e87fa..0f5e1640893 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs
@@ -11,7 +11,7 @@
 
 use crate::spec::{base, cvs, FramePointer, PanicStrategy, RelocModel, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv4t-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs
index d92e68cebaa..6ae41ce4399 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, cvs, FramePointer, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv5te-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs
index a0fa58d8175..9d4cc66c7f0 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv6m-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs
index ac37f403860..bc9d9856e03 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv6m-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
index e36aa5ab395..a927cf6902e 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     // Prevent error LNK2013: BRANCH24(T) fixup overflow
     // The LBR optimization tries to eliminate branch islands,
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs
index 2e68dd0ec4e..473113854a8 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7a_uwp_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, PanicStrategy, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7a-pc-windows-msvc".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs
index bd2df9236f6..dca3e73dda5 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs
@@ -11,7 +11,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7em-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
index e2499ef5411..acc5acfbfb6 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
@@ -10,7 +10,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7em-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs
index e21facb78f9..b4cd9686f5c 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs
@@ -11,7 +11,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7em-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs
index 45092711d2e..bdb3a38be93 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs
@@ -10,7 +10,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7em-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs
index 17e37f800f0..f5615de2315 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7m-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs
index 4424b9eaade..0e3663e1603 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv7m-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs
index c562f57252e..9b4d13a96c8 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs
@@ -8,7 +8,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 // See https://developer.android.com/ndk/guides/abis.html#v7a
 // for target ABI requirements.
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::android::opts();
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]);
     Target {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs
index b5e91d61308..b85b9b60b42 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -6,7 +6,7 @@ use crate::spec::{base, Target, TargetOptions};
 // registers enabled as well. See section A2.6.2 on page A2-56 in
 // https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
index 71d5eb43c10..f53f21d7217 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
@@ -6,7 +6,7 @@ use crate::spec::{base, Target, TargetOptions};
 // registers enabled as well. See section A2.6.2 on page A2-56 in
 // https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs
index e18bf113fe7..e392240a333 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.base-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs
index 44c6fb0dd1b..903b8f02911 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs
@@ -2,7 +2,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.base-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs
index 5c2f1e09381..d287321c9f2 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs
@@ -3,7 +3,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.main-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
index 799ac45b479..74b143f6995 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
@@ -3,7 +3,7 @@
 
 use crate::spec::{base, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.main-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs
index 2f0df7ae857..c5de209246c 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs
@@ -3,7 +3,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.main-none-eabi".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs
index ee31f17bc45..44ad78b4684 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs
@@ -3,7 +3,7 @@
 
 use crate::spec::{base, cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "thumbv8m.main-none-eabihf".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs
index 46257a272d1..c22f1589ca1 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     base, cvs, LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     // Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
     let pre_link_args = LinkArgs::new();
     let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]);
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
index bf92f30e8b3..300108530a5 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs
@@ -12,7 +12,7 @@
 
 use crate::spec::{base, Cc, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
     options.os = "unknown".into();
 
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasi.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasi.rs
index 2752125c009..c317ebd9592 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasi.rs
@@ -6,6 +6,6 @@
 
 use crate::spec::Target;
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     super::wasm32_wasip1::target()
 }
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs
index 29e6dff2068..7728d83c2b6 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs
@@ -12,7 +12,7 @@
 
 use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
 
     options.os = "wasi".into();
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
index 4e60806f3a7..0ae844c8da8 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs
@@ -9,7 +9,7 @@
 
 use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
 
     options.os = "wasi".into();
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs
index 489bae4fedf..40f026ca938 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs
@@ -18,7 +18,7 @@
 
 use crate::spec::{base, crt_objects, LinkSelfContainedDefault, RelocModel, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
 
     options.os = "wasi".into();
@@ -53,7 +53,7 @@ pub fn target() -> Target {
     options.entry_name = "__main_void".into();
 
     // Default to PIC unlike base wasm. This makes precompiled objects such as
-    // the standard library more suitable to be used with shared libaries a la
+    // the standard library more suitable to be used with shared libraries a la
     // emscripten's dynamic linking convention.
     options.relocation_model = RelocModel::Pic;
 
diff --git a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
index bc49a3c9f70..35c55374476 100644
--- a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs
@@ -9,7 +9,7 @@
 
 use crate::spec::{base, Cc, LinkerFlavor, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut options = base::wasm::options();
     options.os = "unknown".into();
 
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
index c3a52a506bc..7bf18026735 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64;
     let mut base = opts("macos", arch, TargetAbi::Normal);
     base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
index 3cabca03360..76a0bb1d91e 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64;
     // x86_64-apple-ios is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
index c23a20ff084..f66efbbf709 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64;
     let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
index 2a3125157dd..f9d5f6e77d9 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64;
     // x86_64-apple-tvos is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
index 62e60b5e32d..1fced10c895 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64;
     Target {
         llvm_target: watchos_sim_llvm_target(arch).into(),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
index 5a72fad8263..a3d18e5ecda 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 
 use crate::spec::{cvs, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::No, Lld::No),
         &[
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs
index 46df00e9c02..ce3e1e159b7 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_fuchsia.rs
@@ -1 +1 @@
-pub use crate::spec::targets::x86_64_unknown_fuchsia::target;
+pub(crate) use crate::spec::targets::x86_64_unknown_fuchsia::target;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs
index 257093b7554..84a747e1feb 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::android::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs
index f6d22ff3204..45963565b06 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "x86_64-pc-unknown".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
index 697daf590ad..37cc7708d63 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::solaris::opts();
     base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]);
     base.cpu = "x86-64".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
index 89a9bb1e1cc..8efebfd42bb 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_gnu::opts();
     base.cpu = "x86-64".into();
     base.features = "+cx16,+sse3,+sahf".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs
index acf0fd421ba..056b0451bbe 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_gnullvm::opts();
     base.cpu = "x86-64".into();
     base.features = "+cx16,+sse3,+sahf".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
index 3ef3e5114e6..d1881caa273 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.cpu = "x86-64".into();
     base.features = "+cx16,+sse3,+sahf".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs
index 883da26d786..43fac44e48b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "x86_64-unknown-linux-musl".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs
index 171a6f2a51e..7ad0dc69e7b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::dragonfly::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs
index 4692b5a3c74..91cc6669f72 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::freebsd::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
index 5ebf1804302..836d41a0963 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::fuchsia::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs
index b593b79e7bb..7aab43b520a 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::haiku::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs
index 3e81ff9a4ec..6bc3ec54286 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_hermit.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, StackProbeType, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "x86_64-unknown-hermit".into(),
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs
index d683a442027..780fd6eb619 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::illumos::opts();
     base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64", "-std=c99"]);
     base.cpu = "x86-64".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
index adf489ad7b1..f67e9f3b3f1 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_l4re_uclibc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, PanicStrategy, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::l4re::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs
index 4a92d4ef9d5..80f49d3a645 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs
index 3c7db0095a1..dce23e2ebee 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
     base.cpu = "x86-64".into();
     base.abi = "x32".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
index 109fc3c0728..0262c8fd34f 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_musl::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs
index b6e331bd854..47ff0460d7b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux::opts();
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
index c1d888899fc..28982bc1357 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::linux_ohos::opts();
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs
index d413caf4aaf..1ec07fe5a82 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs
@@ -2,7 +2,7 @@ use crate::spec::{
     base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::netbsd::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
index 175a53f237d..cfefb1de993 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs
@@ -9,7 +9,7 @@ use crate::spec::{
     Target, TargetOptions,
 };
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let opts = TargetOptions {
         cpu: "x86-64".into(),
         plt_by_default: false,
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs
index 8f1c3ef9bc7..580d0ef8530 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::openbsd::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs
index ae38f63f034..56943951518 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::redox::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
index 2933da92fcc..f5ab3afffc3 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs
@@ -8,7 +8,7 @@
 use crate::abi::call::Conv;
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::uefi_msvc::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
index c71bc9ed923..69c70c96d2b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_uwp_gnu::opts();
     base.cpu = "x86-64".into();
     base.features = "+cx16,+sse3,+sahf".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs
index 178baeca685..74493f0941f 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_uwp_msvc::opts();
     base.cpu = "x86-64".into();
     base.features = "+cx16,+sse3,+sahf".into();
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
index d44ae9fc4e0..815016e0ade 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::windows_msvc::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
index 7b40f7366d0..604f71ffaa6 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs
@@ -1,6 +1,6 @@
 use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let mut base = base::vxworks::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
index a932d4a3cb4..9b9ffe4e536 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     let arch = Arch::X86_64h;
     let mut base = opts("macos", arch, TargetAbi::Normal);
     base.max_atomic_width = Some(128);
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
index f041e791a9b..804659d3c52 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
@@ -2,7 +2,7 @@ use crate::abi::Endian;
 use crate::spec::base::xtensa;
 use crate::spec::{cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
index 05666bd81aa..51960dbec4a 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
index 83ef520551f..6c15a82e95c 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
@@ -2,7 +2,7 @@ use crate::abi::Endian;
 use crate::spec::base::xtensa;
 use crate::spec::{cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
index aa125eb1ba6..21330615a87 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
index e18acfccf5f..536bd6dc1b2 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
@@ -2,7 +2,7 @@ use crate::abi::Endian;
 use crate::spec::base::xtensa;
 use crate::spec::{cvs, Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
index ecbb51dfb66..fca47b4bdb1 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
@@ -1,7 +1,7 @@
 use crate::spec::base::xtensa;
 use crate::spec::{Target, TargetOptions};
 
-pub fn target() -> Target {
+pub(crate) fn target() -> Target {
     Target {
         llvm_target: "xtensa-none-elf".into(),
         pointer_width: 32,
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 effd9f8cb0c..5918686213a 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
@@ -170,7 +170,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         {
                             return guar;
                         }
-                        // Silence redundant errors on binding acccess that are already
+                        // Silence redundant errors on binding access that are already
                         // reported on the binding definition (#56607).
                         if let Err(guar) = self.fn_arg_obligation(&obligation) {
                             return guar;
@@ -898,7 +898,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let mut suggested = false;
         let mut chain = vec![];
 
-        // The following logic is simlar to `point_at_chain`, but that's focused on associated types
+        // The following logic is similar to `point_at_chain`, but that's focused on associated types
         let mut expr = expr;
         while let hir::ExprKind::MethodCall(path_segment, rcvr_expr, args, span) = expr.kind {
             // Point at every method call in the chain with the `Result` type.
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index efbc2695fd9..41b0ee56a4c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -878,7 +878,7 @@ impl<'tcx> OnUnimplementedFormatString {
             }
         }
         // we cannot return errors from processing the format string as hard error here
-        // as the diagnostic namespace gurantees that malformed input cannot cause an error
+        // as the diagnostic namespace guarantees that malformed input cannot cause an error
         //
         // if we encounter any error while processing we nevertheless want to show it as warning
         // so that users are aware that something is not correct
@@ -986,10 +986,10 @@ impl<'tcx> OnUnimplementedFormatString {
             })
             .collect();
         // we cannot return errors from processing the format string as hard error here
-        // as the diagnostic namespace gurantees that malformed input cannot cause an error
+        // as the diagnostic namespace guarantees that malformed input cannot cause an error
         //
         // if we encounter any error while processing the format string
-        // we don't want to show the potentially half assembled formated string,
+        // we don't want to show the potentially half assembled formatted string,
         // therefore we fall back to just showing the input string in this case
         //
         // The actual parser errors are emitted earlier
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index f2c457aa377..45e157b1080 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -4663,7 +4663,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // because this suggest adding both return type in
         // the `FnSig` and a default return value in the body, so it
         // is not suitable for foreign function without a local body,
-        // and neighter for trait method which may be also implemented
+        // and neither for trait method which may be also implemented
         // in other place, so shouldn't change it's FnSig.
         fn choose_suggest_items<'tcx, 'hir>(
             tcx: TyCtxt<'tcx>,
@@ -5023,24 +5023,32 @@ impl<'v> Visitor<'v> for AwaitsVisitor {
     }
 }
 
+/// Suggest a new type parameter name for diagnostic purposes.
+///
+/// `name` is the preferred name you'd like to suggest if it's not in use already.
 pub trait NextTypeParamName {
     fn next_type_param_name(&self, name: Option<&str>) -> String;
 }
 
 impl NextTypeParamName for &[hir::GenericParam<'_>] {
     fn next_type_param_name(&self, name: Option<&str>) -> String {
-        // This is the list of possible parameter names that we might suggest.
+        // Type names are usually single letters in uppercase. So convert the first letter of input string to uppercase.
         let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string());
         let name = name.as_deref();
+
+        // This is the list of possible parameter names that we might suggest.
         let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"];
-        let used_names = self
+
+        // Filter out used names based on `filter_fn`.
+        let used_names: Vec<Symbol> = self
             .iter()
-            .filter_map(|p| match p.name {
+            .filter_map(|param| match param.name {
                 hir::ParamName::Plain(ident) => Some(ident.name),
                 _ => None,
             })
-            .collect::<Vec<_>>();
+            .collect();
 
+        // Find a name from `possible_names` that is not in `used_names`.
         possible_names
             .iter()
             .find(|n| !used_names.contains(&Symbol::intern(n)))
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index aea47c9e987..a17c007debd 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -32,6 +32,7 @@
 #![feature(unwrap_infallible)]
 #![feature(yeet_expr)]
 #![recursion_limit = "512"] // For rustdoc
+#![warn(unreachable_pub)] // For rustdoc
 // tidy-alphabetical-end
 
 pub mod error_reporting;
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index bf4b0482081..8b55f84bccc 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -29,6 +29,7 @@ use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::InferOk;
 use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
 use crate::solve::{deeply_normalize_for_diagnostics, inspect};
+use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::{
     util, FulfillmentErrorCode, NormalizeExt, Obligation, ObligationCause, PredicateObligation,
@@ -54,7 +55,7 @@ pub fn add_placeholder_note<G: EmissionGuarantee>(err: &mut Diag<'_, G>) {
     );
 }
 
-pub fn suggest_increasing_recursion_limit<'tcx, G: EmissionGuarantee>(
+pub(crate) fn suggest_increasing_recursion_limit<'tcx, G: EmissionGuarantee>(
     tcx: TyCtxt<'tcx>,
     err: &mut Diag<'_, G>,
     overflowing_predicates: &[ty::Predicate<'tcx>],
@@ -624,14 +625,13 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
         // at ambiguous goals, as for others the coherence unknowable candidate
         // was irrelevant.
         match goal.result() {
-            Ok(Certainty::Maybe(_)) => {}
             Ok(Certainty::Yes) | Err(NoSolution) => return,
+            Ok(Certainty::Maybe(_)) => {}
         }
 
-        let Goal { param_env, predicate } = goal.goal();
-
         // For bound predicates we simply call `infcx.enter_forall`
         // and then prove the resulting predicate as a nested goal.
+        let Goal { param_env, predicate } = goal.goal();
         let trait_ref = match predicate.kind().no_bound_vars() {
             Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
             Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)))
@@ -645,7 +645,11 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
             _ => return,
         };
 
-        // Add ambiguity causes for reservation impls.
+        if trait_ref.references_error() {
+            return;
+        }
+
+        let mut candidates = goal.candidates();
         for cand in goal.candidates() {
             if let inspect::ProbeKind::TraitCandidate {
                 source: CandidateSource::Impl(def_id),
@@ -664,78 +668,68 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
             }
         }
 
-        // Add ambiguity causes for unknowable goals.
-        let mut ambiguity_cause = None;
-        for cand in goal.candidates() {
-            if let inspect::ProbeKind::TraitCandidate {
-                source: CandidateSource::CoherenceUnknowable,
-                result: Ok(_),
-            } = cand.kind()
-            {
-                let lazily_normalize_ty = |mut ty: Ty<'tcx>| {
-                    if matches!(ty.kind(), ty::Alias(..)) {
-                        let ocx = ObligationCtxt::new(infcx);
-                        ty = ocx
-                            .structurally_normalize(&ObligationCause::dummy(), param_env, ty)
-                            .map_err(|_| ())?;
-                        if !ocx.select_where_possible().is_empty() {
-                            return Err(());
-                        }
-                    }
-                    Ok(ty)
-                };
+        // We also look for unknowable candidates. In case a goal is unknowable, there's
+        // always exactly 1 candidate.
+        let Some(cand) = candidates.pop() else {
+            return;
+        };
 
-                infcx.probe(|_| {
-                    match trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty) {
-                        Err(()) => {}
-                        Ok(Ok(())) => warn!("expected an unknowable trait ref: {trait_ref:?}"),
-                        Ok(Err(conflict)) => {
-                            if !trait_ref.references_error() {
-                                // Normalize the trait ref for diagnostics, ignoring any errors if this fails.
-                                let trait_ref =
-                                    deeply_normalize_for_diagnostics(infcx, param_env, trait_ref);
-
-                                let self_ty = trait_ref.self_ty();
-                                let self_ty = self_ty.has_concrete_skeleton().then(|| self_ty);
-                                ambiguity_cause = Some(match conflict {
-                                    Conflict::Upstream => {
-                                        IntercrateAmbiguityCause::UpstreamCrateUpdate {
-                                            trait_ref,
-                                            self_ty,
-                                        }
-                                    }
-                                    Conflict::Downstream => {
-                                        IntercrateAmbiguityCause::DownstreamCrate {
-                                            trait_ref,
-                                            self_ty,
-                                        }
-                                    }
-                                });
-                            }
-                        }
-                    }
-                })
-            } else {
-                match cand.result() {
-                    // We only add an ambiguity cause if the goal would otherwise
-                    // result in an error.
-                    //
-                    // FIXME: While this matches the behavior of the
-                    // old solver, it is not the only way in which the unknowable
-                    // candidates *weaken* coherence, they can also force otherwise
-                    // sucessful normalization to be ambiguous.
-                    Ok(Certainty::Maybe(_) | Certainty::Yes) => {
-                        ambiguity_cause = None;
-                        break;
-                    }
-                    Err(NoSolution) => continue,
+        let inspect::ProbeKind::TraitCandidate {
+            source: CandidateSource::CoherenceUnknowable,
+            result: Ok(_),
+        } = cand.kind()
+        else {
+            return;
+        };
+
+        let lazily_normalize_ty = |mut ty: Ty<'tcx>| {
+            if matches!(ty.kind(), ty::Alias(..)) {
+                let ocx = ObligationCtxt::new(infcx);
+                ty = ocx
+                    .structurally_normalize(&ObligationCause::dummy(), param_env, ty)
+                    .map_err(|_| ())?;
+                if !ocx.select_where_possible().is_empty() {
+                    return Err(());
                 }
             }
-        }
+            Ok(ty)
+        };
 
-        if let Some(ambiguity_cause) = ambiguity_cause {
-            self.causes.insert(ambiguity_cause);
-        }
+        infcx.probe(|_| {
+            let conflict = match trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty) {
+                Err(()) => return,
+                Ok(Ok(())) => {
+                    warn!("expected an unknowable trait ref: {trait_ref:?}");
+                    return;
+                }
+                Ok(Err(conflict)) => conflict,
+            };
+
+            // It is only relevant that a goal is unknowable if it would have otherwise
+            // failed.
+            let non_intercrate_infcx = infcx.fork_with_intercrate(false);
+            if non_intercrate_infcx.predicate_may_hold(&Obligation::new(
+                infcx.tcx,
+                ObligationCause::dummy(),
+                param_env,
+                predicate,
+            )) {
+                return;
+            }
+
+            // Normalize the trait ref for diagnostics, ignoring any errors if this fails.
+            let trait_ref = deeply_normalize_for_diagnostics(infcx, param_env, trait_ref);
+            let self_ty = trait_ref.self_ty();
+            let self_ty = self_ty.has_concrete_skeleton().then(|| self_ty);
+            self.causes.insert(match conflict {
+                Conflict::Upstream => {
+                    IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_ref, self_ty }
+                }
+                Conflict::Downstream => {
+                    IntercrateAmbiguityCause::DownstreamCrate { trait_ref, self_ty }
+                }
+            });
+        });
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index f72ae94fffc..16ba06f8667 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -472,7 +472,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     };
 
                     match infcx.at(&obligation.cause, obligation.param_env).eq(
-                        // Only really excercised by generic_const_exprs
+                        // Only really exercised by generic_const_exprs
                         DefineOpaqueTypes::Yes,
                         ct_ty,
                         ty,
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index fa696dcd2f5..a3d5c530797 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -29,8 +29,8 @@ use tracing::{debug, instrument};
 use super::elaborate;
 use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::{util, Obligation, ObligationCause};
-pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
+pub use crate::traits::ObjectSafetyViolation;
+use crate::traits::{util, MethodViolationCode, Obligation, ObligationCause};
 
 /// Returns the object safety violations that affect HIR ty lowering.
 ///
@@ -512,7 +512,7 @@ fn virtual_call_violations_for_method<'tcx>(
 ///
 /// This check is outlined from the object safety check to avoid cycles with
 /// layout computation, which relies on knowing whether methods are object safe.
-pub fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) {
+fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) {
     if !is_vtable_safe_method(tcx, trait_def_id, method) {
         return;
     }
@@ -906,7 +906,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEscapingBoundRegions<'tcx> {
     }
 }
 
-pub fn contains_illegal_impl_trait_in_trait<'tcx>(
+fn contains_illegal_impl_trait_in_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
     fn_def_id: DefId,
     ty: ty::Binder<'tcx, Ty<'tcx>>,
@@ -930,7 +930,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
     })
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers {
         object_safety_violations,
         is_object_safe,
diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs
index 7ead65721f9..f77f83ed447 100644
--- a/compiler/rustc_trait_selection/src/traits/select/_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs
@@ -21,12 +21,12 @@ use tracing::instrument;
 /// Like subtyping, matching is really a binary relation, so the only
 /// important thing about the result is Ok/Err. Also, matching never
 /// affects any type variables or unification state.
-pub struct MatchAgainstFreshVars<'tcx> {
+pub(crate) struct MatchAgainstFreshVars<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
 impl<'tcx> MatchAgainstFreshVars<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstFreshVars<'tcx> {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstFreshVars<'tcx> {
         MatchAgainstFreshVars { tcx }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 91fe19c20f7..241c3a3d141 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -991,7 +991,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     };
 
                     match self.infcx.at(&obligation.cause, obligation.param_env).eq(
-                        // Only really excercised by generic_const_exprs
+                        // Only really exercised by generic_const_exprs
                         DefineOpaqueTypes::Yes,
                         ct_ty,
                         ty,
@@ -3127,7 +3127,7 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
     }
 }
 
-pub enum ProjectionMatchesProjection {
+pub(crate) enum ProjectionMatchesProjection {
     Yes,
     Ambiguous,
     No,
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 0689b880f33..0fb13799e67 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -169,7 +169,7 @@ impl<'tcx> Iterator for TraitAliasExpander<'tcx> {
 /// Instantiate all bound parameters of the impl subject with the given args,
 /// returning the resulting subject and all obligations that arise.
 /// The obligations are closed under normalization.
-pub fn impl_subject_and_oblig<'a, 'tcx>(
+pub(crate) fn impl_subject_and_oblig<'a, 'tcx>(
     selcx: &SelectionContext<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     impl_def_id: DefId,
@@ -209,7 +209,7 @@ pub fn upcast_choices<'tcx>(
     supertraits(tcx, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect()
 }
 
-pub fn closure_trait_ref_and_return_type<'tcx>(
+pub(crate) fn closure_trait_ref_and_return_type<'tcx>(
     tcx: TyCtxt<'tcx>,
     fn_trait_def_id: DefId,
     self_ty: Ty<'tcx>,
@@ -238,7 +238,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
     sig.map_bound(|sig| (trait_ref, sig.output()))
 }
 
-pub fn coroutine_trait_ref_and_outputs<'tcx>(
+pub(crate) fn coroutine_trait_ref_and_outputs<'tcx>(
     tcx: TyCtxt<'tcx>,
     fn_trait_def_id: DefId,
     self_ty: Ty<'tcx>,
@@ -249,7 +249,7 @@ pub fn coroutine_trait_ref_and_outputs<'tcx>(
     (trait_ref, sig.yield_ty, sig.return_ty)
 }
 
-pub fn future_trait_ref_and_outputs<'tcx>(
+pub(crate) fn future_trait_ref_and_outputs<'tcx>(
     tcx: TyCtxt<'tcx>,
     fn_trait_def_id: DefId,
     self_ty: Ty<'tcx>,
@@ -260,7 +260,7 @@ pub fn future_trait_ref_and_outputs<'tcx>(
     (trait_ref, sig.return_ty)
 }
 
-pub fn iterator_trait_ref_and_outputs<'tcx>(
+pub(crate) fn iterator_trait_ref_and_outputs<'tcx>(
     tcx: TyCtxt<'tcx>,
     iterator_def_id: DefId,
     self_ty: Ty<'tcx>,
@@ -271,7 +271,7 @@ pub fn iterator_trait_ref_and_outputs<'tcx>(
     (trait_ref, sig.yield_ty)
 }
 
-pub fn async_iterator_trait_ref_and_outputs<'tcx>(
+pub(crate) fn async_iterator_trait_ref_and_outputs<'tcx>(
     tcx: TyCtxt<'tcx>,
     async_iterator_def_id: DefId,
     self_ty: Ty<'tcx>,
@@ -287,7 +287,7 @@ pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
         && tcx.defaultness(assoc_item.container_id(tcx)).is_final()
 }
 
-pub enum TupleArgumentsFlag {
+pub(crate) enum TupleArgumentsFlag {
     Yes,
     No,
 }
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index ada2c8e81de..11182198246 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -21,7 +21,7 @@ use tracing::debug;
 /// obligations *could be* resolved if we wanted to.
 ///
 /// This also expects that `trait_ref` is fully normalized.
-pub fn codegen_select_candidate<'tcx>(
+pub(crate) fn codegen_select_candidate<'tcx>(
     tcx: TyCtxt<'tcx>,
     (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>),
 ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 697c8391803..d2f979bd6d9 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -2,6 +2,7 @@
 
 // tidy-alphabetical-start
 #![recursion_limit = "256"]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod codegen;
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 2c67e7d4847..c3fd771b797 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -204,7 +204,7 @@ pub(crate) mod rustc {
     }
 
     impl<'tcx> Tree<Def<'tcx>, Ref<'tcx>> {
-        pub fn from_ty(ty: Ty<'tcx>, cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, Err> {
+        pub(crate) fn from_ty(ty: Ty<'tcx>, cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, Err> {
             use rustc_target::abi::HasDataLayout;
             let layout = layout_of(cx, ty)?;
 
diff --git a/compiler/rustc_transmute/src/layout/tree/tests.rs b/compiler/rustc_transmute/src/layout/tree/tests.rs
index 3cb47517c21..44f50a25c93 100644
--- a/compiler/rustc_transmute/src/layout/tree/tests.rs
+++ b/compiler/rustc_transmute/src/layout/tree/tests.rs
@@ -1,7 +1,7 @@
 use super::Tree;
 
 #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
-pub enum Def {
+enum Def {
     NoSafetyInvariants,
     HasSafetyInvariants,
 }
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index bdc98bcea5e..c1d0b704ab2 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -2,6 +2,7 @@
 #![allow(unused_variables)]
 #![feature(alloc_layout_extra)]
 #![feature(never_type)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
index 2762b4e6384..95eaedbf04a 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
@@ -242,7 +242,7 @@ where
                 //   }
                 // ...if `refs_answer` was computed lazily. The below early
                 // returns can be deleted without impacting the correctness of
-                // the algoritm; only its performance.
+                // the algorithm; only its performance.
                 debug!(?bytes_answer);
                 match bytes_answer {
                     Answer::No(_) if !self.assume.validity => return bytes_answer,
@@ -366,13 +366,13 @@ where
     }
 }
 
-pub enum Quantifier {
+enum Quantifier {
     ThereExists,
     ForAll,
 }
 
 impl Quantifier {
-    pub fn apply<R, I>(&self, iter: I) -> Answer<R>
+    fn apply<R, I>(&self, iter: I) -> Answer<R>
     where
         R: layout::Ref,
         I: IntoIterator<Item = Answer<R>>,
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 42ecaaeafa9..5497d7d0bd2 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -7,14 +7,14 @@ use rustc_span::Span;
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_needs_drop_overflow)]
-pub struct NeedsDropOverflow<'tcx> {
+pub(crate) struct NeedsDropOverflow<'tcx> {
     pub query_ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_generic_constant_too_complex)]
 #[help]
-pub struct GenericConstantTooComplex {
+pub(crate) struct GenericConstantTooComplex {
     #[primary_span]
     pub span: Span,
     #[note(ty_utils_maybe_supported)]
@@ -24,7 +24,7 @@ pub struct GenericConstantTooComplex {
 }
 
 #[derive(Subdiagnostic)]
-pub enum GenericConstantTooComplexSub {
+pub(crate) enum GenericConstantTooComplexSub {
     #[label(ty_utils_borrow_not_supported)]
     BorrowNotSupported(#[primary_span] Span),
     #[label(ty_utils_address_and_deref_not_supported)]
@@ -71,40 +71,40 @@ pub enum GenericConstantTooComplexSub {
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_unexpected_fnptr_associated_item)]
-pub struct UnexpectedFnPtrAssociatedItem {
+pub(crate) struct UnexpectedFnPtrAssociatedItem {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_zero_length_simd_type)]
-pub struct ZeroLengthSimdType<'tcx> {
+pub(crate) struct ZeroLengthSimdType<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_multiple_array_fields_simd_type)]
-pub struct MultipleArrayFieldsSimdType<'tcx> {
+pub(crate) struct MultipleArrayFieldsSimdType<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_oversized_simd_type)]
-pub struct OversizedSimdType<'tcx> {
+pub(crate) struct OversizedSimdType<'tcx> {
     pub ty: Ty<'tcx>,
     pub max_lanes: u64,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_non_primitive_simd_type)]
-pub struct NonPrimitiveSimdType<'tcx> {
+pub(crate) struct NonPrimitiveSimdType<'tcx> {
     pub ty: Ty<'tcx>,
     pub e_ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_impl_trait_duplicate_arg)]
-pub struct DuplicateArg<'tcx> {
+pub(crate) struct DuplicateArg<'tcx> {
     pub arg: GenericArg<'tcx>,
     #[primary_span]
     #[label]
@@ -115,7 +115,7 @@ pub struct DuplicateArg<'tcx> {
 
 #[derive(Diagnostic)]
 #[diag(ty_utils_impl_trait_not_param, code = E0792)]
-pub struct NotParam<'tcx> {
+pub(crate) struct NotParam<'tcx> {
     pub arg: GenericArg<'tcx>,
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index ad0bcbfbbc2..dc5303317a8 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -16,6 +16,7 @@
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index d42efbc91e1..f20beb79750 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -776,7 +776,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> {
     }
 
     /// It is sometimes necessary to adjust the De Bruijn indices during instantiation. This occurs
-    /// when we are instantating a type with escaping bound vars into a context where we have
+    /// when we are instantiating a type with escaping bound vars into a context where we have
     /// passed through binders. That's quite a mouthful. Let's see an example:
     ///
     /// ```
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 8e3534b0e9e..f49aa3431b5 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -354,7 +354,7 @@ struct Shifter<I: Interner> {
 }
 
 impl<I: Interner> Shifter<I> {
-    pub fn new(cx: I, amount: u32) -> Self {
+    fn new(cx: I, amount: u32) -> Self {
         Shifter { cx, current_index: ty::INNERMOST, amount }
     }
 }
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 958360faede..59a83ea5412 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -162,7 +162,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
 
     /// Returns `true` when the outermost type cannot be further normalized,
     /// resolved, or instantiated. This includes all primitive types, but also
-    /// things like ADTs and trait objects, sice even if their arguments or
+    /// things like ADTs and trait objects, since even if their arguments or
     /// nested types may be further simplified, the outermost [`ty::TyKind`] or
     /// type constructor remains the same.
     fn is_known_rigid(self) -> bool {
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index de41d2f3cc5..be261b348de 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -5,6 +5,8 @@
     feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
 )]
 #![cfg_attr(feature = "nightly", allow(internal_features))]
+#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_type_ir;
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 578436b622a..9c725f34d8e 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -550,7 +550,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
 /// Any semantic equality, e.g. of unevaluated consts, and inference variables have
 /// to be handled by the caller.
 ///
-/// FIXME: This is not totally structual, which probably should be fixed.
+/// FIXME: This is not totally structural, which probably should be fixed.
 /// See the HACKs below.
 pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
     relation: &mut R,
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 00fc6ba1c5c..96998d2ec9f 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -58,7 +58,7 @@ pub enum Reveal {
     All,
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum SolverMode {
     /// Ordinary trait solving, using everywhere except for coherence.
     Normal,
@@ -132,7 +132,7 @@ pub enum GoalSource {
     /// results in better error messages by avoiding spurious errors.
     /// We do not erase overflow constraints in `normalizes-to` goals unless
     /// they are from an impl where-clause. This is necessary due to
-    /// backwards compatability, cc trait-system-refactor-initiatitive#70.
+    /// backwards compatibility, cc trait-system-refactor-initiatitive#70.
     ImplWhereBound,
     /// Instantiating a higher-ranked goal and re-proving it.
     InstantiateHigherRanked,
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
index 9d3b40e5eea..317bec3050c 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/stable_mir/src/abi.rs
@@ -70,7 +70,7 @@ pub struct TyAndLayout {
 /// The layout of a type in memory.
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
 pub struct LayoutShape {
-    /// The fields location withing the layout
+    /// The fields location within the layout
     pub fields: FieldsShape,
 
     /// Encodes information about multi-variant layouts.
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 2f36aa51829..5bad3d5ae7a 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -267,7 +267,7 @@ impl Span {
         with(|c| c.get_filename(self))
     }
 
-    /// Return lines that corespond to this `Span`
+    /// Return lines that correspond to this `Span`
     pub fn get_lines(&self) -> LineInfo {
         with(|c| c.get_lines(self))
     }
diff --git a/config.example.toml b/config.example.toml
index f1dc32234cc..13f76933b16 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -230,6 +230,13 @@
 # use this rustfmt binary instead as the stage0 snapshot rustfmt.
 #rustfmt = "/path/to/rustfmt"
 
+# Instead of downloading the src/stage0 version of cargo-clippy specified,
+# use this cargo-clippy binary instead as the stage0 snapshot cargo-clippy.
+#
+# Note that this option should be used with the same toolchain as the `rustc` option above. 
+# Otherwise, clippy is likely to fail due to a toolchain conflict.
+#cargo-clippy = "/path/to/cargo-clippy"
+
 # Whether to build documentation by default. If false, rustdoc and
 # friends will still be compiled but they will not be used to generate any
 # documentation.
@@ -512,6 +519,9 @@
 # are disabled statically" because `max_level_info` is enabled, set this value to `true`.
 #debug-logging = rust.debug-assertions (boolean)
 
+# Whether or not to build rustc, tools and the libraries with randomized type layout
+#randomize-layout = false
+
 # Whether or not overflow checks are enabled for the compiler and standard
 # library.
 #
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 4365bcc4ad0..1bd4434d4f7 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -52,4 +52,5 @@ check-cfg = [
     'cfg(no_global_oom_handling)',
     'cfg(no_rc)',
     'cfg(no_sync)',
+    'cfg(randomized_layouts)',
 ]
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 38b1766c174..a924feaf15f 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -53,22 +53,20 @@
 //!
 //! # Memory layout
 //!
-//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
-//! its allocation. It is valid to convert both ways between a [`Box`] and a
-//! raw pointer allocated with the [`Global`] allocator, given that the
-//! [`Layout`] used with the allocator is correct for the type. More precisely,
-//! a `value: *mut T` that has been allocated with the [`Global`] allocator
-//! with `Layout::for_value(&*value)` may be converted into a box using
-//! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut
-//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
-//! [`Global`] allocator with [`Layout::for_value(&*value)`].
+//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for its allocation. It is
+//! valid to convert both ways between a [`Box`] and a raw pointer allocated with the [`Global`]
+//! allocator, given that the [`Layout`] used with the allocator is correct for the type and the raw
+//! pointer points to a valid value of the right type. More precisely, a `value: *mut T` that has
+//! been allocated with the [`Global`] allocator with `Layout::for_value(&*value)` may be converted
+//! into a box using [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut T`
+//! obtained from [`Box::<T>::into_raw`] may be deallocated using the [`Global`] allocator with
+//! [`Layout::for_value(&*value)`].
 //!
-//! For zero-sized values, the `Box` pointer still has to be [valid] for reads
-//! and writes and sufficiently aligned. In particular, casting any aligned
-//! non-zero integer literal to a raw pointer produces a valid pointer, but a
-//! pointer pointing into previously allocated memory that since got freed is
-//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot
-//! be used is to use [`ptr::NonNull::dangling`].
+//! For zero-sized values, the `Box` pointer has to be non-null and sufficiently aligned. The
+//! recommended way to build a Box to a ZST if `Box::new` cannot be used is to use
+//! [`ptr::NonNull::dangling`].
+//!
+//! On top of these basic layout requirements, a `Box<T>` must point to a valid value of `T`.
 //!
 //! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented
 //! as a single pointer and is also ABI-compatible with C pointers
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index f6f773cc42a..c7908578522 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -3302,7 +3302,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
         Some(kv)
     }
 
-    /// Removes the precending element from the `BTreeMap`.
+    /// Removes the preceding element from the `BTreeMap`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
@@ -3408,7 +3408,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> {
         self.inner.remove_next()
     }
 
-    /// Removes the precending element from the `BTreeMap`.
+    /// Removes the preceding element from the `BTreeMap`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs
index d230749d712..4d2fa0f0941 100644
--- a/library/alloc/src/collections/btree/node/tests.rs
+++ b/library/alloc/src/collections/btree/node/tests.rs
@@ -90,7 +90,7 @@ fn test_partial_eq() {
 
 #[test]
 #[cfg(target_arch = "x86_64")]
-#[cfg_attr(miri, ignore)] // We'd like to run Miri with layout randomization
+#[cfg_attr(any(miri, randomized_layouts), ignore)] // We'd like to run Miri with layout randomization
 fn test_sizes() {
     assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
     assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 973e7c66067..2b5bebcd8cd 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -2298,7 +2298,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
         self.inner.remove_next().map(|(k, _)| k)
     }
 
-    /// Removes the precending element from the `BTreeSet`.
+    /// Removes the preceding element from the `BTreeSet`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
@@ -2384,7 +2384,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
         self.inner.remove_next().map(|(k, _)| k)
     }
 
-    /// Removes the precending element from the `BTreeSet`.
+    /// Removes the preceding element from the `BTreeSet`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index cace4582b48..94f343d0670 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -43,6 +43,8 @@ check-cfg = [
     'cfg(bootstrap)',
     'cfg(no_fp_fmt_parse)',
     'cfg(stdarch_intel_sde)',
+    # #[cfg(bootstrap)] rtems
+    'cfg(target_os, values("rtems"))',
     # core use #[path] imports to portable-simd `core_simd` crate
     # and to stdarch `core_arch` crate which messes-up with Cargo list
     # of declared features, we therefor expect any feature cfg
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 61c713c9e81..c63f261edab 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -37,7 +37,7 @@ pub use iter::IntoIter;
 ///
 /// # Example
 ///
-/// Creating muliple copies of a `String`:
+/// Creating multiple copies of a `String`:
 /// ```rust
 /// #![feature(array_repeat)]
 ///
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index ec1f9052a15..dc107c5d22c 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -110,7 +110,7 @@ mod c_char_definition {
             all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
             all(target_os = "l4re", target_arch = "x86_64"),
             all(
-                any(target_os = "freebsd", target_os = "openbsd"),
+                any(target_os = "freebsd", target_os = "openbsd", target_os = "rtems"),
                 any(
                     target_arch = "aarch64",
                     target_arch = "arm",
diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs
index 8971a2c0aaf..16ac77fa150 100644
--- a/library/core/src/future/async_drop.rs
+++ b/library/core/src/future/async_drop.rs
@@ -157,7 +157,7 @@ async unsafe fn surface_drop_in_place<T: Drop + ?Sized>(ptr: *mut T) {
     unsafe { crate::ops::fallback_surface_drop(&mut *ptr) }
 }
 
-/// Wraps a future to continue outputing `Poll::Ready(())` once after
+/// Wraps a future to continue outputting `Poll::Ready(())` once after
 /// wrapped future completes by returning `Poll::Ready(())` on poll. This
 /// is useful for constructing async destructors to guarantee this
 /// "fuse" property
@@ -223,7 +223,7 @@ where
 /// # Safety
 ///
 /// Same as `async_drop_in_place` except is lazy to avoid creating
-/// multiple mutable refernces.
+/// multiple mutable references.
 #[lang = "async_drop_defer"]
 async unsafe fn defer<T: ?Sized>(to_drop: *mut T) {
     // SAFETY: same safety requirements as `async_drop_in_place`
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 6ca5e53df3b..a69f0afdb0a 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -1,6 +1,7 @@
 #![stable(feature = "core_hint", since = "1.27.0")]
 
 //! Hints to compiler that affects how code should be emitted or optimized.
+//!
 //! Hints may be compile time or runtime.
 
 use crate::{intrinsics, ub_checks};
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index c7cec396e1f..fb0aa5398a5 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -310,7 +310,7 @@ define!(
 );
 define!(
     "mir_unwind_cleanup",
-    /// An unwind action that continues execution in a given basic blok.
+    /// An unwind action that continues execution in a given basic block.
     fn UnwindCleanup(goto: BasicBlock) -> UnwindActionArg
 );
 
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index ac51a40d9f4..888832251f6 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1072,7 +1072,7 @@ pub(crate) mod builtin {
     /// If the environment variable is not defined, then a compilation error
     /// will be emitted. To not emit a compile error, use the [`option_env!`]
     /// macro instead. A compilation error will also be emitted if the
-    /// environment variable is not a vaild Unicode string.
+    /// environment variable is not a valid Unicode string.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5654f5aa4b8..d9f197d9510 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -288,8 +288,19 @@ marker_impls! {
 /// }
 /// ```
 ///
-/// There is a small difference between the two: the `derive` strategy will also place a `Copy`
-/// bound on type parameters, which isn't always desired.
+/// There is a small difference between the two. The `derive` strategy will also place a `Copy`
+/// bound on type parameters:
+///
+/// ```
+/// #[derive(Clone)]
+/// struct MyStruct<T>(T);
+///
+/// impl<T: Copy> Copy for MyStruct<T> { }
+/// ```
+///
+/// This isn't always desired. For example, shared references (`&T`) can be copied regardless of
+/// whether `T` is `Copy`. Likewise, a generic struct containing markers such as [`PhantomData`]
+/// could potentially be duplicated with a bit-wise copy.
 ///
 /// ## What's the difference between `Copy` and `Clone`?
 ///
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index 049b32ede9c..cda999a7f0c 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -149,7 +149,7 @@ where
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct Assume {
     /// When `false`, [`TransmuteFrom`] is not implemented for transmutations
-    /// that might violate the the alignment requirements of references; e.g.:
+    /// that might violate the alignment requirements of references; e.g.:
     ///
     #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
     #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")]
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index a7037b2a119..5451e45f6c8 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -832,8 +832,9 @@ mod prim_array {}
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
-/// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here
-/// means that elements are laid out so that every element is the same
+/// A dynamically-sized view into a contiguous sequence, `[T]`.
+///
+/// Contiguous here means that elements are laid out so that every element is the same
 /// distance from its neighbors.
 ///
 /// *[See also the `std::slice` module](crate::slice).*
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 85507eb8a73..2cf3fecb475 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -11,13 +11,13 @@ use crate::{array, ptr, ub_checks};
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+/// * `data` must be non-null, [valid] for reads for `len * mem::size_of::<T>()` many bytes,
 ///   and it must be properly aligned. This means in particular:
 ///
 ///     * The entire memory range of this slice must be contained within a single allocated object!
 ///       Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
 ///       for an example incorrectly not taking this into account.
-///     * `data` must be non-null and aligned even for zero-length slices. One
+///     * `data` must be non-null and aligned even for zero-length slices or slices of ZSTs. One
 ///       reason for this is that enum layout optimizations may rely on references
 ///       (including slices of any length) being aligned and non-null to distinguish
 ///       them from other data. You can obtain a pointer that is usable as `data`
@@ -146,12 +146,12 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * `data` must be [valid] for both reads and writes for `len * mem::size_of::<T>()` many bytes,
+/// * `data` must be non-null, [valid] for both reads and writes for `len * mem::size_of::<T>()` many bytes,
 ///   and it must be properly aligned. This means in particular:
 ///
 ///     * The entire memory range of this slice must be contained within a single allocated object!
 ///       Slices can never span across multiple allocated objects.
-///     * `data` must be non-null and aligned even for zero-length slices. One
+///     * `data` must be non-null and aligned even for zero-length slices or slices of ZSTs. One
 ///       reason for this is that enum layout optimizations may rely on references
 ///       (including slices of any length) being aligned and non-null to distinguish
 ///       them from other data. You can obtain a pointer that is usable as `data`
@@ -219,7 +219,7 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * The `start` pointer of the range must be a [valid] and properly aligned pointer
+/// * The `start` pointer of the range must be a non-null, [valid] and properly aligned pointer
 ///   to the first element of a slice.
 ///
 /// * The `end` pointer must be a [valid] and properly aligned pointer to *one past*
@@ -235,7 +235,7 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
 ///   of lifetime `'a`, except inside an `UnsafeCell`.
 ///
 /// * The total length of the range must be no larger than `isize::MAX`,
-///   and adding that size to `data` must not "wrap around" the address space.
+///   and adding that size to `start` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements.
@@ -288,7 +288,7 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * The `start` pointer of the range must be a [valid] and properly aligned pointer
+/// * The `start` pointer of the range must be a non-null, [valid] and properly aligned pointer
 ///   to the first element of a slice.
 ///
 /// * The `end` pointer must be a [valid] and properly aligned pointer to *one past*
@@ -305,7 +305,7 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
 ///   Both read and write accesses are forbidden.
 ///
 /// * The total length of the range must be no larger than `isize::MAX`,
-///   and adding that size to `data` must not "wrap around" the address space.
+///   and adding that size to `start` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements.
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 495d9191a9f..b06a3bd4487 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -3570,10 +3570,9 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 
 /// An atomic fence.
 ///
-/// Depending on the specified order, a fence prevents the compiler and CPU from
-/// reordering certain types of memory operations around it.
-/// That creates synchronizes-with relationships between it and atomic operations
-/// or fences in other threads.
+/// Fences create synchronization between themselves and atomic operations or fences in other
+/// threads. To achieve this, a fence prevents the compiler and CPU from reordering certain types of
+/// memory operations around it.
 ///
 /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
 /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
@@ -3594,6 +3593,12 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 ///                                                  }
 /// ```
 ///
+/// Note that in the example above, it is crucial that the accesses to `x` are atomic. Fences cannot
+/// be used to establish synchronization among non-atomic accesses in different threads. However,
+/// thanks to the happens-before relationship between A and B, any non-atomic accesses that
+/// happen-before A are now also properly synchronized with any non-atomic accesses that
+/// happen-after B.
+///
 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
 /// with a fence.
 ///
@@ -3659,33 +3664,30 @@ pub fn fence(order: Ordering) {
     }
 }
 
-/// A compiler memory fence.
+/// A "compiler-only" atomic fence.
 ///
-/// `compiler_fence` does not emit any machine code, but restricts the kinds
-/// of memory re-ordering the compiler is allowed to do. Specifically, depending on
-/// the given [`Ordering`] semantics, the compiler may be disallowed from moving reads
-/// or writes from before or after the call to the other side of the call to
-/// `compiler_fence`. Note that it does **not** prevent the *hardware*
-/// from doing such re-ordering. This is not a problem in a single-threaded,
-/// execution context, but when other threads may modify memory at the same
-/// time, stronger synchronization primitives such as [`fence`] are required.
+/// Like [`fence`], this function establishes synchronization with other atomic operations and
+/// fences. However, unlike [`fence`], `compiler_fence` only establishes synchronization with
+/// operations *in the same thread*. This may at first sound rather useless, since code within a
+/// thread is typically already totally ordered and does not need any further synchronization.
+/// However, there are cases where code can run on the same thread without being ordered:
+/// - The most common case is that of a *signal handler*: a signal handler runs in the same thread
+///   as the code it interrupted, but it is not ordered with respect to that code. `compiler_fence`
+///   can be used to establish synchronization between a thread and its signal handler, the same way
+///   that `fence` can be used to establish synchronization across threads.
+/// - Similar situations can arise in embedded programming with interrupt handlers, or in custom
+///   implementations of preemptive green threads. In general, `compiler_fence` can establish
+///   synchronization with code that is guaranteed to run on the same hardware CPU.
 ///
-/// The re-ordering prevented by the different ordering semantics are:
+/// See [`fence`] for how a fence can be used to achieve synchronization. Note that just like
+/// [`fence`], synchronization still requires atomic operations to be used in both threads -- it is
+/// not possible to perform synchronization entirely with fences and non-atomic operations.
 ///
-///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
-///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
-///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
-///  - with [`AcqRel`], both of the above rules are enforced.
+/// `compiler_fence` does not emit any machine code, but restricts the kinds of memory re-ordering
+/// the compiler is allowed to do. `compiler_fence` corresponds to [`atomic_signal_fence`] in C and
+/// C++.
 ///
-/// `compiler_fence` is generally only useful for preventing a thread from
-/// racing *with itself*. That is, if a given thread is executing one piece
-/// of code, and is then interrupted, and starts executing code elsewhere
-/// (while still in the same thread, and conceptually still on the same
-/// core). In traditional programs, this can only occur when a signal
-/// handler is registered. In more low-level code, such situations can also
-/// arise when handling interrupts, when implementing green threads with
-/// pre-emption, etc. Curious readers are encouraged to read the Linux kernel's
-/// discussion of [memory barriers].
+/// [`atomic_signal_fence`]: https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence
 ///
 /// # Panics
 ///
@@ -3723,8 +3725,6 @@ pub fn fence(order: Ordering) {
 ///     }
 /// }
 /// ```
-///
-/// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
 #[inline]
 #[stable(feature = "compiler_fences", since = "1.21.0")]
 #[rustc_diagnostic_item = "compiler_fence"]
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 7e5c1574f53..6924b3c13ec 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -60,22 +60,6 @@ impl RawWaker {
         RawWaker { data, vtable }
     }
 
-    /// Gets the `data` pointer used to create this `RawWaker`.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "waker_getters", issue = "96992")]
-    pub fn data(&self) -> *const () {
-        self.data
-    }
-
-    /// Gets the `vtable` pointer used to create this `RawWaker`.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "waker_getters", issue = "96992")]
-    pub fn vtable(&self) -> &'static RawWakerVTable {
-        self.vtable
-    }
-
     #[unstable(feature = "noop_waker", issue = "98286")]
     const NOOP: RawWaker = {
         const VTABLE: RawWakerVTable = RawWakerVTable::new(
@@ -509,6 +493,37 @@ impl Waker {
         a_data == b_data && ptr::eq(a_vtable, b_vtable)
     }
 
+    /// Creates a new `Waker` from the provided `data` pointer and `vtable`.
+    ///
+    /// The `data` pointer can be used to store arbitrary data as required
+    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
+    /// that is associated with the task.
+    /// The value of this pointer will get passed to all functions that are part
+    /// of the `vtable` as the first parameter.
+    ///
+    /// It is important to consider that the `data` pointer must point to a
+    /// thread safe type such as an `Arc`.
+    ///
+    /// The `vtable` customizes the behavior of a `Waker`. For each operation
+    /// on the `Waker`, the associated function in the `vtable` will be called.
+    ///
+    /// # Safety
+    ///
+    /// The behavior of the returned `Waker` is undefined if the contract defined
+    /// in [`RawWakerVTable`]'s documentation is not upheld.
+    ///
+    /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
+    /// cost of a required heap allocation.)
+    ///
+    /// [`Wake`]: ../../alloc/task/trait.Wake.html
+    #[inline]
+    #[must_use]
+    #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
+    pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
+        Waker { waker: RawWaker { data, vtable } }
+    }
+
     /// Creates a new `Waker` from [`RawWaker`].
     ///
     /// # Safety
@@ -565,12 +580,20 @@ impl Waker {
         WAKER
     }
 
-    /// Gets a reference to the underlying [`RawWaker`].
+    /// Gets the `data` pointer used to create this `Waker`.
     #[inline]
     #[must_use]
-    #[unstable(feature = "waker_getters", issue = "96992")]
-    pub fn as_raw(&self) -> &RawWaker {
-        &self.waker
+    #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
+    pub fn data(&self) -> *const () {
+        self.waker.data
+    }
+
+    /// Gets the `vtable` pointer used to create this `Waker`.
+    #[inline]
+    #[must_use]
+    #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
+    pub fn vtable(&self) -> &'static RawWakerVTable {
+        self.waker.vtable
     }
 }
 
@@ -778,6 +801,30 @@ impl LocalWaker {
         a_data == b_data && ptr::eq(a_vtable, b_vtable)
     }
 
+    /// Creates a new `LocalWaker` from the provided `data` pointer and `vtable`.
+    ///
+    /// The `data` pointer can be used to store arbitrary data as required
+    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
+    /// that is associated with the task.
+    /// The value of this pointer will get passed to all functions that are part
+    /// of the `vtable` as the first parameter.
+    ///
+    /// The `vtable` customizes the behavior of a `LocalWaker`. For each
+    /// operation on the `LocalWaker`, the associated function in the `vtable`
+    /// will be called.
+    ///
+    /// # Safety
+    ///
+    /// The behavior of the returned `Waker` is undefined if the contract defined
+    /// in [`RawWakerVTable`]'s documentation is not upheld.
+    ///
+    #[inline]
+    #[must_use]
+    #[unstable(feature = "local_waker", issue = "118959")]
+    pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
+        LocalWaker { waker: RawWaker { data, vtable } }
+    }
+
     /// Creates a new `LocalWaker` from [`RawWaker`].
     ///
     /// The behavior of the returned `LocalWaker` is undefined if the contract defined
@@ -831,12 +878,20 @@ impl LocalWaker {
         WAKER
     }
 
-    /// Gets a reference to the underlying [`RawWaker`].
+    /// Gets the `data` pointer used to create this `LocalWaker`.
     #[inline]
     #[must_use]
-    #[unstable(feature = "waker_getters", issue = "96992")]
-    pub fn as_raw(&self) -> &RawWaker {
-        &self.waker
+    #[unstable(feature = "local_waker", issue = "118959")]
+    pub fn data(&self) -> *const () {
+        self.waker.data
+    }
+
+    /// Gets the `vtable` pointer used to create this `LocalWaker`.
+    #[inline]
+    #[must_use]
+    #[unstable(feature = "local_waker", issue = "118959")]
+    pub fn vtable(&self) -> &'static RawWakerVTable {
+        self.waker.vtable
     }
 }
 #[unstable(feature = "local_waker", issue = "118959")]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index c205f028dd3..96fc621494f 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -112,7 +112,6 @@
 #![feature(unsize)]
 #![feature(unsized_tuple_coercion)]
 #![feature(unwrap_infallible)]
-#![feature(waker_getters)]
 // tidy-alphabetical-end
 #![allow(internal_features)]
 #![deny(fuzzy_provenance_casts)]
diff --git a/library/core/tests/waker.rs b/library/core/tests/waker.rs
index 361e900e695..8f6bf0565fc 100644
--- a/library/core/tests/waker.rs
+++ b/library/core/tests/waker.rs
@@ -4,14 +4,13 @@ use std::task::{RawWaker, RawWakerVTable, Waker};
 #[test]
 fn test_waker_getters() {
     let raw_waker = RawWaker::new(ptr::without_provenance_mut(42usize), &WAKER_VTABLE);
-    assert_eq!(raw_waker.data() as usize, 42);
-    assert!(ptr::eq(raw_waker.vtable(), &WAKER_VTABLE));
-
     let waker = unsafe { Waker::from_raw(raw_waker) };
+    assert_eq!(waker.data() as usize, 42);
+    assert!(ptr::eq(waker.vtable(), &WAKER_VTABLE));
+
     let waker2 = waker.clone();
-    let raw_waker2 = waker2.as_raw();
-    assert_eq!(raw_waker2.data() as usize, 43);
-    assert!(ptr::eq(raw_waker2.vtable(), &WAKER_VTABLE));
+    assert_eq!(waker2.data() as usize, 43);
+    assert!(ptr::eq(waker2.vtable(), &WAKER_VTABLE));
 }
 
 static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml
index f830808d196..6d1f9764efb 100644
--- a/library/panic_unwind/Cargo.toml
+++ b/library/panic_unwind/Cargo.toml
@@ -20,3 +20,10 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
 libc = { version = "0.2", default-features = false }
+
+[lints.rust.unexpected_cfgs]
+level = "warn"
+check-cfg = [
+    # #[cfg(bootstrap)] rtems
+    'cfg(target_os, values("rtems"))',
+]
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index 2d174f4b1a4..4552fb68d26 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -48,7 +48,7 @@ cfg_if::cfg_if! {
         target_os = "psp",
         target_os = "xous",
         target_os = "solid_asp3",
-        all(target_family = "unix", not(target_os = "espidf")),
+        all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
         all(target_vendor = "fortanix", target_env = "sgx"),
         target_family = "wasm",
     ))] {
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 82cfd603a21..e20fe9feff1 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -146,4 +146,6 @@ check-cfg = [
     # and to the `backtrace` crate which messes-up with Cargo list
     # of declared features, we therefor expect any feature cfg
     'cfg(feature, values(any()))',
+    # #[cfg(bootstrap)] rtems
+    'cfg(target_os, values("rtems"))',
 ]
diff --git a/library/std/build.rs b/library/std/build.rs
index fecdf2c3e1f..ba1eece46f3 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -53,6 +53,7 @@ fn main() {
         || target_os == "uefi"
         || target_os == "teeos"
         || target_os == "zkvm"
+        || target_os == "rtems"
 
         // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
         || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
@@ -142,7 +143,7 @@ fn main() {
 
     // Configure platforms that have reliable basics but may have unreliable math.
 
-    // LLVM is currenlty adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
+    // LLVM is currently adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
     let has_reliable_f16_math = has_reliable_f16
         && match (target_arch.as_str(), target_os.as_str()) {
             // FIXME: Disabled on Miri as the intrinsics are not implemented yet.
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index bb6a53bb290..24e5a1dfd5c 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -738,7 +738,7 @@ fn read_buf_full_read() {
 #[test]
 // Miri does not support signalling OOM
 #[cfg_attr(miri, ignore)]
-// 64-bit only to be sure the allocator will fail fast on an impossible to satsify size
+// 64-bit only to be sure the allocator will fail fast on an impossible to satisfy size
 #[cfg(target_pointer_width = "64")]
 fn try_oom_error() {
     let mut v = Vec::<u8>::new();
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 020a8b324f4..a2496baa63f 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -143,6 +143,8 @@ pub mod nto;
 pub mod openbsd;
 #[cfg(target_os = "redox")]
 pub mod redox;
+#[cfg(target_os = "rtems")]
+pub mod rtems;
 #[cfg(target_os = "solaris")]
 pub mod solaris;
 #[cfg(target_os = "solid_asp3")]
diff --git a/library/std/src/os/rtems/fs.rs b/library/std/src/os/rtems/fs.rs
new file mode 100644
index 00000000000..bec0d41e42d
--- /dev/null
+++ b/library/std/src/os/rtems/fs.rs
@@ -0,0 +1,374 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: crate::fs::Metadata
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Returns the device ID on which this file resides.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_dev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ino());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+
+    /// Returns the file type and mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mode());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+
+    /// Returns the number of hard links to file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_nlink());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+
+    /// Returns the user ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_uid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+
+    /// Returns the group ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_gid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+
+    /// Returns the device ID that this file represents. Only relevant for special file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_rdev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+
+    /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+    ///
+    /// The size of a symbolic link is the length of the pathname it contains,
+    /// without a terminating null byte.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_size());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+
+    /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
+    ///
+    /// [`st_atime`]: Self::st_atime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+
+    /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
+    ///
+    /// [`st_mtime`]: Self::st_mtime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+
+    /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
+    ///
+    /// [`st_ctime`]: Self::st_ctime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+
+    /// Returns the "preferred" block size for efficient filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blksize());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+
+    /// Returns the number of blocks allocated to the file, 512-byte units.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::rtems::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blocks());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+
+    fn st_atime_nsec(&self) -> i64 {
+        0
+    }
+
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+
+    fn st_mtime_nsec(&self) -> i64 {
+        0
+    }
+
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+
+    fn st_ctime_nsec(&self) -> i64 {
+        0
+    }
+
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/library/std/src/os/rtems/mod.rs b/library/std/src/os/rtems/mod.rs
new file mode 100644
index 00000000000..7275bfd1765
--- /dev/null
+++ b/library/std/src/os/rtems/mod.rs
@@ -0,0 +1,4 @@
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![forbid(unsafe_op_in_unsafe_fn)]
+pub mod fs;
+pub(crate) mod raw;
diff --git a/library/std/src/os/rtems/raw.rs b/library/std/src/os/rtems/raw.rs
new file mode 100644
index 00000000000..113079cf4ab
--- /dev/null
+++ b/library/std/src/os/rtems/raw.rs
@@ -0,0 +1,33 @@
+//! rtems raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![deprecated(
+    since = "1.8.0",
+    note = "these type aliases are no longer supported by \
+            the standard library, the `libc` crate on \
+            crates.io should be used instead for the correct \
+            definitions"
+)]
+#![allow(deprecated)]
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = libc::pthread_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = libc::blkcnt_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = libc::blksize_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = libc::dev_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = libc::ino_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = libc::mode_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = libc::nlink_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = libc::off_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = libc::time_t;
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index c6581b9c4c8..7d2f0bd4efe 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -73,6 +73,8 @@ mod platform {
     pub use crate::os::openbsd::*;
     #[cfg(target_os = "redox")]
     pub use crate::os::redox::*;
+    #[cfg(target_os = "rtems")]
+    pub use crate::os::rtems::*;
     #[cfg(target_os = "solaris")]
     pub use crate::os::solaris::*;
     #[cfg(target_os = "vita")]
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index bbea27ebc10..a155855029e 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -617,8 +617,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -699,8 +697,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -748,8 +744,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -786,8 +780,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -822,8 +814,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::{Command, Stdio};
     /// use std::env;
@@ -870,8 +860,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -900,8 +888,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -928,8 +914,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -959,8 +943,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::{Command, Stdio};
     ///
@@ -988,8 +970,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::{Command, Stdio};
     ///
@@ -1017,8 +997,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::{Command, Stdio};
     ///
@@ -1039,8 +1017,6 @@ impl Command {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -2105,8 +2081,6 @@ impl Child {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -2129,8 +2103,6 @@ impl Child {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -2158,8 +2130,6 @@ impl Child {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -2194,8 +2164,6 @@ impl Child {
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```no_run
     /// use std::process::Command;
     ///
@@ -2398,15 +2366,11 @@ pub fn abort() -> ! {
 ///
 /// # Examples
 ///
-/// Basic usage:
-///
 /// ```no_run
 /// use std::process;
 ///
 /// println!("My pid is {}", process::id());
 /// ```
-///
-///
 #[must_use]
 #[stable(feature = "getpid", since = "1.26.0")]
 pub fn id() -> u32 {
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 307a543c9d2..b6f36931ec2 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -146,7 +146,7 @@ fn lang_start_internal(
             rtabort!("drop of the panic payload panicked");
         });
     panic::catch_unwind(cleanup).map_err(rt_abort)?;
-    // Guard against multple threads calling `libc::exit` concurrently.
+    // Guard against multiple threads calling `libc::exit` concurrently.
     // See the documentation for `unique_thread_exit` for more information.
     panic::catch_unwind(|| crate::sys::exit_guard::unique_thread_exit()).map_err(rt_abort)?;
     ret_code
diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs
index bbe205cad04..88a8c75f7c8 100644
--- a/library/std/src/sync/mpmc/list.rs
+++ b/library/std/src/sync/mpmc/list.rs
@@ -551,7 +551,7 @@ impl<T> Channel<T> {
 
         let mut head = self.head.index.load(Ordering::Acquire);
         // The channel may be uninitialized, so we have to swap to avoid overwriting any sender's attempts
-        // to initalize the first block before noticing that the receivers disconnected. Late allocations
+        // to initialize the first block before noticing that the receivers disconnected. Late allocations
         // will be deallocated by the sender in Drop.
         let mut block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel);
 
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index a51e5c1b76b..be615a5a8ef 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -517,7 +517,7 @@ impl<T> OnceLock<T> {
                     res = Err(e);
 
                     // Treat the underlying `Once` as poisoned since we
-                    // failed to initialize our value. Calls
+                    // failed to initialize our value.
                     p.poison();
                 }
             }
diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs
index 84a0b36db17..0b23681e907 100644
--- a/library/std/src/sync/reentrant_lock.rs
+++ b/library/std/src/sync/reentrant_lock.rs
@@ -136,7 +136,7 @@ cfg_if!(
             // match do we read out the actual TID.
             // Note also that we can use relaxed atomic operations here, because
             // we only ever read from the tid if `tls_addr` matches the current
-            // TLS address. In that case, either the the tid has been set by
+            // TLS address. In that case, either the tid has been set by
             // the current thread, or by a thread that has terminated before
             // the current thread was created. In either case, no further
             // synchronization is needed (as per <https://github.com/rust-lang/miri/issues/3450>)
diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs
index 591be66fcb4..bce9aa6d99c 100644
--- a/library/std/src/sys/pal/solid/fs.rs
+++ b/library/std/src/sys/pal/solid/fs.rs
@@ -538,7 +538,7 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
             }
         };
         // ignore internal NotFound errors
-        if let Err(err) = result
+        if let Err(err) = &result
             && err.kind() != io::ErrorKind::NotFound
         {
             return result;
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index fdc5f5d7e4f..0cc9cecb89d 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -470,7 +470,7 @@ mod uefi_command_internal {
             let st_size = unsafe { (*self.st.as_ptr()).hdr.header_size as usize };
             let mut crc32: u32 = 0;
 
-            // Set crc to 0 before calcuation
+            // Set crc to 0 before calculation
             unsafe {
                 (*self.st.as_mut_ptr()).hdr.crc32 = 0;
             }
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs
index 9a37e1a0346..a943e3a581a 100644
--- a/library/std/src/sys/pal/unix/args.rs
+++ b/library/std/src/sys/pal/unix/args.rs
@@ -112,6 +112,7 @@ impl DoubleEndedIterator for Args {
     target_os = "aix",
     target_os = "nto",
     target_os = "hurd",
+    target_os = "rtems",
 ))]
 mod imp {
     use crate::ffi::c_char;
diff --git a/library/std/src/sys/pal/unix/env.rs b/library/std/src/sys/pal/unix/env.rs
index fb1f868644d..b2d399b8791 100644
--- a/library/std/src/sys/pal/unix/env.rs
+++ b/library/std/src/sys/pal/unix/env.rs
@@ -240,6 +240,17 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
+#[cfg(target_os = "rtems")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "rtems";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
+
 #[cfg(target_os = "vxworks")]
 pub mod os {
     pub const FAMILY: &str = "unix";
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 7fa147c9754..4ec577a0a01 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -478,6 +478,7 @@ impl FileAttr {
         target_os = "horizon",
         target_os = "vita",
         target_os = "hurd",
+        target_os = "rtems",
     )))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         #[cfg(target_pointer_width = "32")]
@@ -490,7 +491,12 @@ impl FileAttr {
         SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64)
     }
 
-    #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
+    #[cfg(any(
+        target_os = "vxworks",
+        target_os = "espidf",
+        target_os = "vita",
+        target_os = "rtems",
+    ))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_mtime as i64, 0)
     }
@@ -506,6 +512,7 @@ impl FileAttr {
         target_os = "horizon",
         target_os = "vita",
         target_os = "hurd",
+        target_os = "rtems",
     )))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         #[cfg(target_pointer_width = "32")]
@@ -518,7 +525,12 @@ impl FileAttr {
         SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64)
     }
 
-    #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
+    #[cfg(any(
+        target_os = "vxworks",
+        target_os = "espidf",
+        target_os = "vita",
+        target_os = "rtems"
+    ))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_atime as i64, 0)
     }
@@ -853,6 +865,7 @@ impl Drop for Dir {
             target_os = "fuchsia",
             target_os = "horizon",
             target_os = "vxworks",
+            target_os = "rtems",
         )))]
         {
             let fd = unsafe { libc::dirfd(self.0) };
@@ -970,6 +983,7 @@ impl DirEntry {
         target_os = "aix",
         target_os = "nto",
         target_os = "hurd",
+        target_os = "rtems",
         target_vendor = "apple",
     ))]
     pub fn ino(&self) -> u64 {
diff --git a/library/std/src/sys/pal/unix/l4re.rs b/library/std/src/sys/pal/unix/l4re.rs
index fe9559f2a56..52d39dcfb16 100644
--- a/library/std/src/sys/pal/unix/l4re.rs
+++ b/library/std/src/sys/pal/unix/l4re.rs
@@ -54,6 +54,10 @@ pub mod net {
             unimpl!();
         }
 
+        pub fn read_buf(&self, _: BorrowedCursor<'_>) -> io::Result<()> {
+            unimpl!();
+        }
+
         pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
             unimpl!();
         }
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index ba2f58f9c10..e8428eccb16 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -79,6 +79,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_os = "l4re",
             target_os = "horizon",
             target_os = "vita",
+            target_os = "rtems",
             // The poll on Darwin doesn't set POLLNVAL for closed fds.
             target_vendor = "apple",
         )))]
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index bc0e3f4eeea..d75a666d350 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -215,7 +215,7 @@ impl Socket {
                 _ => {
                     if cfg!(target_os = "vxworks") {
                         // VxWorks poll does not return  POLLHUP or POLLERR in revents. Check if the
-                        // connnection actually succeeded and return ok only when the socket is
+                        // connection actually succeeded and return ok only when the socket is
                         // ready and no errors were found.
                         if let Some(e) = self.take_error()? {
                             return Err(e);
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index a785b97ac8d..503f8915256 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
 }
 
 extern "C" {
-    #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
+    #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
     #[cfg_attr(
         any(
             target_os = "linux",
@@ -61,13 +61,14 @@ extern "C" {
 }
 
 /// Returns the platform-specific value of errno
-#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
+#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
 pub fn errno() -> i32 {
     unsafe { (*errno_location()) as i32 }
 }
 
 /// Sets the platform-specific value of errno
-#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks")))] // needed for readdir and syscall!
+// needed for readdir and syscall!
+#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
 #[allow(dead_code)] // but not all target cfgs actually end up using it
 pub fn set_errno(e: i32) {
     unsafe { *errno_location() = e as c_int }
@@ -78,6 +79,16 @@ pub fn errno() -> i32 {
     unsafe { libc::errnoGet() }
 }
 
+#[cfg(target_os = "rtems")]
+pub fn errno() -> i32 {
+    extern "C" {
+        #[thread_local]
+        static _tls_errno: c_int;
+    }
+
+    unsafe { _tls_errno as i32 }
+}
+
 #[cfg(target_os = "dragonfly")]
 pub fn errno() -> i32 {
     extern "C" {
@@ -472,7 +483,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
-#[cfg(target_os = "redox")]
+#[cfg(any(target_os = "redox", target_os = "rtems"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     crate::fs::read_to_string("sys:exe").map(PathBuf::from)
 }
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 9d091f033e0..4bb22f36709 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -1089,13 +1089,13 @@ fn signal_string(signal: i32) -> &'static str {
         libc::SIGURG => " (SIGURG)",
         #[cfg(not(target_os = "l4re"))]
         libc::SIGXCPU => " (SIGXCPU)",
-        #[cfg(not(target_os = "l4re"))]
+        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
         libc::SIGXFSZ => " (SIGXFSZ)",
-        #[cfg(not(target_os = "l4re"))]
+        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
         libc::SIGVTALRM => " (SIGVTALRM)",
         #[cfg(not(target_os = "l4re"))]
         libc::SIGPROF => " (SIGPROF)",
-        #[cfg(not(target_os = "l4re"))]
+        #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
         libc::SIGWINCH => " (SIGWINCH)",
         #[cfg(not(any(target_os = "haiku", target_os = "l4re")))]
         libc::SIGIO => " (SIGIO)",
diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs
index 00c816a6c09..9e336ff2d47 100644
--- a/library/std/src/sys/pal/windows/api.rs
+++ b/library/std/src/sys/pal/windows/api.rs
@@ -254,7 +254,7 @@ pub struct WinError {
     pub code: u32,
 }
 impl WinError {
-    const fn new(code: u32) -> Self {
+    pub const fn new(code: u32) -> Self {
         Self { code }
     }
 }
@@ -272,8 +272,11 @@ impl WinError {
     // tidy-alphabetical-start
     pub const ACCESS_DENIED: Self = Self::new(c::ERROR_ACCESS_DENIED);
     pub const ALREADY_EXISTS: Self = Self::new(c::ERROR_ALREADY_EXISTS);
+    pub const BAD_NET_NAME: Self = Self::new(c::ERROR_BAD_NET_NAME);
+    pub const BAD_NETPATH: Self = Self::new(c::ERROR_BAD_NETPATH);
     pub const CANT_ACCESS_FILE: Self = Self::new(c::ERROR_CANT_ACCESS_FILE);
     pub const DELETE_PENDING: Self = Self::new(c::ERROR_DELETE_PENDING);
+    pub const DIR_NOT_EMPTY: Self = Self::new(c::ERROR_DIR_NOT_EMPTY);
     pub const DIRECTORY: Self = Self::new(c::ERROR_DIRECTORY);
     pub const FILE_NOT_FOUND: Self = Self::new(c::ERROR_FILE_NOT_FOUND);
     pub const INSUFFICIENT_BUFFER: Self = Self::new(c::ERROR_INSUFFICIENT_BUFFER);
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index afacc370c34..9c2e4500da0 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -34,6 +34,7 @@ Windows.Wdk.Storage.FileSystem.FILE_WRITE_THROUGH
 Windows.Wdk.Storage.FileSystem.NtCreateFile
 Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_DISPOSITION
 Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_OPTIONS
+Windows.Wdk.Storage.FileSystem.NtOpenFile
 Windows.Wdk.Storage.FileSystem.NtReadFile
 Windows.Wdk.Storage.FileSystem.NtWriteFile
 Windows.Wdk.Storage.FileSystem.SYMLINK_FLAG_RELATIVE
@@ -1931,10 +1932,14 @@ Windows.Win32.Foundation.RtlNtStatusToDosError
 Windows.Win32.Foundation.SetHandleInformation
 Windows.Win32.Foundation.SetLastError
 Windows.Win32.Foundation.STATUS_DELETE_PENDING
+Windows.Win32.Foundation.STATUS_DIRECTORY_NOT_EMPTY
 Windows.Win32.Foundation.STATUS_END_OF_FILE
+Windows.Win32.Foundation.STATUS_FILE_DELETED
+Windows.Win32.Foundation.STATUS_INVALID_HANDLE
 Windows.Win32.Foundation.STATUS_INVALID_PARAMETER
 Windows.Win32.Foundation.STATUS_NOT_IMPLEMENTED
 Windows.Win32.Foundation.STATUS_PENDING
+Windows.Win32.Foundation.STATUS_SHARING_VIOLATION
 Windows.Win32.Foundation.STATUS_SUCCESS
 Windows.Win32.Foundation.TRUE
 Windows.Win32.Foundation.UNICODE_STRING
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 529c96a0e1e..ab5f8919d7a 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -105,6 +105,7 @@ windows_targets::link!("kernel32.dll" "system" fn WideCharToMultiByte(codepage :
 windows_targets::link!("kernel32.dll" "system" fn WriteConsoleW(hconsoleoutput : HANDLE, lpbuffer : PCWSTR, nnumberofcharstowrite : u32, lpnumberofcharswritten : *mut u32, lpreserved : *const core::ffi::c_void) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn WriteFileEx(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
 windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
@@ -2982,10 +2983,14 @@ pub struct STARTUPINFOW {
 }
 pub type STARTUPINFOW_FLAGS = u32;
 pub const STATUS_DELETE_PENDING: NTSTATUS = 0xC0000056_u32 as _;
+pub const STATUS_DIRECTORY_NOT_EMPTY: NTSTATUS = 0xC0000101_u32 as _;
 pub const STATUS_END_OF_FILE: NTSTATUS = 0xC0000011_u32 as _;
+pub const STATUS_FILE_DELETED: NTSTATUS = 0xC0000123_u32 as _;
+pub const STATUS_INVALID_HANDLE: NTSTATUS = 0xC0000008_u32 as _;
 pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xC000000D_u32 as _;
 pub const STATUS_NOT_IMPLEMENTED: NTSTATUS = 0xC0000002_u32 as _;
 pub const STATUS_PENDING: NTSTATUS = 0x103_u32 as _;
+pub const STATUS_SHARING_VIOLATION: NTSTATUS = 0xC0000043_u32 as _;
 pub const STATUS_SUCCESS: NTSTATUS = 0x0_u32 as _;
 pub const STD_ERROR_HANDLE: STD_HANDLE = 4294967284u32;
 pub type STD_HANDLE = u32;
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 2134152ea93..5b360640c4e 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -14,8 +14,11 @@ use crate::sys::handle::Handle;
 use crate::sys::path::maybe_verbatim;
 use crate::sys::time::SystemTime;
 use crate::sys::{c, cvt, Align8};
-use crate::sys_common::{ignore_notfound, AsInner, FromInner, IntoInner};
-use crate::{fmt, ptr, slice, thread};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::{fmt, ptr, slice};
+
+mod remove_dir_all;
+use remove_dir_all::remove_dir_all_iterative;
 
 pub struct File {
     handle: Handle,
@@ -646,6 +649,22 @@ impl File {
             Ok(info)
         }
     }
+
+    /// Deletes the file, consuming the file handle to ensure the delete occurs
+    /// as immediately as possible.
+    /// This attempts to use `posix_delete` but falls back to `win32_delete`
+    /// if that is not supported by the filesystem.
+    #[allow(unused)]
+    fn delete(self) -> Result<(), WinError> {
+        // If POSIX delete is not supported for this filesystem then fallback to win32 delete.
+        match self.posix_delete() {
+            Err(WinError::INVALID_PARAMETER)
+            | Err(WinError::NOT_SUPPORTED)
+            | Err(WinError::INVALID_FUNCTION) => self.win32_delete(),
+            result => result,
+        }
+    }
+
     /// Delete using POSIX semantics.
     ///
     /// Files will be deleted as soon as the handle is closed. This is supported
@@ -654,21 +673,23 @@ impl File {
     ///
     /// If the operation is not supported for this filesystem or OS version
     /// then errors will be `ERROR_NOT_SUPPORTED` or `ERROR_INVALID_PARAMETER`.
-    fn posix_delete(&self) -> io::Result<()> {
+    #[allow(unused)]
+    fn posix_delete(&self) -> Result<(), WinError> {
         let info = c::FILE_DISPOSITION_INFO_EX {
             Flags: c::FILE_DISPOSITION_FLAG_DELETE
                 | c::FILE_DISPOSITION_FLAG_POSIX_SEMANTICS
                 | c::FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE,
         };
-        api::set_file_information_by_handle(self.handle.as_raw_handle(), &info).io_result()
+        api::set_file_information_by_handle(self.handle.as_raw_handle(), &info)
     }
 
     /// Delete a file using win32 semantics. The file won't actually be deleted
     /// until all file handles are closed. However, marking a file for deletion
     /// will prevent anyone from opening a new handle to the file.
-    fn win32_delete(&self) -> io::Result<()> {
+    #[allow(unused)]
+    fn win32_delete(&self) -> Result<(), WinError> {
         let info = c::FILE_DISPOSITION_INFO { DeleteFile: c::TRUE as _ };
-        api::set_file_information_by_handle(self.handle.as_raw_handle(), &info).io_result()
+        api::set_file_information_by_handle(self.handle.as_raw_handle(), &info)
     }
 
     /// Fill the given buffer with as many directory entries as will fit.
@@ -684,21 +705,23 @@ impl File {
     /// A symlink directory is simply an empty directory with some "reparse" metadata attached.
     /// So if you open a link (not its target) and iterate the directory,
     /// you will always iterate an empty directory regardless of the target.
-    fn fill_dir_buff(&self, buffer: &mut DirBuff, restart: bool) -> io::Result<bool> {
+    #[allow(unused)]
+    fn fill_dir_buff(&self, buffer: &mut DirBuff, restart: bool) -> Result<bool, WinError> {
         let class =
             if restart { c::FileIdBothDirectoryRestartInfo } else { c::FileIdBothDirectoryInfo };
 
         unsafe {
-            let result = cvt(c::GetFileInformationByHandleEx(
-                self.handle.as_raw_handle(),
+            let result = c::GetFileInformationByHandleEx(
+                self.as_raw_handle(),
                 class,
                 buffer.as_mut_ptr().cast(),
                 buffer.capacity() as _,
-            ));
-            match result {
-                Ok(_) => Ok(true),
-                Err(e) if e.raw_os_error() == Some(c::ERROR_NO_MORE_FILES as _) => Ok(false),
-                Err(e) => Err(e),
+            );
+            if result == 0 {
+                let err = api::get_last_error();
+                if err.code == c::ERROR_NO_MORE_FILES { Ok(false) } else { Err(err) }
+            } else {
+                Ok(true)
             }
         }
     }
@@ -804,62 +827,6 @@ unsafe fn from_maybe_unaligned<'a>(p: *const u16, len: usize) -> Cow<'a, [u16]>
     }
 }
 
-/// Open a link relative to the parent directory, ensure no symlinks are followed.
-fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
-    // This is implemented using the lower level `NtCreateFile` function as
-    // unfortunately opening a file relative to a parent is not supported by
-    // win32 functions. It is however a fundamental feature of the NT kernel.
-    //
-    // See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
-    unsafe {
-        let mut handle = ptr::null_mut();
-        let mut io_status = c::IO_STATUS_BLOCK::PENDING;
-        let mut name_str = c::UNICODE_STRING::from_ref(name);
-        use crate::sync::atomic::{AtomicU32, Ordering};
-        // The `OBJ_DONT_REPARSE` attribute ensures that we haven't been
-        // tricked into following a symlink. However, it may not be available in
-        // earlier versions of Windows.
-        static ATTRIBUTES: AtomicU32 = AtomicU32::new(c::OBJ_DONT_REPARSE);
-        let object = c::OBJECT_ATTRIBUTES {
-            ObjectName: &mut name_str,
-            RootDirectory: parent.as_raw_handle(),
-            Attributes: ATTRIBUTES.load(Ordering::Relaxed),
-            ..c::OBJECT_ATTRIBUTES::default()
-        };
-        let status = c::NtCreateFile(
-            &mut handle,
-            access,
-            &object,
-            &mut io_status,
-            crate::ptr::null_mut(),
-            0,
-            c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE,
-            c::FILE_OPEN,
-            // If `name` is a symlink then open the link rather than the target.
-            c::FILE_OPEN_REPARSE_POINT,
-            crate::ptr::null_mut(),
-            0,
-        );
-        // Convert an NTSTATUS to the more familiar Win32 error codes (aka "DosError")
-        if c::nt_success(status) {
-            Ok(File::from_raw_handle(handle))
-        } else if status == c::STATUS_DELETE_PENDING {
-            // We make a special exception for `STATUS_DELETE_PENDING` because
-            // otherwise this will be mapped to `ERROR_ACCESS_DENIED` which is
-            // very unhelpful.
-            Err(io::Error::from_raw_os_error(c::ERROR_DELETE_PENDING as i32))
-        } else if status == c::STATUS_INVALID_PARAMETER
-            && ATTRIBUTES.load(Ordering::Relaxed) == c::OBJ_DONT_REPARSE
-        {
-            // Try without `OBJ_DONT_REPARSE`. See above.
-            ATTRIBUTES.store(0, Ordering::Relaxed);
-            open_link_no_reparse(parent, name, access)
-        } else {
-            Err(io::Error::from_raw_os_error(c::RtlNtStatusToDosError(status) as _))
-        }
-    }
-}
-
 impl AsInner<Handle> for File {
     #[inline]
     fn as_inner(&self) -> &Handle {
@@ -1142,114 +1109,22 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
     Ok(())
 }
 
-/// Open a file or directory without following symlinks.
-fn open_link(path: &Path, access_mode: u32) -> io::Result<File> {
+pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    // Open a file or directory without following symlinks.
     let mut opts = OpenOptions::new();
-    opts.access_mode(access_mode);
+    opts.access_mode(c::FILE_LIST_DIRECTORY);
     // `FILE_FLAG_BACKUP_SEMANTICS` allows opening directories.
     // `FILE_FLAG_OPEN_REPARSE_POINT` opens a link instead of its target.
     opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT);
-    File::open(path, &opts)
-}
-
-pub fn remove_dir_all(path: &Path) -> io::Result<()> {
-    let file = open_link(path, c::DELETE | c::FILE_LIST_DIRECTORY)?;
+    let file = File::open(path, &opts)?;
 
     // Test if the file is not a directory or a symlink to a directory.
     if (file.basic_info()?.FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) == 0 {
         return Err(io::Error::from_raw_os_error(c::ERROR_DIRECTORY as _));
     }
 
-    match ignore_notfound(remove_dir_all_iterative(&file, File::posix_delete)) {
-        Err(e) => {
-            if let Some(code) = e.raw_os_error() {
-                match code as u32 {
-                    // If POSIX delete is not supported for this filesystem then fallback to win32 delete.
-                    c::ERROR_NOT_SUPPORTED
-                    | c::ERROR_INVALID_FUNCTION
-                    | c::ERROR_INVALID_PARAMETER => {
-                        remove_dir_all_iterative(&file, File::win32_delete)
-                    }
-                    _ => Err(e),
-                }
-            } else {
-                Err(e)
-            }
-        }
-        ok => ok,
-    }
-}
-
-fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
-    // When deleting files we may loop this many times when certain error conditions occur.
-    // This allows remove_dir_all to succeed when the error is temporary.
-    const MAX_RETRIES: u32 = 10;
-
-    let mut buffer = DirBuff::new();
-    let mut dirlist = vec![f.duplicate()?];
-
-    // FIXME: This is a hack so we can push to the dirlist vec after borrowing from it.
-    fn copy_handle(f: &File) -> mem::ManuallyDrop<File> {
-        unsafe { mem::ManuallyDrop::new(File::from_raw_handle(f.as_raw_handle())) }
-    }
-
-    let mut restart = true;
-    while let Some(dir) = dirlist.last() {
-        let dir = copy_handle(dir);
-
-        // Fill the buffer and iterate the entries.
-        let more_data = dir.fill_dir_buff(&mut buffer, restart)?;
-        restart = false;
-        for (name, is_directory) in buffer.iter() {
-            if is_directory {
-                let child_dir = open_link_no_reparse(
-                    &dir,
-                    &name,
-                    c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
-                );
-                // On success, add the handle to the queue.
-                // If opening the directory fails we treat it the same as a file
-                if let Ok(child_dir) = child_dir {
-                    dirlist.push(child_dir);
-                    continue;
-                }
-            }
-            for i in 1..=MAX_RETRIES {
-                let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
-                match result {
-                    Ok(f) => delete(&f)?,
-                    // Already deleted, so skip.
-                    Err(e) if e.kind() == io::ErrorKind::NotFound => break,
-                    // Retry a few times if the file is locked or a delete is already in progress.
-                    Err(e)
-                        if i < MAX_RETRIES
-                            && (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
-                                || e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _)) => {}
-                    // Otherwise return the error.
-                    Err(e) => return Err(e),
-                }
-                thread::yield_now();
-            }
-        }
-        // If there were no more files then delete the directory.
-        if !more_data {
-            if let Some(dir) = dirlist.pop() {
-                // Retry deleting a few times in case we need to wait for a file to be deleted.
-                for i in 1..=MAX_RETRIES {
-                    let result = delete(&dir);
-                    if let Err(e) = result {
-                        if i == MAX_RETRIES || e.kind() != io::ErrorKind::DirectoryNotEmpty {
-                            return Err(e);
-                        }
-                        thread::yield_now();
-                    } else {
-                        break;
-                    }
-                }
-            }
-        }
-    }
-    Ok(())
+    // Remove the directory and all its contents.
+    remove_dir_all_iterative(file).io_result()
 }
 
 pub fn readlink(path: &Path) -> io::Result<PathBuf> {
diff --git a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
new file mode 100644
index 00000000000..e7234ed8e5f
--- /dev/null
+++ b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
@@ -0,0 +1,196 @@
+//! The Windows implementation of std::fs::remove_dir_all.
+//!
+//! This needs to address two issues:
+//!
+//! - It must not be possible to trick this into deleting files outside of
+//!   the parent directory (see CVE-2022-21658).
+//! - It should not fail if many threads or processes call `remove_dir_all`
+//!   on the same path.
+//!
+//! The first is handled by using the low-level `NtOpenFile` API to open a file
+//! relative to a parent directory.
+//!
+//! The second is trickier. Deleting a file works by setting its "disposition"
+//! to delete. However, it isn't actually deleted until the file is closed.
+//! During the gap between these two events, the file is in a kind of limbo
+//! state where it still exists in the filesystem but anything trying to open
+//! it fails with an error.
+//!
+//! The mitigations we use here are:
+//!
+//! - When attempting to open the file, we treat ERROR_DELETE_PENDING as a
+//!   successful delete.
+//! - If the file still hasn't been removed from the filesystem by the time we
+//!   attempt to delete the parent directory, we try to wait for it to finish.
+//!   We can't wait indefinitely though so after some number of spins, we give
+//!   up and return an error.
+//!
+//! In short, we can't guarantee this will always succeed in the event of a
+//! race but we do make a best effort such that it *should* do so.
+
+use core::ptr;
+use core::sync::atomic::{AtomicU32, Ordering};
+
+use super::{AsRawHandle, DirBuff, File, FromRawHandle};
+use crate::sys::c;
+use crate::sys::pal::windows::api::WinError;
+use crate::thread;
+
+// The maximum number of times to spin when waiting for deletes to complete.
+const MAX_RETRIES: usize = 50;
+
+/// A wrapper around a raw NtOpenFile call.
+///
+/// This isn't completely safe because `OBJECT_ATTRIBUTES` contains raw pointers.
+unsafe fn nt_open_file(
+    access: u32,
+    object_attribute: &c::OBJECT_ATTRIBUTES,
+    share: u32,
+    options: u32,
+) -> Result<File, WinError> {
+    unsafe {
+        let mut handle = ptr::null_mut();
+        let mut io_status = c::IO_STATUS_BLOCK::PENDING;
+        let status =
+            c::NtOpenFile(&mut handle, access, object_attribute, &mut io_status, share, options);
+        if c::nt_success(status) {
+            Ok(File::from_raw_handle(handle))
+        } else {
+            // Convert an NTSTATUS to the more familiar Win32 error code (aka "DosError")
+            let win_error = if status == c::STATUS_DELETE_PENDING {
+                // We make a special exception for `STATUS_DELETE_PENDING` because
+                // otherwise this will be mapped to `ERROR_ACCESS_DENIED` which is
+                // very unhelpful because that can also mean a permission error.
+                WinError::DELETE_PENDING
+            } else {
+                WinError::new(c::RtlNtStatusToDosError(status))
+            };
+            Err(win_error)
+        }
+    }
+}
+
+/// Open the file `path` in the directory `parent`, requesting the given `access` rights.
+fn open_link_no_reparse(
+    parent: &File,
+    path: &[u16],
+    access: u32,
+) -> Result<Option<File>, WinError> {
+    // This is implemented using the lower level `NtOpenFile` function as
+    // unfortunately opening a file relative to a parent is not supported by
+    // win32 functions.
+    //
+    // See https://learn.microsoft.com/windows/win32/api/winternl/nf-winternl-ntopenfile
+
+    // The `OBJ_DONT_REPARSE` attribute ensures that we haven't been
+    // tricked into following a symlink. However, it may not be available in
+    // earlier versions of Windows.
+    static ATTRIBUTES: AtomicU32 = AtomicU32::new(c::OBJ_DONT_REPARSE);
+
+    let result = unsafe {
+        let mut path_str = c::UNICODE_STRING::from_ref(path);
+        let mut object = c::OBJECT_ATTRIBUTES {
+            ObjectName: &mut path_str,
+            RootDirectory: parent.as_raw_handle(),
+            Attributes: ATTRIBUTES.load(Ordering::Relaxed),
+            ..c::OBJECT_ATTRIBUTES::default()
+        };
+        let share = c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE;
+        let options = c::FILE_OPEN_REPARSE_POINT;
+        let result = nt_open_file(access, &object, share, options);
+
+        // Retry without OBJ_DONT_REPARSE if it's not supported.
+        if matches!(result, Err(WinError::INVALID_PARAMETER))
+            && ATTRIBUTES.load(Ordering::Relaxed) == c::OBJ_DONT_REPARSE
+        {
+            ATTRIBUTES.store(0, Ordering::Relaxed);
+            object.Attributes = 0;
+            nt_open_file(access, &object, share, options)
+        } else {
+            result
+        }
+    };
+
+    // Ignore not found errors
+    match result {
+        Ok(f) => Ok(Some(f)),
+        Err(
+            WinError::FILE_NOT_FOUND
+            | WinError::PATH_NOT_FOUND
+            | WinError::BAD_NETPATH
+            | WinError::BAD_NET_NAME
+            // `DELETE_PENDING` means something else is already trying to delete it
+            // so we assume that will eventually succeed.
+            | WinError::DELETE_PENDING,
+        ) => Ok(None),
+        Err(e) => Err(e),
+    }
+}
+
+fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
+    open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::FILE_LIST_DIRECTORY)
+}
+
+fn delete(parent: &File, name: &[u16]) -> Result<(), WinError> {
+    // Note that the `delete` function consumes the opened file to ensure it's
+    // dropped immediately. See module comments for why this is important.
+    match open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::DELETE) {
+        Ok(Some(f)) => f.delete(),
+        Ok(None) => Ok(()),
+        Err(e) => Err(e),
+    }
+}
+
+/// A simple retry loop that keeps running `f` while it fails with the given
+/// error code or until `MAX_RETRIES` is reached.
+fn retry<T: PartialEq>(
+    mut f: impl FnMut() -> Result<T, WinError>,
+    ignore: WinError,
+) -> Result<T, WinError> {
+    let mut i = MAX_RETRIES;
+    loop {
+        i -= 1;
+        if i == 0 {
+            return f();
+        } else {
+            let result = f();
+            if result != Err(ignore) {
+                return result;
+            }
+        }
+        thread::yield_now();
+    }
+}
+
+pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
+    let mut buffer = DirBuff::new();
+    let mut dirlist = vec![dir];
+
+    let mut restart = true;
+    'outer: while let Some(dir) = dirlist.pop() {
+        let more_data = dir.fill_dir_buff(&mut buffer, restart)?;
+        for (name, is_directory) in buffer.iter() {
+            if is_directory {
+                let Some(subdir) = open_dir(&dir, &name)? else { continue };
+                dirlist.push(dir);
+                dirlist.push(subdir);
+                continue 'outer;
+            } else {
+                // Attempt to delete, retrying on sharing violation errors as these
+                // can often be very temporary. E.g. if something takes just a
+                // bit longer than expected to release a file handle.
+                retry(|| delete(&dir, &name), WinError::SHARING_VIOLATION)?;
+            }
+        }
+        if more_data {
+            dirlist.push(dir);
+            restart = false;
+        } else {
+            // Attempt to delete, retrying on not empty errors because we may
+            // need to wait some time for files to be removed from the filesystem.
+            retry(|| delete(&dir, &[]), WinError::DIR_NOT_EMPTY)?;
+            restart = true;
+        }
+    }
+    Ok(())
+}
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 272fadd9150..1cc9a2b7ffa 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -13,7 +13,7 @@ use crate::time::Duration;
 #[macro_use]
 pub mod compat;
 
-mod api;
+pub mod api;
 
 pub mod args;
 pub mod c;
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 06eae5a07b0..d40a537e359 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -272,11 +272,24 @@ impl Command {
             None
         };
         let program = resolve_exe(&self.program, || env::var_os("PATH"), child_paths)?;
-        // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
-        let is_batch_file = matches!(
-            program.len().checked_sub(5).and_then(|i| program.get(i..)),
-            Some([46, 98 | 66, 97 | 65, 116 | 84, 0] | [46, 99 | 67, 109 | 77, 100 | 68, 0])
-        );
+        let has_bat_extension = |program: &[u16]| {
+            matches!(
+                // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
+                program.len().checked_sub(4).and_then(|i| program.get(i..)),
+                Some([46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68])
+            )
+        };
+        let is_batch_file = if path::is_verbatim(&program) {
+            has_bat_extension(&program[..program.len() - 1])
+        } else {
+            super::fill_utf16_buf(
+                |buffer, size| unsafe {
+                    // resolve the path so we can test the final file name.
+                    c::GetFullPathNameW(program.as_ptr(), size, buffer, ptr::null_mut())
+                },
+                |program| has_bat_extension(program),
+            )?
+        };
         let (program, mut cmd_str) = if is_batch_file {
             (
                 command_prompt()?,
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index 21841eb18cc..2ae9a0a9199 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -1,5 +1,6 @@
 use crate::ffi::{OsStr, OsString};
 use crate::path::{Path, PathBuf, Prefix};
+use crate::sys::api::utf16;
 use crate::sys::pal::{c, fill_utf16_buf, os2path, to_u16s};
 use crate::{io, ptr};
 
@@ -19,6 +20,10 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     b == b'\\'
 }
 
+pub fn is_verbatim(path: &[u16]) -> bool {
+    path.starts_with(utf16!(r"\\?\")) || path.starts_with(utf16!(r"\??\"))
+}
+
 /// Returns true if `path` looks like a lone filename.
 pub(crate) fn is_file_name(path: &OsStr) -> bool {
     !path.as_encoded_bytes().iter().copied().any(is_sep_byte)
diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs
index 1a6ea1dafcb..68085d026c4 100644
--- a/library/std/src/sys/personality/mod.rs
+++ b/library/std/src/sys/personality/mod.rs
@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
         target_os = "psp",
         target_os = "xous",
         target_os = "solid_asp3",
-        all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re")),
+        all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
         all(target_vendor = "fortanix", target_env = "sgx"),
     ))] {
         mod gcc;
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index bbd1db8dfa5..590de31a678 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -34,3 +34,10 @@ llvm-libunwind = []
 # If crt-static is enabled, static link to `libunwind.a` provided by system
 # If crt-static is disabled, dynamic link to `libunwind.so` provided by system
 system-llvm-libunwind = []
+
+[lints.rust.unexpected_cfgs]
+level = "warn"
+check-cfg = [
+    # #[cfg(bootstrap)] rtems
+    'cfg(target_os, values("rtems"))',
+]
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 250af912e07..26ed00bfbd5 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -22,6 +22,7 @@ cfg_if::cfg_if! {
         target_os = "l4re",
         target_os = "none",
         target_os = "espidf",
+        target_os = "rtems",
     ))] {
         // These "unix" family members do not have unwinder.
     } else if #[cfg(any(
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index edf18e2ebf3..eef548033f1 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1692,16 +1692,8 @@ impl Step for Sysroot {
             build_helper::exit!(1);
         }
 
-        // Unlike rust-src component, we have to handle rustc-src a bit differently.
-        // When using CI rustc, we copy rustc-src component from its sysroot,
-        // otherwise we handle it in a similar way what we do for rust-src above.
-        if builder.download_rustc() {
-            cp_rustc_component_to_ci_sysroot(
-                builder,
-                &sysroot,
-                builder.config.ci_rustc_dev_contents(),
-            );
-        } else {
+        // rustc-src component is already part of CI rustc's sysroot
+        if !builder.download_rustc() {
             let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src");
             t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc));
             let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust");
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 8c52df78ab6..91fbc57429a 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -93,7 +93,6 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, Str
     if !verify_rustfmt_version(build) {
         return Ok(None);
     }
-
     get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"])
 }
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 84a6b26a491..a8e12540473 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1810,6 +1810,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         if builder.config.rust_optimize_tests {
             cmd.arg("--optimize-tests");
         }
+        if builder.config.rust_randomize_layout {
+            cmd.arg("--rust-randomized-layout");
+        }
         if builder.config.cmd.only_modified() {
             cmd.arg("--only-modified");
         }
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index ff0d1f3a725..304fe8da2bf 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1298,8 +1298,12 @@ impl<'a> Builder<'a> {
 
     pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand {
         if run_compiler.stage == 0 {
-            // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
-            let cargo_clippy = self.build.config.download_clippy();
+            let cargo_clippy = self
+                .config
+                .initial_cargo_clippy
+                .clone()
+                .unwrap_or_else(|| self.build.config.download_clippy());
+
             let mut cmd = command(cargo_clippy);
             cmd.env("CARGO", &self.initial_cargo);
             return cmd;
@@ -1614,6 +1618,15 @@ impl<'a> Builder<'a> {
             rustflags.arg("-Csymbol-mangling-version=legacy");
         }
 
+        // FIXME: the following components don't build with `-Zrandomize-layout` yet:
+        // - wasm-component-ld, due to the `wast`crate
+        // - rust-analyzer, due to the rowan crate
+        // so we exclude entire categories of steps here due to lack of fine-grained control over
+        // rustflags.
+        if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc {
+            rustflags.arg("-Zrandomize-layout");
+        }
+
         // Enable compile-time checking of `cfg` names, values and Cargo `features`.
         //
         // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like
@@ -2189,6 +2202,9 @@ impl<'a> Builder<'a> {
                 rustflags.arg("-Zvalidate-mir");
                 rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}"));
             }
+            if self.config.rust_randomize_layout {
+                rustflags.arg("--cfg=randomized_layouts");
+            }
             // Always enable inlining MIR when building the standard library.
             // Without this flag, MIR inlining is disabled when incremental compilation is enabled.
             // That causes some mir-opt tests which inline functions from the standard library to
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index bdfee55d8d1..f7cc9ee7219 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -268,7 +268,6 @@ pub struct Config {
     pub rust_debuginfo_level_std: DebuginfoLevel,
     pub rust_debuginfo_level_tools: DebuginfoLevel,
     pub rust_debuginfo_level_tests: DebuginfoLevel,
-    pub rust_split_debuginfo_for_build_triple: Option<SplitDebuginfo>, // FIXME: Deprecated field. Remove in Q3'24.
     pub rust_rpath: bool,
     pub rust_strip: bool,
     pub rust_frame_pointers: bool,
@@ -280,6 +279,7 @@ pub struct Config {
     pub rust_codegen_backends: Vec<String>,
     pub rust_verify_llvm_ir: bool,
     pub rust_thin_lto_import_instr_limit: Option<u32>,
+    pub rust_randomize_layout: bool,
     pub rust_remap_debuginfo: bool,
     pub rust_new_symbol_mangling: Option<bool>,
     pub rust_profile_use: Option<String>,
@@ -344,6 +344,7 @@ pub struct Config {
     // These are either the stage0 downloaded binaries or the locally installed ones.
     pub initial_cargo: PathBuf,
     pub initial_rustc: PathBuf,
+    pub initial_cargo_clippy: Option<PathBuf>,
 
     #[cfg(not(test))]
     initial_rustfmt: RefCell<RustfmtState>,
@@ -834,6 +835,7 @@ define_config! {
         cargo: Option<PathBuf> = "cargo",
         rustc: Option<PathBuf> = "rustc",
         rustfmt: Option<PathBuf> = "rustfmt",
+        cargo_clippy: Option<PathBuf> = "cargo-clippy",
         docs: Option<bool> = "docs",
         compiler_docs: Option<bool> = "compiler-docs",
         library_docs_private_items: Option<bool> = "library-docs-private-items",
@@ -1088,6 +1090,7 @@ define_config! {
         codegen_units: Option<u32> = "codegen-units",
         codegen_units_std: Option<u32> = "codegen-units-std",
         debug_assertions: Option<bool> = "debug-assertions",
+        randomize_layout: Option<bool> = "randomize-layout",
         debug_assertions_std: Option<bool> = "debug-assertions-std",
         overflow_checks: Option<bool> = "overflow-checks",
         overflow_checks_std: Option<bool> = "overflow-checks-std",
@@ -1097,7 +1100,6 @@ define_config! {
         debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std",
         debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools",
         debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests",
-        split_debuginfo: Option<String> = "split-debuginfo",
         backtrace: Option<bool> = "backtrace",
         incremental: Option<bool> = "incremental",
         parallel_compiler: Option<bool> = "parallel-compiler",
@@ -1179,6 +1181,7 @@ impl Config {
             backtrace: true,
             rust_optimize: RustOptimize::Bool(true),
             rust_optimize_tests: true,
+            rust_randomize_layout: false,
             submodules: None,
             docs: true,
             docs_minification: true,
@@ -1439,6 +1442,7 @@ impl Config {
             cargo,
             rustc,
             rustfmt,
+            cargo_clippy,
             docs,
             compiler_docs,
             library_docs_private_items,
@@ -1491,6 +1495,14 @@ impl Config {
             config.out = absolute(&config.out).expect("can't make empty path absolute");
         }
 
+        if cargo_clippy.is_some() && rustc.is_none() {
+            println!(
+                "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
+            );
+        }
+
+        config.initial_cargo_clippy = cargo_clippy;
+
         config.initial_rustc = if let Some(rustc) = rustc {
             if !flags.skip_stage0_validation {
                 config.check_stage0_version(&rustc, "rustc");
@@ -1625,10 +1637,10 @@ impl Config {
                 debuginfo_level_std: debuginfo_level_std_toml,
                 debuginfo_level_tools: debuginfo_level_tools_toml,
                 debuginfo_level_tests: debuginfo_level_tests_toml,
-                split_debuginfo,
                 backtrace,
                 incremental,
                 parallel_compiler,
+                randomize_layout,
                 default_linker,
                 channel,
                 description,
@@ -1684,18 +1696,6 @@ impl Config {
             debuginfo_level_tests = debuginfo_level_tests_toml;
             lld_enabled = lld_enabled_toml;
 
-            config.rust_split_debuginfo_for_build_triple = split_debuginfo
-                .as_deref()
-                .map(SplitDebuginfo::from_str)
-                .map(|v| v.expect("invalid value for rust.split-debuginfo"));
-
-            if config.rust_split_debuginfo_for_build_triple.is_some() {
-                println!(
-                    "WARNING: specifying `rust.split-debuginfo` is deprecated, use `target.{}.split-debuginfo` instead",
-                    config.build
-                );
-            }
-
             optimize = optimize_toml;
             omit_git_hash = omit_git_hash_toml;
             config.rust_new_symbol_mangling = new_symbol_mangling;
@@ -1718,6 +1718,7 @@ impl Config {
             set(&mut config.lld_mode, lld_mode);
             set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker);
 
+            config.rust_randomize_layout = randomize_layout.unwrap_or_default();
             config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
             config.rustc_parallel =
                 parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
@@ -2493,9 +2494,6 @@ impl Config {
         self.target_config
             .get(&target)
             .and_then(|t| t.split_debuginfo)
-            .or_else(|| {
-                if self.build == target { self.rust_split_debuginfo_for_build_triple } else { None }
-            })
             .unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
     }
 
@@ -2889,6 +2887,7 @@ fn check_incompatible_options_for_ci_rustc(
     let Rust {
         // Following options are the CI rustc incompatible ones.
         optimize,
+        randomize_layout,
         debug_logging,
         debuginfo_level_rustc,
         llvm_tools,
@@ -2916,7 +2915,6 @@ fn check_incompatible_options_for_ci_rustc(
         debuginfo_level_std: _,
         debuginfo_level_tools: _,
         debuginfo_level_tests: _,
-        split_debuginfo: _,
         backtrace: _,
         parallel_compiler: _,
         musl_root: _,
@@ -2953,6 +2951,7 @@ fn check_incompatible_options_for_ci_rustc(
     // otherwise, we just print a warning with `warn` macro.
 
     err!(current_rust_config.optimize, optimize);
+    err!(current_rust_config.randomize_layout, randomize_layout);
     err!(current_rust_config.debug_logging, debug_logging);
     err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc);
     err!(current_rust_config.rpath, rpath);
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 60ec57d0d44..dbc712adadf 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -13,6 +13,8 @@ use std::ffi::{OsStr, OsString};
 use std::path::PathBuf;
 use std::{env, fs};
 
+use build_helper::git::warn_old_master_branch;
+
 #[cfg(not(feature = "bootstrap-self-test"))]
 use crate::builder::Builder;
 use crate::builder::Kind;
@@ -34,6 +36,7 @@ pub struct Finder {
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
+    "armv7-rtems-eabihf",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@@ -374,4 +377,14 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
     if let Some(ref s) = build.config.ccache {
         cmd_finder.must_have(s);
     }
+
+    // this warning is useless in CI,
+    // and CI probably won't have the right branches anyway.
+    if !build_helper::ci::CiEnv::is_ci() {
+        if let Err(e) = warn_old_master_branch(&build.config.git_config(), &build.config.src)
+            .map_err(|e| e.to_string())
+        {
+            eprintln!("unable to check if upstream branch is old: {e}");
+        }
+    }
 }
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 268392c5fb1..5751c398f30 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -678,6 +678,9 @@ impl Build {
         if self.config.rustc_parallel {
             features.push("rustc_use_parallel_compiler");
         }
+        if self.config.rust_randomize_layout {
+            features.push("rustc_randomized_layouts");
+        }
 
         // If debug logging is on, then we want the default for tracing:
         // https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26
@@ -1501,6 +1504,7 @@ Executed at: {executed_at}"#,
                     "refs/remotes/origin/{}..HEAD",
                     self.config.stage0_metadata.config.nightly_branch
                 ))
+                .run_always()
                 .run_capture(self)
                 .stdout()
         });
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 51a25104e4c..3fec2d953d9 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -235,4 +235,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "The `build.profiler` option now tries to use source code from `download-ci-llvm` if possible, instead of checking out the `src/llvm-project` submodule.",
     },
+    ChangeInfo {
+        change_id: 129152,
+        severity: ChangeSeverity::Info,
+        summary: "New option `build.cargo-clippy` added for supporting the use of custom/external clippy.",
+    },
+    ChangeInfo {
+        change_id: 129925,
+        severity: ChangeSeverity::Warning,
+        summary: "Removed `rust.split-debuginfo` as it was deprecated long time ago.",
+    },
 ];
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
index f3591a69bee..2e08c87f278 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
@@ -5,7 +5,7 @@ set -ex
 source shared.sh
 
 # Try to keep the LLVM version here in sync with src/ci/scripts/install-clang.sh
-LLVM=llvmorg-18.1.0
+LLVM=llvmorg-19.1.0-rc3
 
 mkdir llvm-project
 cd llvm-project
@@ -33,6 +33,7 @@ hide_output \
       -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
       -DCOMPILER_RT_BUILD_XRAY=OFF \
       -DCOMPILER_RT_BUILD_MEMPROF=OFF \
+      -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
       -DLLVM_TARGETS_TO_BUILD=X86 \
       -DLLVM_INCLUDE_BENCHMARKS=OFF \
       -DLLVM_INCLUDE_TESTS=OFF \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
index 275acb47c33..3acc2ceb135 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
@@ -50,6 +50,7 @@ ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --llvm-root=/usr/lib/llvm-17 \
       --enable-llvm-link-shared \
+      --set rust.randomize-layout=true \
       --set rust.thin-lto-import-instr-limit=10
 
 COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index 389abb2fdd3..8011e07e92e 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -4,8 +4,8 @@ set -euo pipefail
 
 LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee
 
-# Build rustc, rustdoc and cargo
-../x.py build --stage 1 library rustdoc
+# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
+../x.py build --stage 2 library rustdoc clippy rustfmt
 ../x.py build --stage 0 cargo
 
 # Install rustup so that we can use the built toolchain easily, and also
@@ -16,7 +16,7 @@ sh rustup.sh -y --default-toolchain none
 source /cargo/env
 
 BUILD_DIR=$(realpath ./build)
-rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage1
+rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2
 rustup default local
 
 mkdir -p rfl
@@ -62,11 +62,47 @@ make -C linux LLVM=1 -j$(($(nproc) + 1)) \
     defconfig \
     rfl-for-rust-ci.config
 
-make -C linux LLVM=1 -j$(($(nproc) + 1)) \
-    samples/rust/rust_minimal.o \
-    samples/rust/rust_print.o \
-    drivers/net/phy/ax88796b_rust.o \
+BUILD_TARGETS="
+    samples/rust/rust_minimal.o
+    samples/rust/rust_print.o
+    drivers/net/phy/ax88796b_rust.o
     rust/doctests_kernel_generated.o
+"
+
+# Build a few Rust targets
+#
+# This does not include building the C side of the kernel nor linking,
+# which can find other issues, but it is much faster.
+#
+# This includes transforming `rustdoc` tests into KUnit ones thanks to
+# `CONFIG_RUST_KERNEL_DOCTESTS=y` above (which, for the moment, uses the
+# unstable `--test-builder` and `--no-run`).
+make -C linux LLVM=1 -j$(($(nproc) + 1)) \
+    $BUILD_TARGETS
 
+# Generate documentation
 make -C linux LLVM=1 -j$(($(nproc) + 1)) \
     rustdoc
+
+# Build macro expanded source (`-Zunpretty=expanded`)
+#
+# This target also formats the macro expanded code, thus it is also
+# intended to catch ICEs with formatting `-Zunpretty=expanded` output
+# like https://github.com/rust-lang/rustfmt/issues/6105.
+make -C linux LLVM=1 -j$(($(nproc) + 1)) \
+    samples/rust/rust_minimal.rsi
+
+# Re-build with Clippy enabled
+#
+# This should not introduce Clippy errors, since `CONFIG_WERROR` is not
+# set (thus no `-Dwarnings`) and the kernel uses `-W` for all Clippy
+# lints, including `clippy::all`. However, it could catch ICEs.
+make -C linux LLVM=1 -j$(($(nproc) + 1)) CLIPPY=1 \
+    $BUILD_TARGETS
+
+# Format the code
+#
+# This returns successfully even if there were changes, i.e. it is not
+# a check.
+make -C linux LLVM=1 -j$(($(nproc) + 1)) \
+    rustfmt
diff --git a/src/doc/not_found.md b/src/doc/not_found.md
index f0794fc0be3..9552759d2b8 100644
--- a/src/doc/not_found.md
+++ b/src/doc/not_found.md
@@ -2,7 +2,7 @@
 
 <!-- Completely hide the TOC and the section numbers -->
 <style type="text/css">
-#TOC { display: none; }
+#rustdoc-toc { display: none; }
 .header-section-number { display: none; }
 li {list-style-type: none; }
 #search-input {
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index b3a74a7716b..3e199539694 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -40,6 +40,7 @@
       - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
       - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
     - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
+    - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md)
     - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index a2641b22753..319dc9a7c08 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -280,6 +280,7 @@ target | std | host | notes
 `armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD
 [`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
 [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? |  | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain)
+[`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? |  | RTEMS OS for ARM BSPs
 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ |  | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
 [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
 [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
diff --git a/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md b/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md
new file mode 100644
index 00000000000..2791c21ee45
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md
@@ -0,0 +1,52 @@
+# `armv7-rtems-eabihf`
+
+**Tier: 3**
+
+ARM targets for the [RTEMS realtime operating system](https://www.rtems.org)  using the RTEMS gcc cross-compiler for linking against the libraries of a specified Board Support Package (BSP).
+
+## Target maintainers
+
+- [@thesummer](https://github.com/thesummer)
+
+## Requirements
+
+The target does not support host tools. Only cross-compilation is possible.
+The cross-compiler toolchain can be obtained by following the installation instructions
+of the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html). Additionally to the cross-compiler also a compiled BSP
+for a board fitting the architecture needs to be available on the host.
+Currently tested has been the BSP `xilinx_zynq_a9_qemu` of RTEMS 6.
+
+`std` support is available, but not yet fully tested. Do NOT use in flight software!
+
+The target follows the EABI calling convention for `extern "C"`.
+
+The resulting binaries are in ELF format.
+
+## Building the target
+
+The target can be built by the standard compiler of Rust.
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+In order to build an RTEMS executable it is also necessary to have a basic RTEMS configuration (in C) compiled to link against as this configures the operating system.
+An example can be found at this [`rtems-sys`](https://github.com/thesummer/rtems-sys) crate which could be added as an dependency to your application.
+
+## Testing
+
+The resulting binaries run fine on an emulated target (possibly also on a real Zedboard or similar).
+For example, on qemu the following command can execute the binary:
+```sh
+qemu-system-arm -no-reboot -serial null -serial mon:stdio -net none -nographic -M xilinx-zynq-a9 -m 512M -kernel <binary file>
+```
+
+While basic execution of the unit test harness seems to work. However, running the Rust testsuite on the (emulated) hardware has not yet been tested.
+
+## Cross-compilation toolchains and C code
+
+Compatible C-code can be built with the RTEMS cross-compiler toolchain `arm-rtems6-gcc`.
+For more information how to build the toolchain, RTEMS itself and RTEMS applications please have a look at the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html).
diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
index 12b7817c382..0e06a820a22 100644
--- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
+++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
@@ -195,3 +195,120 @@ conditionally compile code instead. This is notably different to the way native
 platforms such as x86\_64 work, and this is due to the fact that WebAssembly
 binaries must only contain code the engine understands. Native binaries work so
 long as the CPU doesn't execute unknown code dynamically at runtime.
+
+## Broken `extern "C"` ABI
+
+This target has what is considered a broken `extern "C"` ABI implementation at
+this time. Notably the same signature in Rust and C will compile to different
+WebAssembly functions and be incompatible. This is considered a bug and it will
+be fixed in a future version of Rust.
+
+For example this Rust code:
+
+```rust,ignore (does-not-link)
+#[repr(C)]
+struct MyPair {
+    a: u32,
+    b: u32,
+}
+
+extern "C" {
+    fn take_my_pair(pair: MyPair) -> u32;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn call_c() -> u32 {
+    take_my_pair(MyPair { a: 1, b: 2 })
+}
+```
+
+compiles to a WebAssembly module that looks like:
+
+```wasm
+(module
+  (import "env" "take_my_pair" (func $take_my_pair (param i32 i32) (result i32)))
+  (func $call_c
+    i32.const 1
+    i32.const 2
+    call $take_my_pair
+  )
+)
+```
+
+The function when defined in C, however, looks like
+
+```c
+struct my_pair {
+    unsigned a;
+    unsigned b;
+};
+
+unsigned take_my_pair(struct my_pair pair) {
+    return pair.a + pair.b;
+}
+```
+
+```wasm
+(module
+  (import "env" "__linear_memory" (memory 0))
+  (func $take_my_pair (param i32) (result i32)
+    local.get 0
+    i32.load offset=4
+    local.get 0
+    i32.load
+    i32.add
+  )
+)
+```
+
+Notice how Rust thinks `take_my_pair` takes two `i32` parameters but C thinks it
+only takes one.
+
+The correct definition of the `extern "C"` ABI for WebAssembly is located in the
+[WebAssembly/tool-conventions](https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md)
+repository. The `wasm32-unknown-unknown` target (and only this target, not other
+WebAssembly targets Rust support) does not correctly follow this document.
+
+Example issues in the Rust repository about this bug are:
+
+* [#115666](https://github.com/rust-lang/rust/issues/115666)
+* [#129486](https://github.com/rust-lang/rust/issues/129486)
+
+This current state of the `wasm32-unknown-unknown` backend is due to an
+unfortunate accident which got relied on. The `wasm-bindgen` project prior to
+0.2.89 was incompatible with the "correct" definition of `extern "C"` and it was
+seen as not worth the tradeoff of breaking `wasm-bindgen` historically to fix
+this issue in the compiler.
+
+Thanks to the heroic efforts of many involved in this, however, `wasm-bindgen`
+0.2.89 and later are compatible with the correct definition of `extern "C"` and
+the nightly compiler currently supports a `-Zwasm-c-abi` implemented in
+[#117919](https://github.com/rust-lang/rust/pull/117919). This nightly-only flag
+can be used to indicate whether the spec-defined version of `extern "C"` should
+be used instead of the "legacy" version of
+whatever-the-Rust-target-originally-implemented. For example using the above
+code you can see (lightly edited for clarity):
+
+```shell
+$ rustc +nightly -Zwasm-c-abi=spec foo.rs --target wasm32-unknown-unknown --crate-type lib --emit obj -O
+$ wasm-tools print foo.o
+(module
+  (import "env" "take_my_pair" (func $take_my_pair (param i32) (result i32)))
+  (func $call_c (result i32)
+    ;; ...
+  )
+  ;; ...
+)
+```
+
+which shows that the C and Rust definitions of the same function now agree like
+they should.
+
+The `-Zwasm-c-abi` compiler flag is tracked in
+[#122532](https://github.com/rust-lang/rust/issues/122532) and a lint was
+implemented in [#117918](https://github.com/rust-lang/rust/issues/117918) to
+help warn users about the transition if they're using `wasm-bindgen` 0.2.88 or
+prior. The current plan is to, in the future, switch `-Zwasm-c-api=spec` to
+being the default. Some time after that the `-Zwasm-c-abi` flag and the
+"legacy" implementation will all be removed. During this process users on a
+sufficiently updated version of `wasm-bindgen` should not experience breakage.
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 58fcfc4ed8d..5666b229078 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -512,9 +512,6 @@ impl Item {
     pub(crate) fn is_mod(&self) -> bool {
         self.type_() == ItemType::Module
     }
-    pub(crate) fn is_trait(&self) -> bool {
-        self.type_() == ItemType::Trait
-    }
     pub(crate) fn is_struct(&self) -> bool {
         self.type_() == ItemType::Struct
     }
@@ -542,9 +539,6 @@ impl Item {
     pub(crate) fn is_ty_method(&self) -> bool {
         self.type_() == ItemType::TyMethod
     }
-    pub(crate) fn is_type_alias(&self) -> bool {
-        self.type_() == ItemType::TypeAlias
-    }
     pub(crate) fn is_primitive(&self) -> bool {
         self.type_() == ItemType::Primitive
     }
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e37c24c1438..6f4665db6f1 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -51,12 +51,12 @@ use tracing::{debug, trace};
 use crate::clean::RenderedLink;
 use crate::doctest;
 use crate::doctest::GlobalTestOptions;
-use crate::html::escape::Escape;
+use crate::html::escape::{Escape, EscapeBodyText};
 use crate::html::format::Buffer;
 use crate::html::highlight;
 use crate::html::length_limit::HtmlWithLimit;
 use crate::html::render::small_url_encode;
-use crate::html::toc::TocBuilder;
+use crate::html::toc::{Toc, TocBuilder};
 
 #[cfg(test)]
 mod tests;
@@ -102,6 +102,7 @@ pub struct Markdown<'a> {
 /// A struct like `Markdown` that renders the markdown with a table of contents.
 pub(crate) struct MarkdownWithToc<'a> {
     pub(crate) content: &'a str,
+    pub(crate) links: &'a [RenderedLink],
     pub(crate) ids: &'a mut IdMap,
     pub(crate) error_codes: ErrorCodes,
     pub(crate) edition: Edition,
@@ -533,9 +534,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
             let id = self.id_map.derive(id);
 
             if let Some(ref mut builder) = self.toc {
+                let mut text_header = String::new();
+                plain_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut text_header);
                 let mut html_header = String::new();
-                html::push_html(&mut html_header, self.buf.iter().map(|(ev, _)| ev.clone()));
-                let sec = builder.push(level as u32, html_header, id.clone());
+                html_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut html_header);
+                let sec = builder.push(level as u32, text_header, html_header, id.clone());
                 self.buf.push_front((Event::Html(format!("{sec} ").into()), 0..0));
             }
 
@@ -1412,10 +1415,23 @@ impl Markdown<'_> {
 }
 
 impl MarkdownWithToc<'_> {
-    pub(crate) fn into_string(self) -> String {
-        let MarkdownWithToc { content: md, ids, error_codes: codes, edition, playground } = self;
+    pub(crate) fn into_parts(self) -> (Toc, String) {
+        let MarkdownWithToc { content: md, links, ids, error_codes: codes, edition, playground } =
+            self;
 
-        let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
+        // This is actually common enough to special-case
+        if md.is_empty() {
+            return (Toc { entries: Vec::new() }, String::new());
+        }
+        let mut replacer = |broken_link: BrokenLink<'_>| {
+            links
+                .iter()
+                .find(|link| &*link.original_text == &*broken_link.reference)
+                .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
+        };
+
+        let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer));
+        let p = p.into_offset_iter();
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
@@ -1429,7 +1445,11 @@ impl MarkdownWithToc<'_> {
             html::push_html(&mut s, p);
         }
 
-        format!("<nav id=\"TOC\">{toc}</nav>{s}", toc = toc.into_toc().print())
+        (toc.into_toc(), s)
+    }
+    pub(crate) fn into_string(self) -> String {
+        let (toc, s) = self.into_parts();
+        format!("<nav id=\"rustdoc\">{toc}</nav>{s}", toc = toc.print())
     }
 }
 
@@ -1608,7 +1628,16 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
 
     let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
 
-    for event in p {
+    plain_text_from_events(p, &mut s);
+
+    s
+}
+
+pub(crate) fn plain_text_from_events<'a>(
+    events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
+    s: &mut String,
+) {
+    for event in events {
         match &event {
             Event::Text(text) => s.push_str(text),
             Event::Code(code) => {
@@ -1623,8 +1652,29 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
             _ => (),
         }
     }
+}
 
-    s
+pub(crate) fn html_text_from_events<'a>(
+    events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
+    s: &mut String,
+) {
+    for event in events {
+        match &event {
+            Event::Text(text) => {
+                write!(s, "{}", EscapeBodyText(text)).expect("string alloc infallible")
+            }
+            Event::Code(code) => {
+                s.push_str("<code>");
+                write!(s, "{}", EscapeBodyText(code)).expect("string alloc infallible");
+                s.push_str("</code>");
+            }
+            Event::HardBreak | Event::SoftBreak => s.push(' '),
+            Event::Start(Tag::CodeBlock(..)) => break,
+            Event::End(TagEnd::Paragraph) => break,
+            Event::End(TagEnd::Heading(..)) => break,
+            _ => (),
+        }
+    }
 }
 
 #[derive(Debug)]
@@ -1975,7 +2025,8 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     map.insert("default-settings".into(), 1);
     map.insert("sidebar-vars".into(), 1);
     map.insert("copy-path".into(), 1);
-    map.insert("TOC".into(), 1);
+    map.insert("rustdoc-toc".into(), 1);
+    map.insert("rustdoc-modnav".into(), 1);
     // This is the list of IDs used by rustdoc sections (but still generated by
     // rustdoc).
     map.insert("fields".into(), 1);
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 19386fe5e69..9fe43e428f2 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -15,7 +15,7 @@ use rustc_span::{sym, FileName, Symbol};
 use tracing::info;
 
 use super::print_item::{full_path, item_path, print_item};
-use super::sidebar::{print_sidebar, sidebar_module_like, Sidebar};
+use super::sidebar::{print_sidebar, sidebar_module_like, ModuleLike, Sidebar};
 use super::write_shared::write_shared;
 use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath};
 use crate::clean::types::ExternalLocation;
@@ -617,12 +617,14 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         let all = shared.all.replace(AllTypes::new());
         let mut sidebar = Buffer::html();
 
-        let blocks = sidebar_module_like(all.item_sections());
+        // all.html is not customizable, so a blank id map is fine
+        let blocks = sidebar_module_like(all.item_sections(), &mut IdMap::new(), ModuleLike::Crate);
         let bar = Sidebar {
             title_prefix: "",
             title: "",
             is_crate: false,
             is_mod: false,
+            parent_is_crate: false,
             blocks: vec![blocks],
             path: String::new(),
         };
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index fc4033f8320..f67d006116c 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1250,6 +1250,7 @@ fn render_assoc_items_inner(
     let Some(v) = cache.impls.get(&it) else { return };
     let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
     if !non_trait.is_empty() {
+        let mut close_tags = <Vec<&str>>::with_capacity(1);
         let mut tmp_buf = Buffer::html();
         let (render_mode, id, class_html) = match what {
             AssocItemRender::All => {
@@ -1260,6 +1261,8 @@ fn render_assoc_items_inner(
                 let id =
                     cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
                 let derived_id = cx.derive_id(&id);
+                tmp_buf.write_str("<details class=\"toggle big-toggle\" open><summary>");
+                close_tags.push("</details>");
                 write_impl_section_heading(
                     &mut tmp_buf,
                     &format!(
@@ -1269,6 +1272,7 @@ fn render_assoc_items_inner(
                     ),
                     &id,
                 );
+                tmp_buf.write_str("</summary>");
                 if let Some(def_id) = type_.def_id(cx.cache()) {
                     cx.deref_id_map.insert(def_id, id);
                 }
@@ -1302,6 +1306,9 @@ fn render_assoc_items_inner(
                 impls_buf.into_inner()
             )
             .unwrap();
+            for tag in close_tags.into_iter().rev() {
+                w.write_str(tag).unwrap();
+            }
         }
     }
 
@@ -1558,7 +1565,7 @@ fn render_impl(
     let cache = &shared.cache;
     let traits = &cache.traits;
     let trait_ = i.trait_did().map(|did| &traits[&did]);
-    let mut close_tags = String::new();
+    let mut close_tags = <Vec<&str>>::with_capacity(2);
 
     // For trait implementations, the `interesting` output contains all methods that have doc
     // comments, and the `boring` output contains all methods that do not. The distinction is
@@ -1787,13 +1794,64 @@ fn render_impl(
     let mut default_impl_items = Buffer::empty_from(w);
     let impl_ = i.inner_impl();
 
+    // Impl items are grouped by kinds:
+    //
+    // 1. Constants
+    // 2. Types
+    // 3. Functions
+    //
+    // This order is because you can have associated constants used in associated types (like array
+    // length), and both in associcated functions. So with this order, when reading from top to
+    // bottom, you should see items definitions before they're actually used most of the time.
+    let mut assoc_types = Vec::new();
+    let mut methods = Vec::new();
+
     if !impl_.is_negative_trait_impl() {
         for trait_item in &impl_.items {
+            match *trait_item.kind {
+                clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item),
+                clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => {
+                    assoc_types.push(trait_item)
+                }
+                clean::TyAssocConstItem(..) | clean::AssocConstItem(_) => {
+                    // We render it directly since they're supposed to come first.
+                    doc_impl_item(
+                        &mut default_impl_items,
+                        &mut impl_items,
+                        cx,
+                        trait_item,
+                        if trait_.is_some() { &i.impl_item } else { parent },
+                        link,
+                        render_mode,
+                        false,
+                        trait_,
+                        rendering_params,
+                    );
+                }
+                _ => {}
+            }
+        }
+
+        for assoc_type in assoc_types {
             doc_impl_item(
                 &mut default_impl_items,
                 &mut impl_items,
                 cx,
-                trait_item,
+                assoc_type,
+                if trait_.is_some() { &i.impl_item } else { parent },
+                link,
+                render_mode,
+                false,
+                trait_,
+                rendering_params,
+            );
+        }
+        for method in methods {
+            doc_impl_item(
+                &mut default_impl_items,
+                &mut impl_items,
+                cx,
+                method,
                 if trait_.is_some() { &i.impl_item } else { parent },
                 link,
                 render_mode,
@@ -1870,7 +1928,7 @@ fn render_impl(
     if render_mode == RenderMode::Normal {
         let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
         if toggled {
-            close_tags.insert_str(0, "</details>");
+            close_tags.push("</details>");
             write!(
                 w,
                 "<details class=\"toggle implementors-toggle\"{}>\
@@ -1916,14 +1974,16 @@ fn render_impl(
         }
         if !default_impl_items.is_empty() || !impl_items.is_empty() {
             w.write_str("<div class=\"impl-items\">");
-            close_tags.insert_str(0, "</div>");
+            close_tags.push("</div>");
         }
     }
     if !default_impl_items.is_empty() || !impl_items.is_empty() {
         w.push_buffer(default_impl_items);
         w.push_buffer(impl_items);
     }
-    w.write_str(&close_tags);
+    for tag in close_tags.into_iter().rev() {
+        w.write_str(tag);
+    }
 }
 
 // Render the items that appear on the right side of methods, impls, and
@@ -2446,28 +2506,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
         let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
         let locations_encoded = serde_json::to_string(&line_ranges).unwrap();
 
-        write!(
-            &mut w,
-            "<div class=\"scraped-example {expanded_cls}\" data-locs=\"{locations}\">\
-                <div class=\"scraped-example-title\">\
-                   {name} (<a href=\"{url}\">{title}</a>)\
-                </div>\
-                <div class=\"code-wrapper\">",
-            expanded_cls = if needs_expansion { "" } else { "expanded" },
-            name = call_data.display_name,
-            url = init_url,
-            title = init_title,
-            // The locations are encoded as a data attribute, so they can be read
-            // later by the JS for interactions.
-            locations = Escape(&locations_encoded)
-        )
-        .unwrap();
-
-        if line_ranges.len() > 1 {
-            w.write_str(r#"<button class="prev">&pr;</button> <button class="next">&sc;</button>"#)
-                .unwrap();
-        }
-
         // Look for the example file in the source map if it exists, otherwise return a dummy span
         let file_span = (|| {
             let source_map = tcx.sess.source_map();
@@ -2498,9 +2536,16 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
             cx,
             &cx.root_path(),
             highlight::DecorationInfo(decoration_info),
-            sources::SourceContext::Embedded { offset: line_min, needs_expansion },
+            sources::SourceContext::Embedded(sources::ScrapedInfo {
+                needs_prev_next_buttons: line_ranges.len() > 1,
+                needs_expansion,
+                offset: line_min,
+                name: &call_data.display_name,
+                url: init_url,
+                title: init_title,
+                locations: locations_encoded,
+            }),
         );
-        w.write_str("</div></div>").unwrap();
 
         true
     };
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index a0a72d59d12..cda5409a460 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -843,55 +843,55 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
         }
     }
 
-    if !required_types.is_empty() {
+    if !required_consts.is_empty() {
         write_section_heading(
             w,
-            "Required Associated Types",
-            "required-associated-types",
+            "Required Associated Constants",
+            "required-associated-consts",
             None,
             "<div class=\"methods\">",
         );
-        for t in required_types {
+        for t in required_consts {
             trait_item(w, cx, t, it);
         }
         w.write_str("</div>");
     }
-    if !provided_types.is_empty() {
+    if !provided_consts.is_empty() {
         write_section_heading(
             w,
-            "Provided Associated Types",
-            "provided-associated-types",
+            "Provided Associated Constants",
+            "provided-associated-consts",
             None,
             "<div class=\"methods\">",
         );
-        for t in provided_types {
+        for t in provided_consts {
             trait_item(w, cx, t, it);
         }
         w.write_str("</div>");
     }
 
-    if !required_consts.is_empty() {
+    if !required_types.is_empty() {
         write_section_heading(
             w,
-            "Required Associated Constants",
-            "required-associated-consts",
+            "Required Associated Types",
+            "required-associated-types",
             None,
             "<div class=\"methods\">",
         );
-        for t in required_consts {
+        for t in required_types {
             trait_item(w, cx, t, it);
         }
         w.write_str("</div>");
     }
-    if !provided_consts.is_empty() {
+    if !provided_types.is_empty() {
         write_section_heading(
             w,
-            "Provided Associated Constants",
-            "provided-associated-consts",
+            "Provided Associated Types",
+            "provided-associated-types",
             None,
             "<div class=\"methods\">",
         );
-        for t in provided_consts {
+        for t in provided_types {
             trait_item(w, cx, t, it);
         }
         w.write_str("</div>");
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index 5b9c93ef74a..06cc57b2a55 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -13,7 +13,24 @@ use crate::clean;
 use crate::formats::item_type::ItemType;
 use crate::formats::Impl;
 use crate::html::format::Buffer;
-use crate::html::markdown::IdMap;
+use crate::html::markdown::{IdMap, MarkdownWithToc};
+
+#[derive(Clone, Copy)]
+pub(crate) enum ModuleLike {
+    Module,
+    Crate,
+}
+
+impl ModuleLike {
+    pub(crate) fn is_crate(self) -> bool {
+        matches!(self, ModuleLike::Crate)
+    }
+}
+impl<'a> From<&'a clean::Item> for ModuleLike {
+    fn from(it: &'a clean::Item) -> ModuleLike {
+        if it.is_crate() { ModuleLike::Crate } else { ModuleLike::Module }
+    }
+}
 
 #[derive(Template)]
 #[template(path = "sidebar.html")]
@@ -21,6 +38,7 @@ pub(super) struct Sidebar<'a> {
     pub(super) title_prefix: &'static str,
     pub(super) title: &'a str,
     pub(super) is_crate: bool,
+    pub(super) parent_is_crate: bool,
     pub(super) is_mod: bool,
     pub(super) blocks: Vec<LinkBlock<'a>>,
     pub(super) path: String,
@@ -63,15 +81,19 @@ impl<'a> LinkBlock<'a> {
 /// A link to an item. Content should not be escaped.
 #[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)]
 pub(crate) struct Link<'a> {
-    /// The content for the anchor tag
+    /// The content for the anchor tag and title attr
     name: Cow<'a, str>,
+    /// The content for the anchor tag (if different from name)
+    name_html: Option<Cow<'a, str>>,
     /// The id of an anchor within the page (without a `#` prefix)
     href: Cow<'a, str>,
+    /// Nested list of links (used only in top-toc)
+    children: Vec<Link<'a>>,
 }
 
 impl<'a> Link<'a> {
     pub fn new(href: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>) -> Self {
-        Self { href: href.into(), name: name.into() }
+        Self { href: href.into(), name: name.into(), children: vec![], name_html: None }
     }
     pub fn empty() -> Link<'static> {
         Link::new("", "")
@@ -95,17 +117,21 @@ pub(crate) mod filters {
 }
 
 pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
-    let blocks: Vec<LinkBlock<'_>> = match *it.kind {
-        clean::StructItem(ref s) => sidebar_struct(cx, it, s),
-        clean::TraitItem(ref t) => sidebar_trait(cx, it, t),
-        clean::PrimitiveItem(_) => sidebar_primitive(cx, it),
-        clean::UnionItem(ref u) => sidebar_union(cx, it, u),
-        clean::EnumItem(ref e) => sidebar_enum(cx, it, e),
-        clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t),
-        clean::ModuleItem(ref m) => vec![sidebar_module(&m.items)],
-        clean::ForeignTypeItem => sidebar_foreign_type(cx, it),
-        _ => vec![],
-    };
+    let mut ids = IdMap::new();
+    let mut blocks: Vec<LinkBlock<'_>> = docblock_toc(cx, it, &mut ids).into_iter().collect();
+    match *it.kind {
+        clean::StructItem(ref s) => sidebar_struct(cx, it, s, &mut blocks),
+        clean::TraitItem(ref t) => sidebar_trait(cx, it, t, &mut blocks),
+        clean::PrimitiveItem(_) => sidebar_primitive(cx, it, &mut blocks),
+        clean::UnionItem(ref u) => sidebar_union(cx, it, u, &mut blocks),
+        clean::EnumItem(ref e) => sidebar_enum(cx, it, e, &mut blocks),
+        clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t, &mut blocks),
+        clean::ModuleItem(ref m) => {
+            blocks.push(sidebar_module(&m.items, &mut ids, ModuleLike::from(it)))
+        }
+        clean::ForeignTypeItem => sidebar_foreign_type(cx, it, &mut blocks),
+        _ => {}
+    }
     // The sidebar is designed to display sibling functions, modules and
     // other miscellaneous information. since there are lots of sibling
     // items (and that causes quadratic growth in large modules),
@@ -113,15 +139,9 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
     // still, we don't move everything into JS because we want to preserve
     // as much HTML as possible in order to allow non-JS-enabled browsers
     // to navigate the documentation (though slightly inefficiently).
-    let (title_prefix, title) = if it.is_struct()
-        || it.is_trait()
-        || it.is_primitive()
-        || it.is_union()
-        || it.is_enum()
-        // crate title is displayed as part of logo lockup
-        || (it.is_mod() && !it.is_crate())
-        || it.is_type_alias()
-    {
+    //
+    // crate title is displayed as part of logo lockup
+    let (title_prefix, title) = if !blocks.is_empty() && !it.is_crate() {
         (
             match *it.kind {
                 clean::ModuleItem(..) => "Module ",
@@ -146,8 +166,15 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
     } else {
         "".into()
     };
-    let sidebar =
-        Sidebar { title_prefix, title, is_mod: it.is_mod(), is_crate: it.is_crate(), blocks, path };
+    let sidebar = Sidebar {
+        title_prefix,
+        title,
+        is_mod: it.is_mod(),
+        is_crate: it.is_crate(),
+        parent_is_crate: sidebar_path.len() == 1,
+        blocks,
+        path,
+    };
     sidebar.render_into(buffer).unwrap();
 }
 
@@ -163,30 +190,80 @@ fn get_struct_fields_name<'a>(fields: &'a [clean::Item]) -> Vec<Link<'a>> {
     fields
 }
 
+fn docblock_toc<'a>(
+    cx: &'a Context<'_>,
+    it: &'a clean::Item,
+    ids: &mut IdMap,
+) -> Option<LinkBlock<'a>> {
+    let (toc, _) = MarkdownWithToc {
+        content: &it.doc_value(),
+        links: &it.links(cx),
+        ids,
+        error_codes: cx.shared.codes,
+        edition: cx.shared.edition(),
+        playground: &cx.shared.playground,
+    }
+    .into_parts();
+    let links: Vec<Link<'_>> = toc
+        .entries
+        .into_iter()
+        .map(|entry| {
+            Link {
+                name_html: if entry.html == entry.name { None } else { Some(entry.html.into()) },
+                name: entry.name.into(),
+                href: entry.id.into(),
+                children: entry
+                    .children
+                    .entries
+                    .into_iter()
+                    .map(|entry| Link {
+                        name_html: if entry.html == entry.name {
+                            None
+                        } else {
+                            Some(entry.html.into())
+                        },
+                        name: entry.name.into(),
+                        href: entry.id.into(),
+                        // Only a single level of nesting is shown here.
+                        // Going the full six could break the layout,
+                        // so we have to cut it off somewhere.
+                        children: vec![],
+                    })
+                    .collect(),
+            }
+        })
+        .collect();
+    if links.is_empty() {
+        None
+    } else {
+        Some(LinkBlock::new(Link::new("", "Sections"), "top-toc", links))
+    }
+}
+
 fn sidebar_struct<'a>(
     cx: &'a Context<'_>,
     it: &'a clean::Item,
     s: &'a clean::Struct,
-) -> Vec<LinkBlock<'a>> {
+    items: &mut Vec<LinkBlock<'a>>,
+) {
     let fields = get_struct_fields_name(&s.fields);
     let field_name = match s.ctor_kind {
         Some(CtorKind::Fn) => Some("Tuple Fields"),
         None => Some("Fields"),
         _ => None,
     };
-    let mut items = vec![];
     if let Some(name) = field_name {
         items.push(LinkBlock::new(Link::new("fields", name), "structfield", fields));
     }
-    sidebar_assoc_items(cx, it, &mut items);
-    items
+    sidebar_assoc_items(cx, it, items);
 }
 
 fn sidebar_trait<'a>(
     cx: &'a Context<'_>,
     it: &'a clean::Item,
     t: &'a clean::Trait,
-) -> Vec<LinkBlock<'a>> {
+    blocks: &mut Vec<LinkBlock<'a>>,
+) {
     fn filter_items<'a>(
         items: &'a [clean::Item],
         filt: impl Fn(&clean::Item) -> bool,
@@ -223,19 +300,20 @@ fn sidebar_trait<'a>(
         foreign_impls.sort();
     }
 
-    let mut blocks: Vec<LinkBlock<'_>> = [
-        ("required-associated-types", "Required Associated Types", req_assoc),
-        ("provided-associated-types", "Provided Associated Types", prov_assoc),
-        ("required-associated-consts", "Required Associated Constants", req_assoc_const),
-        ("provided-associated-consts", "Provided Associated Constants", prov_assoc_const),
-        ("required-methods", "Required Methods", req_method),
-        ("provided-methods", "Provided Methods", prov_method),
-        ("foreign-impls", "Implementations on Foreign Types", foreign_impls),
-    ]
-    .into_iter()
-    .map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items))
-    .collect();
-    sidebar_assoc_items(cx, it, &mut blocks);
+    blocks.extend(
+        [
+            ("required-associated-consts", "Required Associated Constants", req_assoc_const),
+            ("provided-associated-consts", "Provided Associated Constants", prov_assoc_const),
+            ("required-associated-types", "Required Associated Types", req_assoc),
+            ("provided-associated-types", "Provided Associated Types", prov_assoc),
+            ("required-methods", "Required Methods", req_method),
+            ("provided-methods", "Provided Methods", prov_method),
+            ("foreign-impls", "Implementations on Foreign Types", foreign_impls),
+        ]
+        .into_iter()
+        .map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items)),
+    );
+    sidebar_assoc_items(cx, it, blocks);
 
     if !t.is_object_safe(cx.tcx()) {
         blocks.push(LinkBlock::forced(
@@ -251,20 +329,17 @@ fn sidebar_trait<'a>(
             "impl-auto",
         ));
     }
-    blocks
 }
 
-fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
+fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item, items: &mut Vec<LinkBlock<'a>>) {
     if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
-        let mut items = vec![];
-        sidebar_assoc_items(cx, it, &mut items);
-        items
+        sidebar_assoc_items(cx, it, items);
     } else {
         let shared = Rc::clone(&cx.shared);
         let (concrete, synthetic, blanket_impl) =
             super::get_filtered_impls_for_reference(&shared, it);
 
-        sidebar_render_assoc_items(cx, &mut IdMap::new(), concrete, synthetic, blanket_impl).into()
+        sidebar_render_assoc_items(cx, &mut IdMap::new(), concrete, synthetic, blanket_impl, items);
     }
 }
 
@@ -272,8 +347,8 @@ fn sidebar_type_alias<'a>(
     cx: &'a Context<'_>,
     it: &'a clean::Item,
     t: &'a clean::TypeAlias,
-) -> Vec<LinkBlock<'a>> {
-    let mut items = vec![];
+    items: &mut Vec<LinkBlock<'a>>,
+) {
     if let Some(inner_type) = &t.inner_type {
         items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased type"), "type"));
         match inner_type {
@@ -295,19 +370,18 @@ fn sidebar_type_alias<'a>(
             }
         }
     }
-    sidebar_assoc_items(cx, it, &mut items);
-    items
+    sidebar_assoc_items(cx, it, items);
 }
 
 fn sidebar_union<'a>(
     cx: &'a Context<'_>,
     it: &'a clean::Item,
     u: &'a clean::Union,
-) -> Vec<LinkBlock<'a>> {
+    items: &mut Vec<LinkBlock<'a>>,
+) {
     let fields = get_struct_fields_name(&u.fields);
-    let mut items = vec![LinkBlock::new(Link::new("fields", "Fields"), "structfield", fields)];
-    sidebar_assoc_items(cx, it, &mut items);
-    items
+    items.push(LinkBlock::new(Link::new("fields", "Fields"), "structfield", fields));
+    sidebar_assoc_items(cx, it, items);
 }
 
 /// Adds trait implementations into the blocks of links
@@ -320,6 +394,7 @@ fn sidebar_assoc_items<'a>(
     let cache = cx.cache();
 
     let mut assoc_consts = Vec::new();
+    let mut assoc_types = Vec::new();
     let mut methods = Vec::new();
     if let Some(v) = cache.impls.get(&did) {
         let mut used_links = FxHashSet::default();
@@ -327,40 +402,38 @@ fn sidebar_assoc_items<'a>(
 
         {
             let used_links_bor = &mut used_links;
-            assoc_consts.extend(
-                v.iter()
-                    .filter(|i| i.inner_impl().trait_.is_none())
-                    .flat_map(|i| get_associated_constants(i.inner_impl(), used_links_bor)),
-            );
+            for impl_ in v.iter().map(|i| i.inner_impl()).filter(|i| i.trait_.is_none()) {
+                assoc_consts.extend(get_associated_constants(impl_, used_links_bor));
+                assoc_types.extend(get_associated_types(impl_, used_links_bor));
+                methods.extend(get_methods(impl_, false, used_links_bor, false, cx.tcx()));
+            }
             // We want links' order to be reproducible so we don't use unstable sort.
             assoc_consts.sort();
-
-            #[rustfmt::skip] // rustfmt makes the pipeline less readable
-            methods.extend(
-                v.iter()
-                    .filter(|i| i.inner_impl().trait_.is_none())
-                    .flat_map(|i| get_methods(i.inner_impl(), false, used_links_bor, false, cx.tcx())),
-            );
-
-            // We want links' order to be reproducible so we don't use unstable sort.
+            assoc_types.sort();
             methods.sort();
         }
 
-        let mut deref_methods = Vec::new();
-        let [concrete, synthetic, blanket] = if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
+        let mut blocks = vec![
+            LinkBlock::new(
+                Link::new("implementations", "Associated Constants"),
+                "associatedconstant",
+                assoc_consts,
+            ),
+            LinkBlock::new(
+                Link::new("implementations", "Associated Types"),
+                "associatedtype",
+                assoc_types,
+            ),
+            LinkBlock::new(Link::new("implementations", "Methods"), "method", methods),
+        ];
+
+        if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
             if let Some(impl_) =
                 v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait())
             {
                 let mut derefs = DefIdSet::default();
                 derefs.insert(did);
-                sidebar_deref_methods(
-                    cx,
-                    &mut deref_methods,
-                    impl_,
-                    v,
-                    &mut derefs,
-                    &mut used_links,
-                );
+                sidebar_deref_methods(cx, &mut blocks, impl_, v, &mut derefs, &mut used_links);
             }
 
             let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
@@ -368,21 +441,16 @@ fn sidebar_assoc_items<'a>(
             let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
                 concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_blanket());
 
-            sidebar_render_assoc_items(cx, &mut id_map, concrete, synthetic, blanket_impl)
-        } else {
-            std::array::from_fn(|_| LinkBlock::new(Link::empty(), "", vec![]))
-        };
+            sidebar_render_assoc_items(
+                cx,
+                &mut id_map,
+                concrete,
+                synthetic,
+                blanket_impl,
+                &mut blocks,
+            );
+        }
 
-        let mut blocks = vec![
-            LinkBlock::new(
-                Link::new("implementations", "Associated Constants"),
-                "associatedconstant",
-                assoc_consts,
-            ),
-            LinkBlock::new(Link::new("implementations", "Methods"), "method", methods),
-        ];
-        blocks.append(&mut deref_methods);
-        blocks.extend([concrete, synthetic, blanket]);
         links.append(&mut blocks);
     }
 }
@@ -472,7 +540,8 @@ fn sidebar_enum<'a>(
     cx: &'a Context<'_>,
     it: &'a clean::Item,
     e: &'a clean::Enum,
-) -> Vec<LinkBlock<'a>> {
+    items: &mut Vec<LinkBlock<'a>>,
+) {
     let mut variants = e
         .variants()
         .filter_map(|v| v.name)
@@ -480,24 +549,37 @@ fn sidebar_enum<'a>(
         .collect::<Vec<_>>();
     variants.sort_unstable();
 
-    let mut items = vec![LinkBlock::new(Link::new("variants", "Variants"), "variant", variants)];
-    sidebar_assoc_items(cx, it, &mut items);
-    items
+    items.push(LinkBlock::new(Link::new("variants", "Variants"), "variant", variants));
+    sidebar_assoc_items(cx, it, items);
 }
 
 pub(crate) fn sidebar_module_like(
     item_sections_in_use: FxHashSet<ItemSection>,
+    ids: &mut IdMap,
+    module_like: ModuleLike,
 ) -> LinkBlock<'static> {
-    let item_sections = ItemSection::ALL
+    let item_sections: Vec<Link<'_>> = ItemSection::ALL
         .iter()
         .copied()
         .filter(|sec| item_sections_in_use.contains(sec))
-        .map(|sec| Link::new(sec.id(), sec.name()))
+        .map(|sec| Link::new(ids.derive(sec.id()), sec.name()))
         .collect();
-    LinkBlock::new(Link::empty(), "", item_sections)
+    let header = if let Some(first_section) = item_sections.get(0) {
+        Link::new(
+            first_section.href.to_owned(),
+            if module_like.is_crate() { "Crate Items" } else { "Module Items" },
+        )
+    } else {
+        Link::empty()
+    };
+    LinkBlock::new(header, "", item_sections)
 }
 
-fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> {
+fn sidebar_module(
+    items: &[clean::Item],
+    ids: &mut IdMap,
+    module_like: ModuleLike,
+) -> LinkBlock<'static> {
     let item_sections_in_use: FxHashSet<_> = items
         .iter()
         .filter(|it| {
@@ -518,13 +600,15 @@ fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> {
         .map(|it| item_ty_to_section(it.type_()))
         .collect();
 
-    sidebar_module_like(item_sections_in_use)
+    sidebar_module_like(item_sections_in_use, ids, module_like)
 }
 
-fn sidebar_foreign_type<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
-    let mut items = vec![];
-    sidebar_assoc_items(cx, it, &mut items);
-    items
+fn sidebar_foreign_type<'a>(
+    cx: &'a Context<'_>,
+    it: &'a clean::Item,
+    items: &mut Vec<LinkBlock<'a>>,
+) {
+    sidebar_assoc_items(cx, it, items);
 }
 
 /// Renders the trait implementations for this type
@@ -534,7 +618,8 @@ fn sidebar_render_assoc_items(
     concrete: Vec<&Impl>,
     synthetic: Vec<&Impl>,
     blanket_impl: Vec<&Impl>,
-) -> [LinkBlock<'static>; 3] {
+    items: &mut Vec<LinkBlock<'_>>,
+) {
     let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| {
         let mut links = FxHashSet::default();
 
@@ -559,7 +644,7 @@ fn sidebar_render_assoc_items(
     let concrete = format_impls(concrete, id_map);
     let synthetic = format_impls(synthetic, id_map);
     let blanket = format_impls(blanket_impl, id_map);
-    [
+    items.extend([
         LinkBlock::new(
             Link::new("trait-implementations", "Trait Implementations"),
             "trait-implementation",
@@ -575,7 +660,7 @@ fn sidebar_render_assoc_items(
             "blanket-implementation",
             blanket,
         ),
-    ]
+    ]);
 }
 
 fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
@@ -629,3 +714,19 @@ fn get_associated_constants<'a>(
         })
         .collect::<Vec<_>>()
 }
+
+fn get_associated_types<'a>(
+    i: &'a clean::Impl,
+    used_links: &mut FxHashSet<String>,
+) -> Vec<Link<'a>> {
+    i.items
+        .iter()
+        .filter_map(|item| match item.name {
+            Some(ref name) if !name.is_empty() && item.is_associated_type() => Some(Link::new(
+                get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)),
+                name.as_str(),
+            )),
+            _ => None,
+        })
+        .collect::<Vec<_>>()
+}
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index ae65dd76b5f..551bb56685c 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -290,9 +290,34 @@ where
     }
 }
 
-pub(crate) enum SourceContext {
+pub(crate) struct ScrapedInfo<'a> {
+    pub(crate) offset: usize,
+    pub(crate) needs_prev_next_buttons: bool,
+    pub(crate) name: &'a str,
+    pub(crate) url: &'a str,
+    pub(crate) title: &'a str,
+    pub(crate) locations: String,
+    pub(crate) needs_expansion: bool,
+}
+
+#[derive(Template)]
+#[template(path = "scraped_source.html")]
+struct ScrapedSource<'a, Code: std::fmt::Display> {
+    info: ScrapedInfo<'a>,
+    lines: RangeInclusive<usize>,
+    code_html: Code,
+}
+
+#[derive(Template)]
+#[template(path = "source.html")]
+struct Source<Code: std::fmt::Display> {
+    lines: RangeInclusive<usize>,
+    code_html: Code,
+}
+
+pub(crate) enum SourceContext<'a> {
     Standalone,
-    Embedded { offset: usize, needs_expansion: bool },
+    Embedded(ScrapedInfo<'a>),
 }
 
 /// Wrapper struct to render the source code of a file. This will do things like
@@ -304,23 +329,8 @@ pub(crate) fn print_src(
     context: &Context<'_>,
     root_path: &str,
     decoration_info: highlight::DecorationInfo,
-    source_context: SourceContext,
+    source_context: SourceContext<'_>,
 ) {
-    #[derive(Template)]
-    #[template(path = "source.html")]
-    struct Source<Code: std::fmt::Display> {
-        embedded: bool,
-        needs_expansion: bool,
-        lines: RangeInclusive<usize>,
-        code_html: Code,
-    }
-    let lines = s.lines().count();
-    let (embedded, needs_expansion, lines) = match source_context {
-        SourceContext::Standalone => (false, false, 1..=lines),
-        SourceContext::Embedded { offset, needs_expansion } => {
-            (true, needs_expansion, (1 + offset)..=(lines + offset))
-        }
-    };
     let current_href = context
         .href_from_span(clean::Span::new(file_span), false)
         .expect("only local crates should have sources emitted");
@@ -333,5 +343,14 @@ pub(crate) fn print_src(
         );
         Ok(())
     });
-    Source { embedded, needs_expansion, lines, code_html: code }.render_into(&mut writer).unwrap();
+    let lines = s.lines().count();
+    match source_context {
+        SourceContext::Standalone => {
+            Source { lines: (1..=lines), code_html: code }.render_into(&mut writer).unwrap()
+        }
+        SourceContext::Embedded(info) => {
+            let lines = (1 + info.offset)..=(lines + info.offset);
+            ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap();
+        }
+    };
 }
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index 86e8edad703..e62b16267f1 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -59,6 +59,8 @@ nav.sub {
 	--copy-path-button-color: #999;
 	--copy-path-img-filter: invert(50%);
 	--copy-path-img-hover-filter: invert(35%);
+	--code-example-button-color: #7f7f7f;
+	--code-example-button-hover-color: #595959;
 	--codeblock-error-hover-color: rgb(255, 0, 0);
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -162,6 +164,8 @@ nav.sub {
 		--copy-path-button-color: #999;
 		--copy-path-img-filter: invert(50%);
 		--copy-path-img-hover-filter: invert(65%);
+		--code-example-button-color: #7f7f7f;
+		--code-example-button-hover-color: #a5a5a5;
 		--codeblock-error-hover-color: rgb(255, 0, 0);
 		--codeblock-error-color: rgba(255, 0, 0, .5);
 		--codeblock-ignore-hover-color: rgb(255, 142, 0);
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 28df8d3f011..38154dee3e2 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -378,7 +378,7 @@ pre.item-decl {
 .src .content pre {
 	padding: 20px;
 }
-.rustdoc.src .example-wrap pre.src-line-numbers  {
+.rustdoc.src .example-wrap .src-line-numbers  {
 	padding: 20px 0 20px 4px;
 }
 
@@ -568,12 +568,16 @@ img {
 	width: 48px;
 }
 
-ul.block, .block li {
+ul.block, .block li, .block ul {
 	padding: 0;
 	margin: 0;
 	list-style: none;
 }
 
+.block ul a {
+	padding-left: 1rem;
+}
+
 .sidebar-elems a,
 .sidebar > h2 a {
 	display: block;
@@ -585,6 +589,14 @@ ul.block, .block li {
 	background-clip: border-box;
 }
 
+.hide-toc #rustdoc-toc, .hide-toc .in-crate {
+	display: none;
+}
+
+.hide-modnav #rustdoc-modnav {
+	display: none;
+}
+
 .sidebar h2 {
 	text-wrap: balance;
 	overflow-wrap: anywhere;
@@ -745,10 +757,32 @@ ul.block, .block li {
 	margin-bottom: 10px;
 }
 
-.rustdoc .example-wrap > pre {
+.rustdoc .example-wrap > pre,
+.rustdoc .scraped-example .src-line-numbers,
+.rustdoc .scraped-example .src-line-numbers > pre {
 	border-radius: 6px;
 }
 
+/*
+If the code example line numbers are displayed, there will be a weird radius in the middle from
+both the code example and the line numbers, so we need to remove the radius in this case.
+*/
+.rustdoc .example-wrap > .example-line-numbers,
+.rustdoc .scraped-example .src-line-numbers,
+.rustdoc .scraped-example .src-line-numbers > pre {
+	border-top-right-radius: 0;
+	border-bottom-right-radius: 0;
+}
+.rustdoc .example-wrap > .example-line-numbers + pre,
+.rustdoc .scraped-example .rust {
+	border-top-left-radius: 0;
+	border-bottom-left-radius: 0;
+}
+
+.rustdoc .scraped-example {
+	position: relative;
+}
+
 /* For the last child of a div, the margin will be taken care of
 	by the margin-top of the next item. */
 .rustdoc .example-wrap:last-child {
@@ -760,15 +794,36 @@ ul.block, .block li {
 	flex-grow: 1;
 }
 
-.rustdoc:not(.src) .example-wrap pre {
+.scraped-example:not(.expanded) .example-wrap {
+	/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
+	 * of lines shown in the un-expanded example code viewer. This pre needs to have
+	 * a max-height equal to line-height * N. The line-height is currently 1.5em,
+	 * and we include additional 10px for padding. */
+	max-height: calc(1.5em * 5 + 10px);
+}
+
+.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers,
+.rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre,
+.rustdoc:not(.src) .scraped-example:not(.expanded) pre.rust {
+	padding-bottom: 0;
+	/* See above comment, should be the same max-height. */
 	overflow: auto hidden;
 }
+.rustdoc:not(.src) .scraped-example .src-line-numbers {
+	padding-top: 0;
+}
+.rustdoc:not(.src) .scraped-example.expanded .src-line-numbers {
+	padding-bottom: 0;
+}
+
+.rustdoc:not(.src) .example-wrap pre {
+	overflow: auto;
+}
 
 .rustdoc .example-wrap pre.example-line-numbers,
-.rustdoc .example-wrap pre.src-line-numbers {
-	flex-grow: 0;
+.rustdoc .example-wrap .src-line-numbers {
 	min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */
-	overflow: initial;
+	flex-grow: 0;
 	text-align: right;
 	-webkit-user-select: none;
 	user-select: none;
@@ -776,7 +831,7 @@ ul.block, .block li {
 	color: var(--src-line-numbers-span-color);
 }
 
-.rustdoc .example-wrap pre.src-line-numbers {
+.rustdoc .scraped-example .src-line-numbers {
 	padding: 14px 0;
 }
 .src-line-numbers a, .src-line-numbers span {
@@ -1488,17 +1543,23 @@ instead, we check that it's not a "finger" cursor.
 .example-wrap .button-holder.keep-visible {
 	visibility: visible;
 }
-.example-wrap .button-holder .copy-button, .example-wrap .test-arrow {
+.example-wrap .button-holder > * {
 	background: var(--main-background-color);
 	cursor: pointer;
 	border-radius: var(--button-border-radius);
 	height: var(--copy-path-height);
 	width: var(--copy-path-width);
+	border: 0;
+	color: var(--code-example-button-color);
 }
-.example-wrap .button-holder .copy-button {
+.example-wrap .button-holder > *:hover {
+	color: var(--code-example-button-hover-color);
+}
+.example-wrap .button-holder > *:not(:first-child) {
 	margin-left: var(--button-left-margin);
+}
+.example-wrap .button-holder .copy-button {
 	padding: 2px 0 0 4px;
-	border: 0;
 }
 .example-wrap .button-holder .copy-button::before,
 .example-wrap .test-arrow::before {
@@ -1852,6 +1913,11 @@ details.toggle {
 	position: relative;
 }
 
+details.big-toggle {
+	/* This makes [-] on the same line as <summary>. */
+	contain: inline-size;
+}
+
 /* The hideme class is used on summary tags that contain a span with
 	placeholder text shown only when the toggle is closed. For instance,
 	"Expand description" or "Show methods". */
@@ -1942,6 +2008,11 @@ details.toggle > summary:not(.hideme)::before {
 	left: -24px;
 }
 
+details.big-toggle > summary:not(.hideme)::before {
+	left: -34px;
+	top: 9px;
+}
+
 /* When a "hideme" summary is open and the "Expand description" or "Show
 	methods" text is hidden, we want the [-] toggle that remains to not
 	affect the layout of the items to its right. To do that, we use
@@ -2232,6 +2303,7 @@ in src-script.js and main.js
 	}
 }
 
+
 /* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */
 @media (min-width: 701px) {
 	/* Places file-link for a scraped example on top of the example to save space.
@@ -2334,99 +2406,41 @@ in src-script.js and main.js
 	color: var(--scrape-example-help-hover-color);
 }
 
-.scraped-example {
-	/* So .scraped-example-title can be positioned absolutely */
-	position: relative;
-}
-
-.scraped-example .code-wrapper {
-	position: relative;
-	display: flex;
-	flex-direction: row;
-	flex-wrap: wrap;
-	width: 100%;
-}
-
-.scraped-example:not(.expanded) .code-wrapper {
-	/* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
-	 * of lines shown in the un-expanded example code viewer. This pre needs to have
-	 * a max-height equal to line-height * N. The line-height is currently 1.5em,
-	 * and we include additional 10px for padding. */
-	 max-height: calc(1.5em * 5 + 10px);
-}
-
-.scraped-example:not(.expanded) .code-wrapper pre {
-	overflow-y: hidden;
-	padding-bottom: 0;
-	/* See above comment, should be the same max-height. */
-	max-height: calc(1.5em * 5 + 10px);
-}
-
-.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,
-.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre {
-	/* See above comment, except this height is based on HIDDEN_MAX_LINES. */
-	max-height: calc(1.5em * 10 + 10px);
-}
-
-.scraped-example .code-wrapper .next,
-.scraped-example .code-wrapper .prev,
-.scraped-example .code-wrapper .expand {
-	color: var(--main-color);
-	position: absolute;
-	top: 0.25em;
-	z-index: 1;
-	padding: 0;
-	background: none;
-	border: none;
-	/* iOS button gradient: https://stackoverflow.com/q/5438567 */
-	-webkit-appearance: none;
-	opacity: 1;
-}
-.scraped-example .code-wrapper .prev {
-	right: 2.25em;
-}
-.scraped-example .code-wrapper .next {
-	right: 1.25em;
-}
-.scraped-example .code-wrapper .expand {
-	right: 0.25em;
-}
-
-.scraped-example:not(.expanded) .code-wrapper::before,
-.scraped-example:not(.expanded) .code-wrapper::after {
+.scraped-example:not(.expanded) .example-wrap::before,
+.scraped-example:not(.expanded) .example-wrap::after {
 	content: " ";
 	width: 100%;
 	height: 5px;
 	position: absolute;
 	z-index: 1;
 }
-.scraped-example:not(.expanded) .code-wrapper::before {
+.scraped-example:not(.expanded) .example-wrap::before {
 	top: 0;
 	background: linear-gradient(to bottom,
 		var(--scrape-example-code-wrapper-background-start),
 		var(--scrape-example-code-wrapper-background-end));
 }
-.scraped-example:not(.expanded) .code-wrapper::after {
+.scraped-example:not(.expanded) .example-wrap::after {
 	bottom: 0;
 	background: linear-gradient(to top,
 		var(--scrape-example-code-wrapper-background-start),
 		var(--scrape-example-code-wrapper-background-end));
 }
 
-.scraped-example .code-wrapper .example-wrap {
+.scraped-example:not(.expanded) {
 	width: 100%;
 	overflow-y: hidden;
 	margin-bottom: 0;
 }
 
-.scraped-example:not(.expanded) .code-wrapper .example-wrap {
+.scraped-example:not(.expanded) {
 	overflow-x: hidden;
 }
 
-.scraped-example .example-wrap .rust span.highlight {
+.scraped-example .rust span.highlight {
 	background: var(--scrape-example-code-line-highlight);
 }
-.scraped-example .example-wrap .rust span.highlight.focus {
+.scraped-example .rust span.highlight.focus {
 	background: var(--scrape-example-code-line-highlight-focus);
 }
 
@@ -2520,6 +2534,8 @@ by default.
 	--copy-path-button-color: #999;
 	--copy-path-img-filter: invert(50%);
 	--copy-path-img-hover-filter: invert(35%);
+	--code-example-button-color: #7f7f7f;
+	--code-example-button-hover-color: #595959;
 	--codeblock-error-hover-color: rgb(255, 0, 0);
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -2622,6 +2638,8 @@ by default.
 	--copy-path-button-color: #999;
 	--copy-path-img-filter: invert(50%);
 	--copy-path-img-hover-filter: invert(65%);
+	--code-example-button-color: #7f7f7f;
+	--code-example-button-hover-color: #a5a5a5;
 	--codeblock-error-hover-color: rgb(255, 0, 0);
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
@@ -2731,6 +2749,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--copy-path-button-color: #fff;
 	--copy-path-img-filter: invert(70%);
 	--copy-path-img-hover-filter: invert(100%);
+	--code-example-button-color: #b2b2b2;
+	--code-example-button-hover-color: #fff;
 	--codeblock-error-hover-color: rgb(255, 0, 0);
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index c3e219f2c87..858753a1917 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -499,7 +499,7 @@ function preLoadCss(cssUrl) {
         if (!window.SIDEBAR_ITEMS) {
             return;
         }
-        const sidebar = document.getElementsByClassName("sidebar-elems")[0];
+        const sidebar = document.getElementById("rustdoc-modnav");
 
         /**
          * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
@@ -885,7 +885,7 @@ function preLoadCss(cssUrl) {
         if (!window.ALL_CRATES) {
             return;
         }
-        const sidebarElems = document.getElementsByClassName("sidebar-elems")[0];
+        const sidebarElems = document.getElementById("rustdoc-modnav");
         if (!sidebarElems) {
             return;
         }
@@ -1855,8 +1855,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         // Since the button will be added, no need to keep this listener around.
         elem.removeEventListener("mouseover", addCopyButton);
 
-        const parent = document.createElement("div");
-        parent.className = "button-holder";
+        // If this is a scrapped example, there will already be a "button-holder" element.
+        let parent = elem.querySelector(".button-holder");
+        if (!parent) {
+            parent = document.createElement("div");
+            parent.className = "button-holder";
+        }
+
         const runButton = elem.querySelector(".test-arrow");
         if (runButton !== null) {
             // If there is a run button, we move it into the same div.
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index 7a3a9c5f340..06e42814d33 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -13,7 +13,7 @@
 
     // Scroll code block to the given code location
     function scrollToLoc(elt, loc, isHidden) {
-        const lines = elt.querySelector(".src-line-numbers");
+        const lines = elt.querySelector(".src-line-numbers > pre");
         let scrollOffset;
 
         // If the block is greater than the size of the viewer,
@@ -24,8 +24,7 @@
             const line = Math.max(0, loc[0] - 1);
             scrollOffset = lines.children[line].offsetTop;
         } else {
-            const wrapper = elt.querySelector(".code-wrapper");
-            const halfHeight = wrapper.offsetHeight / 2;
+            const halfHeight = elt.offsetHeight / 2;
             const offsetTop = lines.children[loc[0]].offsetTop;
             const lastLine = lines.children[loc[1]];
             const offsetBot = lastLine.offsetTop + lastLine.offsetHeight;
@@ -33,7 +32,7 @@
             scrollOffset = offsetMid - halfHeight;
         }
 
-        lines.scrollTo(0, scrollOffset);
+        lines.parentElement.scrollTo(0, scrollOffset);
         elt.querySelector(".rust").scrollTo(0, scrollOffset);
     }
 
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 2b42fbebb80..c52a19ef987 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -36,6 +36,20 @@
                     removeClass(document.documentElement, "hide-sidebar");
                 }
                 break;
+            case "hide-toc":
+                if (value === true) {
+                    addClass(document.documentElement, "hide-toc");
+                } else {
+                    removeClass(document.documentElement, "hide-toc");
+                }
+                break;
+            case "hide-modnav":
+                if (value === true) {
+                    addClass(document.documentElement, "hide-modnav");
+                } else {
+                    removeClass(document.documentElement, "hide-modnav");
+                }
+                break;
         }
     }
 
@@ -102,6 +116,11 @@
         let output = "";
 
         for (const setting of settings) {
+            if (setting === "hr") {
+                output += "<hr>";
+                continue;
+            }
+
             const js_data_name = setting["js_name"];
             const setting_name = setting["name"];
 
@@ -199,6 +218,16 @@
                 "default": false,
             },
             {
+                "name": "Hide table of contents",
+                "js_name": "hide-toc",
+                "default": false,
+            },
+            {
+                "name": "Hide module navigation",
+                "js_name": "hide-modnav",
+                "default": false,
+            },
+            {
                 "name": "Disable keyboard shortcuts",
                 "js_name": "disable-shortcuts",
                 "default": false,
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 4a27ca92fff..d75fb7a7fb5 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -196,16 +196,21 @@ updateTheme();
 // This needs to be done here because this JS is render-blocking,
 // so that the sidebar doesn't "jump" after appearing on screen.
 // The user interaction to change this is set up in main.js.
+//
+// At this point in page load, `document.body` is not available yet.
+// Set a class on the `<html>` element instead.
 if (getSettingValue("source-sidebar-show") === "true") {
-    // At this point in page load, `document.body` is not available yet.
-    // Set a class on the `<html>` element instead.
     addClass(document.documentElement, "src-sidebar-expanded");
 }
 if (getSettingValue("hide-sidebar") === "true") {
-    // At this point in page load, `document.body` is not available yet.
-    // Set a class on the `<html>` element instead.
     addClass(document.documentElement, "hide-sidebar");
 }
+if (getSettingValue("hide-toc") === "true") {
+    addClass(document.documentElement, "hide-toc");
+}
+if (getSettingValue("hide-modnav") === "true") {
+    addClass(document.documentElement, "hide-modnav");
+}
 function updateSidebarWidth() {
     const desktopSidebarWidth = getSettingValue("desktop-sidebar-width");
     if (desktopSidebarWidth && desktopSidebarWidth !== "null") {
diff --git a/src/librustdoc/html/templates/scraped_source.html b/src/librustdoc/html/templates/scraped_source.html
new file mode 100644
index 00000000000..e1fc2e69378
--- /dev/null
+++ b/src/librustdoc/html/templates/scraped_source.html
@@ -0,0 +1,33 @@
+<div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
+    <div class="scraped-example-title">
+       {{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
+    </div>
+    <div class="example-wrap"> {# #}
+        {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
+           Do not show "1 2 3 4 5 ..." in web search results. #}
+        <div class="src-line-numbers" data-nosnippet> {# #}
+            <pre>
+                {% for line in lines.clone() %}
+                    {# ~#}
+                    <span>{{line|safe}}</span>
+                {% endfor %}
+            </pre> {# #}
+        </div> {# #}
+        <pre class="rust"> {# #}
+            <code>
+                {{code_html|safe}}
+            </code> {# #}
+        </pre> {# #}
+        {% if info.needs_prev_next_buttons || info.needs_expansion %}
+            <div class="button-holder">
+                {% if info.needs_prev_next_buttons %}
+                    <button class="prev">&pr;</button> {# #}
+                    <button class="next">&sc;</button>
+                {% endif %}
+                {% if info.needs_expansion %}
+                    <button class="expand">&varr;</button>
+                {% endif %}
+            </div>
+        {% endif %}
+    </div> {# #}
+</div> {# #}
diff --git a/src/librustdoc/html/templates/sidebar.html b/src/librustdoc/html/templates/sidebar.html
index 0990c2716b8..fccf65cbefc 100644
--- a/src/librustdoc/html/templates/sidebar.html
+++ b/src/librustdoc/html/templates/sidebar.html
@@ -1,8 +1,3 @@
-{% if !title.is_empty() %}
-    <h2 class="location"> {# #}
-        <a href="#">{{title_prefix}}{{title|wrapped|safe}}</a> {# #}
-    </h2>
-{% endif %}
 <div class="sidebar-elems">
     {% if is_crate %}
         <ul class="block"> {# #}
@@ -11,18 +6,46 @@
     {% endif %}
 
     {% if self.should_render_blocks() %}
-        <section>
+        <section id="rustdoc-toc">
+            {% if !title.is_empty() %}
+            <h2 class="location"> {# #}
+                <a href="#">{{title_prefix}}{{title|wrapped|safe}}</a> {# #}
+            </h2>
+            {% endif %}
             {% for block in blocks %}
                 {% if block.should_render() %}
                     {% if !block.heading.name.is_empty() %}
-                        <h3><a href="#{{block.heading.href|safe}}"> {# #}
-                            {{block.heading.name|wrapped|safe}} {# #}
-                        </a></h3> {# #}
+                        <h3> {# #}
+                            <a href="#{{block.heading.href|safe}}">{{block.heading.name|wrapped|safe}}</a> {# #}
+                        </h3>
                     {% endif %}
                     {% if !block.links.is_empty() %}
                         <ul class="block{% if !block.class.is_empty() +%} {{+block.class}}{% endif %}">
                             {% for link in block.links %}
-                                <li><a href="#{{link.href|safe}}">{{link.name}}</a></li>
+                                <li> {# #}
+                                    <a href="#{{link.href|safe}}" title="{{link.name}}">
+                                        {% match link.name_html %}
+                                            {% when Some with (html) %}
+                                                {{html|safe}}
+                                            {% else %}
+                                                {{link.name}}
+                                        {% endmatch %}
+                                    </a> {# #}
+                                    {% if !link.children.is_empty() %}
+                                        <ul>
+                                            {% for child in link.children %}
+                                                <li><a href="#{{child.href|safe}}" title="{{child.name}}">
+                                                    {% match child.name_html %}
+                                                        {% when Some with (html) %}
+                                                            {{html|safe}}
+                                                        {% else %}
+                                                            {{child.name}}
+                                                    {% endmatch %}
+                                                </a></li>
+                                            {% endfor %}
+                                        </ul>
+                                    {% endif %}
+                                </li>
                             {% endfor %}
                         </ul>
                     {% endif %}
@@ -30,7 +53,11 @@
             {% endfor %}
         </section>
     {% endif %}
+    <div id="rustdoc-modnav">
     {% if !path.is_empty() %}
-        <h2><a href="{% if is_mod %}../{% endif %}index.html">In {{+ path|wrapped|safe}}</a></h2>
+        <h2{% if parent_is_crate +%} class="in-crate"{% endif %}> {# #}
+            <a href="{% if is_mod %}../{% endif %}index.html">In {{+ path|wrapped|safe}}</a> {# #}
+        </h2>
     {% endif %}
+    </div> {# #}
 </div>
diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html
index 42d01277db2..60a47f1b5de 100644
--- a/src/librustdoc/html/templates/source.html
+++ b/src/librustdoc/html/templates/source.html
@@ -1,21 +1,15 @@
-<div class="example-wrap"> {# #}
+<div class="example-wrap">
     {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
        Do not show "1 2 3 4 5 ..." in web search results. #}
     <div data-nosnippet><pre class="src-line-numbers">
         {% for line in lines.clone() %}
-            {% if embedded %}
-                <span>{{line|safe}}</span>
-            {%~ else %}
-                <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a>
-            {%~ endif %}
+            {# ~#}
+            <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a>
         {% endfor %}
     </pre></div> {# #}
     <pre class="rust"> {# #}
         <code>
-            {% if needs_expansion %}
-                <button class="expand">&varr;</button>
-            {% endif %}
             {{code_html|safe}}
         </code> {# #}
     </pre> {# #}
-</div>
+</div> {# #}
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index a12c2a6a16c..7fdce41a634 100644
--- a/src/librustdoc/html/toc.rs
+++ b/src/librustdoc/html/toc.rs
@@ -1,4 +1,5 @@
 //! Table-of-contents creation.
+use crate::html::escape::Escape;
 
 /// A (recursive) table of contents
 #[derive(Debug, PartialEq)]
@@ -16,7 +17,7 @@ pub(crate) struct Toc {
     /// ### A
     /// ## B
     /// ```
-    entries: Vec<TocEntry>,
+    pub(crate) entries: Vec<TocEntry>,
 }
 
 impl Toc {
@@ -27,11 +28,16 @@ impl Toc {
 
 #[derive(Debug, PartialEq)]
 pub(crate) struct TocEntry {
-    level: u32,
-    sec_number: String,
-    name: String,
-    id: String,
-    children: Toc,
+    pub(crate) level: u32,
+    pub(crate) sec_number: String,
+    // name is a plain text header that works in a `title` tag
+    // html includes `<code>` tags
+    // the tooltip is used so that, when a toc is truncated,
+    // you can mouse over it to see the whole thing
+    pub(crate) name: String,
+    pub(crate) html: String,
+    pub(crate) id: String,
+    pub(crate) children: Toc,
 }
 
 /// Progressive construction of a table of contents.
@@ -115,7 +121,7 @@ impl TocBuilder {
     /// Push a level `level` heading into the appropriate place in the
     /// hierarchy, returning a string containing the section number in
     /// `<num>.<num>.<num>` format.
-    pub(crate) fn push(&mut self, level: u32, name: String, id: String) -> &str {
+    pub(crate) fn push(&mut self, level: u32, name: String, html: String, id: String) -> &str {
         assert!(level >= 1);
 
         // collapse all previous sections into their parents until we
@@ -149,6 +155,7 @@ impl TocBuilder {
         self.chain.push(TocEntry {
             level,
             name,
+            html,
             sec_number,
             id,
             children: Toc { entries: Vec::new() },
@@ -170,10 +177,11 @@ impl Toc {
             // recursively format this table of contents
             let _ = write!(
                 v,
-                "\n<li><a href=\"#{id}\">{num} {name}</a>",
+                "\n<li><a href=\"#{id}\" title=\"{name}\">{num} {html}</a>",
                 id = entry.id,
                 num = entry.sec_number,
-                name = entry.name
+                name = Escape(&entry.name),
+                html = &entry.html,
             );
             entry.children.print_inner(&mut *v);
             v.push_str("</li>");
diff --git a/src/librustdoc/html/toc/tests.rs b/src/librustdoc/html/toc/tests.rs
index 014f346862b..81aca737baf 100644
--- a/src/librustdoc/html/toc/tests.rs
+++ b/src/librustdoc/html/toc/tests.rs
@@ -9,7 +9,10 @@ fn builder_smoke() {
     // there's been no macro mistake.
     macro_rules! push {
         ($level: expr, $name: expr) => {
-            assert_eq!(builder.push($level, $name.to_string(), "".to_string()), $name);
+            assert_eq!(
+                builder.push($level, $name.to_string(), $name.to_string(), "".to_string()),
+                $name
+            );
         };
     }
     push!(2, "0.1");
@@ -48,6 +51,7 @@ fn builder_smoke() {
                         TocEntry {
                             level: $level,
                             name: $name.to_string(),
+                            html: $name.to_string(),
                             sec_number: $name.to_string(),
                             id: "".to_string(),
                             children: toc!($($sub),*)
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index a98f81d011e..581ebbbe58d 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -72,6 +72,7 @@ pub(crate) fn render<P: AsRef<Path>>(
     let text = if !options.markdown_no_toc {
         MarkdownWithToc {
             content: text,
+            links: &[],
             ids: &mut ids,
             error_codes,
             edition,
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index da84569c778..cc48a8964a3 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -159,3 +159,37 @@ pub fn get_git_untracked_files(
         .collect();
     Ok(Some(files))
 }
+
+/// Print a warning if the branch returned from `updated_master_branch` is old
+///
+/// For certain configurations of git repository, this remote will not be
+/// updated when running `git pull`.
+///
+/// This can result in formatting thousands of files instead of a dozen,
+/// so we should warn the user something is wrong.
+pub fn warn_old_master_branch(
+    config: &GitConfig<'_>,
+    git_dir: &Path,
+) -> Result<(), Box<dyn std::error::Error>> {
+    use std::time::Duration;
+    const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10);
+    let updated_master = updated_master_branch(config, Some(git_dir))?;
+    let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master);
+    match std::fs::metadata(branch_path) {
+        Ok(meta) => {
+            if meta.modified()?.elapsed()? > WARN_AFTER {
+                eprintln!("warning: {updated_master} has not been updated in 10 days");
+            } else {
+                return Ok(());
+            }
+        }
+        Err(err) => {
+            eprintln!("warning: unable to check if {updated_master} is old due to error: {err}")
+        }
+    }
+    eprintln!(
+        "warning: {updated_master} is used to determine if files have been modified\n\
+               warning: if it is not updated, this may cause files to be needlessly reformatted"
+    );
+    Ok(())
+}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 8f40fc59fb0c8df91c97405785197f3c630304e
+Subproject c1fa840a85eca53818895901a53fae34247448b
diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs
index a559d6f81a2..865aa76ddb0 100644
--- a/src/tools/compiletest/src/command-list.rs
+++ b/src/tools/compiletest/src/command-list.rs
@@ -136,6 +136,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "min-llvm-version",
     "min-system-llvm-version",
     "needs-asm-support",
+    "needs-deterministic-layouts",
     "needs-dlltool",
     "needs-dynamic-linking",
     "needs-force-clang-based-tests",
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 5831f7c3cf2..773d795f75a 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -274,6 +274,9 @@ pub struct Config {
     /// Flags to pass to the compiler when building for the target
     pub target_rustcflags: Vec<String>,
 
+    /// Whether the compiler and stdlib has been built with randomized struct layouts
+    pub rust_randomized_layout: bool,
+
     /// Whether tests should be optimized by default. Individual test-suites and test files may
     /// override this setting.
     pub optimize_tests: bool,
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 72b1b9c6d48..e903f60ceb3 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -135,6 +135,11 @@ pub(super) fn handle_needs(
             ignore_reason: "ignored on targets without PIC relocation model",
         },
         Need {
+            name: "needs-deterministic-layouts",
+            condition: !config.rust_randomized_layout,
+            ignore_reason: "ignored when randomizing layouts",
+        },
+        Need {
             name: "needs-wasmtime",
             condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")),
             ignore_reason: "ignored when wasmtime runner is not available",
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 7018362af54..5402e69bc66 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -99,6 +99,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
         )
         .optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS")
         .optmulti("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS")
+        .optflag(
+            "",
+            "rust-randomized-layout",
+            "set this when rustc/stdlib were compiled with randomized layouts",
+        )
         .optflag("", "optimize-tests", "run tests with optimizations enabled")
         .optflag("", "verbose", "run tests verbosely, showing all output")
         .optflag(
@@ -286,6 +291,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         host_rustcflags: matches.opt_strs("host-rustcflags"),
         target_rustcflags: matches.opt_strs("target-rustcflags"),
         optimize_tests: matches.opt_present("optimize-tests"),
+        rust_randomized_layout: matches.opt_present("rust-randomized-layout"),
         target,
         host: opt_str2(matches.opt_str("host")),
         cdb,
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 4f14caf0e56..3fdad2a91e9 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-e71f9529121ca8f687e4b725e3c9adc3f1ebab4d
+54fdef7799d9ff9470bb5cabd29fde9471a99eaa
diff --git a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs
index 6be13b155f4..dc2b9e4491b 100644
--- a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs
+++ b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs
@@ -1,6 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
+#![feature(arbitrary_self_types_pointers, unsize, coerce_unsized, dispatch_from_dyn)]
 #![feature(rustc_attrs)]
 
 fn pin_box_dyn() {
diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs
index a0b96e25a0c..6b58173b343 100644
--- a/src/tools/run-make-support/src/command.rs
+++ b/src/tools/run-make-support/src/command.rs
@@ -15,7 +15,7 @@ use crate::{
 /// This is a custom command wrapper that simplifies working with commands and makes it easier to
 /// ensure that we check the exit status of executed processes.
 ///
-/// # A [`Command`] must be executed
+/// # A [`Command`] must be executed exactly once
 ///
 /// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If
 /// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test
@@ -23,26 +23,73 @@ use crate::{
 /// containing constructed but never executed commands is dangerous because it can give a false
 /// sense of confidence.
 ///
+/// Each [`Command`] invocation can also only be executed once, because we want to enforce
+/// `std{in,out,err}` config via [`std::process::Stdio`] but [`std::process::Stdio`] is not
+/// cloneable.
+///
+/// In this sense, [`Command`] exhibits linear type semantics but enforced at run-time.
+///
 /// [`run`]: Self::run
 /// [`run_fail`]: Self::run_fail
 /// [`run_unchecked`]: Self::run_unchecked
 #[derive(Debug)]
 pub struct Command {
     cmd: StdCommand,
-    stdin: Option<Box<[u8]>>,
+    // Convience for providing a quick stdin buffer.
+    stdin_buf: Option<Box<[u8]>>,
+
+    // Configurations for child process's std{in,out,err} handles.
+    stdin: Option<Stdio>,
+    stdout: Option<Stdio>,
+    stderr: Option<Stdio>,
+
+    // Emulate linear type semantics.
     drop_bomb: DropBomb,
+    already_executed: bool,
 }
 
 impl Command {
     #[track_caller]
     pub fn new<P: AsRef<OsStr>>(program: P) -> Self {
         let program = program.as_ref();
-        Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) }
+        Self {
+            cmd: StdCommand::new(program),
+            stdin_buf: None,
+            drop_bomb: DropBomb::arm(program),
+            stdin: None,
+            stdout: None,
+            stderr: None,
+            already_executed: false,
+        }
     }
 
-    /// Specify a stdin input
-    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
-        self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
+    /// Specify a stdin input buffer. This is a convenience helper,
+    pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
+        self
+    }
+
+    /// Configuration for the child process’s standard input (stdin) handle.
+    ///
+    /// See [`std::process::Command::stdin`].
+    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
+        self.stdin = Some(cfg.into());
+        self
+    }
+
+    /// Configuration for the child process’s standard output (stdout) handle.
+    ///
+    /// See [`std::process::Command::stdout`].
+    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
+        self.stdout = Some(cfg.into());
+        self
+    }
+
+    /// Configuration for the child process’s standard error (stderr) handle.
+    ///
+    /// See [`std::process::Command::stderr`].
+    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
+        self.stderr = Some(cfg.into());
         self
     }
 
@@ -105,6 +152,8 @@ impl Command {
     }
 
     /// Run the constructed command and assert that it is successfully run.
+    ///
+    /// By default, std{in,out,err} are [`Stdio::piped()`].
     #[track_caller]
     pub fn run(&mut self) -> CompletedProcess {
         let output = self.command_output();
@@ -115,6 +164,8 @@ impl Command {
     }
 
     /// Run the constructed command and assert that it does not successfully run.
+    ///
+    /// By default, std{in,out,err} are [`Stdio::piped()`].
     #[track_caller]
     pub fn run_fail(&mut self) -> CompletedProcess {
         let output = self.command_output();
@@ -124,10 +175,10 @@ impl Command {
         output
     }
 
-    /// Run the command but do not check its exit status.
-    /// Only use if you explicitly don't care about the exit status.
-    /// Prefer to use [`Self::run`] and [`Self::run_fail`]
-    /// whenever possible.
+    /// Run the command but do not check its exit status. Only use if you explicitly don't care
+    /// about the exit status.
+    ///
+    /// Prefer to use [`Self::run`] and [`Self::run_fail`] whenever possible.
     #[track_caller]
     pub fn run_unchecked(&mut self) -> CompletedProcess {
         self.command_output()
@@ -135,13 +186,19 @@ impl Command {
 
     #[track_caller]
     fn command_output(&mut self) -> CompletedProcess {
+        if self.already_executed {
+            panic!("command was already executed");
+        } else {
+            self.already_executed = true;
+        }
+
         self.drop_bomb.defuse();
         // let's make sure we piped all the input and outputs
-        self.cmd.stdin(Stdio::piped());
-        self.cmd.stdout(Stdio::piped());
-        self.cmd.stderr(Stdio::piped());
+        self.cmd.stdin(self.stdin.take().unwrap_or(Stdio::piped()));
+        self.cmd.stdout(self.stdout.take().unwrap_or(Stdio::piped()));
+        self.cmd.stderr(self.stderr.take().unwrap_or(Stdio::piped()));
 
-        let output = if let Some(input) = &self.stdin {
+        let output = if let Some(input) = &self.stdin_buf {
             let mut child = self.cmd.spawn().unwrap();
 
             {
diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs
index e9315856cd7..2522c4aeb93 100644
--- a/src/tools/run-make-support/src/external_deps/llvm.rs
+++ b/src/tools/run-make-support/src/external_deps/llvm.rs
@@ -227,9 +227,10 @@ impl LlvmFilecheck {
         Self { cmd }
     }
 
-    /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call.
-    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
-        self.cmd.stdin(input);
+    /// Provide a buffer representing standard input containing patterns that will be matched
+    /// against the `.patterns(path)` call.
+    pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.cmd.stdin_buf(input);
         self
     }
 
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 cece58d2956..f60ea972839 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -291,9 +291,9 @@ impl Rustc {
         self
     }
 
-    /// Specify a stdin input
-    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
-        self.cmd.stdin(input);
+    /// Specify a stdin input buffer.
+    pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.cmd.stdin_buf(input);
         self
     }
 
diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs
index 96b1c719e2e..df5e5d8a2e8 100644
--- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
@@ -85,9 +85,9 @@ impl Rustdoc {
         self
     }
 
-    /// Specify a stdin input
-    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
-        self.cmd.stdin(input);
+    /// Specify a stdin input buffer.
+    pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.cmd.stdin_buf(input);
         self
     }
 
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 989d00d4c2f..fefafb95b33 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -34,6 +34,7 @@ pub mod rfs {
 }
 
 // Re-exports of third-party library crates.
+// tidy-alphabetical-start
 pub use bstr;
 pub use gimli;
 pub use libc;
@@ -41,6 +42,7 @@ pub use object;
 pub use regex;
 pub use serde_json;
 pub use wasmparser;
+// tidy-alphabetical-end
 
 // Re-exports of external dependencies.
 pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index b0c5eec1fe4..c8610e03939 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -129,6 +129,9 @@
 //@ revisions: armv7_linux_androideabi
 //@ [armv7_linux_androideabi] compile-flags: --target armv7-linux-androideabi
 //@ [armv7_linux_androideabi] needs-llvm-components: arm
+//@ revisions: armv7_rtems_eabihf
+//@ [armv7_rtems_eabihf] compile-flags: --target armv7-rtems-eabihf
+//@ [armv7_rtems_eabihf] needs-llvm-components: arm
 //@ revisions: armv7_sony_vita_newlibeabihf
 //@ [armv7_sony_vita_newlibeabihf] compile-flags: --target armv7-sony-vita-newlibeabihf
 //@ [armv7_sony_vita_newlibeabihf] needs-llvm-components: arm
diff --git a/tests/codegen/intrinsics/likely.rs b/tests/codegen/intrinsics/likely.rs
index 098fd9936ce..9dc31d21045 100644
--- a/tests/codegen/intrinsics/likely.rs
+++ b/tests/codegen/intrinsics/likely.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -C no-prepopulate-passes
+//@ compile-flags: -C no-prepopulate-passes -Copt-level=1
 
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
diff --git a/tests/codegen/issues/issue-86106.rs b/tests/codegen/issues/issue-86106.rs
index e8164c5c380..8d1ce116d26 100644
--- a/tests/codegen/issues/issue-86106.rs
+++ b/tests/codegen/issues/issue-86106.rs
@@ -1,5 +1,6 @@
 //@ only-64bit llvm appears to use stores instead of memset on 32bit
 //@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
+//@ needs-deterministic-layouts
 
 // The below two functions ensure that both `String::new()` and `"".to_string()`
 // produce the identical code.
diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs
index d5eadda4469..e62f1a953df 100644
--- a/tests/codegen/mem-replace-big-type.rs
+++ b/tests/codegen/mem-replace-big-type.rs
@@ -5,6 +5,7 @@
 
 //@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no
 //@ ignore-debug: precondition checks in ptr::read make them a bad candidate for MIR inlining
+//@ needs-deterministic-layouts
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs
index c960688b00c..eda807d3682 100644
--- a/tests/codegen/slice-iter-nonnull.rs
+++ b/tests/codegen/slice-iter-nonnull.rs
@@ -1,4 +1,5 @@
 //@ compile-flags: -O
+//@ needs-deterministic-layouts
 #![crate_type = "lib"]
 #![feature(exact_size_is_empty)]
 
diff --git a/tests/codegen/vecdeque-drain.rs b/tests/codegen/vecdeque-drain.rs
index 31fcf035f11..fca1ed367e6 100644
--- a/tests/codegen/vecdeque-drain.rs
+++ b/tests/codegen/vecdeque-drain.rs
@@ -1,6 +1,7 @@
 // Check that draining at the front or back doesn't copy memory.
 
 //@ compile-flags: -O
+//@ needs-deterministic-layouts
 //@ ignore-debug: FIXME: checks for call detect scoped noalias metadata
 
 #![crate_type = "lib"]
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
index 1f5bb551b8e..7da33b8a094 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
@@ -1,11 +1,11 @@
-// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move
+// MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built
 
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
     debug a => (_1.0: i32);
-    debug b => (_1.1: i32);
+    debug b => (*(_1.1: &i32));
     let mut _0: ();
     let _3: i32;
     scope 1 {
@@ -28,7 +28,7 @@ yields ()
         _4 = &_3;
         FakeRead(ForLet(None), _4);
         StorageLive(_5);
-        _5 = &(_1.1: i32);
+        _5 = &(*(_1.1: &i32));
         FakeRead(ForLet(None), _5);
         _0 = const ();
         StorageDead(_5);
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
index 1f5bb551b8e..a21e82ef5b6 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move
+// MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built
 
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
index a984845fd2c..c1566360995 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10};
+fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:54:33: 54:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:54:53: 57:10 (#0)} { a: move _2, b: move (_1.0: i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir
deleted file mode 100644
index a984845fd2c..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
-
-fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10};
-
-    bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) };
-        return;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
index 17fa9314806..a4a6a535a23 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `main::{closure#0}::{closure#1}::{closure#0}` 0 coroutine_by_move
+// MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built
 
-fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
index 17fa9314806..69bba6f5194 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
@@ -1,6 +1,6 @@
-// MIR for `main::{closure#0}::{closure#1}::{closure#0}` 0 coroutine_by_move
+// MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built
 
-fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
index aab9f7b03b9..134fe145bae 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
+fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir
deleted file mode 100644
index aab9f7b03b9..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move
-
-fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
-
-    bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
-        return;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
index 3fdc81791de..f267d93bd60 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref
 
-fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
+fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir
deleted file mode 100644
index 3fdc81791de..00000000000
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref
-
-fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
-
-    bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
-        return;
-    }
-}
diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs
index 57c55ef055c..b2168ba0c46 100644
--- a/tests/mir-opt/async_closure_shims.rs
+++ b/tests/mir-opt/async_closure_shims.rs
@@ -1,6 +1,5 @@
 //@ edition:2021
 // skip-filecheck
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![feature(async_closure, noop_waker, async_fn_traits)]
 #![allow(unused)]
@@ -22,7 +21,7 @@ pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
     }
 }
 
-async fn call(f: &mut impl AsyncFn(i32)) {
+async fn call(f: &impl AsyncFn(i32)) {
     f(0).await;
 }
 
@@ -43,10 +42,12 @@ async fn call_normal_mut<F: Future<Output = ()>>(f: &mut impl FnMut(i32) -> F) {
 }
 
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
-// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
+// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
 pub fn main() {
     block_on(async {
         let b = 2i32;
@@ -54,7 +55,7 @@ pub fn main() {
             let a = &a;
             let b = &b;
         };
-        call(&mut async_closure).await;
+        call(&async_closure).await;
         call_mut(&mut async_closure).await;
         call_once(async_closure).await;
 
diff --git a/tests/mir-opt/building/receiver_ptr_mutability.rs b/tests/mir-opt/building/receiver_ptr_mutability.rs
index 4bb3b4cade5..1ddb8b71a5a 100644
--- a/tests/mir-opt/building/receiver_ptr_mutability.rs
+++ b/tests/mir-opt/building/receiver_ptr_mutability.rs
@@ -1,7 +1,7 @@
 // skip-filecheck
 // EMIT_MIR receiver_ptr_mutability.main.built.after.mir
 
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 struct Test {}
 
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs
index c92424f2983..08347f71b42 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs
@@ -1,3 +1,4 @@
+//@needs-deterministic-layouts
 // Verify that we do not ICE when printing an invalid constant.
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
diff --git a/tests/run-make/clear-error-blank-output/rmake.rs b/tests/run-make/clear-error-blank-output/rmake.rs
index e0f042cf805..22e030691f2 100644
--- a/tests/run-make/clear-error-blank-output/rmake.rs
+++ b/tests/run-make/clear-error-blank-output/rmake.rs
@@ -8,6 +8,6 @@
 use run_make_support::rustc;
 
 fn main() {
-    let output = rustc().output("").stdin(b"fn main() {}").run_fail();
+    let output = rustc().output("").stdin_buf(b"fn main() {}").run_fail();
     output.assert_stderr_not_contains("panic");
 }
diff --git a/tests/run-make/comment-section/rmake.rs b/tests/run-make/comment-section/rmake.rs
index 1557f50dbd0..ccfc38e870d 100644
--- a/tests/run-make/comment-section/rmake.rs
+++ b/tests/run-make/comment-section/rmake.rs
@@ -14,7 +14,7 @@ fn main() {
 
     rustc()
         .arg("-")
-        .stdin("fn main() {}")
+        .stdin_buf("fn main() {}")
         .emit("link,obj")
         .arg("-Csave-temps")
         .target(target)
diff --git a/tests/run-make/compile-stdin/rmake.rs b/tests/run-make/compile-stdin/rmake.rs
index f93080dfdc4..b8244335855 100644
--- a/tests/run-make/compile-stdin/rmake.rs
+++ b/tests/run-make/compile-stdin/rmake.rs
@@ -8,6 +8,6 @@
 use run_make_support::{run, rustc};
 
 fn main() {
-    rustc().arg("-").stdin("fn main() {}").run();
+    rustc().arg("-").stdin_buf("fn main() {}").run();
     run("rust_out");
 }
diff --git a/tests/run-make/libtest-junit/rmake.rs b/tests/run-make/libtest-junit/rmake.rs
index d631313ed92..5917660b6c7 100644
--- a/tests/run-make/libtest-junit/rmake.rs
+++ b/tests/run-make/libtest-junit/rmake.rs
@@ -21,7 +21,7 @@ fn run_tests(extra_args: &[&str], expected_file: &str) {
         .run_fail();
     let test_stdout = &cmd_out.stdout_utf8();
 
-    python_command().arg("validate_junit.py").stdin(test_stdout).run();
+    python_command().arg("validate_junit.py").stdin_buf(test_stdout).run();
 
     diff()
         .expected_file(expected_file)
diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs
index 9699d0579f6..47e6fc4de15 100644
--- a/tests/run-make/llvm-ident/rmake.rs
+++ b/tests/run-make/llvm-ident/rmake.rs
@@ -17,7 +17,7 @@ fn main() {
         .codegen_units(16)
         .opt_level("2")
         .target(&env_var("TARGET"))
-        .stdin("fn main(){}")
+        .stdin_buf("fn main(){}")
         .run();
 
     // `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR
diff --git a/tests/run-make/llvm-outputs/rmake.rs b/tests/run-make/llvm-outputs/rmake.rs
index b8ac21c98a0..632e9a09ba5 100644
--- a/tests/run-make/llvm-outputs/rmake.rs
+++ b/tests/run-make/llvm-outputs/rmake.rs
@@ -11,8 +11,8 @@ fn main() {
         let p = cwd();
         path_bc = p.join("nonexistant_dir_bc");
         path_ir = p.join("nonexistant_dir_ir");
-        rustc().input("-").stdin("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run();
-        rustc().input("-").stdin("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run();
+        rustc().input("-").stdin_buf("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run();
+        rustc().input("-").stdin_buf("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run();
         assert!(path_bc.exists());
         assert!(path_ir.exists());
     });
diff --git a/tests/run-make/no-builtins-attribute/rmake.rs b/tests/run-make/no-builtins-attribute/rmake.rs
index 1e15b0c03f1..7182c65a2c5 100644
--- a/tests/run-make/no-builtins-attribute/rmake.rs
+++ b/tests/run-make/no-builtins-attribute/rmake.rs
@@ -9,5 +9,5 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
 fn main() {
     rustc().input("no_builtins.rs").emit("link").run();
     rustc().input("main.rs").emit("llvm-ir").run();
-    llvm_filecheck().patterns("filecheck.main.txt").stdin(rfs::read("main.ll")).run();
+    llvm_filecheck().patterns("filecheck.main.txt").stdin_buf(rfs::read("main.ll")).run();
 }
diff --git a/tests/run-make/pgo-branch-weights/rmake.rs b/tests/run-make/pgo-branch-weights/rmake.rs
index ef33d009dbb..105c2fafc5a 100644
--- a/tests/run-make/pgo-branch-weights/rmake.rs
+++ b/tests/run-make/pgo-branch-weights/rmake.rs
@@ -35,5 +35,8 @@ fn main() {
         .codegen_units(1)
         .emit("llvm-ir")
         .run();
-    llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
+    llvm_filecheck()
+        .patterns("filecheck-patterns.txt")
+        .stdin_buf(rfs::read("interesting.ll"))
+        .run();
 }
diff --git a/tests/run-make/pgo-indirect-call-promotion/rmake.rs b/tests/run-make/pgo-indirect-call-promotion/rmake.rs
index d0ccfd8a4d7..28232eb2566 100644
--- a/tests/run-make/pgo-indirect-call-promotion/rmake.rs
+++ b/tests/run-make/pgo-indirect-call-promotion/rmake.rs
@@ -29,5 +29,8 @@ fn main() {
         .codegen_units(1)
         .emit("llvm-ir")
         .run();
-    llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
+    llvm_filecheck()
+        .patterns("filecheck-patterns.txt")
+        .stdin_buf(rfs::read("interesting.ll"))
+        .run();
 }
diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs
index cad49372266..276af9ea263 100644
--- a/tests/run-make/pgo-use/rmake.rs
+++ b/tests/run-make/pgo-use/rmake.rs
@@ -51,5 +51,5 @@ fn main() {
     let lines: Vec<_> = ir.lines().rev().collect();
     let mut reversed_ir = lines.join("\n");
     reversed_ir.push('\n');
-    llvm_filecheck().patterns("filecheck-patterns.txt").stdin(reversed_ir.as_bytes()).run();
+    llvm_filecheck().patterns("filecheck-patterns.txt").stdin_buf(reversed_ir.as_bytes()).run();
 }
diff --git a/tests/run-make/rustdoc-output-stdout/rmake.rs b/tests/run-make/rustdoc-output-stdout/rmake.rs
index dbc9892f3f5..bcf5e4d9723 100644
--- a/tests/run-make/rustdoc-output-stdout/rmake.rs
+++ b/tests/run-make/rustdoc-output-stdout/rmake.rs
@@ -4,17 +4,28 @@
 use std::path::PathBuf;
 
 use run_make_support::path_helpers::{cwd, has_extension, read_dir_entries_recursive};
-use run_make_support::rustdoc;
+use run_make_support::{rustdoc, serde_json};
 
 fn main() {
-    // First we check that we generate the JSON in the stdout.
-    rustdoc()
+    let json_string = rustdoc()
         .input("foo.rs")
         .out_dir("-")
         .arg("-Zunstable-options")
         .output_format("json")
         .run()
-        .assert_stdout_contains("{\"");
+        .stdout_utf8();
+
+    // First we check that we generate the JSON in the stdout.
+    let json_value: serde_json::Value =
+        serde_json::from_str(&json_string).expect("stdout should be valid json");
+
+    // We don't care to test the specifics of the JSON, as that's done
+    // elsewhere, just check that it has a format_version (as all JSON output
+    // should).
+    let format_version = json_value["format_version"]
+        .as_i64()
+        .expect("json output should contain format_version field");
+    assert!(format_version > 30);
 
     // Then we check it didn't generate any JSON file.
     read_dir_entries_recursive(cwd(), |path| {
diff --git a/tests/run-make/separate-link/rmake.rs b/tests/run-make/separate-link/rmake.rs
index e91b25489bc..0ec7334e75d 100644
--- a/tests/run-make/separate-link/rmake.rs
+++ b/tests/run-make/separate-link/rmake.rs
@@ -8,7 +8,7 @@
 use run_make_support::{run, rustc};
 
 fn main() {
-    rustc().stdin(b"fn main(){}").arg("-Zno-link").arg("-").run();
+    rustc().stdin_buf(b"fn main(){}").arg("-Zno-link").arg("-").run();
     rustc().arg("-Zlink-only").input("rust_out.rlink").run();
     run("rust_out");
 }
diff --git a/tests/run-make/static-pie/rmake.rs b/tests/run-make/static-pie/rmake.rs
index 74f86bb8163..1557c170f56 100644
--- a/tests/run-make/static-pie/rmake.rs
+++ b/tests/run-make/static-pie/rmake.rs
@@ -28,7 +28,7 @@ fn ok_compiler_version(compiler: &str) -> bool {
     }
 
     let compiler_output =
-        cmd(compiler).stdin(trigger).arg("-").arg("-E").arg("-x").arg("c").run().stdout_utf8();
+        cmd(compiler).stdin_buf(trigger).arg("-").arg("-E").arg("-x").arg("c").run().stdout_utf8();
     let re = Regex::new(r"(?m)^(\d+)").unwrap();
     let version: u32 =
         re.captures(&compiler_output).unwrap().get(1).unwrap().as_str().parse().unwrap();
diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs
index 68e9cf2fbd8..2d634dd455e 100644
--- a/tests/run-make/stdin-rustc/rmake.rs
+++ b/tests/run-make/stdin-rustc/rmake.rs
@@ -14,7 +14,7 @@ const NOT_UTF8: &[u8] = &[0xff, 0xff, 0xff];
 
 fn main() {
     // echo $HELLO_WORLD | rustc -
-    rustc().arg("-").stdin(HELLO_WORLD).run();
+    rustc().arg("-").stdin_buf(HELLO_WORLD).run();
     assert!(
         PathBuf::from(if !is_windows() { "rust_out" } else { "rust_out.exe" })
             .try_exists()
@@ -22,7 +22,7 @@ fn main() {
     );
 
     // echo $NOT_UTF8 | rustc -
-    rustc().arg("-").stdin(NOT_UTF8).run_fail().assert_stderr_contains(
+    rustc().arg("-").stdin_buf(NOT_UTF8).run_fail().assert_stderr_contains(
         "error: couldn't read from stdin, as it did not contain valid UTF-8",
     );
 }
diff --git a/tests/run-make/stdin-rustdoc/rmake.rs b/tests/run-make/stdin-rustdoc/rmake.rs
index de47a24fbdd..30f97b8a2cd 100644
--- a/tests/run-make/stdin-rustdoc/rmake.rs
+++ b/tests/run-make/stdin-rustdoc/rmake.rs
@@ -15,11 +15,11 @@ fn main() {
     let out_dir = PathBuf::from("doc");
 
     // rustdoc -
-    rustdoc().arg("-").out_dir(&out_dir).stdin(INPUT).run();
+    rustdoc().arg("-").out_dir(&out_dir).stdin_buf(INPUT).run();
     assert!(out_dir.join("rust_out/struct.F.html").try_exists().unwrap());
 
     // rustdoc --test -
-    rustdoc().arg("--test").arg("-").stdin(INPUT).run();
+    rustdoc().arg("--test").arg("-").stdin_buf(INPUT).run();
 
     // rustdoc file.rs -
     rustdoc().arg("file.rs").arg("-").run_fail();
diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
index 2240d87237b..c81c7fafdab 100644
--- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs
+++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
@@ -34,7 +34,7 @@ fn check_crate_is_unstable(cr: &Crate) {
         .target(target())
         .extern_(name, path)
         .input("-")
-        .stdin(format!("extern crate {name};"))
+        .stdin_buf(format!("extern crate {name};"))
         .run_fail();
 
     // Make sure it failed for the intended reason, not some other reason.
diff --git a/tests/run-make/unknown-mod-stdin/rmake.rs b/tests/run-make/unknown-mod-stdin/rmake.rs
index 0fe5c78ed0f..6be3119c0fd 100644
--- a/tests/run-make/unknown-mod-stdin/rmake.rs
+++ b/tests/run-make/unknown-mod-stdin/rmake.rs
@@ -12,7 +12,7 @@
 use run_make_support::{diff, rustc};
 
 fn main() {
-    let out = rustc().crate_type("rlib").stdin(b"mod unknown;").arg("-").run_fail();
+    let out = rustc().crate_type("rlib").stdin_buf(b"mod unknown;").arg("-").run_fail();
     diff()
         .actual_text("actual-stdout", out.stdout_utf8())
         .expected_file("unknown-mod.stdout")
diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
index 130781a4293..e58762aeb6d 100644
--- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
+++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
@@ -78,19 +78,23 @@ fn check(func_re: &str, mut checks: &str) {
     // This is because frame pointers are optional, and them being enabled requires
     // an additional `popq` in the pattern checking file.
     if func_re == "std::io::stdio::_print::[[:alnum:]]+" {
-        let output = llvm_filecheck().stdin(&dump).patterns(checks).run_unchecked();
+        let output = llvm_filecheck().stdin_buf(&dump).patterns(checks).run_unchecked();
         if !output.status().success() {
             checks = "print.without_frame_pointers.checks";
-            llvm_filecheck().stdin(&dump).patterns(checks).run();
+            llvm_filecheck().stdin_buf(&dump).patterns(checks).run();
         }
     } else {
-        llvm_filecheck().stdin(&dump).patterns(checks).run();
+        llvm_filecheck().stdin_buf(&dump).patterns(checks).run();
     }
     if !["rust_plus_one_global_asm", "cmake_plus_one_c_global_asm", "cmake_plus_one_cxx_global_asm"]
         .contains(&func_re)
     {
         // The assembler cannot avoid explicit `ret` instructions. Sequences
         // of `shlq $0x0, (%rsp); lfence; retq` are used instead.
-        llvm_filecheck().args(&["--implicit-check-not", "ret"]).stdin(dump).patterns(checks).run();
+        llvm_filecheck()
+            .args(&["--implicit-check-not", "ret"])
+            .stdin_buf(dump)
+            .patterns(checks)
+            .run();
     }
 }
diff --git a/tests/rustdoc-gui/code-example-buttons.goml b/tests/rustdoc-gui/code-example-buttons.goml
index 4f037ec79f5..c62683b45da 100644
--- a/tests/rustdoc-gui/code-example-buttons.goml
+++ b/tests/rustdoc-gui/code-example-buttons.goml
@@ -94,3 +94,24 @@ call-function: ("check-buttons",{
     "filter": "invert(0.5)",
     "filter_hover": "invert(0.35)",
 })
+
+define-function: (
+    "check-buttons-position",
+    [pre_selector],
+    block {
+        move-cursor-to: |pre_selector| + " .rust:not(.item-decl)"
+        store-position: (|pre_selector| + " .rust:not(.item-decl)", {"x": x, "y": y})
+        assert-position: (|pre_selector| + " .rust:not(.item-decl) + .button-holder", {
+            "y": |y| + 4,
+        })
+    }
+)
+
+call-function: ("check-buttons-position", {"pre_selector": ".example-wrap"})
+
+go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
+// We should work as well for scraped examples.
+call-function: ("check-buttons-position", {"pre_selector": ".scraped-example .example-wrap"})
+// And also when the scraped example "title" goes above.
+set-window-size: (600, 600)
+call-function: ("check-buttons-position", {"pre_selector": ".scraped-example .example-wrap"})
diff --git a/tests/rustdoc-gui/deref-block.goml b/tests/rustdoc-gui/deref-block.goml
new file mode 100644
index 00000000000..24f612f8a6f
--- /dev/null
+++ b/tests/rustdoc-gui/deref-block.goml
@@ -0,0 +1,30 @@
+// This test ensures that several clickable items actually have the pointer cursor.
+go-to: "file://" + |DOC_PATH| + "/lib2/struct.Derefer.html"
+
+assert-text: (".big-toggle summary", "Methods from Deref<Target = str>§")
+// We ensure it doesn't go over `§`.
+assert-css: (".big-toggle summary::before", {
+    "left": "-34px",
+    "top": "9px",
+})
+// It should NOT have the same X or Y position as the other toggles.
+compare-elements-position-false: (
+    ".big-toggle summary::before",
+    ".method-toggle summary::before",
+    ["x", "y"],
+)
+
+// We now check that if we're in mobile mode, it gets back to its original X position.
+set-window-size: (600, 600)
+assert-css: (".big-toggle summary::before", {
+    "left": "-11px",
+    "top": "9px",
+})
+// It should have the same X position as the other toggles.
+compare-elements-position: (".big-toggle summary::before", ".method-toggle summary::before", ["x"])
+// But still shouldn't have the same Y position.
+compare-elements-position-false: (
+    ".big-toggle summary::before",
+    ".method-toggle summary::before",
+    ["y"],
+)
diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml
index 348ce0c992f..03f8f80b10d 100644
--- a/tests/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml
@@ -5,6 +5,18 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 // We check that without this setting, there is no line number displayed.
 assert-false: "pre.example-line-numbers"
 
+// All corners should be rounded.
+assert-css: (
+    ".example-wrap .rust",
+    {
+        "border-top-left-radius": "6px",
+        "border-bottom-left-radius": "6px",
+        "border-top-right-radius": "6px",
+        "border-bottom-right-radius": "6px",
+    },
+    ALL,
+)
+
 // We set the setting to show the line numbers on code examples.
 set-local-storage: {"rustdoc-line-numbers": "true"}
 reload:
@@ -29,9 +41,21 @@ define-function: (
                 "margin": "0px",
                 "padding": "14px 8px",
                 "text-align": "right",
+                // There should not be a radius on the right of the line numbers.
+                "border-top-left-radius": "6px",
+                "border-bottom-left-radius": "6px",
+                "border-top-right-radius": "0px",
+                "border-bottom-right-radius": "0px",
             },
             ALL,
         )
+        // There should not be a radius on the left of the line numbers.
+        assert-css: ("pre.example-line-numbers + .rust", {
+            "border-top-left-radius": "0px",
+            "border-bottom-left-radius": "0px",
+            "border-top-right-radius": "6px",
+            "border-bottom-right-radius": "6px",
+        })
     },
 )
 call-function: ("check-colors", {
@@ -64,7 +88,56 @@ wait-for: 100 // wait-for-false does not exist
 assert-false: "pre.example-line-numbers"
 assert-local-storage: {"rustdoc-line-numbers": "false" }
 
+// Check that the rounded corners are back.
+assert-css: (
+    ".example-wrap .rust",
+    {
+        "border-top-left-radius": "6px",
+        "border-bottom-left-radius": "6px",
+        "border-top-right-radius": "6px",
+        "border-bottom-right-radius": "6px",
+    },
+    ALL,
+)
+
 // Finally, turn it on again.
 click: "input#line-numbers"
 wait-for: "pre.example-line-numbers"
 assert-local-storage: {"rustdoc-line-numbers": "true" }
+
+// Same check with scraped examples line numbers.
+go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
+
+assert-css: (
+    ".scraped-example .src-line-numbers > pre",
+    {
+        // There should not be a radius on the right of the line numbers.
+        "border-top-left-radius": "6px",
+        "border-bottom-left-radius": "6px",
+        "border-top-right-radius": "0px",
+        "border-bottom-right-radius": "0px",
+    },
+    ALL,
+)
+assert-css: (
+    ".scraped-example .src-line-numbers",
+    {
+        // There should not be a radius on the right of the line numbers.
+        "border-top-left-radius": "6px",
+        "border-bottom-left-radius": "6px",
+        "border-top-right-radius": "0px",
+        "border-bottom-right-radius": "0px",
+    },
+    ALL,
+)
+assert-css: (
+    ".scraped-example .rust",
+    {
+        // There should not be a radius on the left of the code.
+        "border-top-left-radius": "0px",
+        "border-bottom-left-radius": "0px",
+        "border-top-right-radius": "6px",
+        "border-bottom-right-radius": "6px",
+    },
+    ALL,
+)
diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml
index af4293dfc00..83ed6a219b2 100644
--- a/tests/rustdoc-gui/scrape-examples-button-focus.goml
+++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml
@@ -3,29 +3,53 @@
 go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
 
 // The next/prev buttons vertically scroll the code viewport between examples
-store-property: (".scraped-example-list > .scraped-example pre", {"scrollTop": initialScrollTop})
+move-cursor-to: ".scraped-example-list > .scraped-example"
+store-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "scrollTop": initialScrollTop,
+})
+assert-property: (".scraped-example-list > .scraped-example .rust", {
+    "scrollTop": |initialScrollTop|,
+})
 focus: ".scraped-example-list > .scraped-example .next"
 press-key: "Enter"
-assert-property-false: (".scraped-example-list > .scraped-example pre", {
+assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "scrollTop": |initialScrollTop|
+}, NEAR)
+assert-property-false: (".scraped-example-list > .scraped-example .rust", {
     "scrollTop": |initialScrollTop|
 }, NEAR)
 focus: ".scraped-example-list > .scraped-example .prev"
 press-key: "Enter"
-assert-property: (".scraped-example-list > .scraped-example pre", {
+assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "scrollTop": |initialScrollTop|
+}, NEAR)
+assert-property: (".scraped-example-list > .scraped-example .rust", {
     "scrollTop": |initialScrollTop|
 }, NEAR)
 
 // The expand button increases the scrollHeight of the minimized code viewport
 store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": smallOffsetHeight})
-assert-property-false: (".scraped-example-list > .scraped-example pre", {
+assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "scrollHeight": |smallOffsetHeight|
+}, NEAR)
+assert-property: (".scraped-example-list > .scraped-example .rust", {
     "scrollHeight": |smallOffsetHeight|
 }, NEAR)
 focus: ".scraped-example-list > .scraped-example .expand"
 press-key: "Enter"
-assert-property-false: (".scraped-example-list > .scraped-example pre", {
+assert-property-false: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "offsetHeight": |smallOffsetHeight|
+}, NEAR)
+assert-property-false: (".scraped-example-list > .scraped-example .rust", {
     "offsetHeight": |smallOffsetHeight|
 }, NEAR)
-store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": fullOffsetHeight})
-assert-property: (".scraped-example-list > .scraped-example pre", {
+store-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
+    "offsetHeight": fullOffsetHeight,
+})
+assert-property: (".scraped-example-list > .scraped-example .rust", {
+    "offsetHeight": |fullOffsetHeight|,
+    "scrollHeight": |fullOffsetHeight|,
+})
+assert-property: (".scraped-example-list > .scraped-example .src-line-numbers", {
     "scrollHeight": |fullOffsetHeight|
 }, NEAR)
diff --git a/tests/rustdoc-gui/scrape-examples-color.goml b/tests/rustdoc-gui/scrape-examples-color.goml
index 588ba08a60c..b0faca190a5 100644
--- a/tests/rustdoc-gui/scrape-examples-color.goml
+++ b/tests/rustdoc-gui/scrape-examples-color.goml
@@ -10,10 +10,10 @@ define-function: (
     block {
         call-function: ("switch-theme", {"theme": |theme|})
         wait-for: ".more-examples-toggle"
-        assert-css: (".scraped-example .example-wrap .rust span.highlight:not(.focus)", {
+        assert-css: (".scraped-example .rust span.highlight:not(.focus)", {
             "background-color": |highlight|,
         }, ALL)
-        assert-css: (".scraped-example .example-wrap .rust span.highlight.focus", {
+        assert-css: (".scraped-example .rust span.highlight.focus", {
             "background-color": |highlight_focus|,
         }, ALL)
 
@@ -67,11 +67,11 @@ define-function: (
     [theme, background_color_start, background_color_end],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
-        assert-css: (".scraped-example:not(.expanded) .code-wrapper::before", {
+        assert-css: (".scraped-example:not(.expanded) .example-wrap::before", {
             "background-image": "linear-gradient(" + |background_color_start| + ", " +
                 |background_color_end| + ")",
         })
-        assert-css: (".scraped-example:not(.expanded) .code-wrapper::after", {
+        assert-css: (".scraped-example:not(.expanded) .example-wrap::after", {
             "background-image": "linear-gradient(to top, " + |background_color_start| + ", " +
                 |background_color_end| + ")",
         })
diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml
index 4fc1c1ac065..6bea352bce4 100644
--- a/tests/rustdoc-gui/scrape-examples-layout.goml
+++ b/tests/rustdoc-gui/scrape-examples-layout.goml
@@ -1,48 +1,115 @@
 // Check that the line number column has the correct layout.
 go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
 
+set-window-size: (1000, 1000)
+
 // Check that it's not zero.
 assert-property-false: (
-    ".more-scraped-examples .scraped-example .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example .src-line-numbers",
     {"clientWidth": "0"}
 )
 
 // Check that examples with very long lines have the same width as ones that don't.
 store-property: (
-    ".more-scraped-examples .scraped-example:nth-child(2) .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example:nth-child(2) .src-line-numbers",
     {"clientWidth": clientWidth},
 )
 
 assert-property: (
-    ".more-scraped-examples .scraped-example:nth-child(3) .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example:nth-child(3) .src-line-numbers",
     {"clientWidth": |clientWidth|}
 )
 
 assert-property: (
-    ".more-scraped-examples .scraped-example:nth-child(4) .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example:nth-child(4) .src-line-numbers",
     {"clientWidth": |clientWidth|}
 )
 
 assert-property: (
-    ".more-scraped-examples .scraped-example:nth-child(5) .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example:nth-child(5) .src-line-numbers",
     {"clientWidth": |clientWidth|}
 )
 
 assert-property: (
-    ".more-scraped-examples .scraped-example:nth-child(6) .code-wrapper .src-line-numbers",
+    ".more-scraped-examples .scraped-example:nth-child(6) .src-line-numbers",
     {"clientWidth": |clientWidth|}
 )
 
+// The "title" should be located at the right bottom corner of the code example.
+store-position: (".scraped-example .example-wrap", {"x": x, "y": y})
+store-size: (".scraped-example .example-wrap", {"width": width, "height": height})
+store-size: (".scraped-example .scraped-example-title", {
+    "width": title_width,
+    "height": title_height,
+})
+assert-position: (".scraped-example .scraped-example-title", {
+    "x": |x| + |width| - |title_width| - 5,
+    "y": |y| + |height| - |title_height| - 8,
+})
+
+// Check that the expand button works and also that line number aligns with code.
+move-cursor-to: ".scraped-example .rust"
+click: ".scraped-example .button-holder .expand"
+wait-for: ".scraped-example.expanded"
+// They should have the same y position.
+compare-elements-position: (
+    ".scraped-example.expanded .src-line-numbers pre span",
+    ".scraped-example.expanded .rust code",
+    ["y"],
+)
+// And they should have the same height.
+compare-elements-size: (
+    ".scraped-example.expanded .src-line-numbers",
+    ".scraped-example.expanded .rust",
+    ["height"],
+)
+// Collapse code again.
+click: ".scraped-example .button-holder .expand"
+
 // Check that for both mobile and desktop sizes, the buttons in scraped examples are displayed
 // correctly.
 
 store-value: (offset_y, 4)
 
 // First with desktop
-assert-position: (".scraped-example .code-wrapper", {"y": 226})
-assert-position: (".scraped-example .code-wrapper .prev", {"y": 226 + |offset_y|})
+assert-position: (".scraped-example", {"y": 226})
+assert-position: (".scraped-example .prev", {"y": 226 + |offset_y|})
+
+// Gradient background should be at the top of the code block.
+assert-css: (".scraped-example .example-wrap::before", {"top": "0px"})
+assert-css: (".scraped-example .example-wrap::after", {"bottom": "0px"})
 
 // Then with mobile
 set-window-size: (600, 600)
-assert-position: (".scraped-example .code-wrapper", {"y": 308})
-assert-position: (".scraped-example .code-wrapper .prev", {"y": 308 + |offset_y|})
+store-size: (".scraped-example .scraped-example-title", {"height": title_height})
+assert-position: (".scraped-example", {"y": 284})
+assert-position: (".scraped-example .prev", {"y": 284 + |offset_y| + |title_height|})
+
+define-function: (
+    "check_title_and_code_position",
+    [],
+    block {
+        // Title should be above the code.
+        store-position: (".scraped-example .example-wrap .src-line-numbers", {"x": x, "y": y})
+        store-size: (".scraped-example .scraped-example-title", { "height": title_height })
+
+        assert-position: (".scraped-example .scraped-example-title", {
+            "x": |x|, // same X position.
+            "y": |y| - |title_height|,
+        })
+
+        // Line numbers should be right beside the code.
+        compare-elements-position: (
+            ".scraped-example .example-wrap .src-line-numbers",
+            ".scraped-example .example-wrap .rust",
+            ["y"],
+        )
+    }
+)
+
+// Check that the title is now above the code.
+call-function: ("check_title_and_code_position", {})
+
+// Then with small mobile
+set-window-size: (300, 300)
+call-function: ("check_title_and_code_position", {})
diff --git a/tests/rustdoc-gui/sidebar-modnav-position.goml b/tests/rustdoc-gui/sidebar-modnav-position.goml
new file mode 100644
index 00000000000..eb86d118ab2
--- /dev/null
+++ b/tests/rustdoc-gui/sidebar-modnav-position.goml
@@ -0,0 +1,44 @@
+// Verifies that, when TOC is hidden, modnav is always in exactly the same spot
+// This is driven by a reasonably common use case:
+//
+// - There are three or more items that might meet my needs.
+// - I open the first one, decide it's not what I want, switch to the second one using the sidebar.
+// - The second one also doesn't meet my needs, so I switch to the third.
+// - The third also doesn't meet my needs, so...
+//
+// because the sibling module nav is in exactly the same place every time,
+// it's very easy to find and switch between pages that way.
+
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+show-text: true
+set-local-storage: {"rustdoc-hide-toc": "true"}
+
+define-function: (
+    "check-positions",
+    [url],
+    block {
+        go-to: "file://" + |DOC_PATH| + |url|
+        // Checking results colors.
+        assert-position: ("#rustdoc-modnav > h2", {"x": |h2_x|, "y": |h2_y|})
+        assert-position: (
+            "#rustdoc-modnav > ul:first-of-type > li:first-of-type",
+            {"x": |x|, "y": |y|}
+        )
+    },
+)
+
+// First, at test_docs root
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y})
+store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y})
+call-function: ("check-positions", {"url": "/test_docs/enum.WhoLetTheDogOut.html"})
+call-function: ("check-positions", {"url": "/test_docs/struct.StructWithPublicUndocumentedFields.html"})
+call-function: ("check-positions", {"url": "/test_docs/codeblock_sub/index.html"})
+
+// Now in a submodule
+go-to: "file://" + |DOC_PATH| + "/test_docs/fields/struct.Struct.html"
+store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y})
+store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y})
+call-function: ("check-positions", {"url": "/test_docs/fields/struct.Struct.html"})
+call-function: ("check-positions", {"url": "/test_docs/fields/union.Union.html"})
+call-function: ("check-positions", {"url": "/test_docs/fields/enum.Enum.html"})
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index e499c159c6c..7794cdbe9e2 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -118,7 +118,7 @@ assert-false: ".sidebar-elems > .crate"
 go-to: "./module/index.html"
 assert-property: (".sidebar", {"clientWidth": "200"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
-assert-text: (".sidebar > .location", "Module module")
+assert-text: (".sidebar .location", "Module module")
 assert-count: (".sidebar .location", 1)
 assert-text: (".sidebar-elems ul.block > li.current > a", "module")
 // Module page requires three headings:
@@ -126,8 +126,8 @@ assert-text: (".sidebar-elems ul.block > li.current > a", "module")
 //   - Module name, followed by TOC for module headings
 //   - "In crate [name]" parent pointer, followed by sibling navigation
 assert-count: (".sidebar h2", 3)
-assert-text: (".sidebar > .sidebar-elems > h2", "In crate lib2")
-assert-property: (".sidebar > .sidebar-elems > h2 > a", {
+assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In crate lib2")
+assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", {
     "href": "/lib2/index.html",
 }, ENDS_WITH)
 // We check that we don't have the crate list.
@@ -136,9 +136,9 @@ assert-false: ".sidebar-elems > .crate"
 go-to: "./sub_module/sub_sub_module/index.html"
 assert-property: (".sidebar", {"clientWidth": "200"})
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
-assert-text: (".sidebar > .location", "Module sub_sub_module")
-assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module")
-assert-property: (".sidebar > .sidebar-elems > h2 > a", {
+assert-text: (".sidebar .location", "Module sub_sub_module")
+assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In lib2::module::sub_module")
+assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", {
     "href": "/module/sub_module/index.html",
 }, ENDS_WITH)
 assert-text: (".sidebar-elems ul.block > li.current > a", "sub_sub_module")
@@ -198,3 +198,36 @@ assert-position-false: (".sidebar-crate > h2 > a", {"x": -3})
 // when line-wrapped, see that it becomes flush-left again
 drag-and-drop: ((205, 100), (108, 100))
 assert-position: (".sidebar-crate > h2 > a", {"x": -3})
+
+// Configuration option to show TOC in sidebar.
+set-local-storage: {"rustdoc-hide-toc": "true"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+assert-css: ("#rustdoc-toc", {"display": "none"})
+assert-css: (".sidebar .in-crate", {"display": "none"})
+set-local-storage: {"rustdoc-hide-toc": "false"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+assert-css: ("#rustdoc-toc", {"display": "block"})
+assert-css: (".sidebar .in-crate", {"display": "block"})
+
+set-local-storage: {"rustdoc-hide-modnav": "true"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+assert-css: ("#rustdoc-modnav", {"display": "none"})
+set-local-storage: {"rustdoc-hide-modnav": "false"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+assert-css: ("#rustdoc-modnav", {"display": "block"})
+
+set-local-storage: {"rustdoc-hide-toc": "true"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-css: ("#rustdoc-toc", {"display": "none"})
+assert-false: ".sidebar .in-crate"
+set-local-storage: {"rustdoc-hide-toc": "false"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-css: ("#rustdoc-toc", {"display": "block"})
+assert-false: ".sidebar .in-crate"
+
+set-local-storage: {"rustdoc-hide-modnav": "true"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-css: ("#rustdoc-modnav", {"display": "none"})
+set-local-storage: {"rustdoc-hide-modnav": "false"}
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+assert-css: ("#rustdoc-modnav", {"display": "block"})
diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs
index 2467c7adae1..8db754f91ce 100644
--- a/tests/rustdoc-gui/src/lib2/lib.rs
+++ b/tests/rustdoc-gui/src/lib2/lib.rs
@@ -356,3 +356,13 @@ pub mod scroll_traits {
         fn this_is_a_method_with_a_long_name_returning_something() -> String;
     }
 }
+
+pub struct Derefer(String);
+
+impl std::ops::Deref for Derefer {
+    type Target = str;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
diff --git a/tests/rustdoc-gui/src/theme_css/custom-theme.css b/tests/rustdoc-gui/src/theme_css/custom-theme.css
index a56c31ab9d2..366f09f22b2 100644
--- a/tests/rustdoc-gui/src/theme_css/custom-theme.css
+++ b/tests/rustdoc-gui/src/theme_css/custom-theme.css
@@ -23,6 +23,8 @@
 	--copy-path-button-color: #999;
 	--copy-path-img-filter: invert(50%);
 	--copy-path-img-hover-filter: invert(35%);
+        --code-example-button-color: #7f7f7f;
+	--code-example-button-hover-color: #a5a5a5;
 	--codeblock-error-hover-color: rgb(255, 0, 0);
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
diff --git a/tests/rustdoc/impl-associated-items-order.rs b/tests/rustdoc/impl-associated-items-order.rs
new file mode 100644
index 00000000000..759e0f0b400
--- /dev/null
+++ b/tests/rustdoc/impl-associated-items-order.rs
@@ -0,0 +1,42 @@
+// This test ensures that impl associated items always follow this order:
+//
+// 1. Consts
+// 2. Types
+// 3. Functions
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Bar.html'
+pub struct Bar;
+
+impl Bar {
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[3]/h4' \
+    // 'pub fn foo()'
+    pub fn foo() {}
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[1]/h4' \
+    // 'pub const X: u8 = 12u8'
+    pub const X: u8 = 12;
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[2]/h4' \
+    // 'pub type Y = u8'
+    pub type Y = u8;
+}
+
+pub trait Foo {
+    const W: u32;
+    fn yeay();
+    type Z;
+}
+
+impl Foo for Bar {
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[2]/h4' \
+    // 'type Z = u8'
+    type Z = u8;
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[1]/h4' \
+    // 'const W: u32 = 12u32'
+    const W: u32 = 12;
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[3]/h4' \
+    // 'fn yeay()'
+    fn yeay() {}
+}
diff --git a/tests/rustdoc/impl-associated-items-sidebar.rs b/tests/rustdoc/impl-associated-items-sidebar.rs
new file mode 100644
index 00000000000..d393a577e50
--- /dev/null
+++ b/tests/rustdoc/impl-associated-items-sidebar.rs
@@ -0,0 +1,42 @@
+// This test ensures that impl/trait associated items are listed in the sidebar.
+
+// ignore-tidy-linelength
+
+#![feature(inherent_associated_types)]
+#![feature(associated_type_defaults)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Bar.html'
+pub struct Bar;
+
+impl Bar {
+    //@ has - '//*[@class="sidebar-elems"]//h3[1]' 'Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block associatedconstant"]/li/a[@href="#associatedconstant.X"]' 'X'
+    pub const X: u8 = 12;
+    //@ has - '//*[@class="sidebar-elems"]//h3[2]' 'Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block associatedtype"]/li/a[@href="#associatedtype.Y"]' 'Y'
+    pub type Y = u8;
+}
+
+//@ has 'foo/trait.Foo.html'
+pub trait Foo {
+    //@ has - '//*[@class="sidebar-elems"]//h3[5]' 'Required Methods'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][5]/li/a[@href="#tymethod.yeay"]' 'yeay'
+    fn yeay();
+    //@ has - '//*[@class="sidebar-elems"]//h3[6]' 'Provided Methods'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][6]/li/a[@href="#method.boo"]' 'boo'
+    fn boo() {}
+    //@ has - '//*[@class="sidebar-elems"]//h3[1]' 'Required Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][1]/li/a[@href="#associatedconstant.W"]' 'W'
+    const W: u32;
+    //@ has - '//*[@class="sidebar-elems"]//h3[2]' 'Provided Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][2]/li/a[@href="#associatedconstant.U"]' 'U'
+    const U: u32 = 0;
+    //@ has - '//*[@class="sidebar-elems"]//h3[3]' 'Required Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][3]/li/a[@href="#associatedtype.Z"]' 'Z'
+    type Z;
+    //@ has - '//*[@class="sidebar-elems"]//h3[4]' 'Provided Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][4]/li/a[@href="#associatedtype.T"]' 'T'
+    type T = u32;
+}
diff --git a/tests/rustdoc/sidebar/module.rs b/tests/rustdoc/sidebar/module.rs
new file mode 100644
index 00000000000..b5bcb9f232c
--- /dev/null
+++ b/tests/rustdoc/sidebar/module.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+//@ has 'foo/index.html'
+//@ has - '//section[@id="rustdoc-toc"]/h3' 'Crate Items'
+
+//@ has 'foo/bar/index.html'
+//@ has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
+pub mod bar {
+    //@ has 'foo/bar/struct.Baz.html'
+    //@ !has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
+    pub struct Baz;
+}
+
+//@ has 'foo/baz/index.html'
+//@ !has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
+pub mod baz {}
diff --git a/tests/rustdoc/sidebar-all-page.rs b/tests/rustdoc/sidebar/sidebar-all-page.rs
index 1f97a414048..1f97a414048 100644
--- a/tests/rustdoc/sidebar-all-page.rs
+++ b/tests/rustdoc/sidebar/sidebar-all-page.rs
diff --git a/tests/rustdoc/sidebar-items.rs b/tests/rustdoc/sidebar/sidebar-items.rs
index f3812143a7d..f3812143a7d 100644
--- a/tests/rustdoc/sidebar-items.rs
+++ b/tests/rustdoc/sidebar/sidebar-items.rs
diff --git a/tests/rustdoc/sidebar-link-generation.rs b/tests/rustdoc/sidebar/sidebar-link-generation.rs
index ee868ec75d3..ee868ec75d3 100644
--- a/tests/rustdoc/sidebar-link-generation.rs
+++ b/tests/rustdoc/sidebar/sidebar-link-generation.rs
diff --git a/tests/rustdoc/sidebar-links-to-foreign-impl.rs b/tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs
index 7c039eeb39f..7c039eeb39f 100644
--- a/tests/rustdoc/sidebar-links-to-foreign-impl.rs
+++ b/tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs
diff --git a/tests/rustdoc/sidebar/top-toc-html.rs b/tests/rustdoc/sidebar/top-toc-html.rs
new file mode 100644
index 00000000000..0f603960434
--- /dev/null
+++ b/tests/rustdoc/sidebar/top-toc-html.rs
@@ -0,0 +1,23 @@
+// ignore-tidy-linelength
+
+#![crate_name = "foo"]
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+//! # Basic [link](https://example.com), *emphasis*, **_very emphasis_** and `code`
+//!
+//! This test case covers TOC entries with rich text inside.
+//! Rustdoc normally supports headers with links, but for the
+//! TOC, that would break the layout.
+//!
+//! For consistency, emphasis is also filtered out.
+
+//@ has foo/index.html
+// User header
+//@ has - '//section[@id="rustdoc-toc"]/h3' 'Sections'
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/@title' 'Basic link, emphasis, very emphasis and `code`'
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]' 'Basic link, emphasis, very emphasis and code'
+//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/em' 0
+//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/a' 0
+//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/code' 1
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/code' 'code'
diff --git a/tests/rustdoc/sidebar/top-toc-idmap.rs b/tests/rustdoc/sidebar/top-toc-idmap.rs
new file mode 100644
index 00000000000..af07cb4179b
--- /dev/null
+++ b/tests/rustdoc/sidebar/top-toc-idmap.rs
@@ -0,0 +1,44 @@
+#![crate_name = "foo"]
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+//! # Structs
+//!
+//! This header has the same name as a built-in header,
+//! and we need to make sure they're disambiguated with
+//! suffixes.
+//!
+//! Module-like headers get derived from the internal ID map,
+//! so the *internal* one gets a suffix here. To make sure it
+//! works right, the one in the `top-toc` needs to match the one
+//! in the `top-doc`, and the one that's not in the `top-doc`
+//! needs to match the one that isn't in the `top-toc`.
+
+//@ has foo/index.html
+// User header
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#structs"]' 'Structs'
+//@ has - '//details[@class="toggle top-doc"]/div[@class="docblock"]/h2[@id="structs"]' 'Structs'
+// Built-in header
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block"]/li/a[@href="#structs-1"]' 'Structs'
+//@ has - '//section[@id="main-content"]/h2[@id="structs-1"]' 'Structs'
+
+/// # Fields
+/// ## Fields
+/// ### Fields
+///
+/// The difference between struct-like headers and module-like headers
+/// is strange, but not actually a problem as long as we're consistent.
+
+//@ has foo/struct.MyStruct.html
+// User header
+//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#fields-1"]' 'Fields'
+//@ has - '//details[@class="toggle top-doc"]/div[@class="docblock"]/h2[@id="fields-1"]' 'Fields'
+// Only one level of nesting
+//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]//a' 2
+// Built-in header
+//@ has - '//section[@id="rustdoc-toc"]/h3/a[@href="#fields"]' 'Fields'
+//@ has - '//section[@id="main-content"]/h2[@id="fields"]' 'Fields'
+
+pub struct MyStruct {
+    pub fields: i32,
+}
diff --git a/tests/rustdoc/sidebar/top-toc-nil.rs b/tests/rustdoc/sidebar/top-toc-nil.rs
new file mode 100644
index 00000000000..d72d41abf88
--- /dev/null
+++ b/tests/rustdoc/sidebar/top-toc-nil.rs
@@ -0,0 +1,7 @@
+#![crate_name = "foo"]
+
+//! This test case covers missing top TOC entries.
+
+//@ has foo/index.html
+// User header
+//@ !has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]' 'Basic link and emphasis'
diff --git a/tests/rustdoc/strip-enum-variant.no-not-shown.html b/tests/rustdoc/strip-enum-variant.no-not-shown.html
index e072335297d..d7a36cc631a 100644
--- a/tests/rustdoc/strip-enum-variant.no-not-shown.html
+++ b/tests/rustdoc/strip-enum-variant.no-not-shown.html
@@ -1 +1 @@
-<ul class="block variant"><li><a href="#variant.Shown">Shown</a></li></ul>
\ No newline at end of file
+<ul class="block variant"><li><a href="#variant.Shown" title="Shown">Shown</a></li></ul>
\ No newline at end of file
diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs
new file mode 100644
index 00000000000..08d86606a6b
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs
@@ -0,0 +1,18 @@
+//@ compile-flags: -Z unstable-options
+
+// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run.
+//@ ignore-stage1
+
+#![feature(rustc_private)]
+#![deny(rustc::usage_of_type_ir_inherent)]
+
+extern crate rustc_type_ir;
+
+use rustc_type_ir::inherent::*;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+use rustc_type_ir::inherent;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+use rustc_type_ir::inherent::Predicate;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr
new file mode 100644
index 00000000000..cc6cb9170c0
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr
@@ -0,0 +1,31 @@
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:11:20
+   |
+LL | use rustc_type_ir::inherent::*;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+note: the lint level is defined here
+  --> $DIR/import-of-type-ir-inherent.rs:7:9
+   |
+LL | #![deny(rustc::usage_of_type_ir_inherent)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:13:20
+   |
+LL | use rustc_type_ir::inherent;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:15:20
+   |
+LL | use rustc_type_ir::inherent::Predicate;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/async-await/async-closures/mac-body.rs b/tests/ui/async-await/async-closures/mac-body.rs
new file mode 100644
index 00000000000..a416227c390
--- /dev/null
+++ b/tests/ui/async-await/async-closures/mac-body.rs
@@ -0,0 +1,12 @@
+//@ edition: 2021
+//@ check-pass
+
+#![feature(async_closure)]
+
+// Make sure we don't ICE if an async closure has a macro body.
+// This happened because we were calling walk instead of visit
+// in the def collector, oops!
+
+fn main() {
+    let _ = async || println!();
+}
diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs
index 96345de01c9..be2b89aab08 100644
--- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs
@@ -2,7 +2,7 @@
 //
 // issue: <https://github.com/rust-lang/rust/issues/120217>
 
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 trait Static<'a> {
     fn proof(self: *const Self, s: &'a str) -> &'static str;
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 0530e1c34c9..144a67025b3 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_os = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 30 warnings emitted
diff --git a/tests/ui/coercion/constrain-expectation-in-arg.rs b/tests/ui/coercion/constrain-expectation-in-arg.rs
new file mode 100644
index 00000000000..c515dedc4bb
--- /dev/null
+++ b/tests/ui/coercion/constrain-expectation-in-arg.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+// Regression test for for #129286.
+// Makes sure that we don't have unconstrained type variables that come from
+// bivariant type parameters due to the way that we construct expectation types
+// when checking call expressions in HIR typeck.
+
+trait Trait {
+    type Item;
+}
+
+struct Struct<A: Trait<Item = B>, B> {
+    pub field: A,
+}
+
+fn identity<T>(x: T) -> T {
+    x
+}
+
+fn test<A: Trait<Item = B>, B>(x: &Struct<A, B>) {
+    let x: &Struct<_, _> = identity(x);
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/normalize-for-errors.next.stderr b/tests/ui/coherence/normalize-for-errors.next.stderr
index 634a10b7a14..44952dc1944 100644
--- a/tests/ui/coherence/normalize-for-errors.next.stderr
+++ b/tests/ui/coherence/normalize-for-errors.next.stderr
@@ -7,7 +7,7 @@ LL |
 LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)`
    |
-   = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
+   = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions
    = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs
index 4188389a3ad..c17bb766b5b 100644
--- a/tests/ui/coherence/normalize-for-errors.rs
+++ b/tests/ui/coherence/normalize-for-errors.rs
@@ -18,6 +18,6 @@ impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
 //~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
 //~| NOTE conflicting implementation for `(Box<(MyType,)>,
 //~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
-//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
+//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions
 
 fn main() {}
diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
index b39689afd1c..52ee6c81ab7 100644
--- a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
+++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr
@@ -4,7 +4,15 @@ error[E0782]: trait objects must include the `dyn` keyword
 LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
    |                 ^^^^^^^^^
    |
-help: add `dyn` keyword before this trait
+help: use a new generic type parameter, constrained by `SomeTrait`
+   |
+LL | fn function<T: SomeTrait>(x: &T, y: Box<SomeTrait>) {
+   |            ++++++++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn function(x: &impl SomeTrait, y: Box<SomeTrait>) {
+   |                 ++++
+help: alternatively, use a trait object to accept any type that implements `SomeTrait`, accessing its methods at runtime using dynamic dispatch
    |
 LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
    |                 +++
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs
new file mode 100644
index 00000000000..79ceb05662b
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs
@@ -0,0 +1,15 @@
+trait Foo {
+    fn foo(self: *const Self); //~ ERROR `*const Self` cannot be used as the type of `self`
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn foo(self: *const Self) {} //~ ERROR `*const Bar` cannot be used as the type of `self`
+}
+
+impl Bar {
+    fn bar(self: *mut Self) {} //~ ERROR `*mut Bar` cannot be used as the type of `self`
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
new file mode 100644
index 00000000000..3bb93cf2ea0
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
@@ -0,0 +1,36 @@
+error[E0658]: `*const Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:8:18
+   |
+LL |     fn foo(self: *const Self) {}
+   |                  ^^^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0658]: `*mut Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:12:18
+   |
+LL |     fn bar(self: *mut Self) {}
+   |                  ^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
+  --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:2:18
+   |
+LL |     fn foo(self: *const Self);
+   |                  ^^^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
index 711025ff93b..856e0595331 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
+++ b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
@@ -1,33 +1,33 @@
-error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:4:18
    |
 LL |     fn foo(self: *const Self) {}
    |                  ^^^^^^^^^^^
    |
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
-   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
    |
 LL |     fn bar(self: *const Self) {}
    |                  ^^^^^^^^^^^
    |
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
-   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
    |
 LL |     fn bar(self: *const Self);
    |                  ^^^^^^^^^^^
    |
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
-   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-but-fine.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-but-fine.rs
new file mode 100644
index 00000000000..e30f785b0ae
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-but-fine.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+
+#![deny(impl_trait_overcaptures)]
+
+struct Ctxt<'tcx>(&'tcx ());
+
+// In `compute`, we don't care that we're "overcapturing" `'tcx`
+// in edition 2024, because it can be shortened at the call site
+// and we know it outlives `'_`.
+
+impl<'tcx> Ctxt<'tcx> {
+    fn compute(&self) -> impl Sized + '_ {}
+}
+
+fn main() {}
diff --git a/tests/ui/inference/auxiliary/inference_unstable_iterator.rs b/tests/ui/inference/auxiliary/inference_unstable_iterator.rs
index 04bc0b1a8ac..8ba6fc89f16 100644
--- a/tests/ui/inference/auxiliary/inference_unstable_iterator.rs
+++ b/tests/ui/inference/auxiliary/inference_unstable_iterator.rs
@@ -1,5 +1,5 @@
 #![feature(staged_api)]
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 #![stable(feature = "ipu_iterator", since = "1.0.0")]
 
diff --git a/tests/ui/inference/auxiliary/inference_unstable_itertools.rs b/tests/ui/inference/auxiliary/inference_unstable_itertools.rs
index fa1efbcfefc..32ca3a45119 100644
--- a/tests/ui/inference/auxiliary/inference_unstable_itertools.rs
+++ b/tests/ui/inference/auxiliary/inference_unstable_itertools.rs
@@ -1,4 +1,4 @@
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 pub trait IpuItertools {
     fn ipu_flatten(&self) -> u32 {
diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
new file mode 100644
index 00000000000..a9795d1569c
--- /dev/null
+++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
@@ -0,0 +1,25 @@
+fn main() {
+    let _ = ['a'; { break 2; 1 }];
+    //~^ ERROR `break` outside of a loop or labeled block
+    //~| HELP consider labeling this block to be able to break within it
+
+    const {
+        {
+            //~^ HELP consider labeling this block to be able to break within it
+            break;
+            //~^ ERROR `break` outside of a loop or labeled block
+        }
+    };
+
+    const {
+        break;
+        //~^ ERROR `break` outside of a loop or labeled block
+    };
+
+    {
+        const {
+            break;
+            //~^ ERROR `break` outside of a loop or labeled block
+        }
+    }
+}
diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr
new file mode 100644
index 00000000000..300cd45ad69
--- /dev/null
+++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr
@@ -0,0 +1,39 @@
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:15:9
+   |
+LL |         break;
+   |         ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:21:13
+   |
+LL |             break;
+   |             ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:2:21
+   |
+LL |     let _ = ['a'; { break 2; 1 }];
+   |                     ^^^^^^^ cannot `break` outside of a loop or labeled block
+   |
+help: consider labeling this block to be able to break within it
+   |
+LL |     let _ = ['a'; 'block: { break 'block 2; 1 }];
+   |                   +++++++         ++++++
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-inline-const-issue-128604.rs:9:13
+   |
+LL |             break;
+   |             ^^^^^ cannot `break` outside of a loop or labeled block
+   |
+help: consider labeling this block to be able to break within it
+   |
+LL ~         'block: {
+LL |
+LL ~             break 'block;
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0268`.
diff --git a/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs
new file mode 100644
index 00000000000..dabaa309c16
--- /dev/null
+++ b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs
@@ -0,0 +1,142 @@
+//@ edition:2021
+
+trait Trait {}
+
+struct IceCream;
+
+impl IceCream {
+    fn foo(_: &Trait) {}
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn bar(self, _: &'a Trait) {}
+    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~| ERROR: use of undeclared lifetime name
+
+    fn alice<'a>(&self, _: &Trait) {}
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn bob<'a>(_: &'a Trait) {}
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn cat() -> &Trait {
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn dog<'a>() -> &Trait {
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn kitten() -> &'a Trait {
+        //~^ ERROR: use of undeclared lifetime name
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn puppy<'a>() -> &'a Trait {
+        //~^ ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn parrot() -> &mut Trait {
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &mut Type
+        //~^ ERROR: cannot return reference to temporary value
+    }
+}
+
+trait Sing {
+    fn foo(_: &Trait);
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn bar(_: &'a Trait);
+    //~^ ERROR: trait objects must include the `dyn` keyword
+    //~| ERROR: use of undeclared lifetime name
+
+    fn alice<'a>(_: &Trait);
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn bob<'a>(_: &'a Trait);
+    //~^ ERROR: trait objects must include the `dyn` keyword
+
+    fn cat() -> &Trait;
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+
+    fn dog<'a>() -> &Trait {
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn kitten() -> &'a Trait {
+        //~^ ERROR: use of undeclared lifetime name
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn puppy<'a>() -> &'a Trait {
+        //~^ ERROR: trait objects must include the `dyn` keyword
+        &Type
+    }
+
+    fn parrot() -> &mut Trait {
+        //~^ ERROR: missing lifetime specifier
+        //~| ERROR: trait objects must include the `dyn` keyword
+        &mut Type
+        //~^ ERROR: cannot return reference to temporary value
+    }
+}
+
+fn foo(_: &Trait) {}
+//~^ ERROR: trait objects must include the `dyn` keyword
+
+fn bar(_: &'a Trait) {}
+//~^ ERROR: trait objects must include the `dyn` keyword
+//~| ERROR: use of undeclared lifetime name
+
+fn alice<'a>(_: &Trait) {}
+//~^ ERROR: trait objects must include the `dyn` keyword
+
+fn bob<'a>(_: &'a Trait) {}
+//~^ ERROR: trait objects must include the `dyn` keyword
+
+struct Type;
+
+impl Trait for Type {}
+
+fn cat() -> &Trait {
+//~^ ERROR: missing lifetime specifier
+//~| ERROR: trait objects must include the `dyn` keyword
+    &Type
+}
+
+fn dog<'a>() -> &Trait {
+//~^ ERROR: missing lifetime specifier
+//~| ERROR: trait objects must include the `dyn` keyword
+    &Type
+}
+
+fn kitten() -> &'a Trait {
+//~^ ERROR: use of undeclared lifetime name
+//~| ERROR: trait objects must include the `dyn` keyword
+    &Type
+}
+
+fn puppy<'a>() -> &'a Trait {
+//~^ ERROR: trait objects must include the `dyn` keyword
+    &Type
+}
+
+fn parrot() -> &mut Trait {
+    //~^ ERROR: missing lifetime specifier
+    //~| ERROR: trait objects must include the `dyn` keyword
+    &mut Type
+    //~^ ERROR: cannot return reference to temporary value
+}
+
+fn main() {}
diff --git a/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
new file mode 100644
index 00000000000..8bdfea7766e
--- /dev/null
+++ b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr
@@ -0,0 +1,673 @@
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:22
+   |
+LL |     fn bar(self, _: &'a Trait) {}
+   |                      ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn bar<'a>(self, _: &'a Trait) {}
+   |           ++++
+help: consider introducing lifetime `'a` here
+   |
+LL | impl<'a> IceCream {
+   |     ++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:17
+   |
+LL |     fn cat() -> &Trait {
+   |                 ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL |     fn cat() -> &'static Trait {
+   |                  +++++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:21
+   |
+LL |     fn dog<'a>() -> &Trait {
+   |                     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'a` lifetime
+   |
+LL |     fn dog<'a>() -> &'a Trait {
+   |                      ++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:21
+   |
+LL |     fn kitten() -> &'a Trait {
+   |                     ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn kitten<'a>() -> &'a Trait {
+   |              ++++
+help: consider introducing lifetime `'a` here
+   |
+LL | impl<'a> IceCream {
+   |     ++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:20
+   |
+LL |     fn parrot() -> &mut Trait {
+   |                    ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL |     fn parrot() -> &'static mut Trait {
+   |                     +++++++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:16
+   |
+LL |     fn bar(_: &'a Trait);
+   |                ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn bar<'a>(_: &'a Trait);
+   |           ++++
+help: consider introducing lifetime `'a` here
+   |
+LL | trait Sing<'a> {
+   |           ++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:17
+   |
+LL |     fn cat() -> &Trait;
+   |                 ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL |     fn cat() -> &'static Trait;
+   |                  +++++++
+help: instead, you are more likely to want to return an owned value
+   |
+LL -     fn cat() -> &Trait;
+LL +     fn cat() -> Trait;
+   |
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:21
+   |
+LL |     fn dog<'a>() -> &Trait {
+   |                     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'a` lifetime
+   |
+LL |     fn dog<'a>() -> &'a Trait {
+   |                      ++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:21
+   |
+LL |     fn kitten() -> &'a Trait {
+   |                     ^^ undeclared lifetime
+   |
+help: consider introducing lifetime `'a` here
+   |
+LL |     fn kitten<'a>() -> &'a Trait {
+   |              ++++
+help: consider introducing lifetime `'a` here
+   |
+LL | trait Sing<'a> {
+   |           ++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:20
+   |
+LL |     fn parrot() -> &mut Trait {
+   |                    ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL |     fn parrot() -> &'static mut Trait {
+   |                     +++++++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:12
+   |
+LL | fn bar(_: &'a Trait) {}
+   |       -    ^^ undeclared lifetime
+   |       |
+   |       help: consider introducing lifetime `'a` here: `<'a>`
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:13
+   |
+LL | fn cat() -> &Trait {
+   |             ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL | fn cat() -> &'static Trait {
+   |              +++++++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:17
+   |
+LL | fn dog<'a>() -> &Trait {
+   |                 ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'a` lifetime
+   |
+LL | fn dog<'a>() -> &'a Trait {
+   |                  ++
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:17
+   |
+LL | fn kitten() -> &'a Trait {
+   |          -      ^^ undeclared lifetime
+   |          |
+   |          help: consider introducing lifetime `'a` here: `<'a>`
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:16
+   |
+LL | fn parrot() -> &mut Trait {
+   |                ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`
+   |
+LL | fn parrot() -> &'static mut Trait {
+   |                 +++++++
+
+error[E0515]: cannot return reference to temporary value
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:47:9
+   |
+LL |         &mut Type
+   |         ^^^^^----
+   |         |    |
+   |         |    temporary value created here
+   |         returns a reference to data owned by the current function
+
+error[E0515]: cannot return reference to temporary value
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:90:9
+   |
+LL |         &mut Type
+   |         ^^^^^----
+   |         |    |
+   |         |    temporary value created here
+   |         returns a reference to data owned by the current function
+
+error[E0515]: cannot return reference to temporary value
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:138:5
+   |
+LL |     &mut Type
+   |     ^^^^^----
+   |     |    |
+   |     |    temporary value created here
+   |     returns a reference to data owned by the current function
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:53:16
+   |
+LL |     fn foo(_: &Trait);
+   |                ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn foo<T: Trait>(_: &T);
+   |           ++++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn foo(_: &impl Trait);
+   |                ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn foo(_: &dyn Trait);
+   |                +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:19
+   |
+LL |     fn bar(_: &'a Trait);
+   |                   ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn bar<T: Trait>(_: &'a T);
+   |           ++++++++++        ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn bar(_: &'a impl Trait);
+   |                   ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn bar(_: &'a dyn Trait);
+   |                   +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:60:22
+   |
+LL |     fn alice<'a>(_: &Trait);
+   |                      ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn alice<'a, T: Trait>(_: &T);
+   |                ++++++++++      ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn alice<'a>(_: &impl Trait);
+   |                      ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn alice<'a>(_: &dyn Trait);
+   |                      +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:63:23
+   |
+LL |     fn bob<'a>(_: &'a Trait);
+   |                       ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn bob<'a, T: Trait>(_: &'a T);
+   |              ++++++++++         ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn bob<'a>(_: &'a impl Trait);
+   |                       ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn bob<'a>(_: &'a dyn Trait);
+   |                       +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:18
+   |
+LL |     fn cat() -> &Trait;
+   |                  ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn cat() -> &impl Trait;
+   |                  ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn cat() -> Box<dyn Trait>;
+   |                 ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:22
+   |
+LL |     fn dog<'a>() -> &Trait {
+   |                      ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn dog<'a>() -> &impl Trait {
+   |                      ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn dog<'a>() -> Box<dyn Trait> {
+   |                     ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:24
+   |
+LL |     fn kitten() -> &'a Trait {
+   |                        ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn kitten() -> &'a impl Trait {
+   |                        ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn kitten() -> Box<dyn Trait> {
+   |                    ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:82:27
+   |
+LL |     fn puppy<'a>() -> &'a Trait {
+   |                           ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn puppy<'a>() -> &'a impl Trait {
+   |                           ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn puppy<'a>() -> Box<dyn Trait> {
+   |                       ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:25
+   |
+LL |     fn parrot() -> &mut Trait {
+   |                         ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn parrot() -> &mut impl Trait {
+   |                         ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn parrot() -> Box<dyn Trait> {
+   |                    ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:95:12
+   |
+LL | fn foo(_: &Trait) {}
+   |            ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL | fn foo<T: Trait>(_: &T) {}
+   |       ++++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn foo(_: &impl Trait) {}
+   |            ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn foo(_: &dyn Trait) {}
+   |            +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:15
+   |
+LL | fn bar(_: &'a Trait) {}
+   |               ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL | fn bar<T: Trait>(_: &'a T) {}
+   |       ++++++++++        ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn bar(_: &'a impl Trait) {}
+   |               ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn bar(_: &'a dyn Trait) {}
+   |               +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:102:18
+   |
+LL | fn alice<'a>(_: &Trait) {}
+   |                  ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL | fn alice<'a, T: Trait>(_: &T) {}
+   |            ++++++++++      ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn alice<'a>(_: &impl Trait) {}
+   |                  ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn alice<'a>(_: &dyn Trait) {}
+   |                  +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:105:19
+   |
+LL | fn bob<'a>(_: &'a Trait) {}
+   |                   ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL | fn bob<'a, T: Trait>(_: &'a T) {}
+   |          ++++++++++         ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL | fn bob<'a>(_: &'a impl Trait) {}
+   |                   ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL | fn bob<'a>(_: &'a dyn Trait) {}
+   |                   +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:14
+   |
+LL | fn cat() -> &Trait {
+   |              ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn cat() -> &impl Trait {
+   |              ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn cat() -> Box<dyn Trait> {
+   |             ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:18
+   |
+LL | fn dog<'a>() -> &Trait {
+   |                  ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn dog<'a>() -> &impl Trait {
+   |                  ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn dog<'a>() -> Box<dyn Trait> {
+   |                 ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:20
+   |
+LL | fn kitten() -> &'a Trait {
+   |                    ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn kitten() -> &'a impl Trait {
+   |                    ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn kitten() -> Box<dyn Trait> {
+   |                ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:130:23
+   |
+LL | fn puppy<'a>() -> &'a Trait {
+   |                       ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn puppy<'a>() -> &'a impl Trait {
+   |                       ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn puppy<'a>() -> Box<dyn Trait> {
+   |                   ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:21
+   |
+LL | fn parrot() -> &mut Trait {
+   |                     ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL | fn parrot() -> &mut impl Trait {
+   |                     ++++
+help: alternatively, you can return an owned trait object
+   |
+LL | fn parrot() -> Box<dyn Trait> {
+   |                ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:8:16
+   |
+LL |     fn foo(_: &Trait) {}
+   |                ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn foo<T: Trait>(_: &T) {}
+   |           ++++++++++     ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn foo(_: &impl Trait) {}
+   |                ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn foo(_: &dyn Trait) {}
+   |                +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:25
+   |
+LL |     fn bar(self, _: &'a Trait) {}
+   |                         ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn bar<T: Trait>(self, _: &'a T) {}
+   |           ++++++++++              ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn bar(self, _: &'a impl Trait) {}
+   |                         ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn bar(self, _: &'a dyn Trait) {}
+   |                         +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:15:29
+   |
+LL |     fn alice<'a>(&self, _: &Trait) {}
+   |                             ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn alice<'a, T: Trait>(&self, _: &T) {}
+   |                ++++++++++             ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn alice<'a>(&self, _: &impl Trait) {}
+   |                             ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn alice<'a>(&self, _: &dyn Trait) {}
+   |                             +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:18:23
+   |
+LL |     fn bob<'a>(_: &'a Trait) {}
+   |                       ^^^^^
+   |
+help: use a new generic type parameter, constrained by `Trait`
+   |
+LL |     fn bob<'a, T: Trait>(_: &'a T) {}
+   |              ++++++++++         ~
+help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+   |
+LL |     fn bob<'a>(_: &'a impl Trait) {}
+   |                       ++++
+help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch
+   |
+LL |     fn bob<'a>(_: &'a dyn Trait) {}
+   |                       +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:18
+   |
+LL |     fn cat() -> &Trait {
+   |                  ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn cat() -> &impl Trait {
+   |                  ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn cat() -> Box<dyn Trait> {
+   |                 ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:22
+   |
+LL |     fn dog<'a>() -> &Trait {
+   |                      ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn dog<'a>() -> &impl Trait {
+   |                      ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn dog<'a>() -> Box<dyn Trait> {
+   |                     ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:24
+   |
+LL |     fn kitten() -> &'a Trait {
+   |                        ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn kitten() -> &'a impl Trait {
+   |                        ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn kitten() -> Box<dyn Trait> {
+   |                    ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:39:27
+   |
+LL |     fn puppy<'a>() -> &'a Trait {
+   |                           ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn puppy<'a>() -> &'a impl Trait {
+   |                           ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn puppy<'a>() -> Box<dyn Trait> {
+   |                       ~~~~~~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:25
+   |
+LL |     fn parrot() -> &mut Trait {
+   |                         ^^^^^
+   |
+help: use `impl Trait` to return an opaque type, as long as you return a single underlying type
+   |
+LL |     fn parrot() -> &mut impl Trait {
+   |                         ++++
+help: alternatively, you can return an owned trait object
+   |
+LL |     fn parrot() -> Box<dyn Trait> {
+   |                    ~~~~~~~~~~~~~~
+
+error: aborting due to 45 previous errors
+
+Some errors have detailed explanations: E0106, E0261, E0515, E0782.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs
index a2735d4cbfb..e1799761b69 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs
@@ -7,11 +7,17 @@ pub enum UninhabitedEnum {
 
 #[non_exhaustive]
 pub struct UninhabitedStruct {
-    _priv: !,
+    pub never: !,
+    _priv: (),
 }
 
 #[non_exhaustive]
-pub struct UninhabitedTupleStruct(!);
+pub struct PrivatelyUninhabitedStruct {
+    never: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(pub !);
 
 pub enum UninhabitedVariants {
     #[non_exhaustive] Tuple(!),
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
index 66e93291c72..f332e6deeb8 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
@@ -5,7 +5,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedEnum` defined here
-  --> $DIR/auxiliary/uninhabited.rs:26:1
+  --> $DIR/auxiliary/uninhabited.rs:32:1
    |
 LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:28:1
+  --> $DIR/auxiliary/uninhabited.rs:34:1
    |
 LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedTupleStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:30:1
+  --> $DIR/auxiliary/uninhabited.rs:36:1
    |
 LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedVariants` defined here
-  --> $DIR/auxiliary/uninhabited.rs:32:1
+  --> $DIR/auxiliary/uninhabited.rs:38:1
    |
 LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
index 745b196a0e3..48f3857bfa7 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedEnum` defined here
-  --> $DIR/auxiliary/uninhabited.rs:26:1
+  --> $DIR/auxiliary/uninhabited.rs:32:1
    |
 LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:28:1
+  --> $DIR/auxiliary/uninhabited.rs:34:1
    |
 LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedTupleStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:30:1
+  --> $DIR/auxiliary/uninhabited.rs:36:1
    |
 LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL |     match x {}
    |           ^
    |
 note: `IndirectUninhabitedVariants` defined here
-  --> $DIR/auxiliary/uninhabited.rs:32:1
+  --> $DIR/auxiliary/uninhabited.rs:38:1
    |
 LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
index fd77fab8738..6bee019e897 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
@@ -11,11 +11,12 @@ use uninhabited::PartiallyInhabitedVariants;
 
 pub fn foo(x: PartiallyInhabitedVariants) {
     match x {
-        PartiallyInhabitedVariants::Struct { .. } => {},
-        PartiallyInhabitedVariants::Struct { .. } => {},
+        PartiallyInhabitedVariants::Struct { .. } => {}
         //~^ ERROR unreachable pattern
-        _ => {},
+        PartiallyInhabitedVariants::Struct { .. } => {}
+        //~^ ERROR unreachable pattern
+        _ => {}
     }
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
index 956725fc10e..4fa53101a55 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
@@ -1,16 +1,23 @@
 error: unreachable pattern
-  --> $DIR/issue-65157-repeated-match-arm.rs:15:9
+  --> $DIR/issue-65157-repeated-match-arm.rs:14:9
    |
-LL |         PartiallyInhabitedVariants::Struct { .. } => {},
-   |         ----------------------------------------- matches all the relevant values
-LL |         PartiallyInhabitedVariants::Struct { .. } => {},
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
+LL |         PartiallyInhabitedVariants::Struct { .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
    |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 note: the lint level is defined here
   --> $DIR/issue-65157-repeated-match-arm.rs:2:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: unreachable pattern
+  --> $DIR/issue-65157-repeated-match-arm.rs:16:9
+   |
+LL |         PartiallyInhabitedVariants::Struct { .. } => {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `PartiallyInhabitedVariants` is uninhabited
+   |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs
index c330f3aa05c..58d7bbd2c17 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.rs
@@ -3,12 +3,7 @@
 
 extern crate uninhabited;
 
-use uninhabited::{
-    UninhabitedEnum,
-    UninhabitedStruct,
-    UninhabitedTupleStruct,
-    UninhabitedVariants,
-};
+use uninhabited::*;
 
 struct A;
 
@@ -19,16 +14,20 @@ fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
     match x {} //~ ERROR non-exhaustive patterns
 }
 
-fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
-    match x {} //~ ERROR non-exhaustive patterns
+fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
+    match x {}
 }
 
-fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+fn cannot_empty_match_on_privately_empty_struct(x: PrivatelyUninhabitedStruct) -> A {
     match x {} //~ ERROR non-exhaustive patterns
 }
 
-fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
-    match x {} //~ ERROR non-exhaustive patterns
+fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
+    match x {}
+}
+
+fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
+    match x {}
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.stderr
index c125756a646..0232e7106aa 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -1,15 +1,15 @@
-error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
-  --> $DIR/match.rs:19:11
+error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
+  --> $DIR/match.rs:14:11
    |
 LL |     match x {}
    |           ^
    |
-note: `UninhabitedEnum` defined here
+note: `uninhabited::UninhabitedEnum` defined here
   --> $DIR/auxiliary/uninhabited.rs:5:1
    |
 LL | pub enum UninhabitedEnum {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
+   = note: the matched value is of type `uninhabited::UninhabitedEnum`, which is marked as non-exhaustive
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
    |
 LL ~     match x {
@@ -17,18 +17,18 @@ LL +         _ => todo!(),
 LL ~     }
    |
 
-error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
-  --> $DIR/match.rs:23:11
+error[E0004]: non-exhaustive patterns: type `uninhabited::PrivatelyUninhabitedStruct` is non-empty
+  --> $DIR/match.rs:22:11
    |
 LL |     match x {}
    |           ^
    |
-note: `UninhabitedStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:9:1
+note: `uninhabited::PrivatelyUninhabitedStruct` defined here
+  --> $DIR/auxiliary/uninhabited.rs:15:1
    |
-LL | pub struct UninhabitedStruct {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the matched value is of type `UninhabitedStruct`
+LL | pub struct PrivatelyUninhabitedStruct {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: the matched value is of type `uninhabited::PrivatelyUninhabitedStruct`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
    |
 LL ~     match x {
@@ -36,48 +36,6 @@ LL +         _ => todo!(),
 LL ~     }
    |
 
-error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
-  --> $DIR/match.rs:27:11
-   |
-LL |     match x {}
-   |           ^
-   |
-note: `UninhabitedTupleStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:14:1
-   |
-LL | pub struct UninhabitedTupleStruct(!);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the matched value is of type `UninhabitedTupleStruct`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match x {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
-error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
-  --> $DIR/match.rs:31:11
-   |
-LL |     match x {}
-   |           ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
-   |
-note: `UninhabitedVariants` defined here
-  --> $DIR/auxiliary/uninhabited.rs:16:1
-   |
-LL | pub enum UninhabitedVariants {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     #[non_exhaustive] Tuple(!),
-   |                       ----- not covered
-LL |     #[non_exhaustive] Struct { x: ! }
-   |                       ------ not covered
-   = note: the matched value is of type `UninhabitedVariants`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
-   |
-LL ~     match x {
-LL +         UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
-LL ~     }
-   |
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs
index 108cac7099e..c214581549c 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs
@@ -5,32 +5,28 @@
 extern crate uninhabited;
 
 use uninhabited::{
-    UninhabitedEnum,
-    UninhabitedStruct,
-    UninhabitedTupleStruct,
-    UninhabitedVariants,
+    UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct, UninhabitedVariants,
 };
 
 struct A;
 
-// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
-// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can
-// change the branch used in the compiler to determine this.
-
-fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+// This test checks that non-exhaustive enums are never considered uninhabited outside their
+// defining crate, and non-exhaustive structs are considered uninhabited the same way as normal
+// ones.
+fn cannot_empty_match_on_non_exhaustive_empty_enum(x: UninhabitedEnum) -> A {
     match x {} //~ ERROR non-exhaustive patterns
 }
 
-fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
-    match x {} //~ ERROR non-exhaustive patterns
+fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
+    match x {}
 }
 
-fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
-    match x {} //~ ERROR non-exhaustive patterns
+fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
+    match x {}
 }
 
-fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
-    match x {} //~ ERROR non-exhaustive patterns
+fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
+    match x {}
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
index 0c8b14ab69d..d6f0bc724a9 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
-  --> $DIR/match_with_exhaustive_patterns.rs:21:11
+  --> $DIR/match_with_exhaustive_patterns.rs:17:11
    |
 LL |     match x {}
    |           ^
@@ -17,67 +17,6 @@ LL +         _ => todo!(),
 LL ~     }
    |
 
-error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
-  --> $DIR/match_with_exhaustive_patterns.rs:25:11
-   |
-LL |     match x {}
-   |           ^
-   |
-note: `UninhabitedStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:9:1
-   |
-LL | pub struct UninhabitedStruct {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the matched value is of type `UninhabitedStruct`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match x {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
-error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
-  --> $DIR/match_with_exhaustive_patterns.rs:29:11
-   |
-LL |     match x {}
-   |           ^
-   |
-note: `UninhabitedTupleStruct` defined here
-  --> $DIR/auxiliary/uninhabited.rs:14:1
-   |
-LL | pub struct UninhabitedTupleStruct(!);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the matched value is of type `UninhabitedTupleStruct`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match x {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
-error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
-  --> $DIR/match_with_exhaustive_patterns.rs:33:11
-   |
-LL |     match x {}
-   |           ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
-   |
-note: `UninhabitedVariants` defined here
-  --> $DIR/auxiliary/uninhabited.rs:16:1
-   |
-LL | pub enum UninhabitedVariants {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     #[non_exhaustive] Tuple(!),
-   |                       ----- not covered
-LL |     #[non_exhaustive] Struct { x: ! }
-   |                       ------ not covered
-   = note: the matched value is of type `UninhabitedVariants`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
-   |
-LL ~     match x {
-LL +         UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
-LL ~     }
-   |
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs
index 468703c78e0..96620162212 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs
@@ -1,5 +1,4 @@
 //@ check-pass
-
 #![deny(unreachable_patterns)]
 #![feature(never_type)]
 
@@ -9,11 +8,12 @@ pub enum UninhabitedEnum {
 
 #[non_exhaustive]
 pub struct UninhabitedStruct {
-    _priv: !,
+    pub never: !,
+    _priv: (),
 }
 
 #[non_exhaustive]
-pub struct UninhabitedTupleStruct(!);
+pub struct UninhabitedTupleStruct(pub !);
 
 pub enum UninhabitedVariants {
     #[non_exhaustive] Tuple(!),
@@ -22,24 +22,21 @@ pub enum UninhabitedVariants {
 
 struct A;
 
-// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
-// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
-// change the branch used in the compiler to determine this.
-// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
-
-fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+// This checks that `non_exhaustive` annotations do not affect exhaustiveness checking within the
+// defining crate.
+fn empty_match_on_empty_enum(x: UninhabitedEnum) -> A {
     match x {}
 }
 
-fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+fn empty_match_on_empty_struct(x: UninhabitedStruct) -> A {
     match x {}
 }
 
-fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+fn empty_match_on_empty_tuple_struct(x: UninhabitedTupleStruct) -> A {
     match x {}
 }
 
-fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
+fn empty_match_on_enum_with_empty_variants_struct(x: UninhabitedVariants) -> A {
     match x {}
 }
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
index be55ad51578..edc588777eb 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.rs
@@ -1,14 +1,10 @@
 //@ aux-build:uninhabited.rs
-//@ build-pass (FIXME(62277): could be check-pass?)
 #![deny(unreachable_patterns)]
 
 extern crate uninhabited;
 
 use uninhabited::{
-    PartiallyInhabitedVariants,
-    UninhabitedEnum,
-    UninhabitedStruct,
-    UninhabitedTupleStruct,
+    PartiallyInhabitedVariants, UninhabitedEnum, UninhabitedStruct, UninhabitedTupleStruct,
     UninhabitedVariants,
 };
 
@@ -32,27 +28,26 @@ fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
     None
 }
 
-// This test checks that non-exhaustive types that would normally be considered uninhabited within
-// the defining crate are not considered uninhabited from extern crates.
-
+// This test checks that non-exhaustive enums are never considered uninhabited outside their
+// defining crate, and non-exhaustive structs are considered uninhabited the same way as normal
+// ones.
 fn main() {
     match uninhabited_enum() {
-        Some(_x) => (), // This line would normally error.
+        Some(_x) => (), // This would error without `non_exhaustive`
         None => (),
     }
 
     match uninhabited_variant() {
-        Some(_x) => (), // This line would normally error.
+        Some(_x) => (), //~ ERROR unreachable
         None => (),
     }
 
     // This line would normally error.
-    while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {
-    }
+    while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {} //~ ERROR unreachable
 
-    while let Some(_x) = uninhabited_struct() { // This line would normally error.
+    while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable
     }
 
-    while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
+    while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable
     }
 }
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr
new file mode 100644
index 00000000000..deaa2ffd927
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns.stderr
@@ -0,0 +1,39 @@
+error: unreachable pattern
+  --> $DIR/patterns.rs:41:9
+   |
+LL |         Some(_x) => (),
+   |         ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
+   |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
+note: the lint level is defined here
+  --> $DIR/patterns.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/patterns.rs:46:15
+   |
+LL |     while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
+   |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
+
+error: unreachable pattern
+  --> $DIR/patterns.rs:48:15
+   |
+LL |     while let Some(_x) = uninhabited_struct() {
+   |               ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
+   |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
+
+error: unreachable pattern
+  --> $DIR/patterns.rs:51:15
+   |
+LL |     while let Some(_x) = uninhabited_tuple_struct() {
+   |               ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited
+   |
+   = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
index 1194d7b858d..58cced3d23d 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
@@ -6,11 +6,12 @@ pub enum UninhabitedEnum {
 }
 
 #[non_exhaustive]
-pub struct UninhabitedTupleStruct(!);
+pub struct UninhabitedTupleStruct(pub !);
 
 #[non_exhaustive]
 pub struct UninhabitedStruct {
-    _priv: !,
+    pub never: !,
+    _priv: (),
 }
 
 pub enum UninhabitedVariants {
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
index 7e7dc802e7f..38524bf5b95 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
@@ -1,5 +1,5 @@
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:51:9
+  --> $DIR/patterns_same_crate.rs:52:9
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^ matches no values because `UninhabitedEnum` is uninhabited
@@ -12,7 +12,7 @@ LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:56:9
+  --> $DIR/patterns_same_crate.rs:57:9
    |
 LL |         Some(_x) => (),
    |         ^^^^^^^^ matches no values because `UninhabitedVariants` is uninhabited
@@ -20,7 +20,7 @@ LL |         Some(_x) => (),
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:60:15
+  --> $DIR/patterns_same_crate.rs:61:15
    |
 LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited
@@ -28,7 +28,7 @@ LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabite
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:64:15
+  --> $DIR/patterns_same_crate.rs:65:15
    |
 LL |     while let Some(_x) = uninhabited_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited
@@ -36,7 +36,7 @@ LL |     while let Some(_x) = uninhabited_struct() {
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/patterns_same_crate.rs:67:15
+  --> $DIR/patterns_same_crate.rs:68:15
    |
 LL |     while let Some(_x) = uninhabited_tuple_struct() {
    |               ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited
diff --git a/tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs b/tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs
index 1f45d91847f..7f76ed7fd2a 100644
--- a/tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs
+++ b/tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 use std::rc::Rc;
 
diff --git a/tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs b/tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs
index 43f596659b9..6f34c9281b0 100644
--- a/tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs
+++ b/tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
 
 use std::ptr;
 
diff --git a/tests/ui/stats/hir-stats.rs b/tests/ui/stats/hir-stats.rs
index 249413d80e8..7c5da8cf554 100644
--- a/tests/ui/stats/hir-stats.rs
+++ b/tests/ui/stats/hir-stats.rs
@@ -1,12 +1,15 @@
 //@ check-pass
 //@ compile-flags: -Zhir-stats
 //@ only-x86_64
+// layout randomization affects the hir stat output
+//@ needs-deterministic-layouts
 
 // Type layouts sometimes change. When that happens, until the next bootstrap
 // bump occurs, stage1 and stage2 will give different outputs for this test.
 // Add an `ignore-stage1` comment marker to work around that problem during
 // that time.
 
+
 // The aim here is to include at least one of every different type of top-level
 // AST/HIR node reported by `-Zhir-stats`.
 
diff --git a/tests/ui/std/windows-bat-args.rs b/tests/ui/std/windows-bat-args.rs
index a9b6252b78c..cc4a43692ab 100644
--- a/tests/ui/std/windows-bat-args.rs
+++ b/tests/ui/std/windows-bat-args.rs
@@ -32,7 +32,9 @@ fn parent() {
     let bat2 = String::from(bat.to_str().unwrap());
     bat.set_file_name("windows-bat-args3.bat");
     let bat3 = String::from(bat.to_str().unwrap());
-    let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str()];
+    bat.set_file_name("windows-bat-args1.bat .. ");
+    let bat4 = String::from(bat.to_str().unwrap());
+    let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str(), bat4.as_str()];
 
     check_args(&bat, &["a", "b"]).unwrap();
     check_args(&bat, &["c is for cat", "d is for dog"]).unwrap();
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 9c933a9ef1c..5ca9c8678b7 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -1,4 +1,5 @@
 //@ run-pass
+//@ needs-deterministic-layouts
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs
new file mode 100644
index 00000000000..a83141f0e4e
--- /dev/null
+++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs
@@ -0,0 +1,34 @@
+fn main() {
+    let a = ["_"; unsafe { break; 1 + 2 }];
+    //~^ ERROR `break` outside of a loop or labeled block
+
+    unsafe {
+        {
+            //~^ HELP consider labeling this block to be able to break within it
+            break;
+            //~^ ERROR `break` outside of a loop or labeled block
+        }
+    }
+
+    unsafe {
+        break;
+        //~^ ERROR `break` outside of a loop or labeled block
+    }
+
+    {
+        //~^ HELP consider labeling this block to be able to break within it
+        unsafe {
+            break;
+            //~^ ERROR `break` outside of a loop or labeled block
+        }
+    }
+
+    while 2 > 1 {
+        unsafe {
+            if true || false {
+                break;
+            }
+        }
+    }
+
+}
diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
new file mode 100644
index 00000000000..b7cbe1a5cf4
--- /dev/null
+++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
@@ -0,0 +1,42 @@
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
+   |
+LL |     let a = ["_"; unsafe { break; 1 + 2 }];
+   |                            ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-unsafe-block-issue-128604.rs:14:9
+   |
+LL |         break;
+   |         ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-unsafe-block-issue-128604.rs:8:13
+   |
+LL |             break;
+   |             ^^^^^ cannot `break` outside of a loop or labeled block
+   |
+help: consider labeling this block to be able to break within it
+   |
+LL ~         'block: {
+LL |
+LL ~             break 'block;
+   |
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/break-inside-unsafe-block-issue-128604.rs:21:13
+   |
+LL |             break;
+   |             ^^^^^ cannot `break` outside of a loop or labeled block
+   |
+help: consider labeling this block to be able to break within it
+   |
+LL ~     'block: {
+LL |
+LL |         unsafe {
+LL ~             break 'block;
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0268`.
diff --git a/triagebot.toml b/triagebot.toml
index d3333b67d15..1afcad7d131 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -913,7 +913,13 @@ cc = ["@kobzol"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "jhpratt", "oli-obk", "kobzol", "joboet"]
+users_on_vacation = [
+    "jhpratt",
+    "joboet",
+    "jyn514",
+    "oli-obk",
+    "tgross35",
+]
 
 [assign.adhoc_groups]
 compiler-team = [