about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-08-28 05:12:48 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-08-28 05:12:48 +0000
commitf4f3447c5748c4699ef4bfe6c09efab4997aff94 (patch)
treefcd6a49c72ffdeee7275d9b8259ee7441ef69104
parentae3c270480940edfae6f008f5f3fd2f9a68efe7c (diff)
parent0589dc75d314152de3ddf095ff2fc774c4a2d9c1 (diff)
downloadrust-f4f3447c5748c4699ef4bfe6c09efab4997aff94.tar.gz
rust-f4f3447c5748c4699ef4bfe6c09efab4997aff94.zip
Merge from rustc
-rw-r--r--compiler/rustc_abi/src/lib.rs5
-rw-r--r--compiler/rustc_arena/src/lib.rs1
-rw-r--r--compiler/rustc_arena/src/tests.rs22
-rw-r--r--compiler/rustc_ast/src/lib.rs1
-rw-r--r--compiler/rustc_ast_ir/src/lib.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs80
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs37
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs164
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pp/convenience.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pp/ring.rs22
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/fixup.rs14
-rw-r--r--compiler/rustc_attr/src/lib.rs1
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs4
-rw-r--r--compiler/rustc_baked_icu_data/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs4
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs13
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs14
-rw-r--r--compiler/rustc_borrowck/src/lib.rs26
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs4
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs42
-rw-r--r--compiler/rustc_borrowck/src/util/collect_writes.rs2
-rw-r--r--compiler/rustc_borrowck/src/util/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs68
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs44
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs20
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/back/profiling.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs20
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs58
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs31
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs24
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/utils.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs44
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs32
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/value.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs8
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs50
-rw-r--r--compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs2
-rw-r--r--compiler/rustc_driver_impl/src/signal_handler.rs2
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-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.rs5
-rw-r--r--compiler/rustc_errors/src/lock.rs4
-rw-r--r--compiler/rustc_errors/src/markdown/parse.rs2
-rw-r--r--compiler/rustc_errors/src/markdown/term.rs4
-rw-r--r--compiler/rustc_errors/src/snippet.rs32
-rw-r--r--compiler/rustc_errors/src/styled_buffer.rs20
-rw-r--r--compiler/rustc_expand/src/errors.rs14
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs7
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs11
-rw-r--r--compiler/rustc_expand/src/placeholders.rs4
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs4
-rw-r--r--compiler/rustc_feature/src/lib.rs1
-rw-r--r--compiler/rustc_fluent_macro/src/lib.rs1
-rw-r--r--compiler/rustc_graphviz/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/def.rs11
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/errs.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs180
-rw-r--r--compiler/rustc_hir_analysis/src/errors/pattern_types.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors/precise_captures.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/explicit.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/solve.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/terms.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/variance/xform.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/autoderef.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/diverges.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs104
-rw-r--r--compiler/rustc_hir_typeck/src/expectation.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs40
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/rvalue_scopes.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs4
-rw-r--r--compiler/rustc_incremental/src/errors.rs82
-rw-r--r--compiler/rustc_incremental/src/lib.rs1
-rw-r--r--compiler/rustc_incremental/src/persist/data.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/file_format.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs2
-rw-r--r--compiler/rustc_index/src/lib.rs1
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/free_regions.rs6
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs2
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs2
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/undo_log.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs3
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_infer/src/traits/project.rs2
-rw-r--r--compiler/rustc_interface/src/callbacks.rs18
-rw-r--r--compiler/rustc_interface/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/passes.rs14
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lexer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/early.rs2
-rw-r--r--compiler/rustc_lint/src/errors.rs18
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs10
-rw-r--r--compiler/rustc_lint/src/late.rs2
-rw-r--r--compiler/rustc_lint/src/levels.rs2
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs494
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs2
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs4
-rw-r--r--compiler/rustc_lint/src/shadowed_into_iter.rs2
-rw-r--r--compiler/rustc_lint/src/types.rs6
-rw-r--r--compiler/rustc_lint/src/unused.rs4
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp9
-rw-r--r--compiler/rustc_llvm/src/lib.rs6
-rw-r--r--compiler/rustc_macros/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs34
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs17
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs1
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs15
-rw-r--r--compiler/rustc_middle/src/ty/context.rs18
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs16
-rw-r--r--compiler/rustc_middle/src/ty/list.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs264
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs1
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs1
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs42
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs6
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs12
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs19
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs1
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs3
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs140
-rw-r--r--compiler/rustc_session/messages.ftl4
-rw-r--r--compiler/rustc_session/src/errors.rs10
-rw-r--r--compiler/rustc_session/src/filesearch.rs16
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_session/src/session.rs34
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs1
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs19
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs8
-rw-r--r--compiler/rustc_target/src/spec/abi/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs34
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs37
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs33
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs3
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs5
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs3
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs2
-rw-r--r--library/core/src/error.rs3
-rw-r--r--library/core/src/intrinsics/simd.rs2
-rw-r--r--library/core/src/mem/transmutability.rs371
-rw-r--r--library/core/src/num/f128.rs30
-rw-r--r--library/core/src/num/f16.rs30
-rw-r--r--library/core/src/num/f32.rs14
-rw-r--r--library/core/src/num/f64.rs14
-rw-r--r--library/core/src/num/int_macros.rs62
-rw-r--r--library/core/src/num/uint_macros.rs56
-rw-r--r--library/core/src/primitive_docs.rs92
-rw-r--r--library/core/src/ptr/const_ptr.rs54
-rw-r--r--library/core/src/ptr/mod.rs38
-rw-r--r--library/core/src/ptr/mut_ptr.rs111
-rw-r--r--library/core/src/ptr/non_null.rs72
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/num/int_macros.rs759
-rw-r--r--library/core/tests/num/mod.rs2
-rw-r--r--library/core/tests/num/uint_macros.rs543
-rw-r--r--library/std/src/f128.rs15
-rw-r--r--library/std/src/f16.rs15
-rw-r--r--library/std/src/f32.rs15
-rw-r--r--library/std/src/f64.rs15
-rw-r--r--library/std/src/process.rs9
-rw-r--r--library/std/src/sys/alloc/hermit.rs (renamed from library/std/src/sys/pal/hermit/alloc.rs)1
-rw-r--r--library/std/src/sys/alloc/mod.rs (renamed from library/std/src/sys/pal/common/alloc.rs)67
-rw-r--r--library/std/src/sys/alloc/sgx.rs (renamed from library/std/src/sys/pal/sgx/alloc.rs)7
-rw-r--r--library/std/src/sys/alloc/solid.rs (renamed from library/std/src/sys/pal/solid/alloc.rs)2
-rw-r--r--library/std/src/sys/alloc/uefi.rs (renamed from library/std/src/sys/pal/uefi/alloc.rs)2
-rw-r--r--library/std/src/sys/alloc/unix.rs (renamed from library/std/src/sys/pal/unix/alloc.rs)20
-rw-r--r--library/std/src/sys/alloc/wasm.rs (renamed from library/std/src/sys/pal/wasm/alloc.rs)0
-rw-r--r--library/std/src/sys/alloc/windows.rs (renamed from library/std/src/sys/pal/windows/alloc.rs)15
-rw-r--r--library/std/src/sys/alloc/windows/tests.rs (renamed from library/std/src/sys/pal/windows/alloc/tests.rs)0
-rw-r--r--library/std/src/sys/alloc/xous.rs (renamed from library/std/src/sys/pal/xous/alloc.rs)0
-rw-r--r--library/std/src/sys/alloc/zkvm.rs (renamed from library/std/src/sys/pal/zkvm/alloc.rs)2
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/pal/common/mod.rs1
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs1
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs5
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs1
-rw-r--r--library/std/src/sys/pal/solid/mod.rs1
-rw-r--r--library/std/src/sys/pal/teeos/alloc.rs57
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs1
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs4
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/unsupported/alloc.rs23
-rw-r--r--library/std/src/sys/pal/unsupported/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs1
-rw-r--r--library/std/src/sys/pal/windows/mod.rs1
-rw-r--r--library/std/src/sys/pal/xous/mod.rs1
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs9
-rw-r--r--src/bootstrap/src/core/config/config.rs17
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile6
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh (renamed from src/ci/docker/scripts/zstd.sh)0
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile3
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/trusty.md51
-rw-r--r--src/doc/style-guide/src/items.md4
-rw-r--r--src/doc/unstable-book/src/compiler-flags/embed-source.md12
-rw-r--r--src/librustdoc/formats/item_type.rs3
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/tools/compiletest/src/command-list.rs1
-rw-r--r--src/tools/compiletest/src/header.rs101
-rw-r--r--src/tools/compiletest/src/header/needs.rs12
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs19
-rw-r--r--src/tools/miri/src/concurrency/weak_memory.rs164
-rw-r--r--src/tools/miri/tests/fail/alloc/global_system_mixup.rs4
-rw-r--r--src/tools/miri/tests/fail/alloc/global_system_mixup.stderr4
-rw-r--r--src/tools/miri/tests/fail/weak_memory/weak_uninit.rs43
-rw-r--r--src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr15
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs19
-rw-r--r--src/tools/tidy/src/edition.rs10
-rw-r--r--tests/assembly/asm/aarch64-types.rs116
-rw-r--r--tests/assembly/targets/targets-elf.rs6
-rw-r--r--tests/crashes/129205.rs5
-rw-r--r--tests/crashes/129216.rs12
-rw-r--r--tests/mir-opt/issue_72181_1.main.built.after.mir2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/run-make/compressed-debuginfo-zstd/main.rs (renamed from tests/run-make/rust-lld-compress-debug-sections/main.rs)0
-rw-r--r--tests/run-make/compressed-debuginfo-zstd/rmake.rs42
-rw-r--r--tests/run-make/embed-source-dwarf/main.rs2
-rw-r--r--tests/run-make/embed-source-dwarf/rmake.rs70
-rw-r--r--tests/run-make/rust-lld-compress-debug-sections/rmake.rs39
-rw-r--r--tests/rustdoc/anchors.no_type_anchor2.html2
-rw-r--r--tests/rustdoc/assoc-type-source-link.rs26
-rw-r--r--tests/ui/abi/compatibility.rs7
-rw-r--r--tests/ui/asm/aarch64/type-check-3.stderr6
-rw-r--r--tests/ui/asm/aarch64/type-f16.rs25
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr4
-rw-r--r--tests/ui/closures/coerce-unsafe-to-closure.stderr4
-rw-r--r--tests/ui/consts/const-float-bits-conv.rs70
-rw-r--r--tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr12
-rw-r--r--tests/ui/consts/precise-drop-allow-const-fn-unstable.rs17
-rw-r--r--tests/ui/duplicate-label-E0381-issue-129274.rs13
-rw-r--r--tests/ui/duplicate-label-E0381-issue-129274.stderr15
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed4
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs4
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr20
-rw-r--r--tests/ui/intrinsics/reify-intrinsic.stderr4
-rw-r--r--tests/ui/lint/unused/lint-unused-variables.stderr12
-rw-r--r--tests/ui/methods/missing-method-on-type-parameter.rs6
-rw-r--r--tests/ui/methods/missing-method-on-type-parameter.stderr19
-rw-r--r--tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr12
-rw-r--r--tests/ui/simd/shuffle.rs27
374 files changed, 4287 insertions, 3053 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 3dc548c4554..df29b3d54f0 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -3,6 +3,7 @@
 #![cfg_attr(feature = "nightly", doc(rust_logo))]
 #![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
 #![cfg_attr(feature = "nightly", feature(step_trait))]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::fmt;
@@ -1699,7 +1700,9 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
 
     /// Checks if these two `Layout` are equal enough to be considered "the same for all function
     /// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
-    /// `Layout`; the `PassMode` need to be compared as well.
+    /// `Layout`; the `PassMode` need to be compared as well. Also note that we assume
+    /// aggregates are passed via `PassMode::Indirect` or `PassMode::Cast`; more strict
+    /// checks would otherwise be required.
     pub fn eq_abi(&self, other: &Self) -> bool {
         // The one thing that we are not capturing here is that for unsized types, the metadata must
         // also have the same ABI, and moreover that the same metadata leads to the same size. The
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index f5f01348e46..84933540147 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -25,6 +25,7 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(strict_provenance)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::alloc::Layout;
diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs
index 9eaa292e989..bfde8abd589 100644
--- a/compiler/rustc_arena/src/tests.rs
+++ b/compiler/rustc_arena/src/tests.rs
@@ -32,7 +32,7 @@ impl<T> TypedArena<T> {
 }
 
 #[test]
-pub fn test_unused() {
+fn test_unused() {
     let arena: TypedArena<Point> = TypedArena::default();
     assert!(arena.chunks.borrow().is_empty());
 }
@@ -75,7 +75,7 @@ fn test_arena_alloc_nested() {
 }
 
 #[test]
-pub fn test_copy() {
+fn test_copy() {
     let arena = TypedArena::default();
     #[cfg(not(miri))]
     const N: usize = 100000;
@@ -87,13 +87,13 @@ pub fn test_copy() {
 }
 
 #[bench]
-pub fn bench_copy(b: &mut Bencher) {
+fn bench_copy(b: &mut Bencher) {
     let arena = TypedArena::default();
     b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
 }
 
 #[bench]
-pub fn bench_copy_nonarena(b: &mut Bencher) {
+fn bench_copy_nonarena(b: &mut Bencher) {
     b.iter(|| {
         let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 });
     })
@@ -106,7 +106,7 @@ struct Noncopy {
 }
 
 #[test]
-pub fn test_noncopy() {
+fn test_noncopy() {
     let arena = TypedArena::default();
     #[cfg(not(miri))]
     const N: usize = 100000;
@@ -118,7 +118,7 @@ pub fn test_noncopy() {
 }
 
 #[test]
-pub fn test_typed_arena_zero_sized() {
+fn test_typed_arena_zero_sized() {
     let arena = TypedArena::default();
     #[cfg(not(miri))]
     const N: usize = 100000;
@@ -130,7 +130,7 @@ pub fn test_typed_arena_zero_sized() {
 }
 
 #[test]
-pub fn test_typed_arena_clear() {
+fn test_typed_arena_clear() {
     let mut arena = TypedArena::default();
     for _ in 0..10 {
         arena.clear();
@@ -145,7 +145,7 @@ pub fn test_typed_arena_clear() {
 }
 
 #[bench]
-pub fn bench_typed_arena_clear(b: &mut Bencher) {
+fn bench_typed_arena_clear(b: &mut Bencher) {
     let mut arena = TypedArena::default();
     b.iter(|| {
         arena.alloc(Point { x: 1, y: 2, z: 3 });
@@ -154,7 +154,7 @@ pub fn bench_typed_arena_clear(b: &mut Bencher) {
 }
 
 #[bench]
-pub fn bench_typed_arena_clear_100(b: &mut Bencher) {
+fn bench_typed_arena_clear_100(b: &mut Bencher) {
     let mut arena = TypedArena::default();
     b.iter(|| {
         for _ in 0..100 {
@@ -230,7 +230,7 @@ fn test_typed_arena_drop_small_count() {
 }
 
 #[bench]
-pub fn bench_noncopy(b: &mut Bencher) {
+fn bench_noncopy(b: &mut Bencher) {
     let arena = TypedArena::default();
     b.iter(|| {
         arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] })
@@ -238,7 +238,7 @@ pub fn bench_noncopy(b: &mut Bencher) {
 }
 
 #[bench]
-pub fn bench_noncopy_nonarena(b: &mut Bencher) {
+fn bench_noncopy_nonarena(b: &mut Bencher) {
     b.iter(|| {
         let _: Box<_> =
             Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 27e9f3d137f..7730d0b4b78 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -19,6 +19,7 @@
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(stmt_expr_attributes)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod util {
diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs
index 1d0c76f6cea..eeed5d36151 100644
--- a/compiler/rustc_ast_ir/src/lib.rs
+++ b/compiler/rustc_ast_ir/src/lib.rs
@@ -2,6 +2,7 @@
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 #![cfg_attr(feature = "nightly", feature(never_type))]
 #![cfg_attr(feature = "nightly", feature(rustc_attrs))]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[cfg(feature = "nightly")]
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 9c073130827..80077348204 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -51,7 +51,7 @@ use rustc_span::Span;
 use rustc_target::spec::abi;
 use {rustc_ast as ast, rustc_hir as hir};
 
-use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
+use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
 use crate::{ImplTraitPosition, ResolverAstLoweringExt};
 
 pub(crate) struct DelegationResults<'hir> {
@@ -323,7 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 delegation.path.span,
                 ast_segment,
                 ParamMode::Optional,
-                ParenthesizedGenericArgs::Err,
+                GenericArgsMode::Err,
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 8237bfd6792..6b39c2d3955 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
-pub struct GenericTypeWithParentheses {
+pub(crate) struct GenericTypeWithParentheses {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -16,7 +16,7 @@ pub struct GenericTypeWithParentheses {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")]
-pub struct UseAngleBrackets {
+pub(crate) struct UseAngleBrackets {
     #[suggestion_part(code = "<")]
     pub open_param: Span,
     #[suggestion_part(code = ">")]
@@ -26,7 +26,7 @@ pub struct UseAngleBrackets {
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_abi, code = E0703)]
 #[note]
-pub struct InvalidAbi {
+pub(crate) struct InvalidAbi {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -38,7 +38,7 @@ pub struct InvalidAbi {
     pub suggestion: Option<InvalidAbiSuggestion>,
 }
 
-pub struct InvalidAbiReason(pub &'static str);
+pub(crate) struct InvalidAbiReason(pub &'static str);
 
 impl Subdiagnostic for InvalidAbiReason {
     fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
@@ -57,7 +57,7 @@ impl Subdiagnostic for InvalidAbiReason {
     code = "{suggestion}",
     applicability = "maybe-incorrect"
 )]
-pub struct InvalidAbiSuggestion {
+pub(crate) struct InvalidAbiSuggestion {
     #[primary_span]
     pub span: Span,
     pub suggestion: String,
@@ -65,7 +65,7 @@ pub struct InvalidAbiSuggestion {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_assoc_ty_parentheses)]
-pub struct AssocTyParentheses {
+pub(crate) struct AssocTyParentheses {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -73,7 +73,7 @@ pub struct AssocTyParentheses {
 }
 
 #[derive(Subdiagnostic)]
-pub enum AssocTyParenthesesSub {
+pub(crate) enum AssocTyParenthesesSub {
     #[multipart_suggestion(ast_lowering_remove_parentheses)]
     Empty {
         #[suggestion_part(code = "")]
@@ -91,7 +91,7 @@ pub enum AssocTyParenthesesSub {
 #[derive(Diagnostic)]
 #[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
 #[note]
-pub struct MisplacedImplTrait<'a> {
+pub(crate) struct MisplacedImplTrait<'a> {
     #[primary_span]
     pub span: Span,
     pub position: DiagArgFromDisplay<'a>,
@@ -99,7 +99,7 @@ pub struct MisplacedImplTrait<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_assoc_ty_binding_in_dyn)]
-pub struct MisplacedAssocTyBinding {
+pub(crate) struct MisplacedAssocTyBinding {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
@@ -108,7 +108,7 @@ pub struct MisplacedAssocTyBinding {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_underscore_expr_lhs_assign)]
-pub struct UnderscoreExprLhsAssign {
+pub(crate) struct UnderscoreExprLhsAssign {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -116,7 +116,7 @@ pub struct UnderscoreExprLhsAssign {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_base_expression_double_dot, code = E0797)]
-pub struct BaseExpressionDoubleDot {
+pub(crate) struct BaseExpressionDoubleDot {
     #[primary_span]
     #[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
     pub span: Span,
@@ -124,7 +124,7 @@ pub struct BaseExpressionDoubleDot {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
-pub struct AwaitOnlyInAsyncFnAndBlocks {
+pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {
     #[primary_span]
     #[label]
     pub await_kw_span: Span,
@@ -134,21 +134,21 @@ pub struct AwaitOnlyInAsyncFnAndBlocks {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
-pub struct CoroutineTooManyParameters {
+pub(crate) struct CoroutineTooManyParameters {
     #[primary_span]
     pub fn_decl_span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
-pub struct ClosureCannotBeStatic {
+pub(crate) struct ClosureCannotBeStatic {
     #[primary_span]
     pub fn_decl_span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_functional_record_update_destructuring_assignment)]
-pub struct FunctionalRecordUpdateDestructuringAssignment {
+pub(crate) struct FunctionalRecordUpdateDestructuringAssignment {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub span: Span,
@@ -156,28 +156,28 @@ pub struct FunctionalRecordUpdateDestructuringAssignment {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
-pub struct AsyncCoroutinesNotSupported {
+pub(crate) struct AsyncCoroutinesNotSupported {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
-pub struct InlineAsmUnsupportedTarget {
+pub(crate) struct InlineAsmUnsupportedTarget {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_att_syntax_only_x86)]
-pub struct AttSyntaxOnlyX86 {
+pub(crate) struct AttSyntaxOnlyX86 {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_abi_specified_multiple_times)]
-pub struct AbiSpecifiedMultipleTimes {
+pub(crate) struct AbiSpecifiedMultipleTimes {
     #[primary_span]
     pub abi_span: Span,
     pub prev_name: Symbol,
@@ -189,7 +189,7 @@ pub struct AbiSpecifiedMultipleTimes {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_clobber_abi_not_supported)]
-pub struct ClobberAbiNotSupported {
+pub(crate) struct ClobberAbiNotSupported {
     #[primary_span]
     pub abi_span: Span,
 }
@@ -197,7 +197,7 @@ pub struct ClobberAbiNotSupported {
 #[derive(Diagnostic)]
 #[note]
 #[diag(ast_lowering_invalid_abi_clobber_abi)]
-pub struct InvalidAbiClobberAbi {
+pub(crate) struct InvalidAbiClobberAbi {
     #[primary_span]
     pub abi_span: Span,
     pub supported_abis: String,
@@ -205,7 +205,7 @@ pub struct InvalidAbiClobberAbi {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_register)]
-pub struct InvalidRegister<'a> {
+pub(crate) struct InvalidRegister<'a> {
     #[primary_span]
     pub op_span: Span,
     pub reg: Symbol,
@@ -214,7 +214,7 @@ pub struct InvalidRegister<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_register_class)]
-pub struct InvalidRegisterClass<'a> {
+pub(crate) struct InvalidRegisterClass<'a> {
     #[primary_span]
     pub op_span: Span,
     pub reg_class: Symbol,
@@ -223,7 +223,7 @@ pub struct InvalidRegisterClass<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_asm_template_modifier_reg_class)]
-pub struct InvalidAsmTemplateModifierRegClass {
+pub(crate) struct InvalidAsmTemplateModifierRegClass {
     #[primary_span]
     #[label(ast_lowering_template_modifier)]
     pub placeholder_span: Span,
@@ -234,7 +234,7 @@ pub struct InvalidAsmTemplateModifierRegClass {
 }
 
 #[derive(Subdiagnostic)]
-pub enum InvalidAsmTemplateModifierRegClassSub {
+pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
     #[note(ast_lowering_support_modifiers)]
     SupportModifier { class_name: Symbol, modifiers: String },
     #[note(ast_lowering_does_not_support_modifiers)]
@@ -243,7 +243,7 @@ pub enum InvalidAsmTemplateModifierRegClassSub {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_asm_template_modifier_const)]
-pub struct InvalidAsmTemplateModifierConst {
+pub(crate) struct InvalidAsmTemplateModifierConst {
     #[primary_span]
     #[label(ast_lowering_template_modifier)]
     pub placeholder_span: Span,
@@ -253,7 +253,7 @@ pub struct InvalidAsmTemplateModifierConst {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_asm_template_modifier_sym)]
-pub struct InvalidAsmTemplateModifierSym {
+pub(crate) struct InvalidAsmTemplateModifierSym {
     #[primary_span]
     #[label(ast_lowering_template_modifier)]
     pub placeholder_span: Span,
@@ -263,7 +263,7 @@ pub struct InvalidAsmTemplateModifierSym {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_invalid_asm_template_modifier_label)]
-pub struct InvalidAsmTemplateModifierLabel {
+pub(crate) struct InvalidAsmTemplateModifierLabel {
     #[primary_span]
     #[label(ast_lowering_template_modifier)]
     pub placeholder_span: Span,
@@ -273,7 +273,7 @@ pub struct InvalidAsmTemplateModifierLabel {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_register_class_only_clobber)]
-pub struct RegisterClassOnlyClobber {
+pub(crate) struct RegisterClassOnlyClobber {
     #[primary_span]
     pub op_span: Span,
     pub reg_class_name: Symbol,
@@ -281,7 +281,7 @@ pub struct RegisterClassOnlyClobber {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_register_conflict)]
-pub struct RegisterConflict<'a> {
+pub(crate) struct RegisterConflict<'a> {
     #[primary_span]
     #[label(ast_lowering_register1)]
     pub op_span1: Span,
@@ -296,7 +296,7 @@ pub struct RegisterConflict<'a> {
 #[derive(Diagnostic)]
 #[help]
 #[diag(ast_lowering_sub_tuple_binding)]
-pub struct SubTupleBinding<'a> {
+pub(crate) struct SubTupleBinding<'a> {
     #[primary_span]
     #[label]
     #[suggestion(
@@ -313,7 +313,7 @@ pub struct SubTupleBinding<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_extra_double_dot)]
-pub struct ExtraDoubleDot<'a> {
+pub(crate) struct ExtraDoubleDot<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -325,21 +325,21 @@ pub struct ExtraDoubleDot<'a> {
 #[derive(Diagnostic)]
 #[note]
 #[diag(ast_lowering_misplaced_double_dot)]
-pub struct MisplacedDoubleDot {
+pub(crate) struct MisplacedDoubleDot {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_misplaced_relax_trait_bound)]
-pub struct MisplacedRelaxTraitBound {
+pub(crate) struct MisplacedRelaxTraitBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_match_arm_with_no_body)]
-pub struct MatchArmWithNoBody {
+pub(crate) struct MatchArmWithNoBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
@@ -348,7 +348,7 @@ pub struct MatchArmWithNoBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_never_pattern_with_body)]
-pub struct NeverPatternWithBody {
+pub(crate) struct NeverPatternWithBody {
     #[primary_span]
     #[label]
     #[suggestion(code = "", applicability = "maybe-incorrect")]
@@ -357,7 +357,7 @@ pub struct NeverPatternWithBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_never_pattern_with_guard)]
-pub struct NeverPatternWithGuard {
+pub(crate) struct NeverPatternWithGuard {
     #[primary_span]
     #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
@@ -365,7 +365,7 @@ pub struct NeverPatternWithGuard {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_arbitrary_expression_in_pattern)]
-pub struct ArbitraryExpressionInPattern {
+pub(crate) struct ArbitraryExpressionInPattern {
     #[primary_span]
     pub span: Span,
     #[note(ast_lowering_pattern_from_macro_note)]
@@ -374,13 +374,13 @@ pub struct ArbitraryExpressionInPattern {
 
 #[derive(Diagnostic)]
 #[diag(ast_lowering_inclusive_range_with_no_end)]
-pub struct InclusiveRangeWithNoEnd {
+pub(crate) struct InclusiveRangeWithNoEnd {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-pub enum BadReturnTypeNotation {
+pub(crate) enum BadReturnTypeNotation {
     #[diag(ast_lowering_bad_return_type_notation_inputs)]
     Inputs {
         #[primary_span]
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index bb86e5c9325..a6c7714a182 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -20,7 +20,7 @@ use super::errors::{
     NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign,
 };
 use super::{
-    ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs, ResolverAstLoweringExt,
+    GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
 };
 use crate::errors::YieldInClosure;
 use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
@@ -107,7 +107,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         e.span,
                         seg,
                         ParamMode::Optional,
-                        ParenthesizedGenericArgs::Err,
+                        GenericArgsMode::Err,
                         ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         // Method calls can't have bound modifiers
                         None,
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index eef87879c24..c8ec8f308a8 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -764,18 +764,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         &mut self,
         (index, f): (usize, &FieldDef),
     ) -> hir::FieldDef<'hir> {
-        let ty = if let TyKind::Path(qself, path) = &f.ty.kind {
-            let t = self.lower_path_ty(
-                &f.ty,
-                qself,
-                path,
-                ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
-                ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
-            );
-            self.arena.alloc(t)
-        } else {
-            self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
-        };
+        let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
         let hir_id = self.lower_node_id(f.id);
         self.lower_attrs(hir_id, &f.attrs);
         hir::FieldDef {
@@ -1188,7 +1177,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// into the body. This is to make sure that the future actually owns the
     /// arguments that are passed to the function, and to ensure things like
     /// drop order are stable.
-    pub fn lower_coroutine_body_with_moved_arguments(
+    pub(crate) fn lower_coroutine_body_with_moved_arguments(
         &mut self,
         decl: &FnDecl,
         lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4b8c47ac4b4..bcc2c29a2ff 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -37,6 +37,7 @@
 #![feature(box_patterns)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::collections::hash_map::Entry;
@@ -481,13 +482,11 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
 enum ParamMode {
     /// Any path in a type context.
     Explicit,
-    /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
-    ExplicitNamed,
     /// The `module::Type` in `module::Type::method` in an expression.
     Optional,
 }
 
-enum ParenthesizedGenericArgs {
+enum GenericArgsMode {
     ParenSugar,
     Err,
 }
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 077b06acd7c..2ab30eff6d8 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -15,8 +15,8 @@ use super::errors::{
     GenericTypeWithParentheses, UseAngleBrackets,
 };
 use super::{
-    GenericArgsCtor, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
-    ParenthesizedGenericArgs, ResolverAstLoweringExt,
+    GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
+    ResolverAstLoweringExt,
 };
 use crate::ImplTraitPosition;
 
@@ -90,10 +90,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         _ => param_mode,
                     };
 
-                    let parenthesized_generic_args = match base_res {
+                    let generic_args_mode = match base_res {
                         // `a::b::Trait(Args)`
                         Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
-                            ParenthesizedGenericArgs::ParenSugar
+                            GenericArgsMode::ParenSugar
                         }
                         // `a::b::Trait(Args)::TraitItem`
                         Res::Def(DefKind::AssocFn, _)
@@ -101,19 +101,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         | Res::Def(DefKind::AssocTy, _)
                             if i + 2 == proj_start =>
                         {
-                            ParenthesizedGenericArgs::ParenSugar
+                            GenericArgsMode::ParenSugar
                         }
                         // Avoid duplicated errors.
-                        Res::Err => ParenthesizedGenericArgs::ParenSugar,
+                        Res::Err => GenericArgsMode::ParenSugar,
                         // An error
-                        _ => ParenthesizedGenericArgs::Err,
+                        _ => GenericArgsMode::Err,
                     };
 
                     self.lower_path_segment(
                         p.span,
                         segment,
                         param_mode,
-                        parenthesized_generic_args,
+                        generic_args_mode,
                         itctx,
                         bound_modifier_allowed_features.clone(),
                     )
@@ -168,7 +168,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 p.span,
                 segment,
                 param_mode,
-                ParenthesizedGenericArgs::Err,
+                GenericArgsMode::Err,
                 itctx,
                 None,
             ));
@@ -210,7 +210,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     p.span,
                     segment,
                     param_mode,
-                    ParenthesizedGenericArgs::Err,
+                    GenericArgsMode::Err,
                     ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                 )
@@ -224,7 +224,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         path_span: Span,
         segment: &PathSegment,
         param_mode: ParamMode,
-        parenthesized_generic_args: ParenthesizedGenericArgs,
+        generic_args_mode: GenericArgsMode,
         itctx: ImplTraitContext,
         // Additional features ungated with a bound modifier like `async`.
         // This is passed down to the implicit associated type binding in
@@ -237,14 +237,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 GenericArgs::AngleBracketed(data) => {
                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
                 }
-                GenericArgs::Parenthesized(data) => match parenthesized_generic_args {
-                    ParenthesizedGenericArgs::ParenSugar => self
-                        .lower_parenthesized_parameter_data(
-                            data,
-                            itctx,
-                            bound_modifier_allowed_features,
-                        ),
-                    ParenthesizedGenericArgs::Err => {
+                GenericArgs::Parenthesized(data) => match generic_args_mode {
+                    GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
+                        data,
+                        itctx,
+                        bound_modifier_allowed_features,
+                    ),
+                    GenericArgsMode::Err => {
                         // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
                         let sub = if !data.inputs.is_empty() {
                             // Start of the span to the 1st character of 1st argument
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index de1b3f55e80..67c0396333c 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -11,7 +11,7 @@ use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_visibility_not_permitted, code = E0449)]
-pub struct VisibilityNotPermitted {
+pub(crate) struct VisibilityNotPermitted {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -25,7 +25,7 @@ pub struct VisibilityNotPermitted {
 }
 
 #[derive(Subdiagnostic)]
-pub enum VisibilityNotPermittedNote {
+pub(crate) enum VisibilityNotPermittedNote {
     #[note(ast_passes_enum_variant)]
     EnumVariant,
     #[note(ast_passes_trait_impl)]
@@ -38,7 +38,7 @@ pub enum VisibilityNotPermittedNote {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_trait_fn_const, code = E0379)]
-pub struct TraitFnConst {
+pub(crate) struct TraitFnConst {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -64,21 +64,21 @@ pub struct TraitFnConst {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_forbidden_bound)]
-pub struct ForbiddenBound {
+pub(crate) struct ForbiddenBound {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_forbidden_const_param)]
-pub struct ForbiddenConstParam {
+pub(crate) struct ForbiddenConstParam {
     #[primary_span]
     pub const_param_spans: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_param_too_many)]
-pub struct FnParamTooMany {
+pub(crate) struct FnParamTooMany {
     #[primary_span]
     pub span: Span,
     pub max_num_args: usize,
@@ -86,14 +86,14 @@ pub struct FnParamTooMany {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_param_c_var_args_not_last)]
-pub struct FnParamCVarArgsNotLast {
+pub(crate) struct FnParamCVarArgsNotLast {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_param_doc_comment)]
-pub struct FnParamDocComment {
+pub(crate) struct FnParamDocComment {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -101,7 +101,7 @@ pub struct FnParamDocComment {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_param_forbidden_attr)]
-pub struct FnParamForbiddenAttr {
+pub(crate) struct FnParamForbiddenAttr {
     #[primary_span]
     pub span: Span,
 }
@@ -109,7 +109,7 @@ pub struct FnParamForbiddenAttr {
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_param_forbidden_self)]
 #[note]
-pub struct FnParamForbiddenSelf {
+pub(crate) struct FnParamForbiddenSelf {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -117,7 +117,7 @@ pub struct FnParamForbiddenSelf {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_forbidden_default)]
-pub struct ForbiddenDefault {
+pub(crate) struct ForbiddenDefault {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -126,7 +126,7 @@ pub struct ForbiddenDefault {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_assoc_const_without_body)]
-pub struct AssocConstWithoutBody {
+pub(crate) struct AssocConstWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
@@ -135,7 +135,7 @@ pub struct AssocConstWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_assoc_fn_without_body)]
-pub struct AssocFnWithoutBody {
+pub(crate) struct AssocFnWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
@@ -144,7 +144,7 @@ pub struct AssocFnWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_assoc_type_without_body)]
-pub struct AssocTypeWithoutBody {
+pub(crate) struct AssocTypeWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
@@ -153,7 +153,7 @@ pub struct AssocTypeWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_const_without_body)]
-pub struct ConstWithoutBody {
+pub(crate) struct ConstWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
@@ -162,7 +162,7 @@ pub struct ConstWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_static_without_body)]
-pub struct StaticWithoutBody {
+pub(crate) struct StaticWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
@@ -171,7 +171,7 @@ pub struct StaticWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_ty_alias_without_body)]
-pub struct TyAliasWithoutBody {
+pub(crate) struct TyAliasWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " = <type>;", applicability = "has-placeholders")]
@@ -180,7 +180,7 @@ pub struct TyAliasWithoutBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fn_without_body)]
-pub struct FnWithoutBody {
+pub(crate) struct FnWithoutBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
@@ -190,7 +190,7 @@ pub struct FnWithoutBody {
 }
 
 #[derive(Subdiagnostic)]
-pub enum ExternBlockSuggestion {
+pub(crate) enum ExternBlockSuggestion {
     #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
     Implicit {
         #[suggestion_part(code = "extern {{")]
@@ -210,7 +210,7 @@ pub enum ExternBlockSuggestion {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_extern_invalid_safety)]
-pub struct InvalidSafetyOnExtern {
+pub(crate) struct InvalidSafetyOnExtern {
     #[primary_span]
     pub item_span: Span,
     #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")]
@@ -219,28 +219,28 @@ pub struct InvalidSafetyOnExtern {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_item_invalid_safety)]
-pub struct InvalidSafetyOnItem {
+pub(crate) struct InvalidSafetyOnItem {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_bare_fn_invalid_safety)]
-pub struct InvalidSafetyOnBareFn {
+pub(crate) struct InvalidSafetyOnBareFn {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_unsafe_static)]
-pub struct UnsafeStatic {
+pub(crate) struct UnsafeStatic {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_bound_in_context)]
-pub struct BoundInContext<'a> {
+pub(crate) struct BoundInContext<'a> {
     #[primary_span]
     pub span: Span,
     pub ctx: &'a str,
@@ -249,7 +249,7 @@ pub struct BoundInContext<'a> {
 #[derive(Diagnostic)]
 #[diag(ast_passes_extern_types_cannot)]
 #[note(ast_passes_extern_keyword_link)]
-pub struct ExternTypesCannotHave<'a> {
+pub(crate) struct ExternTypesCannotHave<'a> {
     #[primary_span]
     #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
@@ -262,7 +262,7 @@ pub struct ExternTypesCannotHave<'a> {
 #[derive(Diagnostic)]
 #[diag(ast_passes_body_in_extern)]
 #[note(ast_passes_extern_keyword_link)]
-pub struct BodyInExtern<'a> {
+pub(crate) struct BodyInExtern<'a> {
     #[primary_span]
     #[label(ast_passes_cannot_have)]
     pub span: Span,
@@ -277,7 +277,7 @@ pub struct BodyInExtern<'a> {
 #[diag(ast_passes_fn_body_extern)]
 #[help]
 #[note(ast_passes_extern_keyword_link)]
-pub struct FnBodyInExtern {
+pub(crate) struct FnBodyInExtern {
     #[primary_span]
     #[label(ast_passes_cannot_have)]
     pub span: Span,
@@ -289,7 +289,7 @@ pub struct FnBodyInExtern {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_extern_fn_qualifiers)]
-pub struct FnQualifierInExtern {
+pub(crate) struct FnQualifierInExtern {
     #[primary_span]
     #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
@@ -300,7 +300,7 @@ pub struct FnQualifierInExtern {
 #[derive(Diagnostic)]
 #[diag(ast_passes_extern_item_ascii)]
 #[note]
-pub struct ExternItemAscii {
+pub(crate) struct ExternItemAscii {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -309,14 +309,14 @@ pub struct ExternItemAscii {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_bad_c_variadic)]
-pub struct BadCVariadic {
+pub(crate) struct BadCVariadic {
     #[primary_span]
     pub span: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_item_underscore)]
-pub struct ItemUnderscore<'a> {
+pub(crate) struct ItemUnderscore<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -325,7 +325,7 @@ pub struct ItemUnderscore<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_nomangle_ascii, code = E0754)]
-pub struct NoMangleAscii {
+pub(crate) struct NoMangleAscii {
     #[primary_span]
     pub span: Span,
 }
@@ -333,7 +333,7 @@ pub struct NoMangleAscii {
 #[derive(Diagnostic)]
 #[diag(ast_passes_module_nonascii, code = E0754)]
 #[help]
-pub struct ModuleNonAscii {
+pub(crate) struct ModuleNonAscii {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -341,7 +341,7 @@ pub struct ModuleNonAscii {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_auto_generic, code = E0567)]
-pub struct AutoTraitGeneric {
+pub(crate) struct AutoTraitGeneric {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub span: Span,
@@ -351,7 +351,7 @@ pub struct AutoTraitGeneric {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_auto_super_lifetime, code = E0568)]
-pub struct AutoTraitBounds {
+pub(crate) struct AutoTraitBounds {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub span: Span,
@@ -361,7 +361,7 @@ pub struct AutoTraitBounds {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_auto_items, code = E0380)]
-pub struct AutoTraitItems {
+pub(crate) struct AutoTraitItems {
     #[primary_span]
     pub spans: Vec<Span>,
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -372,7 +372,7 @@ pub struct AutoTraitItems {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_generic_before_constraints)]
-pub struct ArgsBeforeConstraint {
+pub(crate) struct ArgsBeforeConstraint {
     #[primary_span]
     pub arg_spans: Vec<Span>,
     #[label(ast_passes_constraints)]
@@ -390,7 +390,7 @@ pub struct ArgsBeforeConstraint {
     pub arg_spans2: EmptyLabelManySpans,
 }
 
-pub struct EmptyLabelManySpans(pub Vec<Span>);
+pub(crate) struct EmptyLabelManySpans(pub Vec<Span>);
 
 // The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
 impl Subdiagnostic for EmptyLabelManySpans {
@@ -405,28 +405,28 @@ impl Subdiagnostic for EmptyLabelManySpans {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
-pub struct PatternFnPointer {
+pub(crate) struct PatternFnPointer {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_trait_object_single_bound, code = E0226)]
-pub struct TraitObjectBound {
+pub(crate) struct TraitObjectBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_impl_trait_path, code = E0667)]
-pub struct ImplTraitPath {
+pub(crate) struct ImplTraitPath {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_nested_impl_trait, code = E0666)]
-pub struct NestedImplTrait {
+pub(crate) struct NestedImplTrait {
     #[primary_span]
     pub span: Span,
     #[label(ast_passes_outer)]
@@ -437,14 +437,14 @@ pub struct NestedImplTrait {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_at_least_one_trait)]
-pub struct AtLeastOneTrait {
+pub(crate) struct AtLeastOneTrait {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_out_of_order_params)]
-pub struct OutOfOrderParams<'a> {
+pub(crate) struct OutOfOrderParams<'a> {
     #[primary_span]
     pub spans: Vec<Span>,
     #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")]
@@ -457,14 +457,14 @@ pub struct OutOfOrderParams<'a> {
 #[derive(Diagnostic)]
 #[diag(ast_passes_obsolete_auto)]
 #[help]
-pub struct ObsoleteAuto {
+pub(crate) struct ObsoleteAuto {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_unsafe_negative_impl, code = E0198)]
-pub struct UnsafeNegativeImpl {
+pub(crate) struct UnsafeNegativeImpl {
     #[primary_span]
     pub span: Span,
     #[label(ast_passes_negative)]
@@ -475,7 +475,7 @@ pub struct UnsafeNegativeImpl {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_inherent_cannot_be)]
-pub struct InherentImplCannot<'a> {
+pub(crate) struct InherentImplCannot<'a> {
     #[primary_span]
     pub span: Span,
     #[label(ast_passes_because)]
@@ -489,7 +489,7 @@ pub struct InherentImplCannot<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_inherent_cannot_be, code = E0197)]
-pub struct InherentImplCannotUnsafe<'a> {
+pub(crate) struct InherentImplCannotUnsafe<'a> {
     #[primary_span]
     pub span: Span,
     #[label(ast_passes_because)]
@@ -501,7 +501,7 @@ pub struct InherentImplCannotUnsafe<'a> {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_unsafe_item)]
-pub struct UnsafeItem {
+pub(crate) struct UnsafeItem {
     #[primary_span]
     pub span: Span,
     pub kind: &'static str,
@@ -509,14 +509,14 @@ pub struct UnsafeItem {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_missing_unsafe_on_extern)]
-pub struct MissingUnsafeOnExtern {
+pub(crate) struct MissingUnsafeOnExtern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_fieldless_union)]
-pub struct FieldlessUnion {
+pub(crate) struct FieldlessUnion {
     #[primary_span]
     pub span: Span,
 }
@@ -524,7 +524,7 @@ pub struct FieldlessUnion {
 #[derive(Diagnostic)]
 #[diag(ast_passes_where_clause_after_type_alias)]
 #[note]
-pub struct WhereClauseAfterTypeAlias {
+pub(crate) struct WhereClauseAfterTypeAlias {
     #[primary_span]
     pub span: Span,
     #[help]
@@ -534,7 +534,7 @@ pub struct WhereClauseAfterTypeAlias {
 #[derive(Diagnostic)]
 #[diag(ast_passes_where_clause_before_type_alias)]
 #[note]
-pub struct WhereClauseBeforeTypeAlias {
+pub(crate) struct WhereClauseBeforeTypeAlias {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -543,7 +543,7 @@ pub struct WhereClauseBeforeTypeAlias {
 
 #[derive(Subdiagnostic)]
 
-pub enum WhereClauseBeforeTypeAliasSugg {
+pub(crate) enum WhereClauseBeforeTypeAliasSugg {
     #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")]
     Remove {
         #[primary_span]
@@ -565,14 +565,14 @@ pub enum WhereClauseBeforeTypeAliasSugg {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_generic_default_trailing)]
-pub struct GenericDefaultTrailing {
+pub(crate) struct GenericDefaultTrailing {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_nested_lifetimes, code = E0316)]
-pub struct NestedLifetimes {
+pub(crate) struct NestedLifetimes {
     #[primary_span]
     pub span: Span,
 }
@@ -580,7 +580,7 @@ pub struct NestedLifetimes {
 #[derive(Diagnostic)]
 #[diag(ast_passes_optional_trait_supertrait)]
 #[note]
-pub struct OptionalTraitSupertrait {
+pub(crate) struct OptionalTraitSupertrait {
     #[primary_span]
     pub span: Span,
     pub path_str: String,
@@ -588,14 +588,14 @@ pub struct OptionalTraitSupertrait {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_optional_trait_object)]
-pub struct OptionalTraitObject {
+pub(crate) struct OptionalTraitObject {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_const_bound_trait_object)]
-pub struct ConstBoundTraitObject {
+pub(crate) struct ConstBoundTraitObject {
     #[primary_span]
     pub span: Span,
 }
@@ -604,7 +604,7 @@ pub struct ConstBoundTraitObject {
 // FIXME(effects): Provide structured suggestions (e.g., add `const` / `#[const_trait]` here).
 #[derive(Diagnostic)]
 #[diag(ast_passes_tilde_const_disallowed)]
-pub struct TildeConstDisallowed {
+pub(crate) struct TildeConstDisallowed {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -612,7 +612,7 @@ pub struct TildeConstDisallowed {
 }
 
 #[derive(Subdiagnostic, Copy, Clone)]
-pub enum TildeConstReason {
+pub(crate) enum TildeConstReason {
     #[note(ast_passes_closure)]
     Closure,
     #[note(ast_passes_function)]
@@ -658,7 +658,7 @@ pub enum TildeConstReason {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_const_and_async)]
-pub struct ConstAndAsync {
+pub(crate) struct ConstAndAsync {
     #[primary_span]
     pub spans: Vec<Span>,
     #[label(ast_passes_const)]
@@ -671,7 +671,7 @@ pub struct ConstAndAsync {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_const_and_c_variadic)]
-pub struct ConstAndCVariadic {
+pub(crate) struct ConstAndCVariadic {
     #[primary_span]
     pub spans: Vec<Span>,
     #[label(ast_passes_const)]
@@ -683,7 +683,7 @@ pub struct ConstAndCVariadic {
 #[derive(Diagnostic)]
 #[diag(ast_passes_pattern_in_foreign, code = E0130)]
 // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
-pub struct PatternInForeign {
+pub(crate) struct PatternInForeign {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -692,7 +692,7 @@ pub struct PatternInForeign {
 #[derive(Diagnostic)]
 #[diag(ast_passes_pattern_in_bodiless, code = E0642)]
 // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
-pub struct PatternInBodiless {
+pub(crate) struct PatternInBodiless {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -701,7 +701,7 @@ pub struct PatternInBodiless {
 #[derive(Diagnostic)]
 #[diag(ast_passes_equality_in_where)]
 #[note]
-pub struct EqualityInWhere {
+pub(crate) struct EqualityInWhere {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -718,7 +718,7 @@ pub struct EqualityInWhere {
     style = "verbose",
     applicability = "maybe-incorrect"
 )]
-pub struct AssociatedSuggestion {
+pub(crate) struct AssociatedSuggestion {
     #[primary_span]
     pub span: Span,
     pub ident: Ident,
@@ -728,7 +728,7 @@ pub struct AssociatedSuggestion {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")]
-pub struct AssociatedSuggestion2 {
+pub(crate) struct AssociatedSuggestion2 {
     #[suggestion_part(code = "{args}")]
     pub span: Span,
     pub args: String,
@@ -740,14 +740,14 @@ pub struct AssociatedSuggestion2 {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_stability_outside_std, code = E0734)]
-pub struct StabilityOutsideStd {
+pub(crate) struct StabilityOutsideStd {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_feature_on_non_nightly, code = E0554)]
-pub struct FeatureOnNonNightly {
+pub(crate) struct FeatureOnNonNightly {
     #[primary_span]
     pub span: Span,
     pub channel: &'static str,
@@ -757,7 +757,7 @@ pub struct FeatureOnNonNightly {
     pub sugg: Option<Span>,
 }
 
-pub struct StableFeature {
+pub(crate) struct StableFeature {
     pub name: Symbol,
     pub since: Symbol,
 }
@@ -777,7 +777,7 @@ impl Subdiagnostic for StableFeature {
 #[derive(Diagnostic)]
 #[diag(ast_passes_incompatible_features)]
 #[help]
-pub struct IncompatibleFeatures {
+pub(crate) struct IncompatibleFeatures {
     #[primary_span]
     pub spans: Vec<Span>,
     pub f1: Symbol,
@@ -786,7 +786,7 @@ pub struct IncompatibleFeatures {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_show_span)]
-pub struct ShowSpan {
+pub(crate) struct ShowSpan {
     #[primary_span]
     pub span: Span,
     pub msg: &'static str,
@@ -794,28 +794,28 @@ pub struct ShowSpan {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_negative_bound_not_supported)]
-pub struct NegativeBoundUnsupported {
+pub(crate) struct NegativeBoundUnsupported {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_constraint_on_negative_bound)]
-pub struct ConstraintOnNegativeBound {
+pub(crate) struct ConstraintOnNegativeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_negative_bound_with_parenthetical_notation)]
-pub struct NegativeBoundWithParentheticalNotation {
+pub(crate) struct NegativeBoundWithParentheticalNotation {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_invalid_unnamed_field_ty)]
-pub struct InvalidUnnamedFieldTy {
+pub(crate) struct InvalidUnnamedFieldTy {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -824,7 +824,7 @@ pub struct InvalidUnnamedFieldTy {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_invalid_unnamed_field)]
-pub struct InvalidUnnamedField {
+pub(crate) struct InvalidUnnamedField {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -833,7 +833,7 @@ pub struct InvalidUnnamedField {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_anon_struct_or_union_not_allowed)]
-pub struct AnonStructOrUnionNotAllowed {
+pub(crate) struct AnonStructOrUnionNotAllowed {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -842,7 +842,7 @@ pub struct AnonStructOrUnionNotAllowed {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_match_arm_with_no_body)]
-pub struct MatchArmWithNoBody {
+pub(crate) struct MatchArmWithNoBody {
     #[primary_span]
     pub span: Span,
     #[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
@@ -851,7 +851,7 @@ pub struct MatchArmWithNoBody {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_precise_capturing_not_allowed_here)]
-pub struct PreciseCapturingNotAllowedHere {
+pub(crate) struct PreciseCapturingNotAllowedHere {
     #[primary_span]
     pub span: Span,
     pub loc: &'static str,
@@ -859,7 +859,7 @@ pub struct PreciseCapturingNotAllowedHere {
 
 #[derive(Diagnostic)]
 #[diag(ast_passes_precise_capturing_duplicated)]
-pub struct DuplicatePreciseCapturing {
+pub(crate) struct DuplicatePreciseCapturing {
     #[primary_span]
     pub bound1: Span,
     #[label]
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 1f4bcd59afa..88c6bde3106 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -12,6 +12,7 @@
 #![feature(iter_is_partitioned)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod ast_validation;
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 84d9ce278a2..602ab69ee5b 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -3,6 +3,7 @@
 #![doc(rust_logo)]
 #![feature(box_patterns)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod helpers;
diff --git a/compiler/rustc_ast_pretty/src/pp/convenience.rs b/compiler/rustc_ast_pretty/src/pp/convenience.rs
index 6d46c26311b..7559b181f7d 100644
--- a/compiler/rustc_ast_pretty/src/pp/convenience.rs
+++ b/compiler/rustc_ast_pretty/src/pp/convenience.rs
@@ -89,7 +89,7 @@ impl Printer {
 }
 
 impl Token {
-    pub fn is_hardbreak_tok(&self) -> bool {
+    pub(crate) fn is_hardbreak_tok(&self) -> bool {
         *self == Printer::hardbreak_tok_offset(0)
     }
 }
diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs
index 8187394fe30..003c0a999b5 100644
--- a/compiler/rustc_ast_pretty/src/pp/ring.rs
+++ b/compiler/rustc_ast_pretty/src/pp/ring.rs
@@ -11,54 +11,54 @@ use std::ops::{Index, IndexMut};
 /// Holding a RingBuffer whose view is elements left..right gives the ability to
 /// use Index and IndexMut to access elements i in the infinitely long queue for
 /// which left <= i < right.
-pub struct RingBuffer<T> {
+pub(super) struct RingBuffer<T> {
     data: VecDeque<T>,
     // Abstract index of data[0] in the infinitely sized queue.
     offset: usize,
 }
 
 impl<T> RingBuffer<T> {
-    pub fn new() -> Self {
+    pub(super) fn new() -> Self {
         RingBuffer { data: VecDeque::new(), offset: 0 }
     }
 
-    pub fn is_empty(&self) -> bool {
+    pub(super) fn is_empty(&self) -> bool {
         self.data.is_empty()
     }
 
-    pub fn push(&mut self, value: T) -> usize {
+    pub(super) fn push(&mut self, value: T) -> usize {
         let index = self.offset + self.data.len();
         self.data.push_back(value);
         index
     }
 
-    pub fn clear(&mut self) {
+    pub(super) fn clear(&mut self) {
         self.data.clear();
     }
 
-    pub fn index_of_first(&self) -> usize {
+    pub(super) fn index_of_first(&self) -> usize {
         self.offset
     }
 
-    pub fn first(&self) -> Option<&T> {
+    pub(super) fn first(&self) -> Option<&T> {
         self.data.front()
     }
 
-    pub fn first_mut(&mut self) -> Option<&mut T> {
+    pub(super) fn first_mut(&mut self) -> Option<&mut T> {
         self.data.front_mut()
     }
 
-    pub fn pop_first(&mut self) -> Option<T> {
+    pub(super) fn pop_first(&mut self) -> Option<T> {
         let first = self.data.pop_front()?;
         self.offset += 1;
         Some(first)
     }
 
-    pub fn last(&self) -> Option<&T> {
+    pub(super) fn last(&self) -> Option<&T> {
         self.data.back()
     }
 
-    pub fn last_mut(&mut self) -> Option<&mut T> {
+    pub(super) fn last_mut(&mut self) -> Option<&mut T> {
         self.data.back_mut()
     }
 }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
index 86d4796e9ce..c9baca72485 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
@@ -110,13 +110,13 @@ impl Default for FixupContext {
 impl FixupContext {
     /// Create the initial fixup for printing an expression in statement
     /// position.
-    pub fn new_stmt() -> Self {
+    pub(crate) fn new_stmt() -> Self {
         FixupContext { stmt: true, ..FixupContext::default() }
     }
 
     /// Create the initial fixup for printing an expression as the right-hand
     /// side of a match arm.
-    pub fn new_match_arm() -> Self {
+    pub(crate) fn new_match_arm() -> Self {
         FixupContext { match_arm: true, ..FixupContext::default() }
     }
 
@@ -124,7 +124,7 @@ impl FixupContext {
     /// of an `if` or `while`. There are a few other positions which are
     /// grammatically equivalent and also use this, such as the iterator
     /// expression in `for` and the scrutinee in `match`.
-    pub fn new_cond() -> Self {
+    pub(crate) fn new_cond() -> Self {
         FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() }
     }
 
@@ -139,7 +139,7 @@ impl FixupContext {
     ///
     /// Not every expression has a leftmost subexpression. For example neither
     /// `-$a` nor `[$a]` have one.
-    pub fn leftmost_subexpression(self) -> Self {
+    pub(crate) fn leftmost_subexpression(self) -> Self {
         FixupContext {
             stmt: false,
             leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
@@ -158,7 +158,7 @@ impl FixupContext {
     /// current expression, and is not surrounded by a paren/bracket/brace. For
     /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
     /// `$a.f($b)`.
-    pub fn subsequent_subexpression(self) -> Self {
+    pub(crate) fn subsequent_subexpression(self) -> Self {
         FixupContext {
             stmt: false,
             leftmost_subexpression_in_stmt: false,
@@ -173,7 +173,7 @@ impl FixupContext {
     ///
     /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
     /// examples.
-    pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
+    pub(crate) fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
         (self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr))
             || (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr))
     }
@@ -189,7 +189,7 @@ impl FixupContext {
     ///
     ///   - `true && false`, because otherwise this would be misinterpreted as a
     ///     "let chain".
-    pub fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
+    pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
         self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
             || parser::needs_par_as_let_scrutinee(expr.precedence().order())
     }
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index 1ecfc42ec1d..0dad6372389 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -9,6 +9,7 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod builtin;
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 9b69325a053..234a0ef28a2 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -127,7 +127,7 @@ pub(crate) enum InvalidIssueStringCause {
 }
 
 impl InvalidIssueStringCause {
-    pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
+    pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
         match kind {
             IntErrorKind::Empty => Some(Self::Empty { span }),
             IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
@@ -303,7 +303,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
 }
 
 impl<'a> IncorrectReprFormatGenericCause<'a> {
-    pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
+    pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
         match kind {
             ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
                 Some(Self::Int { span, name, int: int.get() })
diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs
index e964a709757..f86a9db61c6 100644
--- a/compiler/rustc_baked_icu_data/src/lib.rs
+++ b/compiler/rustc_baked_icu_data/src/lib.rs
@@ -25,6 +25,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code
 // tidy-alphabetical-end
 
 mod data {
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 70f89e80dc9..2c672dbf8c4 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
 impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
-    pub fn dcx(&self) -> DiagCtxtHandle<'infcx> {
+    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> {
         self.infcx.dcx()
     }
 
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 77794a8525f..2795bc7162f 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -14,7 +14,7 @@ use rustc_mir_dataflow::{Analysis, AnalysisDomain, GenKill, Results, ResultsVisi
 use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
 
 /// The results of the dataflow analyses used by the borrow checker.
-pub struct BorrowckResults<'a, 'mir, 'tcx> {
+pub(crate) struct BorrowckResults<'a, 'mir, 'tcx> {
     pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
     pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
     pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
@@ -22,7 +22,7 @@ pub struct BorrowckResults<'a, 'mir, 'tcx> {
 
 /// The transient state of the dataflow analyses used by the borrow checker.
 #[derive(Debug)]
-pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
+pub(crate) struct BorrowckFlowState<'a, 'mir, 'tcx> {
     pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
     pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
     pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index e07d7dd309a..263f68d6a3d 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -4,13 +4,13 @@ use rustc_middle::mir::visit::{
 };
 
 #[derive(Eq, PartialEq, Clone)]
-pub enum DefUse {
+pub(crate) enum DefUse {
     Def,
     Use,
     Drop,
 }
 
-pub fn categorize(context: PlaceContext) -> Option<DefUse> {
+pub(crate) fn categorize(context: PlaceContext) -> Option<DefUse> {
     match context {
         ///////////////////////////////////////////////////////////////////////////
         // DEFS
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 2b46e5597f7..aaeedde2bed 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -645,7 +645,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         }
     }
 
-    pub fn suggest_reborrow(
+    pub(crate) fn suggest_reborrow(
         &self,
         err: &mut Diag<'infcx>,
         span: Span,
@@ -678,14 +678,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         let inits = &self.move_data.init_path_map[mpi];
         let move_path = &self.move_data.move_paths[mpi];
         let decl_span = self.body.local_decls[move_path.place.local].source_info.span;
-        let mut spans = vec![];
+        let mut spans_set = FxIndexSet::default();
         for init_idx in inits {
             let init = &self.move_data.inits[*init_idx];
             let span = init.span(self.body);
             if !span.is_dummy() {
-                spans.push(span);
+                spans_set.insert(span);
             }
         }
+        let spans: Vec<_> = spans_set.into_iter().collect();
 
         let (name, desc) = match self.describe_place_with_options(
             moved_place,
@@ -1891,10 +1892,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         struct FindUselessClone<'tcx> {
             tcx: TyCtxt<'tcx>,
             typeck_results: &'tcx ty::TypeckResults<'tcx>,
-            pub clones: Vec<&'tcx hir::Expr<'tcx>>,
+            clones: Vec<&'tcx hir::Expr<'tcx>>,
         }
         impl<'tcx> FindUselessClone<'tcx> {
-            pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
+            fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
                 Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] }
             }
         }
@@ -1916,7 +1917,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         let body = hir.body(body_id).value;
         expr_finder.visit_expr(body);
 
-        pub struct Holds<'tcx> {
+        struct Holds<'tcx> {
             ty: Ty<'tcx>,
         }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index a2e5c7b8514..33f91d7ad30 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -58,11 +58,11 @@ pub(crate) use region_name::{RegionName, RegionNameSource};
 pub(crate) use rustc_middle::util::CallKind;
 
 pub(super) struct DescribePlaceOpt {
-    pub including_downcast: bool,
+    including_downcast: bool,
 
     /// Enable/Disable tuple fields.
     /// For example `x` tuple. if it's `true` `x.0`. Otherwise `x`
-    pub including_tuple_field: bool,
+    including_tuple_field: bool,
 }
 
 pub(super) struct IncludingTupleField(pub(super) bool);
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 792f1548e08..42b1ffd58ad 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -16,7 +16,7 @@ use crate::prefixes::PrefixSet;
 use crate::MirBorrowckCtxt;
 
 #[derive(Debug)]
-pub enum IllegalMoveOriginKind<'tcx> {
+pub(crate) enum IllegalMoveOriginKind<'tcx> {
     /// Illegal move due to attempt to move from behind a reference.
     BorrowedContent {
         /// The place the reference refers to: if erroneous code was trying to
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 0303b80cace..7b791928689 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1374,7 +1374,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder {
     }
 }
 
-pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
+fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
     debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
 
     match *local_decl.local_info() {
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index de0df347429..a59b7b3cde9 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -31,7 +31,7 @@ enum SuggestedConstraint {
 ///
 /// Adds a help note suggesting adding a where clause with the needed constraints.
 #[derive(Default)]
-pub struct OutlivesSuggestionBuilder {
+pub(crate) struct OutlivesSuggestionBuilder {
     /// The list of outlives constraints that need to be added. Specifically, we map each free
     /// region to all other regions that it must outlive. I will use the shorthand `fr:
     /// outlived_frs`. Not all of these regions will already have names necessarily. Some could be
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 451e8bcb16d..ab48a09cfa4 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -72,22 +72,24 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
 pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);
 
 impl<'tcx> RegionErrors<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self {
         Self(vec![], tcx)
     }
     #[track_caller]
-    pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
+    pub(crate) fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
         let val = val.into();
         let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
         self.0.push((val, guar));
     }
-    pub fn is_empty(&self) -> bool {
+    pub(crate) fn is_empty(&self) -> bool {
         self.0.is_empty()
     }
-    pub fn into_iter(self) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
+    pub(crate) fn into_iter(
+        self,
+    ) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
         self.0.into_iter()
     }
-    pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
+    pub(crate) fn has_errors(&self) -> Option<ErrorGuaranteed> {
         self.0.get(0).map(|x| x.1)
     }
 }
@@ -141,7 +143,7 @@ pub(crate) enum RegionErrorKind<'tcx> {
 
 /// Information about the various region constraints involved in a borrow checker error.
 #[derive(Clone, Debug)]
-pub struct ErrorConstraintInfo<'tcx> {
+pub(crate) struct ErrorConstraintInfo<'tcx> {
     // fr: outlived_fr
     pub(super) fr: RegionVid,
     pub(super) fr_is_local: bool,
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index a529df76bcb..bb1aea14693 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -12,6 +12,7 @@
 #![feature(rustdoc_internals)]
 #![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[macro_use]
@@ -2444,7 +2445,7 @@ mod diags {
         }
     }
 
-    pub struct BorrowckDiags<'infcx, 'tcx> {
+    pub(crate) struct BorrowckDiags<'infcx, 'tcx> {
         /// This field keeps track of move errors that are to be reported for given move indices.
         ///
         /// There are situations where many errors can be reported for a single move out (see
@@ -2468,7 +2469,7 @@ mod diags {
     }
 
     impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> {
-        pub fn new() -> Self {
+        pub(crate) fn new() -> Self {
             BorrowckDiags {
                 buffered_move_errors: BTreeMap::new(),
                 buffered_mut_errors: Default::default(),
@@ -2476,25 +2477,25 @@ mod diags {
             }
         }
 
-        pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
+        pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
             self.buffered_diags.push(BufferedDiag::Error(diag));
         }
 
-        pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
+        pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
             self.buffered_diags.push(BufferedDiag::NonError(diag));
         }
     }
 
     impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
-        pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
+        pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
             self.diags.buffer_error(diag);
         }
 
-        pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
+        pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
             self.diags.buffer_non_error(diag);
         }
 
-        pub fn buffer_move_error(
+        pub(crate) fn buffer_move_error(
             &mut self,
             move_out_indices: Vec<MoveOutIndex>,
             place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
@@ -2510,16 +2511,19 @@ mod diags {
             }
         }
 
-        pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> {
+        pub(crate) fn get_buffered_mut_error(
+            &mut self,
+            span: Span,
+        ) -> Option<(Diag<'infcx>, usize)> {
             // FIXME(#120456) - is `swap_remove` correct?
             self.diags.buffered_mut_errors.swap_remove(&span)
         }
 
-        pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
+        pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
             self.diags.buffered_mut_errors.insert(span, (diag, count));
         }
 
-        pub fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
+        pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
             let mut res = None;
 
             // Buffer any move errors that we collected and de-duplicated.
@@ -2553,7 +2557,7 @@ mod diags {
             self.diags.buffered_diags.is_empty()
         }
 
-        pub fn has_move_error(
+        pub(crate) fn has_move_error(
             &self,
             move_out_indices: &[MoveOutIndex],
         ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index d3bfd1c418f..39d831378cd 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -8,7 +8,7 @@ use rustc_middle::mir::{PlaceRef, ProjectionElem};
 
 use super::MirBorrowckCtxt;
 
-pub trait IsPrefixOf<'tcx> {
+pub(crate) trait IsPrefixOf<'tcx> {
     fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
 }
 
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index c8dc012de4a..6cbdd890b5e 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -42,9 +42,9 @@ mod graphviz;
 mod opaque_types;
 mod reverse_sccs;
 
-pub mod values;
+pub(crate) mod values;
 
-pub type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex, RegionTracker>;
+pub(crate) type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex, RegionTracker>;
 
 /// An annotation for region graph SCCs that tracks
 /// the values of its elements.
@@ -226,7 +226,7 @@ pub(crate) struct AppliedMemberConstraint {
 }
 
 #[derive(Debug)]
-pub struct RegionDefinition<'tcx> {
+pub(crate) struct RegionDefinition<'tcx> {
     /// What kind of variable is this -- a free region? existential
     /// variable? etc. (See the `NllRegionVariableOrigin` for more
     /// info.)
@@ -288,7 +288,7 @@ pub(crate) enum Cause {
 /// `InferCtxt::process_registered_region_obligations` and
 /// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
 #[derive(Clone, Debug)]
-pub struct TypeTest<'tcx> {
+pub(crate) struct TypeTest<'tcx> {
     /// The type `T` that must outlive the region.
     pub generic_kind: GenericKind<'tcx>,
 
@@ -320,7 +320,7 @@ enum Trace<'tcx> {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub enum ExtraConstraintInfo {
+pub(crate) enum ExtraConstraintInfo {
     PlaceholderFromPredicate(Span),
 }
 
@@ -2259,7 +2259,7 @@ impl<'tcx> RegionDefinition<'tcx> {
 }
 
 #[derive(Clone, Debug)]
-pub struct BlameConstraint<'tcx> {
+pub(crate) struct BlameConstraint<'tcx> {
     pub category: ConstraintCategory<'tcx>,
     pub from_closure: bool,
     pub cause: ObligationCause<'tcx>,
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 1073ea40694..cd66acd0a8f 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -473,20 +473,20 @@ struct LazyOpaqueTyEnv<'tcx> {
 }
 
 impl<'tcx> LazyOpaqueTyEnv<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
+    fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
         Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() }
     }
 
-    pub fn param_equal_static(&self, param_index: usize) -> bool {
+    fn param_equal_static(&self, param_index: usize) -> bool {
         self.get_canonical_args()[param_index].expect_region().is_static()
     }
 
-    pub fn params_equal(&self, param1: usize, param2: usize) -> bool {
+    fn params_equal(&self, param1: usize, param2: usize) -> bool {
         let canonical_args = self.get_canonical_args();
         canonical_args[param1] == canonical_args[param2]
     }
 
-    pub fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
+    fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> {
         self.get_canonical_args()[param_index].error_reported()
     }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 3b3898ccd4d..d8f74840eb5 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -86,7 +86,7 @@ macro_rules! span_mirbug_and_err {
 
 mod canonical;
 mod constraint_conversion;
-pub mod free_region_relations;
+pub(crate) mod free_region_relations;
 mod input_output;
 pub(crate) mod liveness;
 mod relate_tys;
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 8da4d80badf..35d8e2573fe 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -57,7 +57,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     }
 }
 
-pub struct NllTypeRelating<'me, 'bccx, 'tcx> {
+struct NllTypeRelating<'me, 'bccx, 'tcx> {
     type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
 
     /// Where (and why) is this relation taking place?
@@ -82,7 +82,7 @@ pub struct NllTypeRelating<'me, 'bccx, 'tcx> {
 }
 
 impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
-    pub fn new(
+    fn new(
         type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
         locations: Locations,
         category: ConstraintCategory<'tcx>,
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 1ad80cb122a..2e41c918774 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -39,7 +39,7 @@ use crate::renumber::RegionCtxt;
 use crate::BorrowckInferCtxt;
 
 #[derive(Debug)]
-pub struct UniversalRegions<'tcx> {
+pub(crate) struct UniversalRegions<'tcx> {
     indices: UniversalRegionIndices<'tcx>,
 
     /// The vid assigned to `'static`
@@ -95,7 +95,7 @@ pub struct UniversalRegions<'tcx> {
 /// regions appear free in the defining type and late-bound regions
 /// appear bound in the signature.
 #[derive(Copy, Clone, Debug)]
-pub enum DefiningTy<'tcx> {
+pub(crate) enum DefiningTy<'tcx> {
     /// The MIR is a closure. The signature is found via
     /// `ClosureArgs::closure_sig_ty`.
     Closure(DefId, GenericArgsRef<'tcx>),
@@ -131,7 +131,7 @@ impl<'tcx> DefiningTy<'tcx> {
     /// not a closure or coroutine, there are no upvars, and hence it
     /// will be an empty list. The order of types in this list will
     /// match up with the upvar order in the HIR, typesystem, and MIR.
-    pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
+    pub(crate) fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
         match self {
             DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
             DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
@@ -145,7 +145,7 @@ impl<'tcx> DefiningTy<'tcx> {
     /// Number of implicit inputs -- notably the "environment"
     /// parameter for closures -- that appear in MIR but not in the
     /// user's code.
-    pub fn implicit_inputs(self) -> usize {
+    pub(crate) fn implicit_inputs(self) -> usize {
         match self {
             DefiningTy::Closure(..)
             | DefiningTy::CoroutineClosure(..)
@@ -154,15 +154,15 @@ impl<'tcx> DefiningTy<'tcx> {
         }
     }
 
-    pub fn is_fn_def(&self) -> bool {
+    pub(crate) fn is_fn_def(&self) -> bool {
         matches!(*self, DefiningTy::FnDef(..))
     }
 
-    pub fn is_const(&self) -> bool {
+    pub(crate) fn is_const(&self) -> bool {
         matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..))
     }
 
-    pub fn def_id(&self) -> DefId {
+    pub(crate) fn def_id(&self) -> DefId {
         match *self {
             DefiningTy::Closure(def_id, ..)
             | DefiningTy::CoroutineClosure(def_id, ..)
@@ -196,7 +196,7 @@ struct UniversalRegionIndices<'tcx> {
 }
 
 #[derive(Debug, PartialEq)]
-pub enum RegionClassification {
+pub(crate) enum RegionClassification {
     /// A **global** region is one that can be named from
     /// anywhere. There is only one, `'static`.
     Global,
@@ -246,7 +246,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// MIR -- that is, all the regions that appear in the function's
     /// signature. This will also compute the relationships that are
     /// known between those regions.
-    pub fn new(
+    pub(crate) fn new(
         infcx: &BorrowckInferCtxt<'tcx>,
         mir_def: LocalDefId,
         param_env: ty::ParamEnv<'tcx>,
@@ -263,7 +263,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// if the `ClosureRegionRequirements` contains something like
     /// `'1: '2`, then the caller would impose the constraint that
     /// `V[1]: V[2]`.
-    pub fn closure_mapping(
+    pub(crate) fn closure_mapping(
         tcx: TyCtxt<'tcx>,
         closure_args: GenericArgsRef<'tcx>,
         expected_num_vars: usize,
@@ -289,13 +289,13 @@ impl<'tcx> UniversalRegions<'tcx> {
     }
 
     /// Returns `true` if `r` is a member of this set of universal regions.
-    pub fn is_universal_region(&self, r: RegionVid) -> bool {
+    pub(crate) fn is_universal_region(&self, r: RegionVid) -> bool {
         (FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index())
     }
 
     /// Classifies `r` as a universal region, returning `None` if this
     /// is not a member of this set of universal regions.
-    pub fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
+    pub(crate) fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
         let index = r.index();
         if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) {
             Some(RegionClassification::Global)
@@ -310,17 +310,17 @@ impl<'tcx> UniversalRegions<'tcx> {
 
     /// Returns an iterator over all the RegionVids corresponding to
     /// universally quantified free regions.
-    pub fn universal_regions(&self) -> impl Iterator<Item = RegionVid> {
+    pub(crate) fn universal_regions(&self) -> impl Iterator<Item = RegionVid> {
         (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
     }
 
     /// Returns `true` if `r` is classified as a local region.
-    pub fn is_local_free_region(&self, r: RegionVid) -> bool {
+    pub(crate) fn is_local_free_region(&self, r: RegionVid) -> bool {
         self.region_classification(r) == Some(RegionClassification::Local)
     }
 
     /// Returns the number of universal regions created in any category.
-    pub fn len(&self) -> usize {
+    pub(crate) fn len(&self) -> usize {
         self.num_universals
     }
 
@@ -329,19 +329,19 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// closure type (versus those bound in the closure
     /// signature). They are therefore the regions between which the
     /// closure may impose constraints that its creator must verify.
-    pub fn num_global_and_external_regions(&self) -> usize {
+    pub(crate) fn num_global_and_external_regions(&self) -> usize {
         self.first_local_index
     }
 
     /// Gets an iterator over all the early-bound regions that have names.
-    pub fn named_universal_regions<'s>(
+    pub(crate) fn named_universal_regions<'s>(
         &'s self,
     ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's {
         self.indices.indices.iter().map(|(&r, &v)| (r, v))
     }
 
     /// See `UniversalRegionIndices::to_region_vid`.
-    pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
+    pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         self.indices.to_region_vid(r)
     }
 
@@ -416,7 +416,7 @@ impl<'tcx> UniversalRegions<'tcx> {
         }
     }
 
-    pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
+    pub(crate) fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
         self.indices.tainted_by_errors.get()
     }
 }
@@ -880,7 +880,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// reference those regions from the `ParamEnv`. It is also used
     /// during initialization. Relies on the `indices` map having been
     /// fully initialized.
-    pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
+    fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         if let ty::ReVar(..) = *r {
             r.as_var()
         } else if let ty::ReError(guar) = *r {
@@ -899,7 +899,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
 
     /// Replaces all free regions in `value` with region vids, as
     /// returned by `to_region_vid`.
-    pub fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
+    fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
diff --git a/compiler/rustc_borrowck/src/util/collect_writes.rs b/compiler/rustc_borrowck/src/util/collect_writes.rs
index 93c7810b545..55f1073176a 100644
--- a/compiler/rustc_borrowck/src/util/collect_writes.rs
+++ b/compiler/rustc_borrowck/src/util/collect_writes.rs
@@ -1,7 +1,7 @@
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location};
 
-pub trait FindAssignments {
+pub(crate) trait FindAssignments {
     // Finds all statements that assign directly to local (i.e., X = ...)
     // and returns their locations.
     fn find_assignments(&self, local: Local) -> Vec<Location>;
diff --git a/compiler/rustc_borrowck/src/util/mod.rs b/compiler/rustc_borrowck/src/util/mod.rs
index 7377d4de727..5f2960b768b 100644
--- a/compiler/rustc_borrowck/src/util/mod.rs
+++ b/compiler/rustc_borrowck/src/util/mod.rs
@@ -1,3 +1,3 @@
 mod collect_writes;
 
-pub use collect_writes::FindAssignments;
+pub(crate) use collect_writes::FindAssignments;
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index c90a9164886..289e92a69b2 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -351,15 +351,15 @@ struct TypeParameter {
 pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
 
 impl BlockOrExpr {
-    pub fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
+    pub(crate) fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
         BlockOrExpr(stmts, None)
     }
 
-    pub fn new_expr(expr: P<Expr>) -> BlockOrExpr {
+    pub(crate) fn new_expr(expr: P<Expr>) -> BlockOrExpr {
         BlockOrExpr(ThinVec::new(), Some(expr))
     }
 
-    pub fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
+    pub(crate) fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr {
         BlockOrExpr(stmts, expr)
     }
 
@@ -461,7 +461,7 @@ fn find_type_parameters(
 }
 
 impl<'a> TraitDef<'a> {
-    pub fn expand(
+    pub(crate) fn expand(
         self,
         cx: &ExtCtxt<'_>,
         mitem: &ast::MetaItem,
@@ -471,7 +471,7 @@ impl<'a> TraitDef<'a> {
         self.expand_ext(cx, mitem, item, push, false);
     }
 
-    pub fn expand_ext(
+    pub(crate) fn expand_ext(
         self,
         cx: &ExtCtxt<'_>,
         mitem: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 747da2ee43b..42855e255a8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -27,17 +27,17 @@ pub(crate) enum PathKind {
 }
 
 impl Path {
-    pub fn new(path: Vec<Symbol>) -> Path {
+    pub(crate) fn new(path: Vec<Symbol>) -> Path {
         Path::new_(path, Vec::new(), PathKind::Std)
     }
-    pub fn new_local(path: Symbol) -> Path {
+    pub(crate) fn new_local(path: Symbol) -> Path {
         Path::new_(vec![path], Vec::new(), PathKind::Local)
     }
-    pub fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
+    pub(crate) fn new_(path: Vec<Symbol>, params: Vec<Box<Ty>>, kind: PathKind) -> Path {
         Path { path, params, kind }
     }
 
-    pub fn to_ty(
+    pub(crate) fn to_ty(
         &self,
         cx: &ExtCtxt<'_>,
         span: Span,
@@ -46,7 +46,7 @@ impl Path {
     ) -> P<ast::Ty> {
         cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
     }
-    pub fn to_path(
+    pub(crate) fn to_path(
         &self,
         cx: &ExtCtxt<'_>,
         span: Span,
@@ -87,7 +87,7 @@ pub(crate) fn self_ref() -> Ty {
 }
 
 impl Ty {
-    pub fn to_ty(
+    pub(crate) fn to_ty(
         &self,
         cx: &ExtCtxt<'_>,
         span: Span,
@@ -108,7 +108,7 @@ impl Ty {
         }
     }
 
-    pub fn to_path(
+    pub(crate) fn to_path(
         &self,
         cx: &ExtCtxt<'_>,
         span: Span,
@@ -167,10 +167,10 @@ pub(crate) struct Bounds {
 }
 
 impl Bounds {
-    pub fn empty() -> Bounds {
+    pub(crate) fn empty() -> Bounds {
         Bounds { bounds: Vec::new() }
     }
-    pub fn to_generics(
+    pub(crate) fn to_generics(
         &self,
         cx: &ExtCtxt<'_>,
         span: Span,
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index 7eb1f17a59c..c88c5bd35a5 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -18,7 +18,7 @@ macro_rules! path {
     ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
 }
 
-pub fn expand_deriving_smart_ptr(
+pub(crate) fn expand_deriving_smart_ptr(
     cx: &ExtCtxt<'_>,
     span: Span,
     _mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 6ca43441e05..4fffffb91c8 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -930,7 +930,7 @@ pub(crate) struct ExpectedItem<'a> {
 
 #[derive(Diagnostic)]
 #[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
-pub struct NakedFunctionTestingAttribute {
+pub(crate) struct NakedFunctionTestingAttribute {
     #[primary_span]
     #[label(builtin_macros_naked_attribute)]
     pub naked_span: Span,
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index b52f606f342..866ec72f116 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -5,7 +5,7 @@ pub(crate) mod printf {
 
     /// Represents a single `printf`-style substitution.
     #[derive(Clone, PartialEq, Debug)]
-    pub enum Substitution<'a> {
+    pub(crate) enum Substitution<'a> {
         /// A formatted output substitution with its internal byte offset.
         Format(Format<'a>),
         /// A literal `%%` escape, with its start and end indices.
@@ -13,21 +13,21 @@ pub(crate) mod printf {
     }
 
     impl<'a> Substitution<'a> {
-        pub fn as_str(&self) -> &str {
+        pub(crate) fn as_str(&self) -> &str {
             match self {
                 Substitution::Format(fmt) => fmt.span,
                 Substitution::Escape(_) => "%%",
             }
         }
 
-        pub fn position(&self) -> InnerSpan {
+        pub(crate) fn position(&self) -> InnerSpan {
             match self {
                 Substitution::Format(fmt) => fmt.position,
                 &Substitution::Escape((start, end)) => InnerSpan::new(start, end),
             }
         }
 
-        pub fn set_position(&mut self, start: usize, end: usize) {
+        pub(crate) fn set_position(&mut self, start: usize, end: usize) {
             match self {
                 Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end),
                 Substitution::Escape(pos) => *pos = (start, end),
@@ -38,7 +38,7 @@ pub(crate) mod printf {
         ///
         /// This ignores cases where the substitution does not have an exact equivalent, or where
         /// the substitution would be unnecessary.
-        pub fn translate(&self) -> Result<String, Option<String>> {
+        pub(crate) fn translate(&self) -> Result<String, Option<String>> {
             match self {
                 Substitution::Format(fmt) => fmt.translate(),
                 Substitution::Escape(_) => Err(None),
@@ -48,23 +48,23 @@ pub(crate) mod printf {
 
     #[derive(Clone, PartialEq, Debug)]
     /// A single `printf`-style formatting directive.
-    pub struct Format<'a> {
+    pub(crate) struct Format<'a> {
         /// The entire original formatting directive.
-        pub span: &'a str,
+        span: &'a str,
         /// The (1-based) parameter to be converted.
-        pub parameter: Option<u16>,
+        parameter: Option<u16>,
         /// Formatting flags.
-        pub flags: &'a str,
+        flags: &'a str,
         /// Minimum width of the output.
-        pub width: Option<Num>,
+        width: Option<Num>,
         /// Precision of the conversion.
-        pub precision: Option<Num>,
+        precision: Option<Num>,
         /// Length modifier for the conversion.
-        pub length: Option<&'a str>,
+        length: Option<&'a str>,
         /// Type of parameter being converted.
-        pub type_: &'a str,
+        type_: &'a str,
         /// Byte offset for the start and end of this formatting directive.
-        pub position: InnerSpan,
+        position: InnerSpan,
     }
 
     impl Format<'_> {
@@ -72,7 +72,7 @@ pub(crate) mod printf {
         ///
         /// Returns `Err` in cases where the `printf` directive does not have an exact Rust
         /// equivalent, rather than guessing.
-        pub fn translate(&self) -> Result<String, Option<String>> {
+        pub(crate) fn translate(&self) -> Result<String, Option<String>> {
             use std::fmt::Write;
 
             let (c_alt, c_zero, c_left, c_plus) = {
@@ -249,7 +249,7 @@ pub(crate) mod printf {
 
     /// A general number used in a `printf` formatting directive.
     #[derive(Copy, Clone, PartialEq, Debug)]
-    pub enum Num {
+    enum Num {
         // The range of these values is technically bounded by `NL_ARGMAX`... but, at least for GNU
         // libc, it apparently has no real fixed limit. A `u16` is used here on the basis that it
         // is *vanishingly* unlikely that *anyone* is going to try formatting something wider, or
@@ -288,12 +288,12 @@ pub(crate) mod printf {
     }
 
     /// Returns an iterator over all substitutions in a given string.
-    pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
+    pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
         Substitutions { s, pos: start_pos }
     }
 
     /// Iterator over substitutions in a string.
-    pub struct Substitutions<'a> {
+    pub(crate) struct Substitutions<'a> {
         s: &'a str,
         pos: usize,
     }
@@ -327,7 +327,7 @@ pub(crate) mod printf {
     }
 
     /// Parse the next substitution from the input string.
-    pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
+    fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
         use self::State::*;
 
         let at = {
@@ -615,20 +615,20 @@ pub(crate) mod printf {
     mod tests;
 }
 
-pub mod shell {
+pub(crate) mod shell {
     use rustc_span::InnerSpan;
 
     use super::strcursor::StrCursor as Cur;
 
     #[derive(Clone, PartialEq, Debug)]
-    pub enum Substitution<'a> {
+    pub(crate) enum Substitution<'a> {
         Ordinal(u8, (usize, usize)),
         Name(&'a str, (usize, usize)),
         Escape((usize, usize)),
     }
 
     impl Substitution<'_> {
-        pub fn as_str(&self) -> String {
+        pub(crate) fn as_str(&self) -> String {
             match self {
                 Substitution::Ordinal(n, _) => format!("${n}"),
                 Substitution::Name(n, _) => format!("${n}"),
@@ -636,17 +636,17 @@ pub mod shell {
             }
         }
 
-        pub fn position(&self) -> InnerSpan {
+        pub(crate) fn position(&self) -> InnerSpan {
             let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
             InnerSpan::new(pos.0, pos.1)
         }
 
-        pub fn set_position(&mut self, start: usize, end: usize) {
+        fn set_position(&mut self, start: usize, end: usize) {
             let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
             *pos = (start, end);
         }
 
-        pub fn translate(&self) -> Result<String, Option<String>> {
+        pub(crate) fn translate(&self) -> Result<String, Option<String>> {
             match self {
                 Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
                 Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
@@ -656,12 +656,12 @@ pub mod shell {
     }
 
     /// Returns an iterator over all substitutions in a given string.
-    pub fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
+    pub(crate) fn iter_subs(s: &str, start_pos: usize) -> Substitutions<'_> {
         Substitutions { s, pos: start_pos }
     }
 
     /// Iterator over substitutions in a string.
-    pub struct Substitutions<'a> {
+    pub(crate) struct Substitutions<'a> {
         s: &'a str,
         pos: usize,
     }
@@ -683,7 +683,7 @@ pub mod shell {
     }
 
     /// Parse the next substitution from the input string.
-    pub fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
+    fn parse_next_substitution(s: &str) -> Option<(Substitution<'_>, &str)> {
         let at = {
             let start = s.find('$')?;
             match s[start + 1..].chars().next()? {
@@ -743,24 +743,24 @@ pub mod shell {
 }
 
 mod strcursor {
-    pub struct StrCursor<'a> {
+    pub(crate) struct StrCursor<'a> {
         s: &'a str,
         pub at: usize,
     }
 
     impl<'a> StrCursor<'a> {
-        pub fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
+        pub(crate) fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
             StrCursor { s, at }
         }
 
-        pub fn at_next_cp(mut self) -> Option<StrCursor<'a>> {
+        pub(crate) fn at_next_cp(mut self) -> Option<StrCursor<'a>> {
             match self.try_seek_right_cp() {
                 true => Some(self),
                 false => None,
             }
         }
 
-        pub fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> {
+        pub(crate) fn next_cp(mut self) -> Option<(char, StrCursor<'a>)> {
             let cp = self.cp_after()?;
             self.seek_right(cp.len_utf8());
             Some((cp, self))
@@ -770,11 +770,11 @@ mod strcursor {
             &self.s[0..self.at]
         }
 
-        pub fn slice_after(&self) -> &'a str {
+        pub(crate) fn slice_after(&self) -> &'a str {
             &self.s[self.at..]
         }
 
-        pub fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> {
+        pub(crate) fn slice_between(&self, until: StrCursor<'a>) -> Option<&'a str> {
             if !str_eq_literal(self.s, until.s) {
                 None
             } else {
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index a9ba7334d93..30e1c8d2622 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -16,6 +16,7 @@
 #![feature(proc_macro_quote)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate proc_macro;
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index ca910dccb0d..604a88393fd 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -191,6 +191,14 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                     })
                     .try_into()
                     .unwrap(),
+                _ if idx_ty.is_simd()
+                    && matches!(
+                        idx_ty.simd_size_and_type(fx.tcx).1.kind(),
+                        ty::Uint(ty::UintTy::U32)
+                    ) =>
+                {
+                    idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
+                }
                 _ => {
                     fx.tcx.dcx().span_err(
                         span,
@@ -213,6 +221,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
 
             let total_len = lane_count * 2;
 
+            // FIXME: this is a terrible abstraction-breaking hack.
+            // Find a way to reuse `immediate_const_vector` from `codegen_ssa` instead.
             let indexes = {
                 use rustc_middle::mir::interpret::*;
                 let idx_const = match &idx.node {
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 47b378cc1cd..6ba678e2e7c 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1923,15 +1923,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         v2: RValue<'gcc>,
         mask: RValue<'gcc>,
     ) -> RValue<'gcc> {
-        let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
-
         // TODO(antoyo): use a recursive unqualified() here.
         let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type");
         let element_type = vector_type.get_element_type();
         let vec_num_units = vector_type.get_num_units();
 
-        let mask_num_units = struct_type.get_field_count();
-        let mut vector_elements = vec![];
         let mask_element_type = if element_type.is_integral() {
             element_type
         } else {
@@ -1942,19 +1938,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             #[cfg(not(feature = "master"))]
             self.int_type
         };
-        for i in 0..mask_num_units {
-            let field = struct_type.get_field(i as i32);
-            vector_elements.push(self.context.new_cast(
-                self.location,
-                mask.access_field(self.location, field).to_rvalue(),
-                mask_element_type,
-            ));
-        }
+
+        let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
+            let mask_num_units = vector_type.get_num_units();
+            let mut mask_elements = vec![];
+            for i in 0..mask_num_units {
+                let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
+                mask_elements.push(self.context.new_cast(
+                    self.location,
+                    self.extract_element(mask, index).to_rvalue(),
+                    mask_element_type,
+                ));
+            }
+            mask_elements
+        } else {
+            let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
+            let mask_num_units = struct_type.get_field_count();
+            let mut mask_elements = vec![];
+            for i in 0..mask_num_units {
+                let field = struct_type.get_field(i as i32);
+                mask_elements.push(self.context.new_cast(
+                    self.location,
+                    mask.access_field(self.location, field).to_rvalue(),
+                    mask_element_type,
+                ));
+            }
+            mask_elements
+        };
+        let mask_num_units = mask_elements.len();
 
         // NOTE: the mask needs to be the same length as the input vectors, so add the missing
         // elements in the mask if needed.
         for _ in mask_num_units..vec_num_units {
-            vector_elements.push(self.context.new_rvalue_zero(mask_element_type));
+            mask_elements.push(self.context.new_rvalue_zero(mask_element_type));
         }
 
         let result_type = self.context.new_vector_type(element_type, mask_num_units as u64);
@@ -1998,7 +2014,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
 
         let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units);
         let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64);
-        let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements);
+        let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &mask_elements);
         let result = self.context.new_rvalue_vector_perm(self.location, v1, v2, mask);
 
         if vec_num_units != mask_num_units {
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 8da1df3be15..96a833ccaf2 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -353,19 +353,24 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
     }
 
     if name == sym::simd_shuffle {
-        // Make sure this is actually an array, since typeck only checks the length-suffixed
+        // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
         // version of this intrinsic.
-        let n: u64 = match *args[2].layout.ty.kind() {
+        let idx_ty = args[2].layout.ty;
+        let n: u64 = match idx_ty.kind() {
             ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => {
                 len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
                     || span_bug!(span, "could not evaluate shuffle index array length"),
                 )
             }
-            _ => return_error!(InvalidMonomorphization::SimdShuffle {
-                span,
-                name,
-                ty: args[2].layout.ty
-            }),
+            _ if idx_ty.is_simd()
+                && matches!(
+                    idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
+                    ty::Uint(ty::UintTy::U32)
+                ) =>
+            {
+                idx_ty.simd_size_and_type(bx.cx.tcx).0
+            }
+            _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
         };
         require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
 
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 5ff580e295a..dea574a53cd 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -6,13 +6,13 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::MemFlags;
 use rustc_middle::ty::layout::LayoutOf;
-pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
+pub(crate) use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use rustc_middle::ty::Ty;
 use rustc_middle::{bug, ty};
 use rustc_session::config;
-pub use rustc_target::abi::call::*;
+pub(crate) use rustc_target::abi::call::*;
 use rustc_target::abi::{self, HasDataLayout, Int, Size};
-pub use rustc_target::spec::abi::Abi;
+pub(crate) use rustc_target::spec::abi::Abi;
 use rustc_target::spec::SanitizerSet;
 use smallvec::SmallVec;
 
@@ -25,7 +25,7 @@ use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use crate::{attributes, llvm_util};
 
-pub trait ArgAttributesExt {
+trait ArgAttributesExt {
     fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
     fn apply_attrs_to_callsite(
         &self,
@@ -111,7 +111,7 @@ impl ArgAttributesExt for ArgAttributes {
     }
 }
 
-pub trait LlvmType {
+pub(crate) trait LlvmType {
     fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
 }
 
@@ -171,7 +171,7 @@ impl LlvmType for CastTarget {
     }
 }
 
-pub trait ArgAbiExt<'ll, 'tcx> {
+trait ArgAbiExt<'ll, 'tcx> {
     fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
     fn store(
         &self,
@@ -307,7 +307,7 @@ impl<'ll, 'tcx> ArgAbiMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 }
 
-pub trait FnAbiLlvmExt<'ll, 'tcx> {
+pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
     fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
     fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
     fn llvm_cconv(&self) -> llvm::CallConv;
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index f931698c38f..1d91c3fb17d 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -913,8 +913,10 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
         Primitive::Int(Integer::I16, _) => cx.type_i16(),
         Primitive::Int(Integer::I32, _) => cx.type_i32(),
         Primitive::Int(Integer::I64, _) => cx.type_i64(),
+        Primitive::Float(Float::F16) => cx.type_f16(),
         Primitive::Float(Float::F32) => cx.type_f32(),
         Primitive::Float(Float::F64) => cx.type_f64(),
+        Primitive::Float(Float::F128) => cx.type_f128(),
         // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
         Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
         _ => unreachable!(),
@@ -948,7 +950,9 @@ fn llvm_fixup_input<'ll, 'tcx>(
                 value
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
+        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+            if s.primitive() != Primitive::Float(Float::F128) =>
+        {
             let elem_ty = llvm_asm_scalar_type(bx.cx, s);
             let count = 16 / layout.size.bytes();
             let vec_ty = bx.cx.type_vector(elem_ty, count);
@@ -1090,7 +1094,9 @@ fn llvm_fixup_output<'ll, 'tcx>(
                 value
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
+        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+            if s.primitive() != Primitive::Float(Float::F128) =>
+        {
             value = bx.extract_element(value, bx.const_i32(0));
             if let Primitive::Pointer(_) = s.primitive() {
                 value = bx.inttoptr(value, layout.llvm_type(bx.cx));
@@ -1222,7 +1228,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
                 layout.llvm_type(cx)
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
+        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+            if s.primitive() != Primitive::Float(Float::F128) =>
+        {
             let elem_ty = llvm_asm_scalar_type(cx, s);
             let count = 16 / layout.size.bytes();
             cx.type_vector(elem_ty, count)
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index fde95104093..317e970d704 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -1,6 +1,6 @@
 //! Set and unset common attributes on LLVM values.
 
-pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
+use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_codegen_ssa::traits::*;
 use rustc_hir::def_id::DefId;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
@@ -17,13 +17,13 @@ use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace
 use crate::value::Value;
 use crate::{attributes, llvm_util};
 
-pub fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
+pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
     if !attrs.is_empty() {
         llvm::AddFunctionAttributes(llfn, idx, attrs);
     }
 }
 
-pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
+pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attribute]) {
     if !attrs.is_empty() {
         llvm::AddCallSiteAttributes(callsite, idx, attrs);
     }
@@ -80,7 +80,7 @@ fn patchable_function_entry_attrs<'ll>(
 
 /// Get LLVM sanitize attributes.
 #[inline]
-pub fn sanitize_attrs<'ll>(
+pub(crate) fn sanitize_attrs<'ll>(
     cx: &CodegenCx<'ll, '_>,
     no_sanitize: SanitizerSet,
 ) -> SmallVec<[&'ll Attribute; 4]> {
@@ -120,7 +120,7 @@ pub fn sanitize_attrs<'ll>(
 
 /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
 #[inline]
-pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute {
+pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Attribute {
     // NOTE: We should determine if we even need async unwind tables, as they
     // take have more overhead and if we can use sync unwind tables we
     // probably should.
@@ -128,7 +128,7 @@ pub fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>) -> &Att
     llvm::CreateUWTableAttr(llcx, async_unwind)
 }
 
-pub fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
+pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
     let mut fp = cx.sess().target.frame_pointer;
     let opts = &cx.sess().opts;
     // "mcount" function relies on stack pointer.
@@ -280,19 +280,19 @@ fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
     if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None }
 }
 
-pub fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute {
+pub(crate) fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute {
     let target_cpu = llvm_util::target_cpu(cx.tcx.sess);
     llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
 }
 
-pub fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
+pub(crate) fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
     llvm_util::tune_cpu(cx.tcx.sess)
         .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu))
 }
 
 /// Get the `NonLazyBind` LLVM attribute,
 /// if the codegen options allow skipping the PLT.
-pub fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
+pub(crate) fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
     // Don't generate calls through PLT if it's not necessary
     if !cx.sess().needs_plt() {
         Some(AttributeKind::NonLazyBind.create_attr(cx.llcx))
@@ -327,7 +327,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
 /// Helper for `FnAbi::apply_attrs_llfn`:
 /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
 /// attributes.
-pub fn llfn_attrs_from_instance<'ll, 'tcx>(
+pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     llfn: &'ll Value,
     instance: ty::Instance<'tcx>,
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index c0ec4f86b4d..4f2c83634a8 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -86,7 +86,7 @@ impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> {
     }
 }
 
-pub struct LlvmArchiveBuilderBuilder;
+pub(crate) struct LlvmArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index aac446f3149..aa6842c75ce 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -33,9 +33,9 @@ use crate::{LlvmCodegenBackend, ModuleLlvm};
 
 /// We keep track of the computed LTO cache keys from the previous
 /// session to determine which CGUs we can reuse.
-pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
+const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
 
-pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
+fn crate_type_allows_lto(crate_type: CrateType) -> bool {
     match crate_type {
         CrateType::Executable
         | CrateType::Dylib
@@ -710,7 +710,7 @@ impl Drop for ThinBuffer {
     }
 }
 
-pub unsafe fn optimize_thin_module(
+pub(crate) unsafe fn optimize_thin_module(
     thin_module: ThinModule<LlvmCodegenBackend>,
     cgcx: &CodegenContext<LlvmCodegenBackend>,
 ) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
@@ -806,7 +806,7 @@ pub unsafe fn optimize_thin_module(
 
 /// Maps LLVM module identifiers to their corresponding LLVM LTO cache keys
 #[derive(Debug, Default)]
-pub struct ThinLTOKeysMap {
+struct ThinLTOKeysMap {
     // key = llvm name of importing module, value = LLVM cache key
     keys: BTreeMap<String, String>,
 }
@@ -863,7 +863,7 @@ fn module_name_to_str(c_str: &CStr) -> &str {
     })
 }
 
-pub fn parse_module<'a>(
+pub(crate) fn parse_module<'a>(
     cx: &'a llvm::Context,
     name: &CStr,
     data: &[u8],
diff --git a/compiler/rustc_codegen_llvm/src/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs
index 26fb4a96f84..79794775b7b 100644
--- a/compiler/rustc_codegen_llvm/src/back/profiling.rs
+++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs
@@ -21,14 +21,14 @@ fn llvm_args_to_string_id(profiler: &SelfProfiler, pass_name: &str, ir_name: &st
     EventId::from_label(profiler.alloc_string(components.as_slice()))
 }
 
-pub struct LlvmSelfProfiler<'a> {
+pub(crate) struct LlvmSelfProfiler<'a> {
     profiler: Arc<SelfProfiler>,
     stack: Vec<TimingGuard<'a>>,
     llvm_pass_event_kind: StringId,
 }
 
 impl<'a> LlvmSelfProfiler<'a> {
-    pub fn new(profiler: Arc<SelfProfiler>) -> Self {
+    pub(crate) fn new(profiler: Arc<SelfProfiler>) -> Self {
         let llvm_pass_event_kind = profiler.alloc_string("LLVM Pass");
         Self { profiler, stack: Vec::default(), llvm_pass_event_kind }
     }
@@ -43,7 +43,7 @@ impl<'a> LlvmSelfProfiler<'a> {
     }
 }
 
-pub unsafe extern "C" fn selfprofile_before_pass_callback(
+pub(crate) unsafe extern "C" fn selfprofile_before_pass_callback(
     llvm_self_profiler: *mut c_void,
     pass_name: *const c_char,
     ir_name: *const c_char,
@@ -56,7 +56,7 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback(
     }
 }
 
-pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
+pub(crate) unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
     let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
     llvm_self_profiler.after_pass_callback();
 }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 51b02891d02..adf7e933f43 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -43,14 +43,14 @@ use crate::llvm::{self, DiagnosticInfo, PassManager};
 use crate::type_::Type;
 use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
 
-pub fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError {
+pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> FatalError {
     match llvm::last_error() {
         Some(llvm_err) => dcx.emit_almost_fatal(WithLlvmError(err, llvm_err)),
         None => dcx.emit_almost_fatal(err),
     }
 }
 
-pub fn write_output_file<'ll>(
+fn write_output_file<'ll>(
     dcx: DiagCtxtHandle<'_>,
     target: &'ll llvm::TargetMachine,
     pm: &llvm::PassManager<'ll>,
@@ -95,7 +95,7 @@ pub fn write_output_file<'ll>(
     }
 }
 
-pub fn create_informational_target_machine(
+pub(crate) fn create_informational_target_machine(
     sess: &Session,
     only_base_features: bool,
 ) -> OwnedTargetMachine {
@@ -107,7 +107,7 @@ pub fn create_informational_target_machine(
         .unwrap_or_else(|err| llvm_err(sess.dcx(), err).raise())
 }
 
-pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
+pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
     let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
         tcx.output_filenames(()).split_dwarf_path(
             tcx.sess.split_debuginfo(),
@@ -130,9 +130,7 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMach
     .unwrap_or_else(|err| llvm_err(tcx.dcx(), err).raise())
 }
 
-pub fn to_llvm_opt_settings(
-    cfg: config::OptLevel,
-) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) {
+fn to_llvm_opt_settings(cfg: config::OptLevel) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) {
     use self::config::OptLevel::*;
     match cfg {
         No => (llvm::CodeGenOptLevel::None, llvm::CodeGenOptSizeNone),
@@ -179,7 +177,7 @@ pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeMod
     }
 }
 
-pub fn target_machine_factory(
+pub(crate) fn target_machine_factory(
     sess: &Session,
     optlvl: config::OptLevel,
     target_features: &[String],
@@ -320,7 +318,7 @@ pub(crate) fn save_temp_bitcode(
 }
 
 /// In what context is a dignostic handler being attached to a codegen unit?
-pub enum CodegenDiagnosticsStage {
+pub(crate) enum CodegenDiagnosticsStage {
     /// Prelink optimization stage.
     Opt,
     /// LTO/ThinLTO postlink optimization stage.
@@ -329,14 +327,14 @@ pub enum CodegenDiagnosticsStage {
     Codegen,
 }
 
-pub struct DiagnosticHandlers<'a> {
+pub(crate) struct DiagnosticHandlers<'a> {
     data: *mut (&'a CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'a>),
     llcx: &'a llvm::Context,
     old_handler: Option<&'a llvm::DiagnosticHandler>,
 }
 
 impl<'a> DiagnosticHandlers<'a> {
-    pub fn new(
+    pub(crate) fn new(
         cgcx: &'a CodegenContext<LlvmCodegenBackend>,
         dcx: DiagCtxtHandle<'a>,
         llcx: &'a llvm::Context,
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index e8236b45c89..0ba8d82406a 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -32,7 +32,7 @@ use crate::context::CodegenCx;
 use crate::value::Value;
 use crate::{attributes, llvm};
 
-pub struct ValueIter<'ll> {
+pub(crate) struct ValueIter<'ll> {
     cur: Option<&'ll Value>,
     step: unsafe extern "C" fn(&'ll Value) -> Option<&'ll Value>,
 }
@@ -49,11 +49,14 @@ impl<'ll> Iterator for ValueIter<'ll> {
     }
 }
 
-pub fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> {
+pub(crate) fn iter_globals(llmod: &llvm::Module) -> ValueIter<'_> {
     unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } }
 }
 
-pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen<ModuleLlvm>, u64) {
+pub(crate) fn compile_codegen_unit(
+    tcx: TyCtxt<'_>,
+    cgu_name: Symbol,
+) -> (ModuleCodegen<ModuleLlvm>, u64) {
     let start_time = Instant::now();
 
     let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
@@ -140,7 +143,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
     (module, cost)
 }
 
-pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
+pub(crate) fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
     let Some(sect) = attrs.link_section else { return };
     unsafe {
         let buf = SmallCStr::new(sect.as_str());
@@ -148,7 +151,7 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
     }
 }
 
-pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
+pub(crate) fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
     match linkage {
         Linkage::External => llvm::Linkage::ExternalLinkage,
         Linkage::AvailableExternally => llvm::Linkage::AvailableExternallyLinkage,
@@ -164,7 +167,7 @@ pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
     }
 }
 
-pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
+pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
     match linkage {
         Visibility::Default => llvm::Visibility::Default,
         Visibility::Hidden => llvm::Visibility::Hidden,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index cc081f29e12..40783825cae 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -36,7 +36,7 @@ use crate::{attributes, llvm_util};
 
 // All Builders must have an llfn associated with them
 #[must_use]
-pub struct Builder<'a, 'll, 'tcx> {
+pub(crate) struct Builder<'a, 'll, 'tcx> {
     pub llbuilder: &'ll mut llvm::Builder<'ll>,
     pub cx: &'a CodegenCx<'ll, 'tcx>,
 }
@@ -1343,7 +1343,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         Builder { llbuilder, cx }
     }
 
-    pub fn llfn(&self) -> &'ll Value {
+    pub(crate) fn llfn(&self) -> &'ll Value {
         unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
     }
 
@@ -1375,7 +1375,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         }
     }
 
-    pub fn set_unpredictable(&mut self, inst: &'ll Value) {
+    pub(crate) fn set_unpredictable(&mut self, inst: &'ll Value) {
         unsafe {
             llvm::LLVMSetMetadata(
                 inst,
@@ -1385,15 +1385,15 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         }
     }
 
-    pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+    pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
     }
 
-    pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+    pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
     }
 
-    pub fn insert_element(
+    pub(crate) fn insert_element(
         &mut self,
         vec: &'ll Value,
         elt: &'ll Value,
@@ -1402,7 +1402,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) }
     }
 
-    pub fn shuffle_vector(
+    pub(crate) fn shuffle_vector(
         &mut self,
         v1: &'ll Value,
         v2: &'ll Value,
@@ -1411,65 +1411,77 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) }
     }
 
-    pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
     }
-    pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
     }
-    pub fn vector_reduce_fadd_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fadd_reassoc(
+        &mut self,
+        acc: &'ll Value,
+        src: &'ll Value,
+    ) -> &'ll Value {
         unsafe {
             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
             llvm::LLVMRustSetAllowReassoc(instr);
             instr
         }
     }
-    pub fn vector_reduce_fmul_reassoc(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fmul_reassoc(
+        &mut self,
+        acc: &'ll Value,
+        src: &'ll Value,
+    ) -> &'ll Value {
         unsafe {
             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
             llvm::LLVMRustSetAllowReassoc(instr);
             instr
         }
     }
-    pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
     }
-    pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
     }
-    pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
     }
-    pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
     }
-    pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
     }
-    pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe {
             llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false)
         }
     }
-    pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
+    pub(crate) fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
         unsafe {
             llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false)
         }
     }
-    pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
+    pub(crate) fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
     }
-    pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
+    pub(crate) fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
         unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
     }
 
-    pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
+    pub(crate) fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
         unsafe {
             llvm::LLVMAddClause(landing_pad, clause);
         }
     }
 
-    pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
+    pub(crate) fn catch_ret(
+        &mut self,
+        funclet: &Funclet<'ll>,
+        unwind: &'ll BasicBlock,
+    ) -> &'ll Value {
         let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
         ret.expect("LLVM does not have support for catchret")
     }
@@ -1515,7 +1527,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         Cow::Owned(casted_args)
     }
 
-    pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
+    pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 663c5be46e5..949fd1bc124 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -20,7 +20,7 @@ use crate::value::Value;
 ///
 /// - `cx`: the crate context
 /// - `instance`: the instance to be instantiated
-pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
+pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
     let tcx = cx.tcx();
 
     debug!("get_fn(instance={:?})", instance);
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index a3997900184..ef6560ecbe5 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -13,7 +13,7 @@ use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer};
 use tracing::debug;
 
 use crate::consts::const_alloc_to_llvm;
-pub use crate::context::CodegenCx;
+pub(crate) use crate::context::CodegenCx;
 use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True};
 use crate::type_::Type;
 use crate::value::Value;
@@ -58,21 +58,21 @@ use crate::value::Value;
 /// When inside of a landing pad, each function call in LLVM IR needs to be
 /// annotated with which landing pad it's a part of. This is accomplished via
 /// the `OperandBundleDef` value created for MSVC landing pads.
-pub struct Funclet<'ll> {
+pub(crate) struct Funclet<'ll> {
     cleanuppad: &'ll Value,
     operand: OperandBundleDef<'ll>,
 }
 
 impl<'ll> Funclet<'ll> {
-    pub fn new(cleanuppad: &'ll Value) -> Self {
+    pub(crate) fn new(cleanuppad: &'ll Value) -> Self {
         Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]) }
     }
 
-    pub fn cleanuppad(&self) -> &'ll Value {
+    pub(crate) fn cleanuppad(&self) -> &'ll Value {
         self.cleanuppad
     }
 
-    pub fn bundle(&self) -> &OperandBundleDef<'ll> {
+    pub(crate) fn bundle(&self) -> &OperandBundleDef<'ll> {
         &self.operand
     }
 }
@@ -92,16 +92,16 @@ impl<'ll> BackendTypes for CodegenCx<'ll, '_> {
 }
 
 impl<'ll> CodegenCx<'ll, '_> {
-    pub fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
+    pub(crate) fn const_array(&self, ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
         let len = u64::try_from(elts.len()).expect("LLVMConstArray2 elements len overflow");
         unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
     }
 
-    pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
+    pub(crate) fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
         bytes_in_context(self.llcx, bytes)
     }
 
-    pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
+    pub(crate) fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
         unsafe {
             let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow");
             let r = llvm::LLVMGetAggregateElement(v, idx).unwrap();
@@ -339,18 +339,18 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 }
 
 /// Get the [LLVM type][Type] of a [`Value`].
-pub fn val_ty(v: &Value) -> &Type {
+pub(crate) fn val_ty(v: &Value) -> &Type {
     unsafe { llvm::LLVMTypeOf(v) }
 }
 
-pub fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
+pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
     unsafe {
         let ptr = bytes.as_ptr() as *const c_char;
         llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), True)
     }
 }
 
-pub fn struct_in_context<'ll>(
+fn struct_in_context<'ll>(
     llcx: &'ll llvm::Context,
     elts: &[&'ll Value],
     packed: bool,
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index a764b263ec7..b143e28c5f9 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -29,7 +29,7 @@ use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 use crate::{base, debuginfo};
 
-pub fn const_alloc_to_llvm<'ll>(
+pub(crate) fn const_alloc_to_llvm<'ll>(
     cx: &CodegenCx<'ll, '_>,
     alloc: ConstAllocation<'_>,
     is_static: bool,
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index fe71b2e669e..01aae24ab56 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -40,7 +40,7 @@ use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
 /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
 /// `llvm::Context` so that several compilation units may be optimized in parallel.
 /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
-pub struct CodegenCx<'ll, 'tcx> {
+pub(crate) struct CodegenCx<'ll, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
     pub use_dll_storage_attrs: bool,
     pub tls_model: llvm::ThreadLocalMode,
@@ -111,7 +111,7 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
     }
 }
 
-pub unsafe fn create_module<'ll>(
+pub(crate) unsafe fn create_module<'ll>(
     tcx: TyCtxt<'_>,
     llcx: &'ll llvm::Context,
     mod_name: &str,
@@ -562,7 +562,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     }
 
     #[inline]
-    pub fn coverage_context(&self) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
+    pub(crate) fn coverage_context(
+        &self,
+    ) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
         self.coverage_cx.as_ref()
     }
 
@@ -1097,7 +1099,7 @@ impl<'ll> CodegenCx<'ll, '_> {
 impl CodegenCx<'_, '_> {
     /// Generates a new symbol name with the given prefix. This symbol name must
     /// only be used for definitions with `internal` or `private` linkage.
-    pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
+    pub(crate) fn generate_local_symbol_name(&self, prefix: &str) -> String {
         let idx = self.local_gen_sym_counter.get();
         self.local_gen_sym_counter.set(idx + 1);
         // Include a '.' character, so there can be no accidental conflicts with
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
index 584d033d6bd..cabdd310d1f 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -80,7 +80,7 @@ pub struct CounterExpression {
 /// Must match the layout of `LLVMRustCounterMappingRegionKind`.
 #[derive(Copy, Clone, Debug)]
 #[repr(C)]
-pub enum RegionKind {
+enum RegionKind {
     /// A CodeRegion associates some code with a counter
     CodeRegion = 0,
 
@@ -110,13 +110,13 @@ pub enum RegionKind {
     MCDCBranchRegion = 6,
 }
 
-pub mod mcdc {
+mod mcdc {
     use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo};
 
     /// Must match the layout of `LLVMRustMCDCDecisionParameters`.
     #[repr(C)]
     #[derive(Clone, Copy, Debug, Default)]
-    pub struct DecisionParameters {
+    pub(crate) struct DecisionParameters {
         bitmap_idx: u32,
         num_conditions: u16,
     }
@@ -127,14 +127,14 @@ pub mod mcdc {
     /// Must match the layout of `LLVMRustMCDCBranchParameters`.
     #[repr(C)]
     #[derive(Clone, Copy, Debug, Default)]
-    pub struct BranchParameters {
+    pub(crate) struct BranchParameters {
         condition_id: LLVMConditionId,
         condition_ids: [LLVMConditionId; 2],
     }
 
     #[repr(C)]
     #[derive(Clone, Copy, Debug)]
-    pub enum ParameterTag {
+    enum ParameterTag {
         None = 0,
         Decision = 1,
         Branch = 2,
@@ -142,24 +142,24 @@ pub mod mcdc {
     /// Same layout with `LLVMRustMCDCParameters`
     #[repr(C)]
     #[derive(Clone, Copy, Debug)]
-    pub struct Parameters {
+    pub(crate) struct Parameters {
         tag: ParameterTag,
         decision_params: DecisionParameters,
         branch_params: BranchParameters,
     }
 
     impl Parameters {
-        pub fn none() -> Self {
+        pub(crate) fn none() -> Self {
             Self {
                 tag: ParameterTag::None,
                 decision_params: Default::default(),
                 branch_params: Default::default(),
             }
         }
-        pub fn decision(decision_params: DecisionParameters) -> Self {
+        pub(crate) fn decision(decision_params: DecisionParameters) -> Self {
             Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() }
         }
-        pub fn branch(branch_params: BranchParameters) -> Self {
+        pub(crate) fn branch(branch_params: BranchParameters) -> Self {
             Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params }
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
index 9433385c23a..44eafab6060 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
@@ -14,7 +14,7 @@ use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
 /// Holds all of the coverage mapping data associated with a function instance,
 /// collected during traversal of `Coverage` statements in the function's MIR.
 #[derive(Debug)]
-pub struct FunctionCoverageCollector<'tcx> {
+pub(crate) struct FunctionCoverageCollector<'tcx> {
     /// Coverage info that was attached to this function by the instrumentor.
     function_coverage_info: &'tcx FunctionCoverageInfo,
     is_used: bool,
@@ -32,7 +32,7 @@ pub struct FunctionCoverageCollector<'tcx> {
 
 impl<'tcx> FunctionCoverageCollector<'tcx> {
     /// Creates a new set of coverage data for a used (called) function.
-    pub fn new(
+    pub(crate) fn new(
         instance: Instance<'tcx>,
         function_coverage_info: &'tcx FunctionCoverageInfo,
     ) -> Self {
@@ -40,7 +40,7 @@ impl<'tcx> FunctionCoverageCollector<'tcx> {
     }
 
     /// Creates a new set of coverage data for an unused (never called) function.
-    pub fn unused(
+    pub(crate) fn unused(
         instance: Instance<'tcx>,
         function_coverage_info: &'tcx FunctionCoverageInfo,
     ) -> Self {
@@ -195,7 +195,7 @@ impl<'tcx> FunctionCoverage<'tcx> {
 
     /// Return the source hash, generated from the HIR node structure, and used to indicate whether
     /// or not the source code structure changed between different compilations.
-    pub fn source_hash(&self) -> u64 {
+    pub(crate) fn source_hash(&self) -> u64 {
         if self.is_used { self.function_coverage_info.function_source_hash } else { 0 }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index f8929a26011..069b62af5e7 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -27,7 +27,7 @@ use crate::{coverageinfo, llvm};
 /// implementing this Rust version, and though the format documentation is very explicit and
 /// detailed, some undocumented details in Clang's implementation (that may or may not be important)
 /// were also replicated for Rust's Coverage Map.
-pub fn finalize(cx: &CodegenCx<'_, '_>) {
+pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
     let tcx = cx.tcx;
 
     // Ensure that LLVM is using a version of the coverage mapping format that
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 20a713b8564..69babc7c9cf 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -22,10 +22,10 @@ use crate::llvm;
 
 pub(crate) mod ffi;
 pub(crate) mod map_data;
-pub mod mapgen;
+mod mapgen;
 
 /// A context object for maintaining all state needed by the coverageinfo module.
-pub struct CrateCoverageContext<'ll, 'tcx> {
+pub(crate) struct CrateCoverageContext<'ll, 'tcx> {
     /// Coverage data for each instrumented function identified by DefId.
     pub(crate) function_coverage_map:
         RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
@@ -34,7 +34,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
 }
 
 impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
-    pub fn new() -> Self {
+    pub(crate) fn new() -> Self {
         Self {
             function_coverage_map: Default::default(),
             pgo_func_name_var_map: Default::default(),
@@ -42,7 +42,7 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
         }
     }
 
-    pub fn take_function_coverage_map(
+    fn take_function_coverage_map(
         &self,
     ) -> FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>> {
         self.function_coverage_map.replace(FxIndexMap::default())
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 0a02c230cfc..c3087d8ec30 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -15,7 +15,7 @@ use crate::llvm::debuginfo::{DILocation, DIScope};
 
 /// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
 // FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
-pub fn compute_mir_scopes<'ll, 'tcx>(
+pub(crate) fn compute_mir_scopes<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     instance: Instance<'tcx>,
     mir: &Body<'tcx>,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index e91bcea16a2..dc228e94811 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -16,7 +16,7 @@ use crate::value::Value;
 
 /// Inserts a side-effect free instruction sequence that makes sure that the
 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
-pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
+pub(crate) fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) {
     if needs_gdb_debug_scripts_section(bx) {
         let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
         // Load just the first byte as that's all that's necessary to force
@@ -30,7 +30,9 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_,
 
 /// Allocates the global variable responsible for the .debug_gdb_scripts binary
 /// section.
-pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Value {
+pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
+    cx: &CodegenCx<'ll, '_>,
+) -> &'ll Value {
     let c_section_var_name = c"__rustc_debug_gdb_scripts_section__";
     let section_var_name = c_section_var_name.to_str().unwrap();
 
@@ -82,7 +84,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '
     })
 }
 
-pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
+pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
     let omit_gdb_pretty_printer_section =
         attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section);
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 30f90bada9a..dc59e9349b0 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -85,7 +85,7 @@ const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = |
 
 // SmallVec is used quite a bit in this module, so create a shorthand.
 // The actual number of elements is not so important.
-pub type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
+type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
 
 mod enums;
 mod type_map;
@@ -425,7 +425,7 @@ fn build_slice_type_di_node<'ll, 'tcx>(
 ///
 /// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
 /// will create the node by dispatching to the corresponding `build_*_di_node()` function.
-pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
+pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
     let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
 
     if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
@@ -531,7 +531,7 @@ fn hex_encode(data: &[u8]) -> String {
     hex_string
 }
 
-pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
+pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
     let cache_key = Some((source_file.stable_id, source_file.src_hash));
     return debug_context(cx)
         .created_files
@@ -629,6 +629,9 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
         };
         let hash_value = hex_encode(source_file.src_hash.hash_bytes());
 
+        let source =
+            cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref());
+
         unsafe {
             llvm::LLVMRustDIBuilderCreateFile(
                 DIB(cx),
@@ -639,12 +642,14 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
                 hash_kind,
                 hash_value.as_ptr().cast(),
                 hash_value.len(),
+                source.map_or(ptr::null(), |x| x.as_ptr().cast()),
+                source.map_or(0, |x| x.len()),
             )
         }
     }
 }
 
-pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
+fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
     debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
         let file_name = "<unknown>";
         let directory = "";
@@ -659,6 +664,8 @@ pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
             llvm::ChecksumKind::None,
             hash_value.as_ptr().cast(),
             hash_value.len(),
+            ptr::null(),
+            0,
         )
     })
 }
@@ -859,7 +866,7 @@ fn build_param_type_di_node<'ll, 'tcx>(
     }
 }
 
-pub fn build_compile_unit_di_node<'ll, 'tcx>(
+pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
     tcx: TyCtxt<'tcx>,
     codegen_unit_name: &str,
     debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
@@ -943,6 +950,8 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>(
             llvm::ChecksumKind::None,
             ptr::null(),
             0,
+            ptr::null(),
+            0,
         );
 
         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
@@ -1319,7 +1328,11 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
 /// Creates debug information for the given global variable.
 ///
 /// Adds the created debuginfo nodes directly to the crate's IR.
-pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, global: &'ll Value) {
+pub(crate) fn build_global_var_di_node<'ll>(
+    cx: &CodegenCx<'ll, '_>,
+    def_id: DefId,
+    global: &'ll Value,
+) {
     if cx.dbg_cx.is_none() {
         return;
     }
@@ -1559,7 +1572,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
 /// given type.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_vtable_di_node<'ll, 'tcx>(
+pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     ty: Ty<'tcx>,
     poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
@@ -1604,7 +1617,7 @@ pub fn create_vtable_di_node<'ll, 'tcx>(
 }
 
 /// Creates an "extension" of an existing `DIScope` into another file.
-pub fn extend_scope_to_file<'ll>(
+pub(crate) fn extend_scope_to_file<'ll>(
     cx: &CodegenCx<'ll, '_>,
     scope_metadata: &'ll DIScope,
     file: &SourceFile,
@@ -1613,7 +1626,7 @@ pub fn extend_scope_to_file<'ll>(
     unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
 }
 
-pub fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
+fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
     const TUPLE_FIELD_NAMES: [&'static str; 16] = [
         "__0", "__1", "__2", "__3", "__4", "__5", "__6", "__7", "__8", "__9", "__10", "__11",
         "__12", "__13", "__14", "__15",
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index 77cbcd86cdd..edaf73b74a2 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -257,7 +257,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
 ///  --->   DW_TAG_structure_type            (type of variant 3)
 ///
 /// ```
-pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
+fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     variant_index: VariantIdx,
     coroutine_type_and_layout: TyAndLayout<'tcx>,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
index 25b2df9c52c..6d21f4204e3 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -22,7 +22,7 @@ mod private {
     // `UniqueTypeId` from being constructed directly, without asserting
     // the preconditions.
     #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, HashStable)]
-    pub struct HiddenZst;
+    pub(crate) struct HiddenZst;
 }
 
 /// A unique identifier for anything that we create a debuginfo node for.
@@ -48,17 +48,17 @@ pub(super) enum UniqueTypeId<'tcx> {
 }
 
 impl<'tcx> UniqueTypeId<'tcx> {
-    pub fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
+    pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
         assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
         UniqueTypeId::Ty(t, private::HiddenZst)
     }
 
-    pub fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
+    pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
         assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
         UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
     }
 
-    pub fn for_enum_variant_struct_type(
+    pub(crate) fn for_enum_variant_struct_type(
         tcx: TyCtxt<'tcx>,
         enum_ty: Ty<'tcx>,
         variant_idx: VariantIdx,
@@ -67,7 +67,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
         UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
     }
 
-    pub fn for_enum_variant_struct_type_wrapper(
+    pub(crate) fn for_enum_variant_struct_type_wrapper(
         tcx: TyCtxt<'tcx>,
         enum_ty: Ty<'tcx>,
         variant_idx: VariantIdx,
@@ -76,7 +76,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
         UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
     }
 
-    pub fn for_vtable_ty(
+    pub(crate) fn for_vtable_ty(
         tcx: TyCtxt<'tcx>,
         self_type: Ty<'tcx>,
         implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
@@ -93,7 +93,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
     /// argument of the various `LLVMRustDIBuilderCreate*Type()` methods.
     ///
     /// Right now this takes the form of a hex-encoded opaque hash value.
-    pub fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String {
+    fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String {
         let mut hasher = StableHasher::new();
         tcx.with_stable_hashing_context(|mut hcx| {
             hcx.while_hashing_spans(false, |hcx| self.hash_stable(hcx, &mut hasher))
@@ -101,7 +101,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
         hasher.finish::<Fingerprint>().to_hex()
     }
 
-    pub fn expect_ty(self) -> Ty<'tcx> {
+    pub(crate) fn expect_ty(self) -> Ty<'tcx> {
         match self {
             UniqueTypeId::Ty(ty, _) => ty,
             _ => bug!("Expected `UniqueTypeId::Ty` but found `{:?}`", self),
@@ -133,25 +133,25 @@ impl<'ll, 'tcx> TypeMap<'ll, 'tcx> {
     }
 }
 
-pub struct DINodeCreationResult<'ll> {
+pub(crate) struct DINodeCreationResult<'ll> {
     pub di_node: &'ll DIType,
     pub already_stored_in_typemap: bool,
 }
 
 impl<'ll> DINodeCreationResult<'ll> {
-    pub fn new(di_node: &'ll DIType, already_stored_in_typemap: bool) -> Self {
+    pub(crate) fn new(di_node: &'ll DIType, already_stored_in_typemap: bool) -> Self {
         DINodeCreationResult { di_node, already_stored_in_typemap }
     }
 }
 
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum Stub<'ll> {
+pub(crate) enum Stub<'ll> {
     Struct,
     Union,
     VTableTy { vtable_holder: &'ll DIType },
 }
 
-pub struct StubInfo<'ll, 'tcx> {
+pub(crate) struct StubInfo<'ll, 'tcx> {
     metadata: &'ll DIType,
     unique_type_id: UniqueTypeId<'tcx>,
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index eb446d2d7b2..f5d6fc6f080 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -40,13 +40,13 @@ use crate::llvm::debuginfo::{
 use crate::value::Value;
 
 mod create_scope_map;
-pub mod gdb;
-pub mod metadata;
+mod gdb;
+pub(crate) mod metadata;
 mod namespace;
 mod utils;
 
-pub use self::create_scope_map::compute_mir_scopes;
-pub use self::metadata::build_global_var_di_node;
+use self::create_scope_map::compute_mir_scopes;
+pub(crate) use self::metadata::build_global_var_di_node;
 
 #[allow(non_upper_case_globals)]
 const DW_TAG_auto_variable: c_uint = 0x100;
@@ -54,7 +54,7 @@ const DW_TAG_auto_variable: c_uint = 0x100;
 const DW_TAG_arg_variable: c_uint = 0x101;
 
 /// A context object for maintaining all state needed by the debuginfo module.
-pub struct CodegenUnitDebugContext<'ll, 'tcx> {
+pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
     llcontext: &'ll llvm::Context,
     llmod: &'ll llvm::Module,
     builder: &'ll mut DIBuilder<'ll>,
@@ -74,7 +74,7 @@ impl Drop for CodegenUnitDebugContext<'_, '_> {
 }
 
 impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
-    pub fn new(llmod: &'ll llvm::Module) -> Self {
+    pub(crate) fn new(llmod: &'ll llvm::Module) -> Self {
         debug!("CodegenUnitDebugContext::new");
         let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
@@ -90,7 +90,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
         }
     }
 
-    pub fn finalize(&self, sess: &Session) {
+    pub(crate) fn finalize(&self, sess: &Session) {
         unsafe {
             llvm::LLVMRustDIBuilderFinalize(self.builder);
 
@@ -134,7 +134,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
 }
 
 /// Creates any deferred debug metadata nodes
-pub fn finalize(cx: &CodegenCx<'_, '_>) {
+pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
     if let Some(dbg_cx) = &cx.dbg_cx {
         debug!("finalize");
 
@@ -241,13 +241,13 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
 // FIXME(eddyb) rename this to better indicate it's a duplicate of
 // `rustc_span::Loc` rather than `DILocation`, perhaps by making
 // `lookup_char_pos` return the right information instead.
-pub struct DebugLoc {
+struct DebugLoc {
     /// Information about the original source file.
-    pub file: Lrc<SourceFile>,
+    file: Lrc<SourceFile>,
     /// The (1-based) line number.
-    pub line: u32,
+    line: u32,
     /// The (1-based) column number.
-    pub col: u32,
+    col: u32,
 }
 
 impl CodegenCx<'_, '_> {
@@ -255,7 +255,7 @@ impl CodegenCx<'_, '_> {
     // FIXME(eddyb) rename this to better indicate it's a duplicate of
     // `lookup_char_pos` rather than `dbg_loc`, perhaps by making
     // `lookup_char_pos` return the right information instead.
-    pub fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc {
+    fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc {
         let (file, line, col) = match self.sess().source_map().lookup_line(pos) {
             Ok(SourceFileAndLine { sf: file, line }) => {
                 let line_pos = file.lines()[line];
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
index 5c4f8fe99e3..83d7a82dadc 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
@@ -9,7 +9,7 @@ use crate::common::CodegenCx;
 use crate::llvm;
 use crate::llvm::debuginfo::DIScope;
 
-pub fn mangled_name_of_instance<'a, 'tcx>(
+pub(crate) fn mangled_name_of_instance<'a, 'tcx>(
     cx: &CodegenCx<'a, 'tcx>,
     instance: Instance<'tcx>,
 ) -> ty::SymbolName<'tcx> {
@@ -17,7 +17,7 @@ pub fn mangled_name_of_instance<'a, 'tcx>(
     tcx.symbol_name(instance)
 }
 
-pub fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
+pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
     if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) {
         return scope;
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
index e542aa96e8a..321553a3df0 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
@@ -11,7 +11,7 @@ use crate::common::CodegenCx;
 use crate::llvm;
 use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope};
 
-pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
+pub(crate) fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
     // The is_local_to_unit flag indicates whether a function is local to the
     // current compilation unit (i.e., if it is *static* in the C-sense). The
     // *reachable* set should provide a good approximation of this, as it
@@ -24,7 +24,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
 }
 
 #[allow(non_snake_case)]
-pub fn create_DIArray<'ll>(
+pub(crate) fn create_DIArray<'ll>(
     builder: &DIBuilder<'ll>,
     arr: &[Option<&'ll DIDescriptor>],
 ) -> &'ll DIArray {
@@ -32,7 +32,7 @@ pub fn create_DIArray<'ll>(
 }
 
 #[inline]
-pub fn debug_context<'a, 'll, 'tcx>(
+pub(crate) fn debug_context<'a, 'll, 'tcx>(
     cx: &'a CodegenCx<'ll, 'tcx>,
 ) -> &'a CodegenUnitDebugContext<'ll, 'tcx> {
     cx.dbg_cx.as_ref().unwrap()
@@ -40,11 +40,11 @@ pub fn debug_context<'a, 'll, 'tcx>(
 
 #[inline]
 #[allow(non_snake_case)]
-pub fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> {
+pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> {
     cx.dbg_cx.as_ref().unwrap().builder
 }
 
-pub fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
+pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
     item_namespace(cx, cx.tcx.parent(def_id))
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 2aa349b2782..4e4500b6373 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -65,7 +65,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     ///
     /// If there’s a value with the same name already declared, the function will
     /// return its Value instead.
-    pub fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
+    pub(crate) fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
         debug!("declare_global(name={:?})", name);
         unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) }
     }
@@ -77,7 +77,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     ///
     /// If there’s a value with the same name already declared, the function will
     /// update the declaration and return existing Value instead.
-    pub fn declare_cfn(
+    pub(crate) fn declare_cfn(
         &self,
         name: &str,
         unnamed: llvm::UnnamedAddr,
@@ -100,7 +100,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     ///
     /// If there’s a value with the same name already declared, the function will
     /// update the declaration and return existing Value instead.
-    pub fn declare_entry_fn(
+    pub(crate) fn declare_entry_fn(
         &self,
         name: &str,
         callconv: llvm::CallConv,
@@ -119,7 +119,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     ///
     /// If there’s a value with the same name already declared, the function will
     /// update the declaration and return existing Value instead.
-    pub fn declare_fn(
+    pub(crate) fn declare_fn(
         &self,
         name: &str,
         fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
@@ -199,7 +199,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     /// return `None` if the name already has a definition associated with it. In that
     /// case an error should be reported to the user, because it usually happens due
     /// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes).
-    pub fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
+    pub(crate) fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
         if self.get_defined_value(name).is_some() {
             None
         } else {
@@ -210,19 +210,19 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     /// Declare a private global
     ///
     /// Use this function when you intend to define a global without a name.
-    pub fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
+    pub(crate) fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) }
     }
 
     /// Gets declared value by name.
-    pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
+    pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
         debug!("get_declared_value(name={:?})", name);
         unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) }
     }
 
     /// Gets defined or externally defined (AvailableExternally linkage) value by
     /// name.
-    pub fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
+    pub(crate) fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
         self.get_declared_value(name).and_then(|val| {
             let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 };
             if !declaration { Some(val) } else { None }
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index e0ec9cdca56..bb481d2a308 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -207,13 +207,13 @@ pub(crate) struct CopyBitcode {
 
 #[derive(Diagnostic)]
 #[diag(codegen_llvm_unknown_debuginfo_compression)]
-pub struct UnknownCompression {
+pub(crate) struct UnknownCompression {
     pub algorithm: &'static str,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_llvm_mismatch_data_layout)]
-pub struct MismatchedDataLayout<'a> {
+pub(crate) struct MismatchedDataLayout<'a> {
     pub rustc_target: &'a str,
     pub rustc_layout: &'a str,
     pub llvm_target: &'a str,
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index abfe38d4c0c..a300f5f707a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1287,19 +1287,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     }
 
     if name == sym::simd_shuffle {
-        // Make sure this is actually an array, since typeck only checks the length-suffixed
+        // Make sure this is actually an array or SIMD vector, since typeck only checks the length-suffixed
         // version of this intrinsic.
-        let n: u64 = match args[2].layout.ty.kind() {
+        let idx_ty = args[2].layout.ty;
+        let n: u64 = match idx_ty.kind() {
             ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
                 len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
                     || span_bug!(span, "could not evaluate shuffle index array length"),
                 )
             }
-            _ => return_error!(InvalidMonomorphization::SimdShuffle {
-                span,
-                name,
-                ty: args[2].layout.ty
-            }),
+            _ if idx_ty.is_simd()
+                && matches!(
+                    idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(),
+                    ty::Uint(ty::UintTy::U32)
+                ) =>
+            {
+                idx_ty.simd_size_and_type(bx.cx.tcx).0
+            }
+            _ => return_error!(InvalidMonomorphization::SimdShuffle { span, name, ty: idx_ty }),
         };
 
         let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 43164390a1c..6a303e1e602 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -6,6 +6,7 @@
 
 // tidy-alphabetical-start
 #![allow(internal_features)]
+#![cfg_attr(bootstrap, feature(unsafe_extern_blocks))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
@@ -16,6 +17,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::any::Any;
@@ -45,11 +47,11 @@ use rustc_session::Session;
 use rustc_span::symbol::Symbol;
 
 mod back {
-    pub mod archive;
-    pub mod lto;
-    pub mod owned_target_machine;
+    pub(crate) mod archive;
+    pub(crate) mod lto;
+    pub(crate) mod owned_target_machine;
     mod profiling;
-    pub mod write;
+    pub(crate) mod write;
 }
 
 mod abi;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index faabbcb020d..5e0d7418993 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -564,12 +564,12 @@ pub enum ArchiveKind {
 }
 
 // LLVMRustThinLTOData
-extern "C" {
+unsafe extern "C" {
     pub type ThinLTOData;
 }
 
 // LLVMRustThinLTOBuffer
-extern "C" {
+unsafe extern "C" {
     pub type ThinLTOBuffer;
 }
 
@@ -621,7 +621,7 @@ pub enum MemoryEffects {
     InaccessibleMemOnly,
 }
 
-extern "C" {
+unsafe extern "C" {
     type Opaque;
 }
 #[repr(C)]
@@ -631,54 +631,54 @@ struct InvariantOpaque<'a> {
 }
 
 // Opaque pointer types
-extern "C" {
+unsafe extern "C" {
     pub type Module;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Context;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Type;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Value;
 }
-extern "C" {
+unsafe extern "C" {
     pub type ConstantInt;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Attribute;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Metadata;
 }
-extern "C" {
+unsafe extern "C" {
     pub type BasicBlock;
 }
 #[repr(C)]
 pub struct Builder<'a>(InvariantOpaque<'a>);
 #[repr(C)]
 pub struct PassManager<'a>(InvariantOpaque<'a>);
-extern "C" {
+unsafe extern "C" {
     pub type Pass;
 }
-extern "C" {
+unsafe extern "C" {
     pub type TargetMachine;
 }
-extern "C" {
+unsafe extern "C" {
     pub type Archive;
 }
 #[repr(C)]
 pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
 #[repr(C)]
 pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
-extern "C" {
+unsafe extern "C" {
     pub type Twine;
 }
-extern "C" {
+unsafe extern "C" {
     pub type DiagnosticInfo;
 }
-extern "C" {
+unsafe extern "C" {
     pub type SMDiagnostic;
 }
 #[repr(C)]
@@ -688,7 +688,7 @@ pub struct OperandBundleDef<'a>(InvariantOpaque<'a>);
 #[repr(C)]
 pub struct Linker<'a>(InvariantOpaque<'a>);
 
-extern "C" {
+unsafe extern "C" {
     pub type DiagnosticHandler;
 }
 
@@ -823,7 +823,7 @@ bitflags! {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     pub type ModuleBuffer;
 }
 
@@ -834,7 +834,7 @@ pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
 pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
 pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
 
-extern "C" {
+unsafe extern "C" {
     // Create and destroy contexts.
     pub fn LLVMContextDispose(C: &'static mut Context);
     pub fn LLVMGetMDKindIDInContext(C: &Context, Name: *const c_char, SLen: c_uint) -> c_uint;
@@ -1518,7 +1518,7 @@ extern "C" {
 }
 
 #[link(name = "llvm-wrapper", kind = "static")]
-extern "C" {
+unsafe extern "C" {
     pub fn LLVMRustInstallErrorHandlers();
     pub fn LLVMRustDisableSystemDialogsOnCrash();
 
@@ -1860,6 +1860,8 @@ extern "C" {
         CSKind: ChecksumKind,
         Checksum: *const c_char,
         ChecksumLen: size_t,
+        Source: *const c_char,
+        SourceLen: size_t,
     ) -> &'a DIFile;
 
     pub fn LLVMRustDIBuilderCreateSubroutineType<'a>(
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 9fd8ca43789..7af5eb9278f 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -136,14 +136,14 @@ unsafe fn configure_llvm(sess: &Session) {
     unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) };
 }
 
-pub fn time_trace_profiler_finish(file_name: &Path) {
+pub(crate) fn time_trace_profiler_finish(file_name: &Path) {
     unsafe {
         let file_name = path_to_c_string(file_name);
         llvm::LLVMRustTimeTraceProfilerFinish(file_name.as_ptr());
     }
 }
 
-pub enum TargetFeatureFoldStrength<'a> {
+enum TargetFeatureFoldStrength<'a> {
     // The feature is only tied when enabling the feature, disabling
     // this feature shouldn't disable the tied feature.
     EnableOnly(&'a str),
@@ -160,28 +160,28 @@ impl<'a> TargetFeatureFoldStrength<'a> {
     }
 }
 
-pub struct LLVMFeature<'a> {
-    pub llvm_feature_name: &'a str,
-    pub dependency: Option<TargetFeatureFoldStrength<'a>>,
+pub(crate) struct LLVMFeature<'a> {
+    llvm_feature_name: &'a str,
+    dependency: Option<TargetFeatureFoldStrength<'a>>,
 }
 
 impl<'a> LLVMFeature<'a> {
-    pub fn new(llvm_feature_name: &'a str) -> Self {
+    fn new(llvm_feature_name: &'a str) -> Self {
         Self { llvm_feature_name, dependency: None }
     }
 
-    pub fn with_dependency(
+    fn with_dependency(
         llvm_feature_name: &'a str,
         dependency: TargetFeatureFoldStrength<'a>,
     ) -> Self {
         Self { llvm_feature_name, dependency: Some(dependency) }
     }
 
-    pub fn contains(&self, feat: &str) -> bool {
+    fn contains(&self, feat: &str) -> bool {
         self.iter().any(|dep| dep == feat)
     }
 
-    pub fn iter(&'a self) -> impl Iterator<Item = &'a str> {
+    fn iter(&'a self) -> impl Iterator<Item = &'a str> {
         let dependencies = self.dependency.iter().map(|feat| feat.as_str());
         std::iter::once(self.llvm_feature_name).chain(dependencies)
     }
@@ -209,7 +209,7 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
 // Though note that Rust can also be build with an external precompiled version of LLVM
 // which might lead to failures if the oldest tested / supported LLVM version
 // doesn't yet support the relevant intrinsics
-pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
+pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
     let arch = if sess.target.arch == "x86_64" {
         "x86"
     } else if sess.target.arch == "arm64ec" {
@@ -257,7 +257,7 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
 
 /// Given a map from target_features to whether they are enabled or disabled,
 /// ensure only valid combinations are allowed.
-pub fn check_tied_features(
+pub(crate) fn check_tied_features(
     sess: &Session,
     features: &FxHashMap<&str, bool>,
 ) -> Option<&'static [&'static str]> {
@@ -337,19 +337,19 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
         .collect()
 }
 
-pub fn print_version() {
+pub(crate) fn print_version() {
     let (major, minor, patch) = get_version();
     println!("LLVM version: {major}.{minor}.{patch}");
 }
 
-pub fn get_version() -> (u32, u32, u32) {
+pub(crate) fn get_version() -> (u32, u32, u32) {
     // Can be called without initializing LLVM
     unsafe {
         (llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch())
     }
 }
 
-pub fn print_passes() {
+pub(crate) fn print_passes() {
     // Can be called without initializing LLVM
     unsafe {
         llvm::LLVMRustPrintPasses();
@@ -479,7 +479,7 @@ fn handle_native(name: &str) -> &str {
     }
 }
 
-pub fn target_cpu(sess: &Session) -> &str {
+pub(crate) fn target_cpu(sess: &Session) -> &str {
     match sess.opts.cg.target_cpu {
         Some(ref name) => handle_native(name),
         None => handle_native(sess.target.cpu.as_ref()),
@@ -699,7 +699,7 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
     Some(feature)
 }
 
-pub fn tune_cpu(sess: &Session) -> Option<&str> {
+pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
     let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
     Some(handle_native(name))
 }
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 7e3ab19898d..ec1e2cb8094 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -12,7 +12,7 @@ use rustc_target::abi::{AddressSpace, Align, Integer, Size};
 
 use crate::abi::{FnAbiLlvmExt, LlvmType};
 use crate::context::CodegenCx;
-pub use crate::llvm::Type;
+pub(crate) use crate::llvm::Type;
 use crate::llvm::{Bool, False, True};
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 4755fa08afb..6e429a1674a 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -139,21 +139,21 @@ fn struct_llfields<'a, 'tcx>(
 }
 
 impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
-    pub fn align_of(&self, ty: Ty<'tcx>) -> Align {
+    pub(crate) fn align_of(&self, ty: Ty<'tcx>) -> Align {
         self.layout_of(ty).align.abi
     }
 
-    pub fn size_of(&self, ty: Ty<'tcx>) -> Size {
+    pub(crate) fn size_of(&self, ty: Ty<'tcx>) -> Size {
         self.layout_of(ty).size
     }
 
-    pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) {
+    pub(crate) fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) {
         let layout = self.layout_of(ty);
         (layout.size, layout.align.abi)
     }
 }
 
-pub trait LayoutLlvmExt<'tcx> {
+pub(crate) trait LayoutLlvmExt<'tcx> {
     fn is_llvm_immediate(&self) -> bool;
     fn is_llvm_scalar_pair(&self) -> bool;
     fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
diff --git a/compiler/rustc_codegen_llvm/src/value.rs b/compiler/rustc_codegen_llvm/src/value.rs
index 6295b0de356..2eabac3be8c 100644
--- a/compiler/rustc_codegen_llvm/src/value.rs
+++ b/compiler/rustc_codegen_llvm/src/value.rs
@@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher};
 use std::{fmt, ptr};
 
 use crate::llvm;
-pub use crate::llvm::Value;
+pub(crate) use crate::llvm::Value;
 
 impl PartialEq for Value {
     fn eq(&self, other: &Self) -> bool {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 7bad9d33e7d..4d19425255f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1207,7 +1207,7 @@ mod win {
 
     /// Get the Windows system OEM code page. This is most notably the code page
     /// used for link.exe's output.
-    pub fn oem_code_page() -> u32 {
+    pub(super) fn oem_code_page() -> u32 {
         unsafe {
             let mut cp: u32 = 0;
             // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32.
@@ -1230,7 +1230,7 @@ mod win {
     ///
     /// It will fail if the multi-byte string is longer than `i32::MAX` or if it contains
     /// any invalid bytes for the expected encoding.
-    pub fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option<String> {
+    pub(super) fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option<String> {
         // `MultiByteToWideChar` requires a length to be a "positive integer".
         if s.len() > isize::MAX as usize {
             return None;
@@ -1317,11 +1317,9 @@ fn link_sanitizer_runtime(
     name: &str,
 ) {
     fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
-        let session_tlib =
-            filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
-        let path = session_tlib.join(filename);
+        let path = sess.target_tlib_path.dir.join(filename);
         if path.exists() {
-            return session_tlib;
+            return sess.target_tlib_path.dir.clone();
         } else {
             let default_sysroot =
                 filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
@@ -1612,19 +1610,18 @@ fn print_native_static_libs(
 }
 
 fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf {
-    let fs = sess.target_filesearch(PathKind::Native);
-    let file_path = fs.get_lib_path().join(name);
+    let file_path = sess.target_tlib_path.dir.join(name);
     if file_path.exists() {
         return file_path;
     }
     // Special directory with objects used only in self-contained linkage mode
     if self_contained {
-        let file_path = fs.get_self_contained_lib_path().join(name);
+        let file_path = sess.target_tlib_path.dir.join("self-contained").join(name);
         if file_path.exists() {
             return file_path;
         }
     }
-    for search_path in fs.search_paths() {
+    for search_path in sess.target_filesearch(PathKind::Native).search_paths() {
         let file_path = search_path.dir.join(name);
         if file_path.exists() {
             return file_path;
@@ -2131,7 +2128,7 @@ fn add_library_search_dirs(
             | LinkSelfContainedComponents::UNWIND
             | LinkSelfContainedComponents::MINGW,
     ) {
-        let lib_path = sess.target_filesearch(PathKind::Native).get_self_contained_lib_path();
+        let lib_path = sess.target_tlib_path.dir.join("self-contained");
         cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
     }
 
@@ -2146,8 +2143,7 @@ fn add_library_search_dirs(
         || sess.target.os == "fuchsia"
         || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
     {
-        let lib_path = sess.target_filesearch(PathKind::Native).get_lib_path();
-        cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
+        cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir));
     }
 
     // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
@@ -2859,15 +2855,14 @@ fn add_upstream_native_libraries(
 //
 // The returned path will always have `fix_windows_verbatim_for_gcc()` applied to it.
 fn rehome_sysroot_lib_dir(sess: &Session, lib_dir: &Path) -> PathBuf {
-    let sysroot_lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
+    let sysroot_lib_path = &sess.target_tlib_path.dir;
     let canonical_sysroot_lib_path =
-        { try_canonicalize(&sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) };
+        { try_canonicalize(sysroot_lib_path).unwrap_or_else(|_| sysroot_lib_path.clone()) };
 
     let canonical_lib_dir = try_canonicalize(lib_dir).unwrap_or_else(|_| lib_dir.to_path_buf());
     if canonical_lib_dir == canonical_sysroot_lib_path {
-        // This path, returned by `target_filesearch().get_lib_path()`, has
-        // already had `fix_windows_verbatim_for_gcc()` applied if needed.
-        sysroot_lib_path
+        // This path already had `fix_windows_verbatim_for_gcc()` applied if needed.
+        sysroot_lib_path.clone()
     } else {
         fix_windows_verbatim_for_gcc(lib_dir)
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 70b45a852ca..7ad31802454 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -754,7 +754,7 @@ pub(crate) enum WorkItem<B: WriteBackendMethods> {
 }
 
 impl<B: WriteBackendMethods> WorkItem<B> {
-    pub fn module_kind(&self) -> ModuleKind {
+    fn module_kind(&self) -> ModuleKind {
         match *self {
             WorkItem::Optimize(ref m) => m.kind,
             WorkItem::CopyPostLtoArtifacts(_) | WorkItem::LTO(_) => ModuleKind::Regular,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index cb6d9d6f66e..c89bfca6687 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -12,6 +12,7 @@
 #![feature(rustdoc_internals)]
 #![feature(strict_provenance)]
 #![feature(try_blocks)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 //! This crate contains codegen code that is used by all codegen backends (LLVM and others).
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index c8cf341628c..386e1f91e7f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -13,7 +13,7 @@ use tracing::debug;
 use super::FunctionCx;
 use crate::traits::*;
 
-pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     fx: &FunctionCx<'a, 'tcx, Bx>,
 ) -> BitSet<mir::Local> {
     let mir = fx.mir;
@@ -251,14 +251,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum CleanupKind {
+pub(crate) enum CleanupKind {
     NotCleanup,
     Funclet,
     Internal { funclet: mir::BasicBlock },
 }
 
 impl CleanupKind {
-    pub fn funclet_bb(self, for_bb: mir::BasicBlock) -> Option<mir::BasicBlock> {
+    pub(crate) fn funclet_bb(self, for_bb: mir::BasicBlock) -> Option<mir::BasicBlock> {
         match self {
             CleanupKind::NotCleanup => None,
             CleanupKind::Funclet => Some(for_bb),
@@ -270,7 +270,7 @@ impl CleanupKind {
 /// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only
 /// branch to itself or to its parent. Luckily, the code we generates matches this pattern.
 /// Recover that structure in an analyze pass.
-pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
+pub(crate) fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
     fn discover_masters<'tcx>(
         result: &mut IndexSlice<mir::BasicBlock, CleanupKind>,
         mir: &mir::Body<'tcx>,
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index c80b3e673b0..6a086a3a7e5 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -1,6 +1,7 @@
 //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
 
 use std::assert_matches::assert_matches;
+use std::borrow::Cow;
 use std::mem;
 use std::ops::Deref;
 
@@ -15,6 +16,8 @@ use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_mir_dataflow::impls::MaybeStorageLive;
+use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_mir_dataflow::Analysis;
 use rustc_span::{sym, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -188,8 +191,9 @@ pub struct Checker<'mir, 'tcx> {
     /// The span of the current statement.
     span: Span,
 
-    /// A set that stores for each local whether it has a `StorageDead` for it somewhere.
-    local_has_storage_dead: Option<BitSet<Local>>,
+    /// A set that stores for each local whether it is "transient", i.e. guaranteed to be dead
+    /// when this MIR body returns.
+    transient_locals: Option<BitSet<Local>>,
 
     error_emitted: Option<ErrorGuaranteed>,
     secondary_errors: Vec<Diag<'tcx>>,
@@ -209,7 +213,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             span: ccx.body.span,
             ccx,
             qualifs: Default::default(),
-            local_has_storage_dead: None,
+            transient_locals: None,
             error_emitted: None,
             secondary_errors: Vec::new(),
         }
@@ -264,23 +268,33 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         }
     }
 
-    fn local_has_storage_dead(&mut self, local: Local) -> bool {
+    fn local_is_transient(&mut self, local: Local) -> bool {
         let ccx = self.ccx;
-        self.local_has_storage_dead
+        self.transient_locals
             .get_or_insert_with(|| {
-                struct StorageDeads {
-                    locals: BitSet<Local>,
-                }
-                impl<'tcx> Visitor<'tcx> for StorageDeads {
-                    fn visit_statement(&mut self, stmt: &Statement<'tcx>, _: Location) {
-                        if let StatementKind::StorageDead(l) = stmt.kind {
-                            self.locals.insert(l);
-                        }
+                // A local is "transient" if it is guaranteed dead at all `Return`.
+                // So first compute the say of "maybe live" locals at each program point.
+                let always_live_locals = &always_storage_live_locals(&ccx.body);
+                let mut maybe_storage_live =
+                    MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
+                        .into_engine(ccx.tcx, &ccx.body)
+                        .iterate_to_fixpoint()
+                        .into_results_cursor(&ccx.body);
+
+                // And then check all `Return` in the MIR, and if a local is "maybe live" at a
+                // `Return` then it is definitely not transient.
+                let mut transient = BitSet::new_filled(ccx.body.local_decls.len());
+                // Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise.
+                for (bb, data) in traversal::reachable(&ccx.body) {
+                    if matches!(data.terminator().kind, TerminatorKind::Return) {
+                        let location = ccx.body.terminator_loc(bb);
+                        maybe_storage_live.seek_after_primary_effect(location);
+                        // If a local may be live here, it is definitely not transient.
+                        transient.subtract(maybe_storage_live.get());
                     }
                 }
-                let mut v = StorageDeads { locals: BitSet::new_empty(ccx.body.local_decls.len()) };
-                v.visit_body(ccx.body);
-                v.locals
+
+                transient
             })
             .contains(local)
     }
@@ -375,7 +389,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
                 // `StorageDead` in every control flow path leading to a `return` terminator.
                 // The good news is that interning will detect if any unexpected mutable
                 // pointer slips through.
-                if place.is_indirect() || self.local_has_storage_dead(place.local) {
+                if place.is_indirect() || self.local_is_transient(place.local) {
                     self.check_op(ops::TransientMutBorrow(kind));
                 } else {
                     self.check_op(ops::MutBorrow(kind));
@@ -526,7 +540,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             // `StorageDead` in every control flow path leading to a `return` terminator.
                             // The good news is that interning will detect if any unexpected mutable
                             // pointer slips through.
-                            if self.local_has_storage_dead(place.local) {
+                            if self.local_is_transient(place.local) {
                                 self.check_op(ops::TransientCellBorrow);
                             } else {
                                 self.check_op(ops::CellBorrow);
diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
index c4f06e5af0b..f0998300dc8 100644
--- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
@@ -9,13 +9,19 @@ use super::check::Qualifs;
 use super::ops::{self, NonConstOp};
 use super::qualifs::{NeedsNonConstDrop, Qualif};
 use super::ConstCx;
+use crate::check_consts::rustc_allow_const_fn_unstable;
 
 /// Returns `true` if we should use the more precise live drop checker that runs after drop
 /// elaboration.
 pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
-    // Const-stable functions must always use the stable live drop checker.
+    // Const-stable functions must always use the stable live drop checker...
     if ccx.is_const_stable_const_fn() {
-        return false;
+        // ...except if they have the feature flag set via `rustc_allow_const_fn_unstable`.
+        return rustc_allow_const_fn_unstable(
+            ccx.tcx,
+            ccx.body.source.def_id().expect_local(),
+            sym::const_precise_live_drops,
+        );
     }
 
     ccx.tcx.features().const_precise_live_drops
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 917a2fa7c6d..f99283c49f5 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -576,7 +576,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             | ty::InstanceKind::ReifyShim(..)
             | ty::InstanceKind::ClosureOnceShim { .. }
             | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceKind::CoroutineKindShim { .. }
             | ty::InstanceKind::FnPtrShim(..)
             | ty::InstanceKind::DropGlue(..)
             | ty::InstanceKind::CloneShim(..)
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 910aec9b8e1..97326fe99a2 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -1014,7 +1014,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ///
     /// We do this so Miri's allocation access tracking does not show the validation
     /// reads as spurious accesses.
-    pub(super) fn run_for_validation<R>(&self, f: impl FnOnce() -> R) -> R {
+    pub fn run_for_validation<R>(&self, f: impl FnOnce() -> R) -> R {
         // This deliberately uses `==` on `bool` to follow the pattern
         // `assert!(val.replace(new) == old)`.
         assert!(
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 2b7dc040f64..820ba96b100 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -7,6 +7,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
+#![cfg_attr(bootstrap, feature(unsafe_extern_blocks))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(decl_macro)]
@@ -15,6 +16,7 @@
 #![feature(panic_update_hook)]
 #![feature(result_flattening)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cmp::max;
diff --git a/compiler/rustc_driver_impl/src/signal_handler.rs b/compiler/rustc_driver_impl/src/signal_handler.rs
index 51f2a508cf9..e1f868c2522 100644
--- a/compiler/rustc_driver_impl/src/signal_handler.rs
+++ b/compiler/rustc_driver_impl/src/signal_handler.rs
@@ -6,7 +6,7 @@ use std::{fmt, mem, ptr};
 
 use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE};
 
-extern "C" {
+unsafe extern "C" {
     fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int);
 }
 
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 2a7bc2501c0..150f99a3ee7 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -6,6 +6,7 @@
 #![deny(rustdoc::invalid_codeblock_attributes)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // This higher-order macro defines the error codes that are in use. It is used
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 87dee2898da..e84d7be45d7 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(type_alias_impl_trait)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index fae8b5647fc..3303e4ee752 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -204,7 +204,7 @@ pub trait LintDiagnostic<'a, G: EmissionGuarantee> {
 }
 
 #[derive(Clone, Debug, Encodable, Decodable)]
-pub struct DiagLocation {
+pub(crate) struct DiagLocation {
     file: Cow<'static, str>,
     line: u32,
     col: u32,
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 9ce5d77ef6c..2bc29dabd18 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2387,7 +2387,7 @@ enum DisplaySuggestion {
 impl FileWithAnnotatedLines {
     /// Preprocess all the annotations so that they are grouped by file and by line number
     /// This helps us quickly iterate over the whole message (including secondary file spans)
-    pub fn collect_annotations(
+    pub(crate) fn collect_annotations(
         emitter: &dyn Emitter,
         args: &FluentArgs<'_>,
         msp: &MultiSpan,
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index fd203c38318..99ee8fb17d7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -25,6 +25,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_errors;
@@ -1701,7 +1702,7 @@ impl DiagCtxtInner {
     }
 
     /// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`.
-    pub fn eagerly_translate<'a>(
+    fn eagerly_translate<'a>(
         &self,
         message: DiagMessage,
         args: impl Iterator<Item = DiagArg<'a>>,
@@ -1710,7 +1711,7 @@ impl DiagCtxtInner {
     }
 
     /// Translate `message` eagerly with `args` to `String`.
-    pub fn eagerly_translate_to_string<'a>(
+    fn eagerly_translate_to_string<'a>(
         &self,
         message: DiagMessage,
         args: impl Iterator<Item = DiagArg<'a>>,
diff --git a/compiler/rustc_errors/src/lock.rs b/compiler/rustc_errors/src/lock.rs
index 915542c9092..7557969f374 100644
--- a/compiler/rustc_errors/src/lock.rs
+++ b/compiler/rustc_errors/src/lock.rs
@@ -12,7 +12,7 @@
 use std::any::Any;
 
 #[cfg(windows)]
-pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
+pub(crate) fn acquire_global_lock(name: &str) -> Box<dyn Any> {
     use std::ffi::CString;
     use std::io;
 
@@ -80,6 +80,6 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
 }
 
 #[cfg(not(windows))]
-pub fn acquire_global_lock(_name: &str) -> Box<dyn Any> {
+pub(crate) fn acquire_global_lock(_name: &str) -> Box<dyn Any> {
     Box::new(())
 }
diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs
index 46f8959b6f2..b1db44dd215 100644
--- a/compiler/rustc_errors/src/markdown/parse.rs
+++ b/compiler/rustc_errors/src/markdown/parse.rs
@@ -74,7 +74,7 @@ enum ParseOpt {
 }
 
 /// Parse a buffer
-pub fn entrypoint(txt: &str) -> MdStream<'_> {
+pub(crate) fn entrypoint(txt: &str) -> MdStream<'_> {
     let ctx = Context { top_block: true, prev: Prev::Newline };
     normalize(parse_recursive(txt.trim().as_bytes(), ctx), &mut Vec::new())
 }
diff --git a/compiler/rustc_errors/src/markdown/term.rs b/compiler/rustc_errors/src/markdown/term.rs
index 06c1333d93d..579e00b8b85 100644
--- a/compiler/rustc_errors/src/markdown/term.rs
+++ b/compiler/rustc_errors/src/markdown/term.rs
@@ -15,7 +15,7 @@ thread_local! {
 }
 
 /// Print to terminal output to a buffer
-pub fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result<()> {
+pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result<()> {
     #[cfg(not(test))]
     if let Some((w, _)) = termize::dimensions() {
         WIDTH.with(|c| c.set(std::cmp::min(w, DEFAULT_COLUMN_WIDTH)));
@@ -47,7 +47,7 @@ fn write_stream(
     Ok(())
 }
 
-pub fn write_tt(tt: &MdTree<'_>, buf: &mut Buffer, indent: usize) -> io::Result<()> {
+fn write_tt(tt: &MdTree<'_>, buf: &mut Buffer, indent: usize) -> io::Result<()> {
     match tt {
         MdTree::CodeBlock { txt, lang: _ } => {
             buf.set_color(ColorSpec::new().set_dimmed(true))?;
diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs
index 50abf8a49c2..8485d7087cf 100644
--- a/compiler/rustc_errors/src/snippet.rs
+++ b/compiler/rustc_errors/src/snippet.rs
@@ -5,13 +5,13 @@ use rustc_macros::{Decodable, Encodable};
 use crate::{Level, Loc};
 
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
-pub struct Line {
+pub(crate) struct Line {
     pub line_index: usize,
     pub annotations: Vec<Annotation>,
 }
 
 #[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Default)]
-pub struct AnnotationColumn {
+pub(crate) struct AnnotationColumn {
     /// the (0-indexed) column for *display* purposes, counted in characters, not utf-8 bytes
     pub display: usize,
     /// the (0-indexed) column in the file, counted in characters, not utf-8 bytes.
@@ -31,13 +31,13 @@ pub struct AnnotationColumn {
 }
 
 impl AnnotationColumn {
-    pub fn from_loc(loc: &Loc) -> AnnotationColumn {
+    pub(crate) fn from_loc(loc: &Loc) -> AnnotationColumn {
         AnnotationColumn { display: loc.col_display, file: loc.col.0 }
     }
 }
 
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
-pub struct MultilineAnnotation {
+pub(crate) struct MultilineAnnotation {
     pub depth: usize,
     pub line_start: usize,
     pub line_end: usize,
@@ -49,19 +49,19 @@ pub struct MultilineAnnotation {
 }
 
 impl MultilineAnnotation {
-    pub fn increase_depth(&mut self) {
+    pub(crate) fn increase_depth(&mut self) {
         self.depth += 1;
     }
 
     /// Compare two `MultilineAnnotation`s considering only the `Span` they cover.
-    pub fn same_span(&self, other: &MultilineAnnotation) -> bool {
+    pub(crate) fn same_span(&self, other: &MultilineAnnotation) -> bool {
         self.line_start == other.line_start
             && self.line_end == other.line_end
             && self.start_col == other.start_col
             && self.end_col == other.end_col
     }
 
-    pub fn as_start(&self) -> Annotation {
+    pub(crate) fn as_start(&self) -> Annotation {
         Annotation {
             start_col: self.start_col,
             end_col: AnnotationColumn {
@@ -76,7 +76,7 @@ impl MultilineAnnotation {
         }
     }
 
-    pub fn as_end(&self) -> Annotation {
+    pub(crate) fn as_end(&self) -> Annotation {
         Annotation {
             start_col: AnnotationColumn {
                 // these might not correspond to the same place anymore,
@@ -91,7 +91,7 @@ impl MultilineAnnotation {
         }
     }
 
-    pub fn as_line(&self) -> Annotation {
+    pub(crate) fn as_line(&self) -> Annotation {
         Annotation {
             start_col: Default::default(),
             end_col: Default::default(),
@@ -103,7 +103,7 @@ impl MultilineAnnotation {
 }
 
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
-pub enum AnnotationType {
+pub(crate) enum AnnotationType {
     /// Annotation under a single line of code
     Singleline,
 
@@ -129,7 +129,7 @@ pub enum AnnotationType {
 }
 
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
-pub struct Annotation {
+pub(crate) struct Annotation {
     /// Start column.
     /// Note that it is important that this field goes
     /// first, so that when we sort, we sort orderings by start
@@ -152,12 +152,12 @@ pub struct Annotation {
 
 impl Annotation {
     /// Whether this annotation is a vertical line placeholder.
-    pub fn is_line(&self) -> bool {
+    pub(crate) fn is_line(&self) -> bool {
         matches!(self.annotation_type, AnnotationType::MultilineLine(_))
     }
 
     /// Length of this annotation as displayed in the stderr output
-    pub fn len(&self) -> usize {
+    pub(crate) fn len(&self) -> usize {
         // Account for usize underflows
         if self.end_col.display > self.start_col.display {
             self.end_col.display - self.start_col.display
@@ -166,7 +166,7 @@ impl Annotation {
         }
     }
 
-    pub fn has_label(&self) -> bool {
+    pub(crate) fn has_label(&self) -> bool {
         if let Some(ref label) = self.label {
             // Consider labels with no text as effectively not being there
             // to avoid weird output with unnecessary vertical lines, like:
@@ -184,7 +184,7 @@ impl Annotation {
         }
     }
 
-    pub fn takes_space(&self) -> bool {
+    pub(crate) fn takes_space(&self) -> bool {
         // Multiline annotations always have to keep vertical space.
         matches!(
             self.annotation_type,
@@ -194,7 +194,7 @@ impl Annotation {
 }
 
 #[derive(Debug)]
-pub struct StyledString {
+pub(crate) struct StyledString {
     pub text: String,
     pub style: Style,
 }
diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs
index 9aa14e1f214..5ca9e9b18f3 100644
--- a/compiler/rustc_errors/src/styled_buffer.rs
+++ b/compiler/rustc_errors/src/styled_buffer.rs
@@ -3,7 +3,7 @@
 use crate::snippet::{Style, StyledString};
 
 #[derive(Debug)]
-pub struct StyledBuffer {
+pub(crate) struct StyledBuffer {
     lines: Vec<Vec<StyledChar>>,
 }
 
@@ -22,12 +22,12 @@ impl StyledChar {
 }
 
 impl StyledBuffer {
-    pub fn new() -> StyledBuffer {
+    pub(crate) fn new() -> StyledBuffer {
         StyledBuffer { lines: vec![] }
     }
 
     /// Returns content of `StyledBuffer` split by lines and line styles
-    pub fn render(&self) -> Vec<Vec<StyledString>> {
+    pub(crate) fn render(&self) -> Vec<Vec<StyledString>> {
         // Tabs are assumed to have been replaced by spaces in calling code.
         debug_assert!(self.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));
 
@@ -70,7 +70,7 @@ impl StyledBuffer {
     /// Sets `chr` with `style` for given `line`, `col`.
     /// If `line` does not exist in our buffer, adds empty lines up to the given
     /// and fills the last line with unstyled whitespace.
-    pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
+    pub(crate) fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
         self.ensure_lines(line);
         if col >= self.lines[line].len() {
             self.lines[line].resize(col + 1, StyledChar::SPACE);
@@ -81,7 +81,7 @@ impl StyledBuffer {
     /// Sets `string` with `style` for given `line`, starting from `col`.
     /// If `line` does not exist in our buffer, adds empty lines up to the given
     /// and fills the last line with unstyled whitespace.
-    pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
+    pub(crate) fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
         let mut n = col;
         for c in string.chars() {
             self.putc(line, n, c, style);
@@ -91,7 +91,7 @@ impl StyledBuffer {
 
     /// For given `line` inserts `string` with `style` before old content of that line,
     /// adding lines if needed
-    pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
+    pub(crate) fn prepend(&mut self, line: usize, string: &str, style: Style) {
         self.ensure_lines(line);
         let string_len = string.chars().count();
 
@@ -107,7 +107,7 @@ impl StyledBuffer {
 
     /// For given `line` inserts `string` with `style` after old content of that line,
     /// adding lines if needed
-    pub fn append(&mut self, line: usize, string: &str, style: Style) {
+    pub(crate) fn append(&mut self, line: usize, string: &str, style: Style) {
         if line >= self.lines.len() {
             self.puts(line, 0, string, style);
         } else {
@@ -116,14 +116,14 @@ impl StyledBuffer {
         }
     }
 
-    pub fn num_lines(&self) -> usize {
+    pub(crate) fn num_lines(&self) -> usize {
         self.lines.len()
     }
 
     /// Set `style` for `line`, `col_start..col_end` range if:
     /// 1. That line and column range exist in `StyledBuffer`
     /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
-    pub fn set_style_range(
+    pub(crate) fn set_style_range(
         &mut self,
         line: usize,
         col_start: usize,
@@ -139,7 +139,7 @@ impl StyledBuffer {
     /// Set `style` for `line`, `col` if:
     /// 1. That line and column exist in `StyledBuffer`
     /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
-    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
+    fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
         if let Some(ref mut line) = self.lines.get_mut(line) {
             if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
                 if overwrite || matches!(s, Style::NoStyle | Style::Quotation) {
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index f6b5cd394b6..0fdccb08918 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -350,7 +350,7 @@ pub(crate) struct ModuleMultipleCandidates {
 
 #[derive(Diagnostic)]
 #[diag(expand_trace_macro)]
-pub struct TraceMacro {
+pub(crate) struct TraceMacro {
     #[primary_span]
     pub span: Span,
 }
@@ -402,14 +402,14 @@ pub(crate) struct CustomAttributePanickedHelp {
 
 #[derive(Diagnostic)]
 #[diag(expand_proc_macro_derive_tokens)]
-pub struct ProcMacroDeriveTokens {
+pub(crate) struct ProcMacroDeriveTokens {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(expand_duplicate_matcher_binding)]
-pub struct DuplicateMatcherBinding {
+pub(crate) struct DuplicateMatcherBinding {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -421,7 +421,7 @@ pub struct DuplicateMatcherBinding {
 #[diag(expand_missing_fragment_specifier)]
 #[note]
 #[help(expand_valid)]
-pub struct MissingFragmentSpecifier {
+pub(crate) struct MissingFragmentSpecifier {
     #[primary_span]
     pub span: Span,
     #[suggestion(
@@ -437,7 +437,7 @@ pub struct MissingFragmentSpecifier {
 #[derive(Diagnostic)]
 #[diag(expand_invalid_fragment_specifier)]
 #[help]
-pub struct InvalidFragmentSpecifier {
+pub(crate) struct InvalidFragmentSpecifier {
     #[primary_span]
     pub span: Span,
     pub fragment: Ident,
@@ -446,7 +446,7 @@ pub struct InvalidFragmentSpecifier {
 
 #[derive(Diagnostic)]
 #[diag(expand_expected_paren_or_brace)]
-pub struct ExpectedParenOrBrace<'a> {
+pub(crate) struct ExpectedParenOrBrace<'a> {
     #[primary_span]
     pub span: Span,
     pub token: Cow<'a, str>,
@@ -479,7 +479,7 @@ pub(crate) struct GlobDelegationTraitlessQpath {
 #[derive(Diagnostic)]
 #[diag(expand_proc_macro_back_compat)]
 #[note]
-pub struct ProcMacroBackCompat {
+pub(crate) struct ProcMacroBackCompat {
     pub crate_name: String,
     pub fixed_version: String,
 }
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 4222c9fe906..777044e3f33 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -13,6 +13,7 @@
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate proc_macro as pm;
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 628c6bfeb79..5778f661622 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -196,13 +196,14 @@ impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
     }
 }
 
-/// Currently used by macro_rules! compilation to extract a little information from the `Failure` case.
-pub struct FailureForwarder<'matcher> {
+/// Currently used by macro_rules! compilation to extract a little information from the `Failure`
+/// case.
+pub(crate) struct FailureForwarder<'matcher> {
     expected_token: Option<&'matcher Token>,
 }
 
 impl<'matcher> FailureForwarder<'matcher> {
-    pub fn new() -> Self {
+    pub(crate) fn new() -> Self {
         Self { expected_token: None }
     }
 }
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index e5b9c627429..9011d02da33 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -407,7 +407,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
 
 // Note: the vectors could be created and dropped within `parse_tt`, but to avoid excess
 // allocations we have a single vector for each kind that is cleared and reused repeatedly.
-pub struct TtParser {
+pub(crate) struct TtParser {
     macro_name: Ident,
 
     /// The set of current mps to be processed. This should be empty by the end of a successful
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index b2f7c8f5183..5df0aebfe57 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -14,12 +14,11 @@ use crate::mbe::macro_parser::count_metavar_decls;
 use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
 
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
-                                        `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
-                                        `literal`, `path`, `meta`, `tt`, `item` and `vis`";
-pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
-                                             `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
-                                             `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
-                                             `item` and `vis`";
+    `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
+    `item` and `vis`";
+pub(crate) const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
+    `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, \
+    `meta`, `tt`, `item` and `vis`";
 
 /// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
 /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 1e455d465e4..469bed3cd59 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -191,12 +191,12 @@ pub(crate) fn placeholder(
 }
 
 #[derive(Default)]
-pub struct PlaceholderExpander {
+pub(crate) struct PlaceholderExpander {
     expanded_fragments: FxHashMap<ast::NodeId, AstFragment>,
 }
 
 impl PlaceholderExpander {
-    pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) {
+    pub(crate) fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) {
         fragment.mut_visit_with(self);
         self.expanded_fragments.insert(id, fragment);
     }
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 1438d1ad11f..4ff5da1a4bd 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -414,7 +414,7 @@ impl ToInternal<rustc_errors::Level> for Level {
     }
 }
 
-pub struct FreeFunctions;
+pub(crate) struct FreeFunctions;
 
 pub(crate) struct Rustc<'a, 'b> {
     ecx: &'a mut ExtCtxt<'b>,
@@ -426,7 +426,7 @@ pub(crate) struct Rustc<'a, 'b> {
 }
 
 impl<'a, 'b> Rustc<'a, 'b> {
-    pub fn new(ecx: &'a mut ExtCtxt<'b>) -> Self {
+    pub(crate) fn new(ecx: &'a mut ExtCtxt<'b>) -> Self {
         let expn_data = ecx.current_expansion.id.expn_data();
         Rustc {
             def_site: ecx.with_def_site_ctxt(expn_data.def_site),
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index dcc1c3202ea..adaaba3cd23 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -15,6 +15,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod accepted;
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index 0a04e6743a8..6e5add24bcc 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_span)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use proc_macro::TokenStream;
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index c8f8fd5be02..b5774f64b66 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -277,6 +277,7 @@
 )]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 59204d79928..b329432d1e1 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -133,6 +133,9 @@ pub enum DefKind {
     /// we treat them all the same, and code which needs to distinguish them can match
     /// or `hir::ClosureKind` or `type_of`.
     Closure,
+    /// The definition of a synthetic coroutine body created by the lowering of a
+    /// coroutine-closure, such as an async closure.
+    SyntheticCoroutineBody,
 }
 
 impl DefKind {
@@ -177,6 +180,7 @@ impl DefKind {
             DefKind::Closure => "closure",
             DefKind::ExternCrate => "extern crate",
             DefKind::GlobalAsm => "global assembly block",
+            DefKind::SyntheticCoroutineBody => "synthetic mir body",
         }
     }
 
@@ -236,7 +240,8 @@ impl DefKind {
             | DefKind::ForeignMod
             | DefKind::GlobalAsm
             | DefKind::Impl { .. }
-            | DefKind::OpaqueTy => None,
+            | DefKind::OpaqueTy
+            | DefKind::SyntheticCoroutineBody => None,
         }
     }
 
@@ -276,6 +281,7 @@ impl DefKind {
             DefKind::GlobalAsm => DefPathData::GlobalAsm,
             DefKind::Impl { .. } => DefPathData::Impl,
             DefKind::Closure => DefPathData::Closure,
+            DefKind::SyntheticCoroutineBody => DefPathData::Closure,
         }
     }
 
@@ -291,7 +297,8 @@ impl DefKind {
             | DefKind::AssocFn
             | DefKind::Ctor(..)
             | DefKind::Closure
-            | DefKind::Static { .. } => true,
+            | DefKind::Static { .. }
+            | DefKind::SyntheticCoroutineBody => true,
             DefKind::Mod
             | DefKind::Struct
             | DefKind::Union
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index e517c3fd07a..c1a4a4497c7 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -10,6 +10,7 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_hir;
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index c30a6f1eeb9..d0b0c08aa79 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -26,13 +26,13 @@ use rustc_span::Span;
 /// Our representation is a bit mixed here -- in some cases, we
 /// include the self type (e.g., `trait_bounds`) but in others we do not
 #[derive(Default, PartialEq, Eq, Clone, Debug)]
-pub struct Bounds<'tcx> {
+pub(crate) struct Bounds<'tcx> {
     clauses: Vec<(ty::Clause<'tcx>, Span)>,
     effects_min_tys: FxIndexMap<Ty<'tcx>, Span>,
 }
 
 impl<'tcx> Bounds<'tcx> {
-    pub fn push_region_bound(
+    pub(crate) fn push_region_bound(
         &mut self,
         tcx: TyCtxt<'tcx>,
         region: ty::PolyTypeOutlivesPredicate<'tcx>,
@@ -42,7 +42,7 @@ impl<'tcx> Bounds<'tcx> {
             .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span));
     }
 
-    pub fn push_trait_bound(
+    pub(crate) fn push_trait_bound(
         &mut self,
         tcx: TyCtxt<'tcx>,
         defining_def_id: DefId,
@@ -154,7 +154,7 @@ impl<'tcx> Bounds<'tcx> {
         self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span));
     }
 
-    pub fn push_projection_bound(
+    pub(crate) fn push_projection_bound(
         &mut self,
         tcx: TyCtxt<'tcx>,
         projection: ty::PolyProjectionPredicate<'tcx>,
@@ -166,14 +166,14 @@ impl<'tcx> Bounds<'tcx> {
         ));
     }
 
-    pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
+    pub(crate) fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
         let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
         let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
         // Preferable to put this obligation first, since we report better errors for sized ambiguity.
         self.clauses.insert(0, (trait_ref.upcast(tcx), span));
     }
 
-    pub fn clauses(
+    pub(crate) fn clauses(
         &self,
         // FIXME(effects): remove tcx
         _tcx: TyCtxt<'tcx>,
@@ -181,7 +181,7 @@ impl<'tcx> Bounds<'tcx> {
         self.clauses.iter().cloned()
     }
 
-    pub fn effects_min_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
+    pub(crate) fn effects_min_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
         self.effects_min_tys.keys().copied()
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 728c3790098..d414bcdb95b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1053,7 +1053,7 @@ fn check_impl_items_against_trait<'tcx>(
     }
 }
 
-pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
+fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
     let t = tcx.type_of(def_id).instantiate_identity();
     if let ty::Adt(def, args) = t.kind()
         && def.is_struct()
diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs
index 19a0476e630..22d7d1fea9c 100644
--- a/compiler/rustc_hir_analysis/src/check/errs.rs
+++ b/compiler/rustc_hir_analysis/src/check/errs.rs
@@ -6,7 +6,7 @@ use rustc_span::Span;
 use crate::errors;
 
 /// Check for shared or mutable references of `static mut` inside expression
-pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
+pub(crate) fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
     let span = expr.span;
     let hir_id = expr.hir_id;
     if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind
@@ -26,7 +26,7 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
 }
 
 /// Check for shared or mutable references of `static mut` inside statement
-pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
+pub(crate) fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
     if let hir::StmtKind::Let(loc) = stmt.kind
         && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
         && let hir::ByRef::Yes(rmutbl) = ba.0
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index bc6641c688c..48335173979 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -22,7 +22,7 @@ use rustc_span::source_map;
 use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut};
 
 #[derive(Debug, Copy, Clone)]
-pub struct Context {
+struct Context {
     /// The scope that contains any new variables declared, plus its depth in
     /// the scope tree.
     var_parent: Option<(Scope, ScopeDepth)>,
@@ -893,7 +893,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
 /// re-use in incremental scenarios. We may sometimes need to rerun the
 /// type checker even when the HIR hasn't changed, and in those cases
 /// we can avoid reconstructing the region scope tree.
-pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
+pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
     let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
     if typeck_root_def_id != def_id {
         return tcx.region_scope_tree(typeck_root_def_id);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index fb9bcc113c6..cb66179ec80 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -2174,7 +2174,8 @@ fn lint_redundant_lifetimes<'tcx>(
         | DefKind::Field
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::Closure => return,
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => return,
     }
 
     // The ordering of this lifetime map is a bit subtle.
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index ed23dc2a827..ca9e2e8a3cc 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -5,7 +5,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_unused_traits, ..*providers };
 }
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index fecd78bc38f..23f1adfe302 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -332,7 +332,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
     }
 }
 
-pub fn coerce_unsized_info<'tcx>(
+pub(crate) fn coerce_unsized_info<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_did: LocalDefId,
 ) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> {
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index 89acb778d6c..bd8b43e28e5 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -19,7 +19,7 @@ use rustc_span::ErrorGuaranteed;
 use crate::errors;
 
 /// On-demand query: yields a map containing all types mapped to their inherent impls.
-pub fn crate_inherent_impls(
+pub(crate) fn crate_inherent_impls(
     tcx: TyCtxt<'_>,
     (): (),
 ) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> {
@@ -32,7 +32,7 @@ pub fn crate_inherent_impls(
     Ok(tcx.arena.alloc(collect.impls_map))
 }
 
-pub fn crate_incoherent_impls(
+pub(crate) fn crate_incoherent_impls(
     tcx: TyCtxt<'_>,
     simp: SimplifiedType,
 ) -> Result<&[DefId], ErrorGuaranteed> {
@@ -43,7 +43,10 @@ pub fn crate_incoherent_impls(
 }
 
 /// On-demand query: yields a vector of the inherent impls for a specific type.
-pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> Result<&[DefId], ErrorGuaranteed> {
+pub(crate) fn inherent_impls(
+    tcx: TyCtxt<'_>,
+    ty_def_id: LocalDefId,
+) -> Result<&[DefId], ErrorGuaranteed> {
     let crate_map = tcx.crate_inherent_impls(())?;
     Ok(match crate_map.inherent_impls.get(&ty_def_id) {
         Some(v) => &v[..],
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index cd5cc33d65a..00bbbf7130f 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -11,7 +11,10 @@ use rustc_span::{ErrorGuaranteed, Symbol};
 use rustc_trait_selection::traits::{self, SkipLeakCheck};
 use smallvec::SmallVec;
 
-pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
+pub(crate) fn crate_inherent_impls_overlap_check(
+    tcx: TyCtxt<'_>,
+    (): (),
+) -> Result<(), ErrorGuaranteed> {
     let mut inherent_overlap_checker = InherentOverlapChecker { tcx };
     let mut res = Ok(());
     for id in tcx.hir().items() {
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 8e4da90ca26..3d800bb165c 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -123,7 +123,7 @@ fn enforce_empty_impls_for_marker_traits(
     .emit())
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     use self::builtin::coerce_unsized_info;
     use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
     use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 0cf9e128bce..e38492d9e64 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -2071,7 +2071,7 @@ fn is_late_bound_map(
     }
 }
 
-pub fn deny_non_region_late_bound(
+fn deny_non_region_late_bound(
     tcx: TyCtxt<'_>,
     bound_vars: &mut FxIndexMap<LocalDefId, ResolvedArg>,
     where_: &str,
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 8cb4ba6c669..96256b91b9f 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -725,7 +725,7 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
     }
 }
 
-pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
+pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
     use hir::intravisit::Visitor;
     if tcx.features().lazy_type_alias {
         return true;
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 620170164f5..edf65245664 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -6,7 +6,7 @@ use rustc_span::Span;
 use rustc_type_ir::fold::TypeFoldable;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub struct Parameter(pub u32);
+pub(crate) struct Parameter(pub u32);
 
 impl From<ty::ParamTy> for Parameter {
     fn from(param: ty::ParamTy) -> Self {
@@ -27,7 +27,7 @@ impl From<ty::ParamConst> for Parameter {
 }
 
 /// Returns the set of parameters constrained by the impl header.
-pub fn parameters_for_impl<'tcx>(
+pub(crate) fn parameters_for_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_self_ty: Ty<'tcx>,
     impl_trait_ref: Option<ty::TraitRef<'tcx>>,
@@ -44,7 +44,7 @@ pub fn parameters_for_impl<'tcx>(
 /// uniquely determined by `value` (see RFC 447). If it is true, return the list
 /// of parameters whose values are needed in order to constrain `value` - these
 /// differ, with the latter being a superset, in the presence of projections.
-pub fn parameters_for<'tcx>(
+pub(crate) fn parameters_for<'tcx>(
     tcx: TyCtxt<'tcx>,
     value: impl TypeFoldable<TyCtxt<'tcx>>,
     include_nonconstraining: bool,
@@ -102,7 +102,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
     }
 }
 
-pub fn identify_constrained_generic_params<'tcx>(
+pub(crate) fn identify_constrained_generic_params<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: ty::GenericPredicates<'tcx>,
     impl_trait_ref: Option<ty::TraitRef<'tcx>>,
@@ -156,7 +156,7 @@ pub fn identify_constrained_generic_params<'tcx>(
 /// which is determined by 1, which requires `U`, that is determined
 /// by 0. I should probably pick a less tangled example, but I can't
 /// think of any.
-pub fn setup_constraining_predicates<'tcx>(
+pub(crate) fn setup_constraining_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: &mut [(ty::Clause<'tcx>, Span)],
     impl_trait_ref: Option<ty::TraitRef<'tcx>>,
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 821f79505f0..39df18ff658 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -11,15 +11,15 @@ use rustc_span::{Span, Symbol};
 
 use crate::fluent_generated as fluent;
 mod pattern_types;
-pub use pattern_types::*;
-pub mod wrong_number_of_generic_args;
+pub(crate) use pattern_types::*;
+pub(crate) mod wrong_number_of_generic_args;
 
 mod precise_captures;
 pub(crate) use precise_captures::*;
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ambiguous_assoc_item)]
-pub struct AmbiguousAssocItem<'a> {
+pub(crate) struct AmbiguousAssocItem<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -30,7 +30,7 @@ pub struct AmbiguousAssocItem<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_assoc_kind_mismatch)]
-pub struct AssocKindMismatch {
+pub(crate) struct AssocKindMismatch {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -52,7 +52,7 @@ pub struct AssocKindMismatch {
     hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg,
     applicability = "maybe-incorrect"
 )]
-pub struct AssocKindMismatchWrapInBracesSugg {
+pub(crate) struct AssocKindMismatchWrapInBracesSugg {
     #[suggestion_part(code = "{{ ")]
     pub lo: Span,
     #[suggestion_part(code = " }}")]
@@ -61,7 +61,7 @@ pub struct AssocKindMismatchWrapInBracesSugg {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_assoc_item_is_private, code = E0624)]
-pub struct AssocItemIsPrivate {
+pub(crate) struct AssocItemIsPrivate {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -73,7 +73,7 @@ pub struct AssocItemIsPrivate {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_assoc_item_not_found, code = E0220)]
-pub struct AssocItemNotFound<'a> {
+pub(crate) struct AssocItemNotFound<'a> {
     #[primary_span]
     pub span: Span,
     pub assoc_name: Ident,
@@ -86,7 +86,7 @@ pub struct AssocItemNotFound<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum AssocItemNotFoundLabel<'a> {
+pub(crate) enum AssocItemNotFoundLabel<'a> {
     #[label(hir_analysis_assoc_item_not_found_label)]
     NotFound {
         #[primary_span]
@@ -105,7 +105,7 @@ pub enum AssocItemNotFoundLabel<'a> {
 
 #[derive(Subdiagnostic)]
 
-pub enum AssocItemNotFoundSugg<'a> {
+pub(crate) enum AssocItemNotFoundSugg<'a> {
     #[suggestion(
         hir_analysis_assoc_item_not_found_similar_sugg,
         code = "{suggested_name}",
@@ -162,7 +162,7 @@ pub enum AssocItemNotFoundSugg<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)]
-pub struct UnrecognizedAtomicOperation<'a> {
+pub(crate) struct UnrecognizedAtomicOperation<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -171,7 +171,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = E0094)]
-pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
+pub(crate) struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -183,7 +183,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_unrecognized_intrinsic_function, code = E0093)]
 #[help]
-pub struct UnrecognizedIntrinsicFunction {
+pub(crate) struct UnrecognizedIntrinsicFunction {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -192,7 +192,7 @@ pub struct UnrecognizedIntrinsicFunction {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_lifetimes_or_bounds_mismatch_on_trait, code = E0195)]
-pub struct LifetimesOrBoundsMismatchOnTrait {
+pub(crate) struct LifetimesOrBoundsMismatchOnTrait {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -208,14 +208,14 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
-pub struct DropImplOnWrongItem {
+pub(crate) struct DropImplOnWrongItem {
     #[primary_span]
     #[label]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-pub enum FieldAlreadyDeclared {
+pub(crate) enum FieldAlreadyDeclared {
     #[diag(hir_analysis_field_already_declared, code = E0124)]
     NotNested {
         field_name: Symbol,
@@ -272,14 +272,14 @@ pub enum FieldAlreadyDeclared {
 
 #[derive(Subdiagnostic)]
 #[help(hir_analysis_field_already_declared_nested_help)]
-pub struct FieldAlreadyDeclaredNestedHelp {
+pub(crate) struct FieldAlreadyDeclaredNestedHelp {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_copy_impl_on_type_with_dtor, code = E0184)]
-pub struct CopyImplOnTypeWithDtor {
+pub(crate) struct CopyImplOnTypeWithDtor {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -287,14 +287,14 @@ pub struct CopyImplOnTypeWithDtor {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)]
-pub struct MultipleRelaxedDefaultBounds {
+pub(crate) struct MultipleRelaxedDefaultBounds {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)]
-pub struct CopyImplOnNonAdt {
+pub(crate) struct CopyImplOnNonAdt {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -302,7 +302,7 @@ pub struct CopyImplOnNonAdt {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_const_param_ty_impl_on_unsized)]
-pub struct ConstParamTyImplOnUnsized {
+pub(crate) struct ConstParamTyImplOnUnsized {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -310,7 +310,7 @@ pub struct ConstParamTyImplOnUnsized {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_const_param_ty_impl_on_non_adt)]
-pub struct ConstParamTyImplOnNonAdt {
+pub(crate) struct ConstParamTyImplOnNonAdt {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -318,7 +318,7 @@ pub struct ConstParamTyImplOnNonAdt {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_trait_object_declared_with_no_traits, code = E0224)]
-pub struct TraitObjectDeclaredWithNoTraits {
+pub(crate) struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
     #[label(hir_analysis_alias_span)]
@@ -327,14 +327,14 @@ pub struct TraitObjectDeclaredWithNoTraits {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ambiguous_lifetime_bound, code = E0227)]
-pub struct AmbiguousLifetimeBound {
+pub(crate) struct AmbiguousLifetimeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)]
-pub struct AssocItemConstraintsNotAllowedHere {
+pub(crate) struct AssocItemConstraintsNotAllowedHere {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -383,7 +383,7 @@ pub(crate) struct EscapingBoundVarInTyOfAssocConstBinding<'tcx> {
 
 #[derive(Subdiagnostic)]
 #[help(hir_analysis_parenthesized_fn_trait_expansion)]
-pub struct ParenthesizedFnTraitExpansion {
+pub(crate) struct ParenthesizedFnTraitExpansion {
     #[primary_span]
     pub span: Span,
 
@@ -392,7 +392,7 @@ pub struct ParenthesizedFnTraitExpansion {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_typeof_reserved_keyword_used, code = E0516)]
-pub struct TypeofReservedKeywordUsed<'tcx> {
+pub(crate) struct TypeofReservedKeywordUsed<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
     #[label]
@@ -403,7 +403,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_value_of_associated_struct_already_specified, code = E0719)]
-pub struct ValueOfAssociatedStructAlreadySpecified {
+pub(crate) struct ValueOfAssociatedStructAlreadySpecified {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -416,7 +416,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_unconstrained_opaque_type)]
 #[note]
-pub struct UnconstrainedOpaqueType {
+pub(crate) struct UnconstrainedOpaqueType {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -426,7 +426,7 @@ pub struct UnconstrainedOpaqueType {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_tait_forward_compat)]
 #[note]
-pub struct TaitForwardCompat {
+pub(crate) struct TaitForwardCompat {
     #[primary_span]
     pub span: Span,
     #[note]
@@ -436,7 +436,7 @@ pub struct TaitForwardCompat {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_tait_forward_compat2)]
 #[note]
-pub struct TaitForwardCompat2 {
+pub(crate) struct TaitForwardCompat2 {
     #[primary_span]
     pub span: Span,
     #[note(hir_analysis_opaque)]
@@ -444,7 +444,7 @@ pub struct TaitForwardCompat2 {
     pub opaque_type: String,
 }
 
-pub struct MissingTypeParams {
+pub(crate) struct MissingTypeParams {
     pub span: Span,
     pub def_span: Span,
     pub span_snippet: Option<String>,
@@ -512,7 +512,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_manual_implementation, code = E0183)]
 #[help]
-pub struct ManualImplementation {
+pub(crate) struct ManualImplementation {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -521,14 +521,14 @@ pub struct ManualImplementation {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_generic_args_on_overridden_impl)]
-pub struct GenericArgsOnOverriddenImpl {
+pub(crate) struct GenericArgsOnOverriddenImpl {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_const_impl_for_non_const_trait)]
-pub struct ConstImplForNonConstTrait {
+pub(crate) struct ConstImplForNonConstTrait {
     #[primary_span]
     pub trait_ref_span: Span,
     pub trait_name: String,
@@ -542,7 +542,7 @@ pub struct ConstImplForNonConstTrait {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_const_bound_for_non_const_trait)]
-pub struct ConstBoundForNonConstTrait {
+pub(crate) struct ConstBoundForNonConstTrait {
     #[primary_span]
     pub span: Span,
     pub modifier: &'static str,
@@ -550,7 +550,7 @@ pub struct ConstBoundForNonConstTrait {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_self_in_impl_self)]
-pub struct SelfInImplSelf {
+pub(crate) struct SelfInImplSelf {
     #[primary_span]
     pub span: MultiSpan,
     #[note]
@@ -567,7 +567,7 @@ pub(crate) struct LinkageType {
 #[derive(Diagnostic)]
 #[help]
 #[diag(hir_analysis_auto_deref_reached_recursion_limit, code = E0055)]
-pub struct AutoDerefReachedRecursionLimit<'a> {
+pub(crate) struct AutoDerefReachedRecursionLimit<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -736,7 +736,7 @@ pub(crate) struct InvalidUnionField {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_invalid_unnamed_field_ty)]
-pub struct InvalidUnnamedFieldTy {
+pub(crate) struct InvalidUnnamedFieldTy {
     #[primary_span]
     pub span: Span,
 }
@@ -894,7 +894,7 @@ pub(crate) struct SIMDFFIHighlyExperimental {
 }
 
 #[derive(Diagnostic)]
-pub enum ImplNotMarkedDefault {
+pub(crate) enum ImplNotMarkedDefault {
     #[diag(hir_analysis_impl_not_marked_default, code = E0520)]
     #[note]
     Ok {
@@ -1137,7 +1137,7 @@ pub(crate) enum LateBoundInApit {
 #[derive(LintDiagnostic)]
 #[diag(hir_analysis_unused_associated_type_bounds)]
 #[note]
-pub struct UnusedAssociatedTypeBounds {
+pub(crate) struct UnusedAssociatedTypeBounds {
     #[suggestion(code = "")]
     pub span: Span,
 }
@@ -1162,7 +1162,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside, code = E0390)]
 #[help]
-pub struct InherentTyOutside {
+pub(crate) struct InherentTyOutside {
     #[primary_span]
     #[help(hir_analysis_span_help)]
     pub span: Span,
@@ -1170,7 +1170,7 @@ pub struct InherentTyOutside {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub struct DispatchFromDynCoercion<'a> {
+pub(crate) struct DispatchFromDynCoercion<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1182,7 +1182,7 @@ pub struct DispatchFromDynCoercion<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
-pub struct DispatchFromDynRepr {
+pub(crate) struct DispatchFromDynRepr {
     #[primary_span]
     pub span: Span,
 }
@@ -1190,7 +1190,7 @@ pub struct DispatchFromDynRepr {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)]
 #[help]
-pub struct InherentTyOutsideRelevant {
+pub(crate) struct InherentTyOutsideRelevant {
     #[primary_span]
     pub span: Span,
     #[help(hir_analysis_span_help)]
@@ -1200,7 +1200,7 @@ pub struct InherentTyOutsideRelevant {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside_new, code = E0116)]
 #[note]
-pub struct InherentTyOutsideNew {
+pub(crate) struct InherentTyOutsideNew {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1209,7 +1209,7 @@ pub struct InherentTyOutsideNew {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside_primitive, code = E0390)]
 #[help]
-pub struct InherentTyOutsidePrimitive {
+pub(crate) struct InherentTyOutsidePrimitive {
     #[primary_span]
     pub span: Span,
     #[help(hir_analysis_span_help)]
@@ -1219,7 +1219,7 @@ pub struct InherentTyOutsidePrimitive {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_primitive_ty, code = E0390)]
 #[help]
-pub struct InherentPrimitiveTy<'a> {
+pub(crate) struct InherentPrimitiveTy<'a> {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -1228,14 +1228,14 @@ pub struct InherentPrimitiveTy<'a> {
 
 #[derive(Subdiagnostic)]
 #[note(hir_analysis_inherent_primitive_ty_note)]
-pub struct InherentPrimitiveTyNote<'a> {
+pub(crate) struct InherentPrimitiveTyNote<'a> {
     pub subty: Ty<'a>,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_dyn, code = E0785)]
 #[note]
-pub struct InherentDyn {
+pub(crate) struct InherentDyn {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1244,7 +1244,7 @@ pub struct InherentDyn {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_nominal, code = E0118)]
 #[note]
-pub struct InherentNominal {
+pub(crate) struct InherentNominal {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1253,7 +1253,7 @@ pub struct InherentNominal {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_dispatch_from_dyn_zst, code = E0378)]
 #[note]
-pub struct DispatchFromDynZST<'a> {
+pub(crate) struct DispatchFromDynZST<'a> {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -1262,7 +1262,7 @@ pub struct DispatchFromDynZST<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub struct DispatchFromDynSingle<'a> {
+pub(crate) struct DispatchFromDynSingle<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1273,7 +1273,7 @@ pub struct DispatchFromDynSingle<'a> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
 #[note]
-pub struct DispatchFromDynMulti {
+pub(crate) struct DispatchFromDynMulti {
     #[primary_span]
     pub span: Span,
     #[note(hir_analysis_coercions_note)]
@@ -1284,7 +1284,7 @@ pub struct DispatchFromDynMulti {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0376)]
-pub struct DispatchFromDynStruct<'a> {
+pub(crate) struct DispatchFromDynStruct<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1292,7 +1292,7 @@ pub struct DispatchFromDynStruct<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0377)]
-pub struct DispatchFromDynSame<'a> {
+pub(crate) struct DispatchFromDynSame<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1304,7 +1304,7 @@ pub struct DispatchFromDynSame<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0374)]
-pub struct CoerceUnsizedOneField<'a> {
+pub(crate) struct CoerceUnsizedOneField<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1315,7 +1315,7 @@ pub struct CoerceUnsizedOneField<'a> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
 #[note]
-pub struct CoerceUnsizedMulti {
+pub(crate) struct CoerceUnsizedMulti {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1327,7 +1327,7 @@ pub struct CoerceUnsizedMulti {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_coerce_unsized_may, code = E0378)]
-pub struct CoerceUnsizedMay<'a> {
+pub(crate) struct CoerceUnsizedMay<'a> {
     #[primary_span]
     pub span: Span,
     pub trait_name: &'a str,
@@ -1335,7 +1335,7 @@ pub struct CoerceUnsizedMay<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
-pub struct TraitCannotImplForTy {
+pub(crate) struct TraitCannotImplForTy {
     #[primary_span]
     pub span: Span,
     pub trait_name: String,
@@ -1347,7 +1347,7 @@ pub struct TraitCannotImplForTy {
 
 #[derive(Subdiagnostic)]
 #[note(hir_analysis_requires_note)]
-pub struct ImplForTyRequires {
+pub(crate) struct ImplForTyRequires {
     #[primary_span]
     pub span: MultiSpan,
     pub error_predicate: String,
@@ -1358,7 +1358,7 @@ pub struct ImplForTyRequires {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_traits_with_defualt_impl, code = E0321)]
 #[note]
-pub struct TraitsWithDefaultImpl<'a> {
+pub(crate) struct TraitsWithDefaultImpl<'a> {
     #[primary_span]
     pub span: Span,
     pub traits: String,
@@ -1368,7 +1368,7 @@ pub struct TraitsWithDefaultImpl<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_cross_crate_traits, code = E0321)]
-pub struct CrossCrateTraits<'a> {
+pub(crate) struct CrossCrateTraits<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1378,7 +1378,7 @@ pub struct CrossCrateTraits<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_cross_crate_traits_defined, code = E0321)]
-pub struct CrossCrateTraitsDefined {
+pub(crate) struct CrossCrateTraitsDefined {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1390,7 +1390,7 @@ pub struct CrossCrateTraitsDefined {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ty_param_first_local, code = E0210)]
 #[note]
-pub struct TyParamFirstLocal<'tcx> {
+pub(crate) struct TyParamFirstLocal<'tcx> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1403,7 +1403,7 @@ pub struct TyParamFirstLocal<'tcx> {
 #[derive(LintDiagnostic)]
 #[diag(hir_analysis_ty_param_first_local, code = E0210)]
 #[note]
-pub struct TyParamFirstLocalLint<'tcx> {
+pub(crate) struct TyParamFirstLocalLint<'tcx> {
     #[label]
     pub span: Span,
     #[note(hir_analysis_case_note)]
@@ -1415,7 +1415,7 @@ pub struct TyParamFirstLocalLint<'tcx> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ty_param_some, code = E0210)]
 #[note]
-pub struct TyParamSome {
+pub(crate) struct TyParamSome {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1427,7 +1427,7 @@ pub struct TyParamSome {
 #[derive(LintDiagnostic)]
 #[diag(hir_analysis_ty_param_some, code = E0210)]
 #[note]
-pub struct TyParamSomeLint {
+pub(crate) struct TyParamSomeLint {
     #[label]
     pub span: Span,
     #[note(hir_analysis_only_note)]
@@ -1436,7 +1436,7 @@ pub struct TyParamSomeLint {
 }
 
 #[derive(Diagnostic)]
-pub enum OnlyCurrentTraits {
+pub(crate) enum OnlyCurrentTraits {
     #[diag(hir_analysis_only_current_traits_outside, code = E0117)]
     Outside {
         #[primary_span]
@@ -1465,20 +1465,20 @@ pub enum OnlyCurrentTraits {
 
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_opaque)]
-pub struct OnlyCurrentTraitsOpaque {
+pub(crate) struct OnlyCurrentTraitsOpaque {
     #[primary_span]
     pub span: Span,
 }
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_foreign)]
-pub struct OnlyCurrentTraitsForeign {
+pub(crate) struct OnlyCurrentTraitsForeign {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_name)]
-pub struct OnlyCurrentTraitsName<'a> {
+pub(crate) struct OnlyCurrentTraitsName<'a> {
     #[primary_span]
     pub span: Span,
     pub name: &'a str,
@@ -1486,7 +1486,7 @@ pub struct OnlyCurrentTraitsName<'a> {
 
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_pointer)]
-pub struct OnlyCurrentTraitsPointer<'a> {
+pub(crate) struct OnlyCurrentTraitsPointer<'a> {
     #[primary_span]
     pub span: Span,
     pub pointer: Ty<'a>,
@@ -1494,7 +1494,7 @@ pub struct OnlyCurrentTraitsPointer<'a> {
 
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_ty)]
-pub struct OnlyCurrentTraitsTy<'a> {
+pub(crate) struct OnlyCurrentTraitsTy<'a> {
     #[primary_span]
     pub span: Span,
     pub ty: Ty<'a>,
@@ -1502,7 +1502,7 @@ pub struct OnlyCurrentTraitsTy<'a> {
 
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_adt)]
-pub struct OnlyCurrentTraitsAdt {
+pub(crate) struct OnlyCurrentTraitsAdt {
     #[primary_span]
     pub span: Span,
     pub name: String,
@@ -1513,11 +1513,11 @@ pub struct OnlyCurrentTraitsAdt {
     hir_analysis_only_current_traits_pointer_sugg,
     applicability = "maybe-incorrect"
 )]
-pub struct OnlyCurrentTraitsPointerSugg<'a> {
+pub(crate) struct OnlyCurrentTraitsPointerSugg<'a> {
     #[suggestion_part(code = "WrapperType")]
     pub wrapper_span: Span,
     #[suggestion_part(code = "struct WrapperType(*{mut_key}{ptr_ty});\n\n")]
-    pub struct_span: Span,
+    pub(crate) struct_span: Span,
     pub mut_key: &'a str,
     pub ptr_ty: Ty<'a>,
 }
@@ -1525,7 +1525,7 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_static_mut_ref, code = E0796)]
 #[note]
-pub struct StaticMutRef<'a> {
+pub(crate) struct StaticMutRef<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1535,7 +1535,7 @@ pub struct StaticMutRef<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum MutRefSugg {
+pub(crate) enum MutRefSugg {
     #[multipart_suggestion(
         hir_analysis_suggestion,
         style = "verbose",
@@ -1565,7 +1565,7 @@ pub enum MutRefSugg {
 #[diag(hir_analysis_static_mut_refs_lint)]
 #[note]
 #[note(hir_analysis_why_note)]
-pub struct RefOfMutStatic<'a> {
+pub(crate) struct RefOfMutStatic<'a> {
     #[label]
     pub span: Span,
     #[subdiagnostic]
@@ -1575,7 +1575,7 @@ pub struct RefOfMutStatic<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_not_supported_delegation)]
-pub struct UnsupportedDelegation<'a> {
+pub(crate) struct UnsupportedDelegation<'a> {
     #[primary_span]
     pub span: Span,
     pub descr: &'a str,
@@ -1585,7 +1585,7 @@ pub struct UnsupportedDelegation<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_method_should_return_future)]
-pub struct MethodShouldReturnFuture {
+pub(crate) struct MethodShouldReturnFuture {
     #[primary_span]
     pub span: Span,
     pub method_name: Symbol,
@@ -1649,7 +1649,7 @@ pub(crate) struct UnconstrainedGenericParameter {
 }
 
 #[derive(Diagnostic)]
-pub enum UnnamedFieldsRepr<'a> {
+pub(crate) enum UnnamedFieldsRepr<'a> {
     #[diag(hir_analysis_unnamed_fields_repr_missing_repr_c)]
     MissingReprC {
         #[primary_span]
@@ -1678,14 +1678,14 @@ pub enum UnnamedFieldsRepr<'a> {
 
 #[derive(Subdiagnostic)]
 #[note(hir_analysis_unnamed_fields_repr_field_defined)]
-pub struct UnnamedFieldsReprFieldDefined {
+pub(crate) struct UnnamedFieldsReprFieldDefined {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
-pub struct OpaqueCapturesHigherRankedLifetime {
+pub(crate) struct OpaqueCapturesHigherRankedLifetime {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -1697,7 +1697,7 @@ pub struct OpaqueCapturesHigherRankedLifetime {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_pattern_type_non_const_range)]
-pub struct NonConstRange {
+pub(crate) struct NonConstRange {
     #[primary_span]
     pub span: Span,
 }
@@ -1706,7 +1706,7 @@ pub struct NonConstRange {
 #[diag(hir_analysis_invalid_receiver_ty, code = E0307)]
 #[note]
 #[help(hir_analysis_invalid_receiver_ty_help)]
-pub struct InvalidReceiverTy<'tcx> {
+pub(crate) struct InvalidReceiverTy<'tcx> {
     #[primary_span]
     pub span: Span,
     pub receiver_ty: Ty<'tcx>,
@@ -1716,12 +1716,12 @@ pub struct InvalidReceiverTy<'tcx> {
 #[diag(hir_analysis_effects_without_next_solver)]
 #[note]
 #[help]
-pub struct EffectsWithoutNextSolver;
+pub(crate) struct EffectsWithoutNextSolver;
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)]
 #[note]
-pub struct CmseCallInputsStackSpill {
+pub(crate) struct CmseCallInputsStackSpill {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1732,7 +1732,7 @@ pub struct CmseCallInputsStackSpill {
 #[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)]
 #[note(hir_analysis_note1)]
 #[note(hir_analysis_note2)]
-pub struct CmseCallOutputStackSpill {
+pub(crate) struct CmseCallOutputStackSpill {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1740,7 +1740,7 @@ pub struct CmseCallOutputStackSpill {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_cmse_call_generic, code = E0798)]
-pub struct CmseCallGeneric {
+pub(crate) struct CmseCallGeneric {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
index 008d2698989..bb771d6ea17 100644
--- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
+++ b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
@@ -3,7 +3,7 @@ use rustc_span::Span;
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_pattern_type_wild_pat)]
-pub struct WildPatTy {
+pub(crate) struct WildPatTy {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
index 8a9b5fe6369..af2bb053c0a 100644
--- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
+++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
@@ -4,7 +4,7 @@ use rustc_span::{Span, Symbol};
 #[derive(Diagnostic)]
 #[diag(hir_analysis_param_not_captured)]
 #[note]
-pub struct ParamNotCaptured {
+pub(crate) struct ParamNotCaptured {
     #[primary_span]
     pub opaque_span: Span,
     #[label]
@@ -15,7 +15,7 @@ pub struct ParamNotCaptured {
 #[derive(Diagnostic)]
 #[diag(hir_analysis_self_ty_not_captured)]
 #[note]
-pub struct SelfTyNotCaptured {
+pub(crate) struct SelfTyNotCaptured {
     #[primary_span]
     pub opaque_span: Span,
     #[label]
@@ -24,7 +24,7 @@ pub struct SelfTyNotCaptured {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_lifetime_not_captured)]
-pub struct LifetimeNotCaptured {
+pub(crate) struct LifetimeNotCaptured {
     #[primary_span]
     pub use_span: Span,
     #[label(hir_analysis_param_label)]
@@ -35,7 +35,7 @@ pub struct LifetimeNotCaptured {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_bad_precise_capture)]
-pub struct BadPreciseCapture {
+pub(crate) struct BadPreciseCapture {
     #[primary_span]
     pub span: Span,
     pub kind: &'static str,
@@ -44,7 +44,7 @@ pub struct BadPreciseCapture {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_precise_capture_self_alias)]
-pub struct PreciseCaptureSelfAlias {
+pub(crate) struct PreciseCaptureSelfAlias {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -54,7 +54,7 @@ pub struct PreciseCaptureSelfAlias {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_duplicate_precise_capture)]
-pub struct DuplicatePreciseCapture {
+pub(crate) struct DuplicatePreciseCapture {
     #[primary_span]
     pub first_span: Span,
     pub name: Symbol,
@@ -64,7 +64,7 @@ pub struct DuplicatePreciseCapture {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_lifetime_must_be_first)]
-pub struct LifetimesMustBeFirst {
+pub(crate) struct LifetimesMustBeFirst {
     #[primary_span]
     pub lifetime_span: Span,
     pub name: Symbol,
diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
index 8ecf53bfacb..f8b2469dfea 100644
--- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
@@ -8,7 +8,7 @@ use rustc_span::def_id::DefId;
 use GenericArgsInfo::*;
 
 /// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
-pub struct WrongNumberOfGenericArgs<'a, 'tcx> {
+pub(crate) struct WrongNumberOfGenericArgs<'a, 'tcx> {
     pub(crate) tcx: TyCtxt<'tcx>,
 
     pub(crate) angle_brackets: AngleBrackets,
@@ -49,7 +49,7 @@ pub(crate) enum AngleBrackets {
 
 // Information about the kind of arguments that are either missing or are unexpected
 #[derive(Debug)]
-pub enum GenericArgsInfo {
+pub(crate) enum GenericArgsInfo {
     MissingLifetimes {
         num_missing_args: usize,
     },
@@ -87,7 +87,7 @@ pub enum GenericArgsInfo {
 }
 
 impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         gen_args_info: GenericArgsInfo,
         path_segment: &'a hir::PathSegment<'_>,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index e99717ce00f..1b73cecd666 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -11,7 +11,7 @@ use crate::errors;
 /// Check conditions on inputs and outputs that the cmse ABIs impose: arguments and results MUST be
 /// returned via registers (i.e. MUST NOT spill to the stack). LLVM will also validate these
 /// conditions, but by checking them here rustc can emit nicer error messages.
-pub fn validate_cmse_abi<'tcx>(
+pub(crate) fn validate_cmse_abi<'tcx>(
     tcx: TyCtxt<'tcx>,
     dcx: DiagCtxtHandle<'_>,
     hir_id: HirId,
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 7d2cabd3f2c..3ecf61501f6 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -11,7 +11,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
 
 use crate::collect::ItemCtxt;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { diagnostic_hir_wf_check, ..*providers };
 }
 
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 02520c472b9..7f183324f04 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -53,7 +53,10 @@ mod min_specialization;
 /// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
 /// //   ^ 'a is unused and appears in assoc type, error
 /// ```
-pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
+pub(crate) fn check_impl_wf(
+    tcx: TyCtxt<'_>,
+    impl_def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
     let min_specialization = tcx.features().min_specialization;
     let mut res = Ok(());
     debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. });
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 291d57f2a17..891e4fcd019 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -72,6 +72,7 @@ This API is completely unstable and subject to change.
 #![feature(slice_partition_dedup)]
 #![feature(try_blocks)]
 #![feature(unwrap_infallible)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[macro_use]
@@ -200,10 +201,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         }
     });
 
-    // Freeze definitions as we don't add new ones at this point. This improves performance by
-    // allowing lock-free access to them.
-    tcx.untracked().definitions.freeze();
-
     // FIXME: Remove this when we implement creating `DefId`s
     // for anon constants during their parents' typeck.
     // Typeck all body owners in parallel will produce queries
diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
index bbfadbb5c30..f576499ecac 100644
--- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
@@ -5,12 +5,12 @@ use rustc_middle::ty::{self, OutlivesPredicate, TyCtxt};
 use super::utils::*;
 
 #[derive(Debug)]
-pub struct ExplicitPredicatesMap<'tcx> {
+pub(crate) struct ExplicitPredicatesMap<'tcx> {
     map: FxIndexMap<DefId, ty::EarlyBinder<'tcx, RequiredPredicates<'tcx>>>,
 }
 
 impl<'tcx> ExplicitPredicatesMap<'tcx> {
-    pub fn new() -> ExplicitPredicatesMap<'tcx> {
+    pub(crate) fn new() -> ExplicitPredicatesMap<'tcx> {
         ExplicitPredicatesMap { map: FxIndexMap::default() }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index cb61ef7c64d..e3cdb1bf5f7 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -9,7 +9,7 @@ mod explicit;
 mod implicit_infer;
 mod utils;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers };
 }
 
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index ce9e73bf245..4fb7a02f8c9 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -12,7 +12,7 @@ use rustc_middle::{bug, span_bug};
 use super::terms::VarianceTerm::*;
 use super::terms::*;
 
-pub struct ConstraintContext<'a, 'tcx> {
+pub(crate) struct ConstraintContext<'a, 'tcx> {
     pub terms_cx: TermsContext<'a, 'tcx>,
 
     // These are pointers to common `ConstantTerm` instances
@@ -27,7 +27,7 @@ pub struct ConstraintContext<'a, 'tcx> {
 /// Declares that the variable `decl_id` appears in a location with
 /// variance `variance`.
 #[derive(Copy, Clone)]
-pub struct Constraint<'a> {
+pub(crate) struct Constraint<'a> {
     pub inferred: InferredIndex,
     pub variance: &'a VarianceTerm<'a>,
 }
@@ -41,11 +41,11 @@ pub struct Constraint<'a> {
 /// ```
 /// then while we are visiting `Bar<T>`, the `CurrentItem` would have
 /// the `DefId` and the start of `Foo`'s inferreds.
-pub struct CurrentItem {
+struct CurrentItem {
     inferred_start: InferredIndex,
 }
 
-pub fn add_constraints_from_crate<'a, 'tcx>(
+pub(crate) fn add_constraints_from_crate<'a, 'tcx>(
     terms_cx: TermsContext<'a, 'tcx>,
 ) -> ConstraintContext<'a, 'tcx> {
     let tcx = terms_cx.tcx;
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 8a4114c3e4b..e8e2caf7e62 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -28,7 +28,7 @@ pub(crate) mod dump;
 /// Code for transforming variances.
 mod xform;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { variances_of, crate_variances, ..*providers };
 }
 
diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs
index e64c6721fe0..4f1bac17e71 100644
--- a/compiler/rustc_hir_analysis/src/variance/solve.rs
+++ b/compiler/rustc_hir_analysis/src/variance/solve.rs
@@ -21,7 +21,7 @@ struct SolveContext<'a, 'tcx> {
     solutions: Vec<ty::Variance>,
 }
 
-pub fn solve_constraints<'tcx>(
+pub(crate) fn solve_constraints<'tcx>(
     constraints_cx: ConstraintContext<'_, 'tcx>,
 ) -> ty::CrateVariancesMap<'tcx> {
     let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs
index 36bff60e019..597699b37b1 100644
--- a/compiler/rustc_hir_analysis/src/variance/terms.rs
+++ b/compiler/rustc_hir_analysis/src/variance/terms.rs
@@ -18,13 +18,13 @@ use rustc_middle::ty::{self, TyCtxt};
 
 use self::VarianceTerm::*;
 
-pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
+pub(crate) type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
 
 #[derive(Copy, Clone, Debug)]
-pub struct InferredIndex(pub usize);
+pub(crate) struct InferredIndex(pub usize);
 
 #[derive(Copy, Clone)]
-pub enum VarianceTerm<'a> {
+pub(crate) enum VarianceTerm<'a> {
     ConstantTerm(ty::Variance),
     TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
     InferredTerm(InferredIndex),
@@ -45,7 +45,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
 
 /// The first pass over the crate simply builds up the set of inferreds.
 
-pub struct TermsContext<'a, 'tcx> {
+pub(crate) struct TermsContext<'a, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
     pub arena: &'a DroplessArena,
 
@@ -62,7 +62,7 @@ pub struct TermsContext<'a, 'tcx> {
     pub inferred_terms: Vec<VarianceTermPtr<'a>>,
 }
 
-pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
+pub(crate) fn determine_parameters_to_be_inferred<'a, 'tcx>(
     tcx: TyCtxt<'tcx>,
     arena: &'a DroplessArena,
 ) -> TermsContext<'a, 'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/variance/xform.rs b/compiler/rustc_hir_analysis/src/variance/xform.rs
index 027f0859fcd..2e9964788e6 100644
--- a/compiler/rustc_hir_analysis/src/variance/xform.rs
+++ b/compiler/rustc_hir_analysis/src/variance/xform.rs
@@ -1,6 +1,6 @@
 use rustc_middle::ty;
 
-pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
+pub(crate) fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
     // Greatest lower bound of the variance lattice as
     // defined in The Paper:
     //
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index cff21173f79..ac6707f9316 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -3,6 +3,7 @@
 
 // tidy-alphabetical-start
 #![recursion_limit = "256"]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cell::Cell;
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index bc0ed4a7fa9..7427fb14716 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn maybe_get_coercion_reason(
+    pub(crate) fn maybe_get_coercion_reason(
         &self,
         hir_id: hir::HirId,
         sp: Span,
@@ -584,7 +584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // (e.g. we're in the tail of a function body)
     //
     // Returns the `LocalDefId` of the RPIT, which is always identity-substituted.
-    pub fn return_position_impl_trait_from_match_expectation(
+    pub(crate) fn return_position_impl_trait_from_match_expectation(
         &self,
         expectation: Expectation<'tcx>,
     ) -> Option<LocalDefId> {
diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs
index 69c4889d7a4..d2d6da8f32b 100644
--- a/compiler/rustc_hir_typeck/src/autoderef.rs
+++ b/compiler/rustc_hir_typeck/src/autoderef.rs
@@ -13,11 +13,11 @@ use super::method::MethodCallee;
 use super::{FnCtxt, PlaceOp};
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> {
+    pub(crate) fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> {
         Autoderef::new(self, self.param_env, self.body_id, span, base_ty)
     }
 
-    pub fn try_overloaded_deref(
+    pub(crate) fn try_overloaded_deref(
         &self,
         span: Span,
         base_ty: Ty<'tcx>,
@@ -26,11 +26,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns the adjustment steps.
-    pub fn adjust_steps(&self, autoderef: &Autoderef<'a, 'tcx>) -> Vec<Adjustment<'tcx>> {
+    pub(crate) fn adjust_steps(&self, autoderef: &Autoderef<'a, 'tcx>) -> Vec<Adjustment<'tcx>> {
         self.register_infer_ok_obligations(self.adjust_steps_as_infer_ok(autoderef))
     }
 
-    pub fn adjust_steps_as_infer_ok(
+    pub(crate) fn adjust_steps_as_infer_ok(
         &self,
         autoderef: &Autoderef<'a, 'tcx>,
     ) -> InferOk<'tcx, Vec<Adjustment<'tcx>>> {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 44cb08e44eb..fc08b872efc 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -29,7 +29,7 @@ use crate::errors;
 /// Checks that it is legal to call methods of the trait corresponding
 /// to `trait_id` (this only cares about the trait, not the specific
 /// method that is called).
-pub fn check_legal_trait_for_method_call(
+pub(crate) fn check_legal_trait_for_method_call(
     tcx: TyCtxt<'_>,
     span: Span,
     receiver: Option<Span>,
@@ -62,7 +62,7 @@ enum CallStep<'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_call(
+    pub(crate) fn check_call(
         &self,
         call_expr: &'tcx hir::Expr<'tcx>,
         callee_expr: &'tcx hir::Expr<'tcx>,
@@ -940,7 +940,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 }
 
 #[derive(Debug)]
-pub struct DeferredCallResolution<'tcx> {
+pub(crate) struct DeferredCallResolution<'tcx> {
     call_expr: &'tcx hir::Expr<'tcx>,
     callee_expr: &'tcx hir::Expr<'tcx>,
     closure_ty: Ty<'tcx>,
@@ -949,7 +949,7 @@ pub struct DeferredCallResolution<'tcx> {
 }
 
 impl<'a, 'tcx> DeferredCallResolution<'tcx> {
-    pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
+    pub(crate) fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
         debug!("DeferredCallResolution::resolve() {:?}", self);
 
         // we should not be invoked until the closure kind has been
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index b47d8a97bce..dabc5a89397 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -976,7 +976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// adjusted type of the expression, if successful.
     /// Adjustments are only recorded if the coercion succeeded.
     /// The expressions *must not* have any preexisting adjustments.
-    pub fn coerce(
+    pub(crate) fn coerce(
         &self,
         expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
@@ -1011,7 +1011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// Returns false if the coercion creates any obligations that result in
     /// errors.
-    pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
+    pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
         // FIXME(-Znext-solver): We need to structurally resolve both types here.
         let source = self.resolve_vars_with_obligations(expr_ty);
         debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
@@ -1032,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Given a type and a target type, this function will calculate and return
     /// how many dereference steps needed to achieve `expr_ty <: target`. If
     /// it's not possible, return `None`.
-    pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<usize> {
+    pub(crate) fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<usize> {
         let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable);
         // We don't ever need two-phase here since we throw out the result of the coercion
         let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
@@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// This function is for diagnostics only, since it does not register
     /// trait or region sub-obligations. (presumably we could, but it's not
     /// particularly important for diagnostics...)
-    pub fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
+    pub(crate) fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
         self.autoderef(DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| {
             self.infcx
                 .type_implements_trait(
@@ -1341,7 +1341,7 @@ pub fn can_coerce<'tcx>(
 /// }
 /// let final_ty = coerce.complete(fcx);
 /// ```
-pub struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> {
+pub(crate) struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> {
     expected_ty: Ty<'tcx>,
     final_ty: Option<Ty<'tcx>>,
     expressions: Expressions<'tcx, 'exprs, E>,
@@ -1350,7 +1350,7 @@ pub struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> {
 
 /// The type of a `CoerceMany` that is storing up the expressions into
 /// a buffer. We use this in `check/mod.rs` for things like `break`.
-pub type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>;
+pub(crate) type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>;
 
 enum Expressions<'tcx, 'exprs, E: AsCoercionSite> {
     Dynamic(Vec<&'tcx hir::Expr<'tcx>>),
@@ -1361,7 +1361,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// The usual case; collect the set of expressions dynamically.
     /// If the full set of coercion sites is known before hand,
     /// consider `with_coercion_sites()` instead to avoid allocation.
-    pub fn new(expected_ty: Ty<'tcx>) -> Self {
+    pub(crate) fn new(expected_ty: Ty<'tcx>) -> Self {
         Self::make(expected_ty, Expressions::Dynamic(vec![]))
     }
 
@@ -1370,7 +1370,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// expected to pass each element in the slice to `coerce(...)` in
     /// order. This is used with arrays in particular to avoid
     /// needlessly cloning the slice.
-    pub fn with_coercion_sites(expected_ty: Ty<'tcx>, coercion_sites: &'exprs [E]) -> Self {
+    pub(crate) fn with_coercion_sites(expected_ty: Ty<'tcx>, coercion_sites: &'exprs [E]) -> Self {
         Self::make(expected_ty, Expressions::UpFront(coercion_sites))
     }
 
@@ -1386,7 +1386,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// Typically, this is used as the expected type when
     /// type-checking each of the alternative expressions whose types
     /// we are trying to merge.
-    pub fn expected_ty(&self) -> Ty<'tcx> {
+    pub(crate) fn expected_ty(&self) -> Ty<'tcx> {
         self.expected_ty
     }
 
@@ -1394,7 +1394,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// at the LUB of the expressions we've seen so far (if any). This
     /// isn't *final* until you call `self.complete()`, which will return
     /// the merged type.
-    pub fn merged_ty(&self) -> Ty<'tcx> {
+    pub(crate) fn merged_ty(&self) -> Ty<'tcx> {
         self.final_ty.unwrap_or(self.expected_ty)
     }
 
@@ -1403,7 +1403,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// could coerce from. This will record `expression`, and later
     /// calls to `coerce` may come back and add adjustments and things
     /// if necessary.
-    pub fn coerce<'a>(
+    pub(crate) fn coerce<'a>(
         &mut self,
         fcx: &FnCtxt<'a, 'tcx>,
         cause: &ObligationCause<'tcx>,
@@ -1425,7 +1425,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     /// The `augment_error` gives you a chance to extend the error
     /// message, in case any results (e.g., we use this to suggest
     /// removing a `;`).
-    pub fn coerce_forced_unit<'a>(
+    pub(crate) fn coerce_forced_unit<'a>(
         &mut self,
         fcx: &FnCtxt<'a, 'tcx>,
         cause: &ObligationCause<'tcx>,
@@ -1920,7 +1920,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         }
     }
 
-    pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> {
+    pub(crate) fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> {
         if let Some(final_ty) = self.final_ty {
             final_ty
         } else {
@@ -1934,7 +1934,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 
 /// Something that can be converted into an expression to which we can
 /// apply a coercion.
-pub trait AsCoercionSite {
+pub(crate) trait AsCoercionSite {
     fn as_coercion_site(&self) -> &hir::Expr<'_>;
 }
 
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 0a9fa5c64a5..89f27e80774 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -18,7 +18,7 @@ use super::method::probe;
 use crate::FnCtxt;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn emit_type_mismatch_suggestions(
+    pub(crate) fn emit_type_mismatch_suggestions(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'tcx>,
@@ -70,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn emit_coerce_suggestions(
+    pub(crate) fn emit_coerce_suggestions(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'tcx>,
@@ -165,13 +165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Requires that the two types unify, and prints an error message if
     /// they don't.
-    pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
+    pub(crate) fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
         if let Err(e) = self.demand_suptype_diag(sp, expected, actual) {
             e.emit();
         }
     }
 
-    pub fn demand_suptype_diag(
+    pub(crate) fn demand_suptype_diag(
         &'a self,
         sp: Span,
         expected: Ty<'tcx>,
@@ -193,13 +193,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e))
     }
 
-    pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
+    pub(crate) fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
         if let Err(err) = self.demand_eqtype_diag(sp, expected, actual) {
             err.emit();
         }
     }
 
-    pub fn demand_eqtype_diag(
+    pub(crate) fn demand_eqtype_diag(
         &'a self,
         sp: Span,
         expected: Ty<'tcx>,
@@ -208,7 +208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
     }
 
-    pub fn demand_eqtype_with_origin(
+    pub(crate) fn demand_eqtype_with_origin(
         &'a self,
         cause: &ObligationCause<'tcx>,
         expected: Ty<'tcx>,
@@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e))
     }
 
-    pub fn demand_coerce(
+    pub(crate) fn demand_coerce(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         checked_ty: Ty<'tcx>,
@@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Notes the point at which a variable is constrained to some type incompatible
     /// with some expectation given by `source`.
-    pub fn note_source_of_type_mismatch_constraint(
+    pub(crate) fn note_source_of_type_mismatch_constraint(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'_>,
@@ -558,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     // When encountering a type error on the value of a `break`, try to point at the reason for the
     // expected type.
-    pub fn annotate_loop_expected_due_to_inference(
+    pub(crate) fn annotate_loop_expected_due_to_inference(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'_>,
@@ -964,7 +964,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
     }
 
-    pub fn get_conversion_methods_for_diagnostic(
+    pub(crate) fn get_conversion_methods_for_diagnostic(
         &self,
         span: Span,
         expected: Ty<'tcx>,
@@ -1186,7 +1186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-pub enum TypeMismatchSource<'tcx> {
+pub(crate) enum TypeMismatchSource<'tcx> {
     /// Expected the binding to have the given type, but it was found to have
     /// a different type. Find out when that type first became incompatible.
     Ty(Ty<'tcx>),
diff --git a/compiler/rustc_hir_typeck/src/diverges.rs b/compiler/rustc_hir_typeck/src/diverges.rs
index aa30fb0f0af..3066561a31d 100644
--- a/compiler/rustc_hir_typeck/src/diverges.rs
+++ b/compiler/rustc_hir_typeck/src/diverges.rs
@@ -8,7 +8,7 @@ use rustc_span::{Span, DUMMY_SP};
 /// as diverging), with some manual adjustments for control-flow
 /// primitives (approximating a CFG).
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub enum Diverges {
+pub(crate) enum Diverges {
     /// Potentially unknown, some cases converge,
     /// others require a CFG to determine them.
     Maybe,
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index c35f7a84c4f..4d2770d2e50 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -17,7 +17,7 @@ use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
-pub struct FieldMultiplySpecifiedInInitializer {
+pub(crate) struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -28,7 +28,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
-pub struct ReturnStmtOutsideOfFnBody {
+pub(crate) struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
     #[label(hir_typeck_encl_body_label)]
@@ -38,7 +38,7 @@ pub struct ReturnStmtOutsideOfFnBody {
     pub statement_kind: ReturnLikeStatementKind,
 }
 
-pub enum ReturnLikeStatementKind {
+pub(crate) enum ReturnLikeStatementKind {
     Return,
     Become,
 }
@@ -57,21 +57,21 @@ impl IntoDiagArg for ReturnLikeStatementKind {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_rustcall_incorrect_args)]
-pub struct RustCallIncorrectArgs {
+pub(crate) struct RustCallIncorrectArgs {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
-pub struct YieldExprOutsideOfCoroutine {
+pub(crate) struct YieldExprOutsideOfCoroutine {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
-pub struct StructExprNonExhaustive {
+pub(crate) struct StructExprNonExhaustive {
     #[primary_span]
     pub span: Span,
     pub what: &'static str,
@@ -79,21 +79,21 @@ pub struct StructExprNonExhaustive {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
-pub struct FunctionalRecordUpdateOnNonStruct {
+pub(crate) struct FunctionalRecordUpdateOnNonStruct {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
-pub struct AddressOfTemporaryTaken {
+pub(crate) struct AddressOfTemporaryTaken {
     #[primary_span]
     #[label]
     pub span: Span,
 }
 
 #[derive(Subdiagnostic)]
-pub enum AddReturnTypeSuggestion {
+pub(crate) enum AddReturnTypeSuggestion {
     #[suggestion(
         hir_typeck_add_return_type_add,
         code = " -> {found}",
@@ -116,7 +116,7 @@ pub enum AddReturnTypeSuggestion {
 }
 
 #[derive(Subdiagnostic)]
-pub enum ExpectedReturnTypeLabel<'tcx> {
+pub(crate) enum ExpectedReturnTypeLabel<'tcx> {
     #[label(hir_typeck_expected_default_return_type)]
     Unit {
         #[primary_span]
@@ -132,7 +132,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_explicit_destructor, code = E0040)]
-pub struct ExplicitDestructorCall {
+pub(crate) struct ExplicitDestructorCall {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -141,7 +141,7 @@ pub struct ExplicitDestructorCall {
 }
 
 #[derive(Subdiagnostic)]
-pub enum ExplicitDestructorCallSugg {
+pub(crate) enum ExplicitDestructorCallSugg {
     #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")]
     Empty(#[primary_span] Span),
     #[multipart_suggestion(hir_typeck_suggestion, style = "short")]
@@ -155,7 +155,7 @@ pub enum ExplicitDestructorCallSugg {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
-pub struct MissingParenthesesInRange {
+pub(crate) struct MissingParenthesesInRange {
     #[primary_span]
     #[label(hir_typeck_missing_parentheses_in_range)]
     pub span: Span,
@@ -166,7 +166,7 @@ pub struct MissingParenthesesInRange {
 }
 
 #[derive(LintDiagnostic)]
-pub enum NeverTypeFallbackFlowingIntoUnsafe {
+pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
     Call,
@@ -187,7 +187,7 @@ pub enum NeverTypeFallbackFlowingIntoUnsafe {
 #[derive(LintDiagnostic)]
 #[help]
 #[diag(hir_typeck_dependency_on_unit_never_type_fallback)]
-pub struct DependencyOnUnitNeverTypeFallback<'tcx> {
+pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
     #[note]
     pub obligation_span: Span,
     pub obligation: ty::Predicate<'tcx>,
@@ -199,7 +199,7 @@ pub struct DependencyOnUnitNeverTypeFallback<'tcx> {
     style = "verbose",
     applicability = "maybe-incorrect"
 )]
-pub struct AddMissingParenthesesInRange {
+pub(crate) struct AddMissingParenthesesInRange {
     pub func_name: String,
     #[suggestion_part(code = "(")]
     pub left: Span,
@@ -207,7 +207,7 @@ pub struct AddMissingParenthesesInRange {
     pub right: Span,
 }
 
-pub struct TypeMismatchFruTypo {
+pub(crate) struct TypeMismatchFruTypo {
     /// Span of the LHS of the range
     pub expr_span: Span,
     /// Span of the `..RHS` part of the range
@@ -246,7 +246,7 @@ impl Subdiagnostic for TypeMismatchFruTypo {
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_lossy_provenance_int2ptr)]
 #[help]
-pub struct LossyProvenanceInt2Ptr<'tcx> {
+pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
     pub expr_ty: Ty<'tcx>,
     pub cast_ty: Ty<'tcx>,
     #[subdiagnostic]
@@ -255,14 +255,14 @@ pub struct LossyProvenanceInt2Ptr<'tcx> {
 
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_ptr_cast_add_auto_to_object)]
-pub struct PtrCastAddAutoToObject {
+pub(crate) struct PtrCastAddAutoToObject {
     pub traits_len: usize,
     pub traits: DiagSymbolList<String>,
 }
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")]
-pub struct LossyProvenanceInt2PtrSuggestion {
+pub(crate) struct LossyProvenanceInt2PtrSuggestion {
     #[suggestion_part(code = "(...).with_addr(")]
     pub lo: Span,
     #[suggestion_part(code = ")")]
@@ -272,7 +272,7 @@ pub struct LossyProvenanceInt2PtrSuggestion {
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_lossy_provenance_ptr2int)]
 #[help]
-pub struct LossyProvenancePtr2Int<'tcx> {
+pub(crate) struct LossyProvenancePtr2Int<'tcx> {
     pub expr_ty: Ty<'tcx>,
     pub cast_ty: Ty<'tcx>,
     #[subdiagnostic]
@@ -280,7 +280,7 @@ pub struct LossyProvenancePtr2Int<'tcx> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum LossyProvenancePtr2IntSuggestion<'tcx> {
+pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> {
     #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
     NeedsParensCast {
         #[suggestion_part(code = "(")]
@@ -314,7 +314,7 @@ pub enum LossyProvenancePtr2IntSuggestion<'tcx> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum HelpUseLatestEdition {
+pub(crate) enum HelpUseLatestEdition {
     #[help(hir_typeck_help_set_edition_cargo)]
     #[note(hir_typeck_note_edition_guide)]
     Cargo { edition: Edition },
@@ -324,7 +324,7 @@ pub enum HelpUseLatestEdition {
 }
 
 impl HelpUseLatestEdition {
-    pub fn new() -> Self {
+    pub(crate) fn new() -> Self {
         let edition = LATEST_STABLE_EDITION;
         if rustc_session::utils::was_invoked_from_cargo() {
             Self::Cargo { edition }
@@ -336,7 +336,7 @@ impl HelpUseLatestEdition {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_invalid_callee, code = E0618)]
-pub struct InvalidCallee {
+pub(crate) struct InvalidCallee {
     #[primary_span]
     pub span: Span,
     pub ty: String,
@@ -344,7 +344,7 @@ pub struct InvalidCallee {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_int_to_fat, code = E0606)]
-pub struct IntToWide<'tcx> {
+pub(crate) struct IntToWide<'tcx> {
     #[primary_span]
     #[label(hir_typeck_int_to_fat_label)]
     pub span: Span,
@@ -357,7 +357,7 @@ pub struct IntToWide<'tcx> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum OptionResultRefMismatch {
+pub(crate) enum OptionResultRefMismatch {
     #[suggestion(
         hir_typeck_option_result_copied,
         code = ".copied()",
@@ -396,7 +396,7 @@ pub enum OptionResultRefMismatch {
     // },
 }
 
-pub struct RemoveSemiForCoerce {
+pub(crate) struct RemoveSemiForCoerce {
     pub expr: Span,
     pub ret: Span,
     pub semi: Span,
@@ -426,7 +426,7 @@ impl Subdiagnostic for RemoveSemiForCoerce {
 #[derive(Diagnostic)]
 #[diag(hir_typeck_const_select_must_be_const)]
 #[help]
-pub struct ConstSelectMustBeConst {
+pub(crate) struct ConstSelectMustBeConst {
     #[primary_span]
     pub span: Span,
 }
@@ -435,7 +435,7 @@ pub struct ConstSelectMustBeConst {
 #[diag(hir_typeck_const_select_must_be_fn)]
 #[note]
 #[help]
-pub struct ConstSelectMustBeFn<'a> {
+pub(crate) struct ConstSelectMustBeFn<'a> {
     #[primary_span]
     pub span: Span,
     pub ty: Ty<'a>,
@@ -443,14 +443,14 @@ pub struct ConstSelectMustBeFn<'a> {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_union_pat_multiple_fields)]
-pub struct UnionPatMultipleFields {
+pub(crate) struct UnionPatMultipleFields {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_union_pat_dotdot)]
-pub struct UnionPatDotDot {
+pub(crate) struct UnionPatDotDot {
     #[primary_span]
     pub span: Span,
 }
@@ -461,7 +461,7 @@ pub struct UnionPatDotDot {
     applicability = "maybe-incorrect",
     style = "verbose"
 )]
-pub struct UseIsEmpty {
+pub(crate) struct UseIsEmpty {
     #[suggestion_part(code = "!")]
     pub lo: Span,
     #[suggestion_part(code = ".is_empty()")]
@@ -471,13 +471,13 @@ pub struct UseIsEmpty {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_arg_mismatch_indeterminate)]
-pub struct ArgMismatchIndeterminate {
+pub(crate) struct ArgMismatchIndeterminate {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Subdiagnostic)]
-pub enum SuggestBoxing {
+pub(crate) enum SuggestBoxing {
     #[note(hir_typeck_suggest_boxing_note)]
     #[multipart_suggestion(
         hir_typeck_suggest_boxing_when_appropriate,
@@ -511,7 +511,7 @@ pub enum SuggestBoxing {
     style = "verbose",
     code = "core::ptr::null_mut()"
 )]
-pub struct SuggestPtrNullMut {
+pub(crate) struct SuggestPtrNullMut {
     #[primary_span]
     pub span: Span,
 }
@@ -519,7 +519,7 @@ pub struct SuggestPtrNullMut {
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_trivial_cast)]
 #[help]
-pub struct TrivialCast<'tcx> {
+pub(crate) struct TrivialCast<'tcx> {
     pub numeric: bool,
     pub expr_ty: Ty<'tcx>,
     pub cast_ty: Ty<'tcx>,
@@ -527,7 +527,7 @@ pub struct TrivialCast<'tcx> {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_no_associated_item, code = E0599)]
-pub struct NoAssociatedItem {
+pub(crate) struct NoAssociatedItem {
     #[primary_span]
     pub span: Span,
     pub item_kind: &'static str,
@@ -539,7 +539,7 @@ pub struct NoAssociatedItem {
 
 #[derive(Subdiagnostic)]
 #[note(hir_typeck_candidate_trait_note)]
-pub struct CandidateTraitNote {
+pub(crate) struct CandidateTraitNote {
     #[primary_span]
     pub span: Span,
     pub trait_name: String,
@@ -549,7 +549,7 @@ pub struct CandidateTraitNote {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
-pub struct CannotCastToBool<'tcx> {
+pub(crate) struct CannotCastToBool<'tcx> {
     #[primary_span]
     pub span: Span,
     pub expr_ty: Ty<'tcx>,
@@ -559,14 +559,14 @@ pub struct CannotCastToBool<'tcx> {
 
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_cast_enum_drop)]
-pub struct CastEnumDrop<'tcx> {
+pub(crate) struct CastEnumDrop<'tcx> {
     pub expr_ty: Ty<'tcx>,
     pub cast_ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
-pub struct CastUnknownPointer {
+pub(crate) struct CastUnknownPointer {
     #[primary_span]
     pub span: Span,
     pub to: bool,
@@ -574,7 +574,7 @@ pub struct CastUnknownPointer {
     pub sub: CastUnknownPointerSub,
 }
 
-pub enum CastUnknownPointerSub {
+pub(crate) enum CastUnknownPointerSub {
     To(Span),
     From(Span),
 }
@@ -601,7 +601,7 @@ impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
 }
 
 #[derive(Subdiagnostic)]
-pub enum CannotCastToBoolHelp {
+pub(crate) enum CannotCastToBoolHelp {
     #[suggestion(
         hir_typeck_suggestion,
         applicability = "machine-applicable",
@@ -615,7 +615,7 @@ pub enum CannotCastToBoolHelp {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_ctor_is_private, code = E0603)]
-pub struct CtorIsPrivate {
+pub(crate) struct CtorIsPrivate {
     #[primary_span]
     pub span: Span,
     pub def: String,
@@ -623,7 +623,7 @@ pub struct CtorIsPrivate {
 
 #[derive(Subdiagnostic)]
 #[note(hir_typeck_deref_is_empty)]
-pub struct DerefImplsIsEmpty {
+pub(crate) struct DerefImplsIsEmpty {
     #[primary_span]
     pub span: Span,
     pub deref_ty: String,
@@ -635,7 +635,7 @@ pub struct DerefImplsIsEmpty {
     applicability = "machine-applicable",
     style = "verbose"
 )]
-pub struct SuggestConvertViaMethod<'tcx> {
+pub(crate) struct SuggestConvertViaMethod<'tcx> {
     #[suggestion_part(code = "{sugg}")]
     pub span: Span,
     #[suggestion_part(code = "")]
@@ -647,13 +647,13 @@ pub struct SuggestConvertViaMethod<'tcx> {
 
 #[derive(Subdiagnostic)]
 #[note(hir_typeck_note_caller_chooses_ty_for_ty_param)]
-pub struct NoteCallerChoosesTyForTyParam<'tcx> {
+pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> {
     pub ty_param_name: Symbol,
     pub found_ty: Ty<'tcx>,
 }
 
 #[derive(Subdiagnostic)]
-pub enum SuggestBoxingForReturnImplTrait {
+pub(crate) enum SuggestBoxingForReturnImplTrait {
     #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")]
     ChangeReturnType {
         #[suggestion_part(code = "Box<dyn")]
@@ -672,7 +672,7 @@ pub enum SuggestBoxingForReturnImplTrait {
 
 #[derive(Diagnostic)]
 #[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)]
-pub struct SelfCtorFromOuterItem {
+pub(crate) struct SelfCtorFromOuterItem {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -683,7 +683,7 @@ pub struct SelfCtorFromOuterItem {
 
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_self_ctor_from_outer_item)]
-pub struct SelfCtorFromOuterItemLint {
+pub(crate) struct SelfCtorFromOuterItemLint {
     #[label]
     pub impl_span: Span,
     #[subdiagnostic]
@@ -692,7 +692,7 @@ pub struct SelfCtorFromOuterItemLint {
 
 #[derive(Subdiagnostic)]
 #[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")]
-pub struct ReplaceWithName {
+pub(crate) struct ReplaceWithName {
     #[primary_span]
     pub span: Span,
     pub name: String,
diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs
index 76ae41db5c5..67f4dbee3cb 100644
--- a/compiler/rustc_hir_typeck/src/expectation.rs
+++ b/compiler/rustc_hir_typeck/src/expectation.rs
@@ -7,7 +7,7 @@ use super::FnCtxt;
 /// When type-checking an expression, we propagate downward
 /// whatever type hint we are able in the form of an `Expectation`.
 #[derive(Copy, Clone, Debug)]
-pub enum Expectation<'tcx> {
+pub(crate) enum Expectation<'tcx> {
     /// We know nothing about what type this expression should have.
     NoExpectation,
 
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 91778a36668..dd33b947b0d 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -51,7 +51,7 @@ use crate::{
 };
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_expr_has_type_or_error(
+    pub(crate) fn check_expr_has_type_or_error(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         expected_ty: Ty<'tcx>,
@@ -977,7 +977,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Check if the expression that could not be assigned to was a typoed expression that
-    pub fn check_for_missing_semi(&self, expr: &'tcx hir::Expr<'tcx>, err: &mut Diag<'_>) -> bool {
+    pub(crate) fn check_for_missing_semi(
+        &self,
+        expr: &'tcx hir::Expr<'tcx>,
+        err: &mut Diag<'_>,
+    ) -> bool {
         if let hir::ExprKind::Binary(binop, lhs, rhs) = expr.kind
             && let hir::BinOpKind::Mul = binop.node
             && self.tcx.sess.source_map().is_multiline(lhs.span.between(rhs.span))
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 6e1b7504626..b1dc19b3777 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -18,7 +18,7 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
 use crate::{errors, FnCtxt, TypeckRootCtxt};
 
 #[derive(Copy, Clone)]
-pub enum DivergingFallbackBehavior {
+pub(crate) enum DivergingFallbackBehavior {
     /// Always fallback to `()` (aka "always spontaneous decay")
     ToUnit,
     /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken.
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 21e6ac9332c..2d205d1ede9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -132,18 +132,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
     }
 
-    pub fn tag(&self) -> String {
+    fn tag(&self) -> String {
         format!("{self:p}")
     }
 
-    pub fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> {
+    pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> {
         self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
             span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
         })
     }
 
     #[inline]
-    pub fn write_ty(&self, id: HirId, ty: Ty<'tcx>) {
+    pub(crate) fn write_ty(&self, id: HirId, ty: Ty<'tcx>) {
         debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
         let mut typeck = self.typeck_results.borrow_mut();
         let mut node_ty = typeck.node_types_mut();
@@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn write_field_index(
+    pub(crate) fn write_field_index(
         &self,
         hir_id: HirId,
         index: FieldIdx,
@@ -198,7 +198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.write_args(hir_id, method.args);
     }
 
-    pub fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) {
+    fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) {
         if !args.is_empty() {
             debug!("write_args({:?}, {:?}) in fcx {}", node_id, args, self.tag());
 
@@ -364,7 +364,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
     }
 
-    pub fn require_type_meets(
+    pub(crate) fn require_type_meets(
         &self,
         ty: Ty<'tcx>,
         span: Span,
@@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
     }
 
-    pub fn require_type_is_sized(
+    pub(crate) fn require_type_is_sized(
         &self,
         ty: Ty<'tcx>,
         span: Span,
@@ -386,7 +386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn require_type_is_sized_deferred(
+    pub(crate) fn require_type_is_sized_deferred(
         &self,
         ty: Ty<'tcx>,
         span: Span,
@@ -397,7 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn require_type_has_static_alignment(
+    pub(crate) fn require_type_has_static_alignment(
         &self,
         ty: Ty<'tcx>,
         span: Span,
@@ -426,7 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn register_bound(
+    pub(crate) fn register_bound(
         &self,
         ty: Ty<'tcx>,
         def_id: DefId,
@@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
+    pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
         let ty = self.lowerer().lower_ty(hir_ty);
         self.register_wf_obligation(ty.into(), hir_ty.span, ObligationCauseCode::WellFormed(None));
         LoweredTy::from_raw(self, hir_ty.span, ty)
@@ -474,7 +474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> {
+    pub(crate) fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> {
         match length {
             hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
             hir::ArrayLen::Body(const_arg) => {
@@ -486,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn lower_const_arg(
+    pub(crate) fn lower_const_arg(
         &self,
         const_arg: &'tcx hir::ConstArg<'tcx>,
         param_def_id: DefId,
@@ -515,7 +515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         t.has_free_regions() || t.has_aliases() || t.has_infer_types()
     }
 
-    pub fn node_ty(&self, id: HirId) -> Ty<'tcx> {
+    pub(crate) fn node_ty(&self, id: HirId) -> Ty<'tcx> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => t,
             None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e),
@@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn node_ty_opt(&self, id: HirId) -> Option<Ty<'tcx>> {
+    pub(crate) fn node_ty_opt(&self, id: HirId) -> Option<Ty<'tcx>> {
         match self.typeck_results.borrow().node_types().get(id) {
             Some(&t) => Some(t),
             None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx, e)),
@@ -538,7 +538,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
-    pub fn register_wf_obligation(
+    pub(crate) fn register_wf_obligation(
         &self,
         arg: ty::GenericArg<'tcx>,
         span: Span,
@@ -555,7 +555,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Registers obligations that all `args` are well-formed.
-    pub fn add_wf_bounds(&self, args: GenericArgsRef<'tcx>, expr: &hir::Expr<'_>) {
+    pub(crate) fn add_wf_bounds(&self, args: GenericArgsRef<'tcx>, expr: &hir::Expr<'_>) {
         for arg in args.iter().filter(|arg| {
             matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
         }) {
@@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // FIXME(arielb1): use this instead of field.ty everywhere
     // Only for fields! Returns <none> for methods>
     // Indifferent to privacy flags
-    pub fn field_ty(
+    pub(crate) fn field_ty(
         &self,
         span: Span,
         field: &'tcx ty::FieldDef,
@@ -897,7 +897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Given a `HirId`, return the `HirId` of the enclosing function, its `FnDecl`, and whether a
     /// suggestion can be made, `None` otherwise.
-    pub fn get_fn_decl(
+    pub(crate) fn get_fn_decl(
         &self,
         blk_id: HirId,
     ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> {
@@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// If no resolution is possible, then an error is reported.
     /// Numeric inference variables may be left unresolved.
-    pub fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub(crate) fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         let ty = self.try_structurally_resolve_type(sp, ty);
 
         if !ty.is_ty_var() {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 130fd130ec8..a8ba9f139cc 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -12,7 +12,7 @@ use rustc_trait_selection::traits;
 use crate::FnCtxt;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn adjust_fulfillment_error_for_expr_obligation(
+    pub(crate) fn adjust_fulfillment_error_for_expr_obligation(
         &self,
         error: &mut traits::FulfillmentError<'tcx>,
     ) -> bool {
@@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
      *
      * This function only updates the error span.
      */
-    pub fn blame_specific_expr_if_possible(
+    pub(crate) fn blame_specific_expr_if_possible(
         &self,
         error: &mut traits::FulfillmentError<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
index 78895689433..cb77d3f85d9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
@@ -17,7 +17,7 @@ rustc_index::newtype_index! {
 }
 
 impl ExpectedIdx {
-    pub fn to_provided_idx(self) -> ProvidedIdx {
+    pub(crate) fn to_provided_idx(self) -> ProvidedIdx {
         ProvidedIdx::from_usize(self.as_usize())
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index aca29d47587..5333982c420 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -45,7 +45,7 @@ use crate::{
 };
 
 #[derive(Clone, Copy, Default)]
-pub enum DivergingBlockBehavior {
+pub(crate) enum DivergingBlockBehavior {
     /// This is the current stable behavior:
     ///
     /// ```rust
@@ -1556,7 +1556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_struct_path(
+    pub(crate) fn check_struct_path(
         &self,
         qpath: &QPath<'tcx>,
         hir_id: HirId,
@@ -1622,7 +1622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_decl_initializer(
+    fn check_decl_initializer(
         &self,
         hir_id: HirId,
         pat: &'tcx hir::Pat<'tcx>,
@@ -1700,7 +1700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Type check a `let` statement.
-    pub fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
+    fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
         self.check_decl(local.into());
         if local.pat.is_never_pattern() {
             self.diverges.set(Diverges::Always {
@@ -1710,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
+    fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {
         // Don't do all the complex logic below for `DeclItem`.
         match stmt.kind {
             hir::StmtKind::Item(..) => return,
@@ -1745,7 +1745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.diverges.set(self.diverges.get() | old_diverges);
     }
 
-    pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
+    pub(crate) fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
         let unit = self.tcx.types.unit;
         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 33f80dd3773..8e69a075030 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -117,7 +117,7 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         root_ctxt: &'a TypeckRootCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         body_id: LocalDefId,
@@ -148,15 +148,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.root_ctxt.infcx.dcx()
     }
 
-    pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {
+    pub(crate) fn cause(
+        &self,
+        span: Span,
+        code: ObligationCauseCode<'tcx>,
+    ) -> ObligationCause<'tcx> {
         ObligationCause::new(span, self.body_id, code)
     }
 
-    pub fn misc(&self, span: Span) -> ObligationCause<'tcx> {
+    pub(crate) fn misc(&self, span: Span) -> ObligationCause<'tcx> {
         self.cause(span, ObligationCauseCode::Misc)
     }
 
-    pub fn sess(&self) -> &Session {
+    pub(crate) fn sess(&self) -> &Session {
         self.tcx.sess
     }
 
@@ -165,7 +169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Use [`InferCtxtErrorExt::err_ctxt`] to start one without a `TypeckResults`.
     ///
     /// [`InferCtxtErrorExt::err_ctxt`]: rustc_trait_selection::error_reporting::InferCtxtErrorExt::err_ctxt
-    pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
+    pub(crate) fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
         let mut sub_relations = SubRelations::default();
         sub_relations.add_constraints(
             self,
@@ -365,7 +369,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
 /// This is a bridge between the interface of HIR ty lowering, which outputs a raw
 /// `Ty`, and the API in this module, which expect `Ty` to be fully normalized.
 #[derive(Clone, Copy, Debug)]
-pub struct LoweredTy<'tcx> {
+pub(crate) struct LoweredTy<'tcx> {
     /// The unnormalized type provided by the user.
     pub raw: Ty<'tcx>,
 
@@ -374,7 +378,7 @@ pub struct LoweredTy<'tcx> {
 }
 
 impl<'tcx> LoweredTy<'tcx> {
-    pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
+    fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
         // FIXME(-Znext-solver): We're still figuring out how to best handle
         // normalization and this doesn't feel too great. We should look at this
         // code again before stabilizing it.
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 11c6e65a211..031aa6159d2 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -64,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// - Points out the method's return type as the reason for the expected type.
     /// - Possible missing semicolon.
     /// - Possible missing return type if the return type is the default, and not `fn main()`.
-    pub fn suggest_mismatched_types_on_tail(
+    pub(crate) fn suggest_mismatched_types_on_tail(
         &self,
         err: &mut Diag<'_>,
         expr: &'tcx hir::Expr<'tcx>,
@@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.err_ctxt().extract_callable_info(self.body_id, self.param_env, ty)
     }
 
-    pub fn suggest_two_fn_call(
+    pub(crate) fn suggest_two_fn_call(
         &self,
         err: &mut Diag<'_>,
         lhs_expr: &'tcx hir::Expr<'tcx>,
@@ -251,7 +251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn suggest_remove_last_method_call(
+    pub(crate) fn suggest_remove_last_method_call(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'tcx>,
@@ -280,7 +280,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
-    pub fn suggest_deref_ref_or_into(
+    pub(crate) fn suggest_deref_ref_or_into(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'tcx>,
@@ -747,7 +747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// If the expression is the expression of a closure without block (`|| expr`), a
     /// block is needed to be added too (`|| { expr; }`). This is denoted by `needs_block`.
-    pub fn suggest_missing_semicolon(
+    pub(crate) fn suggest_missing_semicolon(
         &self,
         err: &mut Diag<'_>,
         expression: &'tcx hir::Expr<'tcx>,
@@ -2077,7 +2077,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     // If the expr is a while or for loop and is the tail expr of its
     // enclosing body suggest returning a value right after it
-    pub fn suggest_returning_value_after_loop(
+    pub(crate) fn suggest_returning_value_after_loop(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index a9c929e76d5..62aa29e673d 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -38,7 +38,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
+    pub(crate) fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
         let tcx = self.tcx;
         let dl = &tcx.data_layout;
         let span = tcx.hir().span(hir_id);
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 8ff4c11f24a..8e6484f1e29 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(try_blocks)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[macro_use]
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index e0c0adac076..2c3cfcf3cbd 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -42,13 +42,13 @@ impl<'a, 'tcx> Deref for ConfirmContext<'a, 'tcx> {
 }
 
 #[derive(Debug)]
-pub struct ConfirmResult<'tcx> {
+pub(crate) struct ConfirmResult<'tcx> {
     pub callee: MethodCallee<'tcx>,
     pub illegal_sized_bound: Option<Span>,
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn confirm_method(
+    pub(crate) fn confirm_method(
         &self,
         span: Span,
         self_expr: &'tcx hir::Expr<'tcx>,
@@ -66,7 +66,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         confirm_cx.confirm(unadjusted_self_ty, pick, segment)
     }
 
-    pub fn confirm_method_for_diagnostic(
+    pub(crate) fn confirm_method_for_diagnostic(
         &self,
         span: Span,
         self_expr: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index d6110ab94c1..39307a29dad 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -4,7 +4,7 @@
 
 mod confirm;
 mod prelude_edition_lints;
-pub mod probe;
+pub(crate) mod probe;
 mod suggest;
 
 use rustc_errors::{Applicability, Diag, SubdiagMessage};
@@ -24,15 +24,15 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{self, NormalizeExt};
 
 use self::probe::{IsSuggestion, ProbeScope};
-pub use self::MethodError::*;
+pub(crate) use self::MethodError::*;
 use crate::FnCtxt;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     probe::provide(providers);
 }
 
 #[derive(Clone, Copy, Debug)]
-pub struct MethodCallee<'tcx> {
+pub(crate) struct MethodCallee<'tcx> {
     /// Impl method ID, for inherent methods, or trait method ID, otherwise.
     pub def_id: DefId,
     pub args: GenericArgsRef<'tcx>,
@@ -44,7 +44,7 @@ pub struct MethodCallee<'tcx> {
 }
 
 #[derive(Debug)]
-pub enum MethodError<'tcx> {
+pub(crate) enum MethodError<'tcx> {
     // Did not find an applicable method, but we did find various near-misses that may work.
     NoMatch(NoMatchData<'tcx>),
 
@@ -70,7 +70,7 @@ pub enum MethodError<'tcx> {
 // Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
 // could lead to matches if satisfied, and a list of not-in-scope traits which may work.
 #[derive(Debug)]
-pub struct NoMatchData<'tcx> {
+pub(crate) struct NoMatchData<'tcx> {
     pub static_candidates: Vec<CandidateSource>,
     pub unsatisfied_predicates:
         Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
@@ -82,7 +82,7 @@ pub struct NoMatchData<'tcx> {
 // A pared down enum describing just the places from which a method
 // candidate can arise. Used for error reporting only.
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum CandidateSource {
+pub(crate) enum CandidateSource {
     Impl(DefId),
     Trait(DefId /* trait id */),
 }
@@ -254,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ok(result.callee)
     }
 
-    pub fn lookup_method_for_diagnostic(
+    pub(crate) fn lookup_method_for_diagnostic(
         &self,
         self_ty: Ty<'tcx>,
         segment: &hir::PathSegment<'tcx>,
@@ -296,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ok(pick)
     }
 
-    pub fn lookup_probe_for_diagnostic(
+    pub(crate) fn lookup_probe_for_diagnostic(
         &self,
         method_name: Ident,
         self_ty: Ty<'tcx>,
@@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Finds item with name `item_name` defined in impl/trait `def_id`
     /// and return it, or `None`, if no such item was defined there.
-    pub fn associated_value(&self, def_id: DefId, item_name: Ident) -> Option<ty::AssocItem> {
+    fn associated_value(&self, def_id: DefId, item_name: Ident) -> Option<ty::AssocItem> {
         self.tcx
             .associated_items(def_id)
             .find_by_name_and_namespace(self.tcx, item_name, Namespace::ValueNS, def_id)
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 28f537c87c4..48e33c81b85 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -38,14 +38,14 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCtxt};
 use smallvec::{smallvec, SmallVec};
 
 use self::CandidateKind::*;
-pub use self::PickKind::*;
+pub(crate) use self::PickKind::*;
 use super::{suggest, CandidateSource, MethodError, NoMatchData};
 use crate::FnCtxt;
 
 /// Boolean flag used to indicate if this search is for a suggestion
 /// or not. If true, we can allow ambiguity and so forth.
 #[derive(Clone, Copy, Debug)]
-pub struct IsSuggestion(pub bool);
+pub(crate) struct IsSuggestion(pub bool);
 
 pub(crate) struct ProbeContext<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -134,7 +134,7 @@ enum ProbeResult {
 /// (at most) one of these. Either the receiver has type `T` and we convert it to `&T` (or with
 /// `mut`), or it has type `*mut T` and we convert it to `*const T`.
 #[derive(Debug, PartialEq, Copy, Clone)]
-pub enum AutorefOrPtrAdjustment {
+pub(crate) enum AutorefOrPtrAdjustment {
     /// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it.
     /// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing.
     Autoref {
@@ -158,7 +158,7 @@ impl AutorefOrPtrAdjustment {
 }
 
 #[derive(Debug, Clone)]
-pub struct Pick<'tcx> {
+pub(crate) struct Pick<'tcx> {
     pub item: ty::AssocItem,
     pub kind: PickKind<'tcx>,
     pub import_ids: SmallVec<[LocalDefId; 1]>,
@@ -179,7 +179,7 @@ pub struct Pick<'tcx> {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub enum PickKind<'tcx> {
+pub(crate) enum PickKind<'tcx> {
     InherentImplPick,
     ObjectPick,
     TraitPick,
@@ -189,10 +189,10 @@ pub enum PickKind<'tcx> {
     ),
 }
 
-pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError<'tcx>>;
+pub(crate) type PickResult<'tcx> = Result<Pick<'tcx>, MethodError<'tcx>>;
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
-pub enum Mode {
+pub(crate) enum Mode {
     // An expression of the form `receiver.method_name(...)`.
     // Autoderefs are performed on `receiver`, lookup is done based on the
     // `self` argument of the method, and static methods aren't considered.
@@ -204,7 +204,7 @@ pub enum Mode {
 }
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
-pub enum ProbeScope {
+pub(crate) enum ProbeScope {
     // Single candidate coming from pre-resolved delegation method.
     Single(DefId),
 
@@ -507,7 +507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     providers.method_autoderef_steps = method_autoderef_steps;
 }
 
@@ -1288,7 +1288,7 @@ impl<'tcx> Pick<'tcx> {
     /// Checks whether two picks do not refer to the same trait item for the same `Self` type.
     /// Only useful for comparisons of picks in order to improve diagnostics.
     /// Do not use for type checking.
-    pub fn differs_from(&self, other: &Self) -> bool {
+    pub(crate) fn differs_from(&self, other: &Self) -> bool {
         let Self {
             item:
                 AssocItem {
@@ -1312,7 +1312,7 @@ impl<'tcx> Pick<'tcx> {
     }
 
     /// In case there were unstable name collisions, emit them as a lint.
-    pub fn maybe_emit_unstable_name_collision_hint(
+    pub(crate) fn maybe_emit_unstable_name_collision_hint(
         &self,
         tcx: TyCtxt<'tcx>,
         span: Span,
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index ffd46ea13b9..b78bb8cb98d 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err
     }
 
-    pub fn suggest_use_shadowed_binding_with_method(
+    fn suggest_use_shadowed_binding_with_method(
         &self,
         self_source: SelfSource<'tcx>,
         method_name: Ident,
@@ -3498,7 +3498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 err,
                                 pick.item.def_id,
                                 rcvr.hir_id,
-                                *rcvr_ty,
+                                Some(*rcvr_ty),
                             );
                         if pick.autoderefs == 0 && !trait_in_other_version_found {
                             err.span_label(
@@ -3689,8 +3689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let SelfSource::QPath(ty) = source
             && !valid_out_of_scope_traits.is_empty()
             && let hir::TyKind::Path(path) = ty.kind
-            && let hir::QPath::Resolved(_, path) = path
-            && let Some(def_id) = path.res.opt_def_id()
+            && let hir::QPath::Resolved(..) = path
             && let Some(assoc) = self
                 .tcx
                 .associated_items(valid_out_of_scope_traits[0])
@@ -3700,7 +3699,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // See if the `Type::function(val)` where `function` wasn't found corresponds to a
             // `Trait` that is imported directly, but `Type` came from a different version of the
             // same crate.
-            let rcvr_ty = self.tcx.type_of(def_id).instantiate_identity();
+
+            let rcvr_ty = self.node_ty_opt(ty.hir_id);
             trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions(
                 err,
                 assoc.def_id,
@@ -4080,7 +4080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err: &mut Diag<'_>,
         item_def_id: DefId,
         hir_id: hir::HirId,
-        rcvr_ty: Ty<'_>,
+        rcvr_ty: Option<Ty<'_>>,
     ) -> bool {
         let hir_id = self.tcx.parent_hir_id(hir_id);
         let Some(traits) = self.tcx.in_scope_traits(hir_id) else { return false };
@@ -4110,8 +4110,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut multi_span: MultiSpan = trait_span.into();
         multi_span.push_span_label(trait_span, format!("this is the trait that is needed"));
         let descr = self.tcx.associated_item(item_def_id).descr();
+        let rcvr_ty =
+            rcvr_ty.map(|t| format!("`{t}`")).unwrap_or_else(|| "the receiver".to_string());
         multi_span
-            .push_span_label(item_span, format!("the {descr} is available for `{rcvr_ty}` here"));
+            .push_span_label(item_span, format!("the {descr} is available for {rcvr_ty} here"));
         for (def_id, import_def_id) in candidates {
             if let Some(import_def_id) = import_def_id {
                 multi_span.push_span_label(
@@ -4221,19 +4223,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum SelfSource<'a> {
+enum SelfSource<'a> {
     QPath(&'a hir::Ty<'a>),
     MethodCall(&'a hir::Expr<'a> /* rcvr */),
 }
 
 #[derive(Copy, Clone, PartialEq, Eq)]
-pub struct TraitInfo {
+pub(crate) struct TraitInfo {
     pub def_id: DefId,
 }
 
 /// Retrieves all traits in this crate and any dependent crates,
 /// and wraps them into `TraitInfo` for custom sorting.
-pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
+pub(crate) fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
     tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
 }
 
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index c54f6cfd099..fb0d30d5b0e 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -25,7 +25,7 @@ use crate::Expectation;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a `a <op>= b`
-    pub fn check_binop_assign(
+    pub(crate) fn check_binop_assign(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
@@ -84,7 +84,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Checks a potentially overloaded binary operator.
-    pub fn check_binop(
+    pub(crate) fn check_binop(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
@@ -770,7 +770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_user_unop(
+    pub(crate) fn check_user_unop(
         &self,
         ex: &'tcx hir::Expr<'tcx>,
         operand_ty: Ty<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index a8e5e09c8bb..206de455cd5 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -944,7 +944,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_dereferenceable(
+    fn check_dereferenceable(
         &self,
         span: Span,
         expected: Ty<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index ad04b6b8b1d..bb227272584 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -246,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// always know whether a place needs to be mutable or not in the first pass.
     /// This happens whether there is an implicit mutable reborrow, e.g. when the type
     /// is used as the receiver of a method call.
-    pub fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
+    pub(crate) fn convert_place_derefs_to_mutable(&self, expr: &hir::Expr<'_>) {
         // Gather up expressions we want to munge.
         let mut exprs = vec![expr];
 
diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
index f22a13d292e..fb0fe23be65 100644
--- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
+++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
@@ -65,7 +65,7 @@ fn record_rvalue_scope(
     }
 }
 
-pub fn resolve_rvalue_scopes<'a, 'tcx>(
+pub(crate) fn resolve_rvalue_scopes<'a, 'tcx>(
     fcx: &'a FnCtxt<'a, 'tcx>,
     scope_tree: &'a ScopeTree,
     def_id: DefId,
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index a43164589b5..e6b8da3e5d6 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -77,7 +77,7 @@ impl<'tcx> Deref for TypeckRootCtxt<'tcx> {
 }
 
 impl<'tcx> TypeckRootCtxt<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
         let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner;
 
         let infcx = tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(def_id).build();
@@ -124,7 +124,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
         infer_ok.value
     }
 
-    pub fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) {
+    fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) {
         let infer_var_info = &mut self.infer_var_info.borrow_mut();
 
         // (*) binder skipped
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 55f002291f0..5350affb3bc 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -74,7 +74,7 @@ enum PlaceAncestryRelation {
 type InferredCaptureInformation<'tcx> = Vec<(Place<'tcx>, ty::CaptureInfo)>;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) {
+    pub(crate) fn closure_analyze(&self, body: &'tcx hir::Body<'tcx>) {
         InferBorrowKindVisitor { fcx: self }.visit_body(body);
 
         // it's our job to process these.
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 0327a3097ec..0853ed9b05b 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -35,7 +35,7 @@ use crate::FnCtxt;
 // resolve_type_vars_in_body, which creates a new TypeTables which
 // doesn't contain any inference types.
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn resolve_type_vars_in_body(
+    pub(crate) fn resolve_type_vars_in_body(
         &self,
         body: &'tcx hir::Body<'tcx>,
     ) -> &'tcx ty::TypeckResults<'tcx> {
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index b29ba59c9f3..46f30526d2a 100644
--- a/compiler/rustc_incremental/src/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
@@ -55,7 +55,7 @@ use {rustc_ast as ast, rustc_graphviz as dot, rustc_hir as hir};
 use crate::errors;
 
 #[allow(missing_docs)]
-pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
+pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
         if tcx.sess.opts.unstable_opts.dump_dep_graph {
             tcx.dep_graph.with_query(dump_graph);
@@ -261,7 +261,7 @@ fn dump_graph(query: &DepGraphQuery) {
 }
 
 #[allow(missing_docs)]
-pub struct GraphvizDepGraph(FxIndexSet<DepKind>, Vec<(DepKind, DepKind)>);
+struct GraphvizDepGraph(FxIndexSet<DepKind>, Vec<(DepKind, DepKind)>);
 
 impl<'a> dot::GraphWalk<'a> for GraphvizDepGraph {
     type Node = DepKind;
diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs
index c6f8b99bcd6..cb21f975878 100644
--- a/compiler/rustc_incremental/src/errors.rs
+++ b/compiler/rustc_incremental/src/errors.rs
@@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
 #[diag(incremental_unrecognized_depnode)]
-pub struct UnrecognizedDepNode {
+pub(crate) struct UnrecognizedDepNode {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -14,28 +14,28 @@ pub struct UnrecognizedDepNode {
 
 #[derive(Diagnostic)]
 #[diag(incremental_missing_depnode)]
-pub struct MissingDepNode {
+pub(crate) struct MissingDepNode {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_missing_if_this_changed)]
-pub struct MissingIfThisChanged {
+pub(crate) struct MissingIfThisChanged {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_ok)]
-pub struct Ok {
+pub(crate) struct Ok {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_no_path)]
-pub struct NoPath {
+pub(crate) struct NoPath {
     #[primary_span]
     pub span: Span,
     pub target: Symbol,
@@ -44,7 +44,7 @@ pub struct NoPath {
 
 #[derive(Diagnostic)]
 #[diag(incremental_assertion_auto)]
-pub struct AssertionAuto<'a> {
+pub(crate) struct AssertionAuto<'a> {
     #[primary_span]
     pub span: Span,
     pub name: &'a str,
@@ -53,7 +53,7 @@ pub struct AssertionAuto<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_undefined_clean_dirty_assertions_item)]
-pub struct UndefinedCleanDirtyItem {
+pub(crate) struct UndefinedCleanDirtyItem {
     #[primary_span]
     pub span: Span,
     pub kind: String,
@@ -61,7 +61,7 @@ pub struct UndefinedCleanDirtyItem {
 
 #[derive(Diagnostic)]
 #[diag(incremental_undefined_clean_dirty_assertions)]
-pub struct UndefinedCleanDirty {
+pub(crate) struct UndefinedCleanDirty {
     #[primary_span]
     pub span: Span,
     pub kind: String,
@@ -69,7 +69,7 @@ pub struct UndefinedCleanDirty {
 
 #[derive(Diagnostic)]
 #[diag(incremental_repeated_depnode_label)]
-pub struct RepeatedDepNodeLabel<'a> {
+pub(crate) struct RepeatedDepNodeLabel<'a> {
     #[primary_span]
     pub span: Span,
     pub label: &'a str,
@@ -77,7 +77,7 @@ pub struct RepeatedDepNodeLabel<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_unrecognized_depnode_label)]
-pub struct UnrecognizedDepNodeLabel<'a> {
+pub(crate) struct UnrecognizedDepNodeLabel<'a> {
     #[primary_span]
     pub span: Span,
     pub label: &'a str,
@@ -85,7 +85,7 @@ pub struct UnrecognizedDepNodeLabel<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_not_dirty)]
-pub struct NotDirty<'a> {
+pub(crate) struct NotDirty<'a> {
     #[primary_span]
     pub span: Span,
     pub dep_node_str: &'a str,
@@ -93,7 +93,7 @@ pub struct NotDirty<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_not_clean)]
-pub struct NotClean<'a> {
+pub(crate) struct NotClean<'a> {
     #[primary_span]
     pub span: Span,
     pub dep_node_str: &'a str,
@@ -101,7 +101,7 @@ pub struct NotClean<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_not_loaded)]
-pub struct NotLoaded<'a> {
+pub(crate) struct NotLoaded<'a> {
     #[primary_span]
     pub span: Span,
     pub dep_node_str: &'a str,
@@ -109,7 +109,7 @@ pub struct NotLoaded<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_unknown_item)]
-pub struct UnknownItem {
+pub(crate) struct UnknownItem {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -117,14 +117,14 @@ pub struct UnknownItem {
 
 #[derive(Diagnostic)]
 #[diag(incremental_no_cfg)]
-pub struct NoCfg {
+pub(crate) struct NoCfg {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_associated_value_expected_for)]
-pub struct AssociatedValueExpectedFor {
+pub(crate) struct AssociatedValueExpectedFor {
     #[primary_span]
     pub span: Span,
     pub ident: Ident,
@@ -132,21 +132,21 @@ pub struct AssociatedValueExpectedFor {
 
 #[derive(Diagnostic)]
 #[diag(incremental_associated_value_expected)]
-pub struct AssociatedValueExpected {
+pub(crate) struct AssociatedValueExpected {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_unchecked_clean)]
-pub struct UncheckedClean {
+pub(crate) struct UncheckedClean {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_old)]
-pub struct DeleteOld<'a> {
+pub(crate) struct DeleteOld<'a> {
     pub name: &'a str,
     pub path: PathBuf,
     pub err: std::io::Error,
@@ -154,7 +154,7 @@ pub struct DeleteOld<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_create_new)]
-pub struct CreateNew<'a> {
+pub(crate) struct CreateNew<'a> {
     pub name: &'a str,
     pub path: PathBuf,
     pub err: std::io::Error,
@@ -162,7 +162,7 @@ pub struct CreateNew<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_write_new)]
-pub struct WriteNew<'a> {
+pub(crate) struct WriteNew<'a> {
     pub name: &'a str,
     pub path: PathBuf,
     pub err: std::io::Error,
@@ -170,14 +170,14 @@ pub struct WriteNew<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_canonicalize_path)]
-pub struct CanonicalizePath {
+pub(crate) struct CanonicalizePath {
     pub path: PathBuf,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_create_incr_comp_dir)]
-pub struct CreateIncrCompDir<'a> {
+pub(crate) struct CreateIncrCompDir<'a> {
     pub tag: &'a str,
     pub path: &'a Path,
     pub err: std::io::Error,
@@ -185,7 +185,7 @@ pub struct CreateIncrCompDir<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_create_lock)]
-pub struct CreateLock<'a> {
+pub(crate) struct CreateLock<'a> {
     pub lock_err: std::io::Error,
     pub session_dir: &'a Path,
     #[note(incremental_lock_unsupported)]
@@ -197,84 +197,84 @@ pub struct CreateLock<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_lock)]
-pub struct DeleteLock<'a> {
+pub(crate) struct DeleteLock<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_hard_link_failed)]
-pub struct HardLinkFailed<'a> {
+pub(crate) struct HardLinkFailed<'a> {
     pub path: &'a Path,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_partial)]
-pub struct DeletePartial<'a> {
+pub(crate) struct DeletePartial<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_full)]
-pub struct DeleteFull<'a> {
+pub(crate) struct DeleteFull<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_finalize)]
-pub struct Finalize<'a> {
+pub(crate) struct Finalize<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_invalid_gc_failed)]
-pub struct InvalidGcFailed<'a> {
+pub(crate) struct InvalidGcFailed<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_finalized_gc_failed)]
-pub struct FinalizedGcFailed<'a> {
+pub(crate) struct FinalizedGcFailed<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_session_gc_failed)]
-pub struct SessionGcFailed<'a> {
+pub(crate) struct SessionGcFailed<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_assert_not_loaded)]
-pub struct AssertNotLoaded;
+pub(crate) struct AssertNotLoaded;
 
 #[derive(Diagnostic)]
 #[diag(incremental_assert_loaded)]
-pub struct AssertLoaded;
+pub(crate) struct AssertLoaded;
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_incompatible)]
-pub struct DeleteIncompatible {
+pub(crate) struct DeleteIncompatible {
     pub path: PathBuf,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_load_dep_graph)]
-pub struct LoadDepGraph {
+pub(crate) struct LoadDepGraph {
     pub path: PathBuf,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_move_dep_graph)]
-pub struct MoveDepGraph<'a> {
+pub(crate) struct MoveDepGraph<'a> {
     pub from: &'a Path,
     pub to: &'a Path,
     pub err: std::io::Error,
@@ -282,14 +282,14 @@ pub struct MoveDepGraph<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_create_dep_graph)]
-pub struct CreateDepGraph<'a> {
+pub(crate) struct CreateDepGraph<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_copy_workproduct_to_cache)]
-pub struct CopyWorkProductToCache<'a> {
+pub(crate) struct CopyWorkProductToCache<'a> {
     pub from: &'a Path,
     pub to: &'a Path,
     pub err: std::io::Error,
@@ -297,13 +297,13 @@ pub struct CopyWorkProductToCache<'a> {
 
 #[derive(Diagnostic)]
 #[diag(incremental_delete_workproduct)]
-pub struct DeleteWorkProduct<'a> {
+pub(crate) struct DeleteWorkProduct<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(incremental_corrupt_file)]
-pub struct CorruptFile<'a> {
+pub(crate) struct CorruptFile<'a> {
     pub path: &'a Path,
 }
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index fcdcb08eed6..c79d108183c 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -6,6 +6,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod assert_dep_graph;
diff --git a/compiler/rustc_incremental/src/persist/data.rs b/compiler/rustc_incremental/src/persist/data.rs
index 81e5410978d..d962dc866f4 100644
--- a/compiler/rustc_incremental/src/persist/data.rs
+++ b/compiler/rustc_incremental/src/persist/data.rs
@@ -4,7 +4,7 @@ use rustc_macros::{Decodable, Encodable};
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 
 #[derive(Debug, Encodable, Decodable)]
-pub struct SerializedWorkProduct {
+pub(crate) struct SerializedWorkProduct {
     /// node that produced the work-product
     pub id: WorkProductId,
 
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 1e02324f404..88cb82f0f37 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -133,7 +133,7 @@ struct Assertion {
     loaded_from_disk: Labels,
 }
 
-pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
+pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
     if !tcx.sess.opts.unstable_opts.query_dep_graph {
         return;
     }
@@ -174,7 +174,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
     })
 }
 
-pub struct DirtyCleanVisitor<'tcx> {
+struct DirtyCleanVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     checked_attrs: FxHashSet<ast::AttrId>,
 }
@@ -429,7 +429,7 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
 /// A visitor that collects all `#[rustc_clean]` attributes from
 /// the HIR. It is used to verify that we really ran checks for all annotated
 /// nodes.
-pub struct FindAllAttrs<'tcx> {
+struct FindAllAttrs<'tcx> {
     tcx: TyCtxt<'tcx>,
     found_attrs: Vec<&'tcx Attribute>,
 }
diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs
index 174414d0c85..f834c48cbf8 100644
--- a/compiler/rustc_incremental/src/persist/file_format.rs
+++ b/compiler/rustc_incremental/src/persist/file_format.rs
@@ -89,7 +89,7 @@ where
 ///   incompatible version of the compiler.
 /// - Returns `Err(..)` if some kind of IO error occurred while reading the
 ///   file.
-pub fn read_file(
+pub(crate) fn read_file(
     path: &Path,
     report_incremental_info: bool,
     is_nightly_build: bool,
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 0e87bc1e692..feb25a9a89d 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -157,7 +157,7 @@ pub(crate) fn work_products_path(sess: &Session) -> PathBuf {
 }
 
 /// Returns the path to a session's query cache.
-pub fn query_cache_path(sess: &Session) -> PathBuf {
+pub(crate) fn query_cache_path(sess: &Session) -> PathBuf {
     in_incr_comp_dir_sess(sess, QUERY_CACHE_FILENAME)
 }
 
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index b9d2a43206b..eb47ac3c68e 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -3,6 +3,7 @@
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 #![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))]
 #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod bit_set;
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 1a5c0137219..76ea9c3433d 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -3,7 +3,7 @@ use rustc_span::Span;
 
 #[derive(Diagnostic)]
 #[diag(infer_opaque_hidden_type)]
-pub struct OpaqueHiddenTypeDiag {
+pub(crate) struct OpaqueHiddenTypeDiag {
     #[primary_span]
     #[label]
     pub span: Span,
diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs
index 0dde3082d48..9a5674369da 100644
--- a/compiler/rustc_infer/src/infer/free_regions.rs
+++ b/compiler/rustc_infer/src/infer/free_regions.rs
@@ -18,11 +18,11 @@ pub(crate) struct RegionRelations<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, free_regions: &'a FreeRegionMap<'tcx>) -> Self {
+    pub(crate) fn new(tcx: TyCtxt<'tcx>, free_regions: &'a FreeRegionMap<'tcx>) -> Self {
         Self { tcx, free_regions }
     }
 
-    pub fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
+    pub(crate) fn lub_param_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {
         self.free_regions.lub_param_regions(self.tcx, r_a, r_b)
     }
 }
@@ -80,7 +80,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
     /// cases, this is more conservative than necessary, in order to
     /// avoid making arbitrary choices. See
     /// `TransitiveRelation::postdom_upper_bound` for more details.
-    pub fn lub_param_regions(
+    pub(crate) fn lub_param_regions(
         &self,
         tcx: TyCtxt<'tcx>,
         r_a: Region<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index c2c0c7a41fe..e5533213400 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -43,7 +43,7 @@ pub(crate) fn resolve<'tcx>(
 /// Contains the result of lexical region resolution. Offers methods
 /// to lookup up the final value of a region variable.
 #[derive(Clone)]
-pub struct LexicalRegionResolutions<'tcx> {
+pub(crate) struct LexicalRegionResolutions<'tcx> {
     pub(crate) values: IndexVec<RegionVid, VarValue<'tcx>>,
 }
 
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 542104fa10b..6fa10a95313 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -705,7 +705,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
 /// not only the generalized type, but also a bool flag
 /// indicating whether further WF checks are needed.
 #[derive(Debug)]
-pub struct Generalization<T> {
+struct Generalization<T> {
     /// When generalizing `<?0 as Trait>::Assoc` or
     /// `<T as Bar<<?0 as Foo>::Assoc>>::Assoc`
     /// for `?0` generalization returns an inference
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index f555fedbb5b..1eafbb9acb3 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -29,7 +29,7 @@ use crate::traits::ObligationCause;
 ///
 /// GLB moves "down" the lattice (to smaller values); LUB moves
 /// "up" the lattice (to bigger values).
-pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<InferCtxt<'tcx>> {
+pub(crate) trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<InferCtxt<'tcx>> {
     fn infcx(&self) -> &'f InferCtxt<'tcx>;
 
     fn cause(&self) -> &ObligationCause<'tcx>;
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index bc954054ea2..fdf55447f79 100644
--- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -170,7 +170,7 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 }
 
-pub struct InferenceFudger<'a, 'tcx> {
+struct InferenceFudger<'a, 'tcx> {
     infcx: &'a InferCtxt<'tcx>,
     type_vars: (Range<TyVid>, Vec<TypeVariableOrigin>),
     int_vars: Range<IntVid>,
diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index 50a0d3bf214..366af913ddc 100644
--- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
@@ -158,7 +158,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
 }
 
 impl<'tcx> InferCtxtUndoLogs<'tcx> {
-    pub fn start_snapshot(&mut self) -> Snapshot<'tcx> {
+    pub(crate) fn start_snapshot(&mut self) -> Snapshot<'tcx> {
         self.num_open_snapshots += 1;
         Snapshot { undo_len: self.logs.len(), _marker: PhantomData }
     }
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 25ac8ba974b..94aa2ddd92f 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -27,9 +27,8 @@
 #![feature(iterator_try_collect)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![feature(try_blocks)]
-#![feature(yeet_expr)]
 #![recursion_limit = "512"] // For rustdoc
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[macro_use]
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 4f34c139545..3a05b576a97 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -22,7 +22,7 @@ pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine};
 pub(crate) use self::project::UndoLog;
 pub use self::project::{
     MismatchedProjectionTypes, Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry,
-    ProjectionCacheKey, ProjectionCacheStorage, Reveal,
+    ProjectionCacheKey, ProjectionCacheStorage,
 };
 pub use self::ImplSource::*;
 pub use self::SelectionError::*;
diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs
index 9ed557ec40b..3d4ec9e51db 100644
--- a/compiler/rustc_infer/src/traits/project.rs
+++ b/compiler/rustc_infer/src/traits/project.rs
@@ -2,7 +2,7 @@
 
 use rustc_data_structures::snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage};
 use rustc_data_structures::undo_log::Rollback;
-pub use rustc_middle::traits::{EvaluationResult, Reveal};
+use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty;
 
 use super::PredicateObligation;
diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs
index 786e2bb511f..f66b9eb3a28 100644
--- a/compiler/rustc_interface/src/callbacks.rs
+++ b/compiler/rustc_interface/src/callbacks.rs
@@ -18,11 +18,19 @@ use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug;
 use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode};
 
 fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
-    tls::with_opt(|tcx| {
-        if let Some(tcx) = tcx {
-            let _span = tcx.source_span(def_id);
-            // Sanity check: relative span's parent must be an absolute span.
-            debug_assert_eq!(_span.data_untracked().parent, None);
+    tls::with_context_opt(|icx| {
+        if let Some(icx) = icx {
+            // `track_span_parent` gets called a lot from HIR lowering code.
+            // Skip doing anything if we aren't tracking dependencies.
+            let tracks_deps = match icx.task_deps {
+                TaskDepsRef::Allow(..) => true,
+                TaskDepsRef::EvalAlways | TaskDepsRef::Ignore | TaskDepsRef::Forbid => false,
+            };
+            if tracks_deps {
+                let _span = icx.tcx.source_span(def_id);
+                // Sanity check: relative span's parent must be an absolute span.
+                debug_assert_eq!(_span.data_untracked().parent, None);
+            }
         }
     })
 }
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 3492df69b8d..3b6c2acaf30 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -2,6 +2,7 @@
 #![feature(decl_macro)]
 #![feature(let_chains)]
 #![feature(try_blocks)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod callbacks;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 96a6f52d60b..779b98d073d 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -784,7 +784,20 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
             }
         );
     });
+
     rustc_hir_analysis::check_crate(tcx);
+    sess.time("MIR_coroutine_by_move_body", || {
+        tcx.hir().par_body_owners(|def_id| {
+            if tcx.needs_coroutine_by_move_body_def_id(def_id) {
+                tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id);
+            }
+        });
+    });
+    // Freeze definitions as we don't add new ones at this point.
+    // We need to wait until now since we synthesize a by-move body
+    // This improves performance by allowing lock-free access to them.
+    tcx.untracked().definitions.freeze();
+
     sess.time("MIR_borrow_checking", || {
         tcx.hir().par_body_owners(|def_id| {
             // Run unsafety check because it's responsible for stealing and
@@ -816,6 +829,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
             );
         }
     });
+
     sess.time("layout_testing", || layout_test::test_layout(tcx));
     sess.time("abi_testing", || abi_test::test_abi(tcx));
 
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 34f2dca7c42..486136a2bcc 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -774,6 +774,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(direct_access_external_data, Some(true));
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
+    tracked!(embed_source, true);
     tracked!(emit_thin_lto, false);
     tracked!(export_executable_symbols, true);
     tracked!(fewer_names, Some(true));
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 2116ba6c079..31fdd2d7cec 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -23,6 +23,7 @@
 // We want to be able to build this crate with a stable compiler,
 // so no `#![feature]` attributes should be added.
 #![deny(unstable_features)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod cursor;
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 6fb0a624644..0ee9dda1fef 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -413,7 +413,7 @@ pub fn check_ast_node<'a>(
     }
 }
 
-pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
+fn check_ast_node_inner<'a, T: EarlyLintPass>(
     sess: &Session,
     check_node: impl EarlyCheckNode<'a>,
     context: EarlyContext<'_>,
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index 85ee18aba8f..d109a5c9030 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -8,7 +8,7 @@ use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
 #[diag(lint_overruled_attribute, code = E0453)]
-pub struct OverruledAttribute<'a> {
+pub(crate) struct OverruledAttribute<'a> {
     #[primary_span]
     pub span: Span,
     #[label]
@@ -19,7 +19,7 @@ pub struct OverruledAttribute<'a> {
     pub sub: OverruledAttributeSub,
 }
 
-pub enum OverruledAttributeSub {
+pub(crate) enum OverruledAttributeSub {
     DefaultSource { id: String },
     NodeSource { span: Span, reason: Option<Symbol> },
     CommandLineSource,
@@ -52,7 +52,7 @@ impl Subdiagnostic for OverruledAttributeSub {
 
 #[derive(Diagnostic)]
 #[diag(lint_malformed_attribute, code = E0452)]
-pub struct MalformedAttribute {
+pub(crate) struct MalformedAttribute {
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
@@ -60,7 +60,7 @@ pub struct MalformedAttribute {
 }
 
 #[derive(Subdiagnostic)]
-pub enum MalformedAttributeSub {
+pub(crate) enum MalformedAttributeSub {
     #[label(lint_bad_attribute_argument)]
     BadAttributeArgument(#[primary_span] Span),
     #[label(lint_reason_must_be_string_literal)]
@@ -71,7 +71,7 @@ pub enum MalformedAttributeSub {
 
 #[derive(Diagnostic)]
 #[diag(lint_unknown_tool_in_scoped_lint, code = E0710)]
-pub struct UnknownToolInScopedLint {
+pub(crate) struct UnknownToolInScopedLint {
     #[primary_span]
     pub span: Option<Span>,
     pub tool_name: Symbol,
@@ -82,7 +82,7 @@ pub struct UnknownToolInScopedLint {
 
 #[derive(Diagnostic)]
 #[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = E0783)]
-pub struct BuiltinEllipsisInclusiveRangePatterns {
+pub(crate) struct BuiltinEllipsisInclusiveRangePatterns {
     #[primary_span]
     pub span: Span,
     #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
@@ -92,20 +92,20 @@ pub struct BuiltinEllipsisInclusiveRangePatterns {
 
 #[derive(Subdiagnostic)]
 #[note(lint_requested_level)]
-pub struct RequestedLevel<'a> {
+pub(crate) struct RequestedLevel<'a> {
     pub level: Level,
     pub lint_name: &'a str,
 }
 
 #[derive(Diagnostic)]
 #[diag(lint_unsupported_group, code = E0602)]
-pub struct UnsupportedGroup {
+pub(crate) struct UnsupportedGroup {
     pub lint_group: String,
 }
 
 #[derive(Diagnostic)]
 #[diag(lint_check_name_unknown_tool, code = E0602)]
-pub struct CheckNameUnknownTool<'a> {
+pub(crate) struct CheckNameUnknownTool<'a> {
     pub tool_name: Symbol,
     #[subdiagnostic]
     pub sub: RequestedLevel<'a>,
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 2e0da69e920..8824e1dfe50 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -10,7 +10,9 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
+use rustc_session::lint::FutureIncompatibilityReason;
 use rustc_session::{declare_lint, declare_lint_pass};
+use rustc_span::edition::Edition;
 use rustc_span::Span;
 
 use crate::{fluent_generated as fluent, LateContext, LateLintPass};
@@ -54,10 +56,10 @@ declare_lint! {
     pub IMPL_TRAIT_OVERCAPTURES,
     Allow,
     "`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
-    //@future_incompatible = FutureIncompatibleInfo {
-    //    reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
-    //    reference: "<FIXME>",
-    //};
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
+        reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>",
+    };
 }
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 638b623510e..cb369d99a84 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -47,7 +47,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
 
 /// Implements the AST traversal for late lint passes. `T` provides the
 /// `check_*` methods.
-pub struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> {
+struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> {
     context: LateContext<'tcx>,
     pass: T,
 }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 91d4f95df80..07ac63ec96c 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1103,7 +1103,7 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers };
 }
 
-pub fn parse_lint_and_tool_name(lint_name: &str) -> (Option<Symbol>, &str) {
+pub(crate) fn parse_lint_and_tool_name(lint_name: &str) -> (Option<Symbol>, &str) {
     match lint_name.split_once("::") {
         Some((tool_name, lint_name)) => {
             let tool_name = Symbol::intern(tool_name);
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index a6e7d288f08..c5a5c5b30af 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -39,6 +39,7 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(trait_upcasting)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod async_closures;
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index c12c5427997..c6bcb1f3e83 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -26,7 +26,7 @@ use crate::{fluent_generated as fluent, LateContext};
 // array_into_iter.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_shadowed_into_iter)]
-pub struct ShadowedIntoIterDiag {
+pub(crate) struct ShadowedIntoIterDiag {
     pub target: &'static str,
     pub edition: &'static str,
     #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
@@ -36,7 +36,7 @@ pub struct ShadowedIntoIterDiag {
 }
 
 #[derive(Subdiagnostic)]
-pub enum ShadowedIntoIterDiagSub {
+pub(crate) enum ShadowedIntoIterDiagSub {
     #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
     RemoveIntoIter {
         #[primary_span]
@@ -57,7 +57,7 @@ pub enum ShadowedIntoIterDiagSub {
 // builtin.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_while_true)]
-pub struct BuiltinWhileTrue {
+pub(crate) struct BuiltinWhileTrue {
     #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
     pub suggestion: Span,
     pub replace: String,
@@ -65,7 +65,7 @@ pub struct BuiltinWhileTrue {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_non_shorthand_field_patterns)]
-pub struct BuiltinNonShorthandFieldPatterns {
+pub(crate) struct BuiltinNonShorthandFieldPatterns {
     pub ident: Ident,
     #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")]
     pub suggestion: Span,
@@ -73,7 +73,7 @@ pub struct BuiltinNonShorthandFieldPatterns {
 }
 
 #[derive(LintDiagnostic)]
-pub enum BuiltinUnsafe {
+pub(crate) enum BuiltinUnsafe {
     #[diag(lint_builtin_allow_internal_unsafe)]
     AllowInternalUnsafe,
     #[diag(lint_builtin_unsafe_block)]
@@ -121,16 +121,16 @@ pub enum BuiltinUnsafe {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_missing_doc)]
-pub struct BuiltinMissingDoc<'a> {
+pub(crate) struct BuiltinMissingDoc<'a> {
     pub article: &'a str,
     pub desc: &'a str,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_missing_copy_impl)]
-pub struct BuiltinMissingCopyImpl;
+pub(crate) struct BuiltinMissingCopyImpl;
 
-pub struct BuiltinMissingDebugImpl<'a> {
+pub(crate) struct BuiltinMissingDebugImpl<'a> {
     pub tcx: TyCtxt<'a>,
     pub def_id: DefId,
 }
@@ -145,7 +145,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_anonymous_params)]
-pub struct BuiltinAnonymousParams<'a> {
+pub(crate) struct BuiltinAnonymousParams<'a> {
     #[suggestion(code = "_: {ty_snip}")]
     pub suggestion: (Span, Applicability),
     pub ty_snip: &'a str,
@@ -154,7 +154,7 @@ pub struct BuiltinAnonymousParams<'a> {
 // FIXME(davidtwco) translatable deprecated attr
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_deprecated_attr_link)]
-pub struct BuiltinDeprecatedAttrLink<'a> {
+pub(crate) struct BuiltinDeprecatedAttrLink<'a> {
     pub name: Symbol,
     pub reason: &'a str,
     pub link: &'a str,
@@ -163,7 +163,7 @@ pub struct BuiltinDeprecatedAttrLink<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
+pub(crate) enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
     #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")]
     Msg {
         #[primary_span]
@@ -179,7 +179,7 @@ pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_deprecated_attr_used)]
-pub struct BuiltinDeprecatedAttrUsed {
+pub(crate) struct BuiltinDeprecatedAttrUsed {
     pub name: String,
     #[suggestion(
         lint_builtin_deprecated_attr_default_suggestion,
@@ -192,7 +192,7 @@ pub struct BuiltinDeprecatedAttrUsed {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_unused_doc_comment)]
-pub struct BuiltinUnusedDocComment<'a> {
+pub(crate) struct BuiltinUnusedDocComment<'a> {
     pub kind: &'a str,
     #[label]
     pub label: Span,
@@ -201,7 +201,7 @@ pub struct BuiltinUnusedDocComment<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum BuiltinUnusedDocCommentSub {
+pub(crate) enum BuiltinUnusedDocCommentSub {
     #[help(lint_plain_help)]
     PlainHelp,
     #[help(lint_block_help)]
@@ -210,7 +210,7 @@ pub enum BuiltinUnusedDocCommentSub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_no_mangle_generic)]
-pub struct BuiltinNoMangleGeneric {
+pub(crate) struct BuiltinNoMangleGeneric {
     // Use of `#[no_mangle]` suggests FFI intent; correct
     // fix may be to monomorphize source by hand
     #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")]
@@ -219,21 +219,21 @@ pub struct BuiltinNoMangleGeneric {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_const_no_mangle)]
-pub struct BuiltinConstNoMangle {
+pub(crate) struct BuiltinConstNoMangle {
     #[suggestion(code = "pub static", applicability = "machine-applicable")]
     pub suggestion: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_mutable_transmutes)]
-pub struct BuiltinMutablesTransmutes;
+pub(crate) struct BuiltinMutablesTransmutes;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_unstable_features)]
-pub struct BuiltinUnstableFeatures;
+pub(crate) struct BuiltinUnstableFeatures;
 
 // lint_ungated_async_fn_track_caller
-pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
+pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> {
     pub label: Span,
     pub session: &'a Session,
 }
@@ -252,7 +252,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_unreachable_pub)]
-pub struct BuiltinUnreachablePub<'a> {
+pub(crate) struct BuiltinUnreachablePub<'a> {
     pub what: &'a str,
     #[suggestion(code = "pub(crate)")]
     pub suggestion: (Span, Applicability),
@@ -262,12 +262,12 @@ pub struct BuiltinUnreachablePub<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_expr_fragment_specifier_2024_migration)]
-pub struct MacroExprFragment2024 {
+pub(crate) struct MacroExprFragment2024 {
     #[suggestion(code = "expr_2021", applicability = "machine-applicable")]
     pub suggestion: Span,
 }
 
-pub struct BuiltinTypeAliasBounds<'a, 'hir> {
+pub(crate) struct BuiltinTypeAliasBounds<'a, 'hir> {
     pub in_where_clause: bool,
     pub label: Span,
     pub enable_feat_help: bool,
@@ -338,13 +338,13 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_, '_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_trivial_bounds)]
-pub struct BuiltinTrivialBounds<'a> {
+pub(crate) struct BuiltinTrivialBounds<'a> {
     pub predicate_kind_name: &'a str,
     pub predicate: Clause<'a>,
 }
 
 #[derive(LintDiagnostic)]
-pub enum BuiltinEllipsisInclusiveRangePatternsLint {
+pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint {
     #[diag(lint_builtin_ellipsis_inclusive_range_patterns)]
     Parenthesise {
         #[suggestion(code = "{replace}", applicability = "machine-applicable")]
@@ -360,7 +360,7 @@ pub enum BuiltinEllipsisInclusiveRangePatternsLint {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_keyword_idents)]
-pub struct BuiltinKeywordIdents {
+pub(crate) struct BuiltinKeywordIdents {
     pub kw: Ident,
     pub next: Edition,
     #[suggestion(code = "r#{kw}", applicability = "machine-applicable")]
@@ -369,7 +369,7 @@ pub struct BuiltinKeywordIdents {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_explicit_outlives)]
-pub struct BuiltinExplicitOutlives {
+pub(crate) struct BuiltinExplicitOutlives {
     pub count: usize,
     #[subdiagnostic]
     pub suggestion: BuiltinExplicitOutlivesSuggestion,
@@ -377,7 +377,7 @@ pub struct BuiltinExplicitOutlives {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion)]
-pub struct BuiltinExplicitOutlivesSuggestion {
+pub(crate) struct BuiltinExplicitOutlivesSuggestion {
     #[suggestion_part(code = "")]
     pub spans: Vec<Span>,
     #[applicability]
@@ -386,7 +386,7 @@ pub struct BuiltinExplicitOutlivesSuggestion {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_incomplete_features)]
-pub struct BuiltinIncompleteFeatures {
+pub(crate) struct BuiltinIncompleteFeatures {
     pub name: Symbol,
     #[subdiagnostic]
     pub note: Option<BuiltinFeatureIssueNote>,
@@ -397,21 +397,21 @@ pub struct BuiltinIncompleteFeatures {
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_internal_features)]
 #[note]
-pub struct BuiltinInternalFeatures {
+pub(crate) struct BuiltinInternalFeatures {
     pub name: Symbol,
 }
 
 #[derive(Subdiagnostic)]
 #[help(lint_help)]
-pub struct BuiltinIncompleteFeaturesHelp;
+pub(crate) struct BuiltinIncompleteFeaturesHelp;
 
 #[derive(Subdiagnostic)]
 #[note(lint_note)]
-pub struct BuiltinFeatureIssueNote {
+pub(crate) struct BuiltinFeatureIssueNote {
     pub n: NonZero<u32>,
 }
 
-pub struct BuiltinUnpermittedTypeInit<'a> {
+pub(crate) struct BuiltinUnpermittedTypeInit<'a> {
     pub msg: DiagMessage,
     pub ty: Ty<'a>,
     pub label: Span,
@@ -436,7 +436,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
 }
 
 // FIXME(davidtwco): make translatable
-pub struct BuiltinUnpermittedTypeInitSub {
+pub(crate) struct BuiltinUnpermittedTypeInitSub {
     pub err: InitError,
 }
 
@@ -463,7 +463,7 @@ impl Subdiagnostic for BuiltinUnpermittedTypeInitSub {
 }
 
 #[derive(LintDiagnostic)]
-pub enum BuiltinClashingExtern<'a> {
+pub(crate) enum BuiltinClashingExtern<'a> {
     #[diag(lint_builtin_clashing_extern_same_name)]
     SameName {
         this: Symbol,
@@ -489,7 +489,7 @@ pub enum BuiltinClashingExtern<'a> {
 }
 
 // FIXME(davidtwco): translatable expected/found
-pub struct BuiltinClashingExternSub<'a> {
+pub(crate) struct BuiltinClashingExternSub<'a> {
     pub tcx: TyCtxt<'a>,
     pub expected: Ty<'a>,
     pub found: Ty<'a>,
@@ -511,7 +511,7 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_builtin_deref_nullptr)]
-pub struct BuiltinDerefNullptr {
+pub(crate) struct BuiltinDerefNullptr {
     #[label]
     pub label: Span,
 }
@@ -519,7 +519,7 @@ pub struct BuiltinDerefNullptr {
 // FIXME: migrate fluent::lint::builtin_asm_labels
 
 #[derive(LintDiagnostic)]
-pub enum BuiltinSpecialModuleNameUsed {
+pub(crate) enum BuiltinSpecialModuleNameUsed {
     #[diag(lint_builtin_special_module_name_used_lib)]
     #[note]
     #[help]
@@ -532,7 +532,7 @@ pub enum BuiltinSpecialModuleNameUsed {
 // deref_into_dyn_supertrait.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_supertrait_as_deref_target)]
-pub struct SupertraitAsDerefTarget<'a> {
+pub(crate) struct SupertraitAsDerefTarget<'a> {
     pub self_ty: Ty<'a>,
     pub supertrait_principal: PolyExistentialTraitRef<'a>,
     pub target_principal: PolyExistentialTraitRef<'a>,
@@ -544,7 +544,7 @@ pub struct SupertraitAsDerefTarget<'a> {
 
 #[derive(Subdiagnostic)]
 #[label(lint_label2)]
-pub struct SupertraitAsDerefTargetLabel {
+pub(crate) struct SupertraitAsDerefTargetLabel {
     #[primary_span]
     pub label: Span,
 }
@@ -552,7 +552,7 @@ pub struct SupertraitAsDerefTargetLabel {
 // enum_intrinsics_non_enums.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_enum_intrinsics_mem_discriminant)]
-pub struct EnumIntrinsicsMemDiscriminate<'a> {
+pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> {
     pub ty_param: Ty<'a>,
     #[note]
     pub note: Span,
@@ -561,14 +561,14 @@ pub struct EnumIntrinsicsMemDiscriminate<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_enum_intrinsics_mem_variant)]
 #[note]
-pub struct EnumIntrinsicsMemVariant<'a> {
+pub(crate) struct EnumIntrinsicsMemVariant<'a> {
     pub ty_param: Ty<'a>,
 }
 
 // expect.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_expectation)]
-pub struct Expectation {
+pub(crate) struct Expectation {
     #[subdiagnostic]
     pub rationale: Option<ExpectationNote>,
     #[note]
@@ -577,13 +577,13 @@ pub struct Expectation {
 
 #[derive(Subdiagnostic)]
 #[note(lint_rationale)]
-pub struct ExpectationNote {
+pub(crate) struct ExpectationNote {
     pub rationale: Symbol,
 }
 
 // ptr_nulls.rs
 #[derive(LintDiagnostic)]
-pub enum PtrNullChecksDiag<'a> {
+pub(crate) enum PtrNullChecksDiag<'a> {
     #[diag(lint_ptr_null_checks_fn_ptr)]
     #[help(lint_help)]
     FnPtr {
@@ -604,7 +604,7 @@ pub enum PtrNullChecksDiag<'a> {
 // for_loops_over_fallibles.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_for_loops_over_fallibles)]
-pub struct ForLoopsOverFalliblesDiag<'a> {
+pub(crate) struct ForLoopsOverFalliblesDiag<'a> {
     pub article: &'static str,
     pub ref_prefix: &'static str,
     pub ty: &'static str,
@@ -617,7 +617,7 @@ pub struct ForLoopsOverFalliblesDiag<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum ForLoopsOverFalliblesLoopSub<'a> {
+pub(crate) enum ForLoopsOverFalliblesLoopSub<'a> {
     #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
     RemoveNext {
         #[primary_span]
@@ -636,14 +636,14 @@ pub enum ForLoopsOverFalliblesLoopSub<'a> {
 
 #[derive(Subdiagnostic)]
 #[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")]
-pub struct ForLoopsOverFalliblesQuestionMark {
+pub(crate) struct ForLoopsOverFalliblesQuestionMark {
     #[primary_span]
     pub suggestion: Span,
 }
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
-pub struct ForLoopsOverFalliblesSuggestion<'a> {
+pub(crate) struct ForLoopsOverFalliblesSuggestion<'a> {
     pub var: &'a str,
     #[suggestion_part(code = "if let {var}(")]
     pub start_span: Span,
@@ -652,7 +652,7 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum UseLetUnderscoreIgnoreSuggestion {
+pub(crate) enum UseLetUnderscoreIgnoreSuggestion {
     #[note(lint_use_let_underscore_ignore_suggestion)]
     Note,
     #[multipart_suggestion(
@@ -671,7 +671,7 @@ pub enum UseLetUnderscoreIgnoreSuggestion {
 // drop_forget_useless.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_dropping_references)]
-pub struct DropRefDiag<'a> {
+pub(crate) struct DropRefDiag<'a> {
     pub arg_ty: Ty<'a>,
     #[label]
     pub label: Span,
@@ -681,7 +681,7 @@ pub struct DropRefDiag<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_dropping_copy_types)]
-pub struct DropCopyDiag<'a> {
+pub(crate) struct DropCopyDiag<'a> {
     pub arg_ty: Ty<'a>,
     #[label]
     pub label: Span,
@@ -691,7 +691,7 @@ pub struct DropCopyDiag<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_forgetting_references)]
-pub struct ForgetRefDiag<'a> {
+pub(crate) struct ForgetRefDiag<'a> {
     pub arg_ty: Ty<'a>,
     #[label]
     pub label: Span,
@@ -701,7 +701,7 @@ pub struct ForgetRefDiag<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_forgetting_copy_types)]
-pub struct ForgetCopyDiag<'a> {
+pub(crate) struct ForgetCopyDiag<'a> {
     pub arg_ty: Ty<'a>,
     #[label]
     pub label: Span,
@@ -711,7 +711,7 @@ pub struct ForgetCopyDiag<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_undropped_manually_drops)]
-pub struct UndroppedManuallyDropsDiag<'a> {
+pub(crate) struct UndroppedManuallyDropsDiag<'a> {
     pub arg_ty: Ty<'a>,
     #[label]
     pub label: Span,
@@ -721,7 +721,7 @@ pub struct UndroppedManuallyDropsDiag<'a> {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
-pub struct UndroppedManuallyDropsSuggestion {
+pub(crate) struct UndroppedManuallyDropsSuggestion {
     #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")]
     pub start_span: Span,
     #[suggestion_part(code = ")")]
@@ -730,7 +730,7 @@ pub struct UndroppedManuallyDropsSuggestion {
 
 // invalid_from_utf8.rs
 #[derive(LintDiagnostic)]
-pub enum InvalidFromUtf8Diag {
+pub(crate) enum InvalidFromUtf8Diag {
     #[diag(lint_invalid_from_utf8_unchecked)]
     Unchecked {
         method: String,
@@ -749,7 +749,7 @@ pub enum InvalidFromUtf8Diag {
 
 // reference_casting.rs
 #[derive(LintDiagnostic)]
-pub enum InvalidReferenceCastingDiag<'tcx> {
+pub(crate) enum InvalidReferenceCastingDiag<'tcx> {
     #[diag(lint_invalid_reference_casting_borrow_as_mut)]
     #[note(lint_invalid_reference_casting_note_book)]
     BorrowAsMut {
@@ -784,7 +784,7 @@ pub enum InvalidReferenceCastingDiag<'tcx> {
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_unicode_codepoints)]
 #[note]
-pub struct HiddenUnicodeCodepointsDiag<'a> {
+pub(crate) struct HiddenUnicodeCodepointsDiag<'a> {
     pub label: &'a str,
     pub count: usize,
     #[label]
@@ -795,7 +795,7 @@ pub struct HiddenUnicodeCodepointsDiag<'a> {
     pub sub: HiddenUnicodeCodepointsDiagSub,
 }
 
-pub struct HiddenUnicodeCodepointsDiagLabels {
+pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
     pub spans: Vec<(char, Span)>,
 }
 
@@ -811,7 +811,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
     }
 }
 
-pub enum HiddenUnicodeCodepointsDiagSub {
+pub(crate) enum HiddenUnicodeCodepointsDiagSub {
     Escape { spans: Vec<(char, Span)> },
     NoEscape { spans: Vec<(char, Span)> },
 }
@@ -866,7 +866,7 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
 #[derive(LintDiagnostic)]
 #[diag(lint_map_unit_fn)]
 #[note]
-pub struct MappingToUnit {
+pub(crate) struct MappingToUnit {
     #[label(lint_function_label)]
     pub function_label: Span,
     #[label(lint_argument_label)]
@@ -882,7 +882,7 @@ pub struct MappingToUnit {
 #[derive(LintDiagnostic)]
 #[diag(lint_default_hash_types)]
 #[note]
-pub struct DefaultHashTypesDiag<'a> {
+pub(crate) struct DefaultHashTypesDiag<'a> {
     pub preferred: &'a str,
     pub used: Symbol,
 }
@@ -890,17 +890,17 @@ pub struct DefaultHashTypesDiag<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_query_instability)]
 #[note]
-pub struct QueryInstability {
+pub(crate) struct QueryInstability {
     pub query: Symbol,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_span_use_eq_ctxt)]
-pub struct SpanUseEqCtxtDiag;
+pub(crate) struct SpanUseEqCtxtDiag;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_tykind_kind)]
-pub struct TykindKind {
+pub(crate) struct TykindKind {
     #[suggestion(code = "ty", applicability = "maybe-incorrect")]
     pub suggestion: Span,
 }
@@ -908,11 +908,11 @@ pub struct TykindKind {
 #[derive(LintDiagnostic)]
 #[diag(lint_tykind)]
 #[help]
-pub struct TykindDiag;
+pub(crate) struct TykindDiag;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_ty_qualified)]
-pub struct TyQualified {
+pub(crate) struct TyQualified {
     pub ty: String,
     #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
     pub suggestion: Span,
@@ -920,7 +920,7 @@ pub struct TyQualified {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_non_glob_import_type_ir_inherent)]
-pub struct NonGlobImportTypeIrInherent {
+pub(crate) struct NonGlobImportTypeIrInherent {
     #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]
     pub suggestion: Option<Span>,
     pub snippet: &'static str,
@@ -929,32 +929,32 @@ pub struct NonGlobImportTypeIrInherent {
 #[derive(LintDiagnostic)]
 #[diag(lint_lintpass_by_hand)]
 #[help]
-pub struct LintPassByHand;
+pub(crate) struct LintPassByHand;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_non_existent_doc_keyword)]
 #[help]
-pub struct NonExistentDocKeyword {
+pub(crate) struct NonExistentDocKeyword {
     pub keyword: Symbol,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_diag_out_of_impl)]
-pub struct DiagOutOfImpl;
+pub(crate) struct DiagOutOfImpl;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_untranslatable_diag)]
-pub struct UntranslatableDiag;
+pub(crate) struct UntranslatableDiag;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_bad_opt_access)]
-pub struct BadOptAccessDiag<'a> {
+pub(crate) struct BadOptAccessDiag<'a> {
     pub msg: &'a str,
 }
 
 // let_underscore.rs
 #[derive(LintDiagnostic)]
-pub enum NonBindingLet {
+pub(crate) enum NonBindingLet {
     #[diag(lint_non_binding_let_on_sync_lock)]
     SyncLock {
         #[label]
@@ -969,7 +969,7 @@ pub enum NonBindingLet {
     },
 }
 
-pub struct NonBindingLetSub {
+pub(crate) struct NonBindingLetSub {
     pub suggestion: Span,
     pub drop_fn_start_end: Option<(Span, Span)>,
     pub is_assign_desugar: bool,
@@ -1012,7 +1012,7 @@ impl Subdiagnostic for NonBindingLetSub {
 // levels.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_overruled_attribute)]
-pub struct OverruledAttributeLint<'a> {
+pub(crate) struct OverruledAttributeLint<'a> {
     #[label]
     pub overruled: Span,
     pub lint_level: &'a str,
@@ -1023,7 +1023,7 @@ pub struct OverruledAttributeLint<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_deprecated_lint_name)]
-pub struct DeprecatedLintName<'a> {
+pub(crate) struct DeprecatedLintName<'a> {
     pub name: String,
     #[suggestion(code = "{replace}", applicability = "machine-applicable")]
     pub suggestion: Span,
@@ -1033,7 +1033,7 @@ pub struct DeprecatedLintName<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_deprecated_lint_name)]
 #[help]
-pub struct DeprecatedLintNameFromCommandLine<'a> {
+pub(crate) struct DeprecatedLintNameFromCommandLine<'a> {
     pub name: String,
     pub replace: &'a str,
     #[subdiagnostic]
@@ -1042,14 +1042,14 @@ pub struct DeprecatedLintNameFromCommandLine<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_renamed_lint)]
-pub struct RenamedLint<'a> {
+pub(crate) struct RenamedLint<'a> {
     pub name: &'a str,
     #[subdiagnostic]
     pub suggestion: RenamedLintSuggestion<'a>,
 }
 
 #[derive(Subdiagnostic)]
-pub enum RenamedLintSuggestion<'a> {
+pub(crate) enum RenamedLintSuggestion<'a> {
     #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
     WithSpan {
         #[primary_span]
@@ -1062,7 +1062,7 @@ pub enum RenamedLintSuggestion<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_renamed_lint)]
-pub struct RenamedLintFromCommandLine<'a> {
+pub(crate) struct RenamedLintFromCommandLine<'a> {
     pub name: &'a str,
     #[subdiagnostic]
     pub suggestion: RenamedLintSuggestion<'a>,
@@ -1072,14 +1072,14 @@ pub struct RenamedLintFromCommandLine<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_removed_lint)]
-pub struct RemovedLint<'a> {
+pub(crate) struct RemovedLint<'a> {
     pub name: &'a str,
     pub reason: &'a str,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_removed_lint)]
-pub struct RemovedLintFromCommandLine<'a> {
+pub(crate) struct RemovedLintFromCommandLine<'a> {
     pub name: &'a str,
     pub reason: &'a str,
     #[subdiagnostic]
@@ -1088,14 +1088,14 @@ pub struct RemovedLintFromCommandLine<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unknown_lint)]
-pub struct UnknownLint {
+pub(crate) struct UnknownLint {
     pub name: String,
     #[subdiagnostic]
     pub suggestion: Option<UnknownLintSuggestion>,
 }
 
 #[derive(Subdiagnostic)]
-pub enum UnknownLintSuggestion {
+pub(crate) enum UnknownLintSuggestion {
     #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
     WithSpan {
         #[primary_span]
@@ -1109,7 +1109,7 @@ pub enum UnknownLintSuggestion {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unknown_lint, code = E0602)]
-pub struct UnknownLintFromCommandLine<'a> {
+pub(crate) struct UnknownLintFromCommandLine<'a> {
     pub name: String,
     #[subdiagnostic]
     pub suggestion: Option<UnknownLintSuggestion>,
@@ -1119,7 +1119,7 @@ pub struct UnknownLintFromCommandLine<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_ignored_unless_crate_specified)]
-pub struct IgnoredUnlessCrateSpecified<'a> {
+pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
     pub level: &'a str,
     pub name: Symbol,
 }
@@ -1129,7 +1129,7 @@ pub struct IgnoredUnlessCrateSpecified<'a> {
 #[diag(lint_cstring_ptr)]
 #[note]
 #[help]
-pub struct CStringPtr {
+pub(crate) struct CStringPtr {
     #[label(lint_as_ptr_label)]
     pub as_ptr: Span,
     #[label(lint_unwrap_label)]
@@ -1139,19 +1139,19 @@ pub struct CStringPtr {
 // multiple_supertrait_upcastable.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_multiple_supertrait_upcastable)]
-pub struct MultipleSupertraitUpcastable {
+pub(crate) struct MultipleSupertraitUpcastable {
     pub ident: Ident,
 }
 
 // non_ascii_idents.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_identifier_non_ascii_char)]
-pub struct IdentifierNonAsciiChar;
+pub(crate) struct IdentifierNonAsciiChar;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_identifier_uncommon_codepoints)]
 #[note]
-pub struct IdentifierUncommonCodepoints {
+pub(crate) struct IdentifierUncommonCodepoints {
     pub codepoints: Vec<char>,
     pub codepoints_len: usize,
     pub identifier_type: &'static str,
@@ -1159,7 +1159,7 @@ pub struct IdentifierUncommonCodepoints {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_confusable_identifier_pair)]
-pub struct ConfusableIdentifierPair {
+pub(crate) struct ConfusableIdentifierPair {
     pub existing_sym: Symbol,
     pub sym: Symbol,
     #[label(lint_other_use)]
@@ -1172,13 +1172,13 @@ pub struct ConfusableIdentifierPair {
 #[diag(lint_mixed_script_confusables)]
 #[note(lint_includes_note)]
 #[note]
-pub struct MixedScriptConfusables {
+pub(crate) struct MixedScriptConfusables {
     pub set: String,
     pub includes: String,
 }
 
 // non_fmt_panic.rs
-pub struct NonFmtPanicUnused {
+pub(crate) struct NonFmtPanicUnused {
     pub count: usize,
     pub suggestion: Option<Span>,
 }
@@ -1209,7 +1209,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
 #[derive(LintDiagnostic)]
 #[diag(lint_non_fmt_panic_braces)]
 #[note]
-pub struct NonFmtPanicBraces {
+pub(crate) struct NonFmtPanicBraces {
     pub count: usize,
     #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
     pub suggestion: Option<Span>,
@@ -1218,7 +1218,7 @@ pub struct NonFmtPanicBraces {
 // nonstandard_style.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_non_camel_case_type)]
-pub struct NonCamelCaseType<'a> {
+pub(crate) struct NonCamelCaseType<'a> {
     pub sort: &'a str,
     pub name: &'a str,
     #[subdiagnostic]
@@ -1226,7 +1226,7 @@ pub struct NonCamelCaseType<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum NonCamelCaseTypeSub {
+pub(crate) enum NonCamelCaseTypeSub {
     #[label(lint_label)]
     Label {
         #[primary_span]
@@ -1242,7 +1242,7 @@ pub enum NonCamelCaseTypeSub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_non_snake_case)]
-pub struct NonSnakeCaseDiag<'a> {
+pub(crate) struct NonSnakeCaseDiag<'a> {
     pub sort: &'a str,
     pub name: &'a str,
     pub sc: String,
@@ -1250,7 +1250,7 @@ pub struct NonSnakeCaseDiag<'a> {
     pub sub: NonSnakeCaseDiagSub,
 }
 
-pub enum NonSnakeCaseDiagSub {
+pub(crate) enum NonSnakeCaseDiagSub {
     Label { span: Span },
     Help,
     RenameOrConvertSuggestion { span: Span, suggestion: Ident },
@@ -1302,7 +1302,7 @@ impl Subdiagnostic for NonSnakeCaseDiagSub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_non_upper_case_global)]
-pub struct NonUpperCaseGlobal<'a> {
+pub(crate) struct NonUpperCaseGlobal<'a> {
     pub sort: &'a str,
     pub name: &'a str,
     #[subdiagnostic]
@@ -1310,7 +1310,7 @@ pub struct NonUpperCaseGlobal<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum NonUpperCaseGlobalSub {
+pub(crate) enum NonUpperCaseGlobalSub {
     #[label(lint_label)]
     Label {
         #[primary_span]
@@ -1328,7 +1328,7 @@ pub enum NonUpperCaseGlobalSub {
 #[derive(LintDiagnostic)]
 #[diag(lint_noop_method_call)]
 #[note]
-pub struct NoopMethodCallDiag<'a> {
+pub(crate) struct NoopMethodCallDiag<'a> {
     pub method: Symbol,
     pub orig_ty: Ty<'a>,
     pub trait_: Symbol,
@@ -1344,18 +1344,18 @@ pub struct NoopMethodCallDiag<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_suspicious_double_ref_deref)]
-pub struct SuspiciousDoubleRefDerefDiag<'a> {
+pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> {
     pub ty: Ty<'a>,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_suspicious_double_ref_clone)]
-pub struct SuspiciousDoubleRefCloneDiag<'a> {
+pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> {
     pub ty: Ty<'a>,
 }
 
 // non_local_defs.rs
-pub enum NonLocalDefinitionsDiag {
+pub(crate) enum NonLocalDefinitionsDiag {
     Impl {
         depth: u32,
         body_kind_descr: &'static str,
@@ -1487,7 +1487,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
 
 #[derive(Subdiagnostic)]
 #[note(lint_non_local_definitions_cargo_update)]
-pub struct NonLocalDefinitionsCargoUpdateNote {
+pub(crate) struct NonLocalDefinitionsCargoUpdateNote {
     pub macro_kind: &'static str,
     pub macro_name: Symbol,
     pub crate_name: Symbol,
@@ -1497,7 +1497,7 @@ pub struct NonLocalDefinitionsCargoUpdateNote {
 #[derive(LintDiagnostic)]
 #[diag(lint_ambiguous_negative_literals)]
 #[note(lint_example)]
-pub struct AmbiguousNegativeLiteralsDiag {
+pub(crate) struct AmbiguousNegativeLiteralsDiag {
     #[subdiagnostic]
     pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
     #[subdiagnostic]
@@ -1506,7 +1506,7 @@ pub struct AmbiguousNegativeLiteralsDiag {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")]
-pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
+pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
     #[suggestion_part(code = "(")]
     pub start_span: Span,
     #[suggestion_part(code = ")")]
@@ -1515,7 +1515,7 @@ pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")]
-pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
+pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
     #[suggestion_part(code = "(")]
     pub start_span: Span,
     #[suggestion_part(code = ")")]
@@ -1525,7 +1525,7 @@ pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
 // pass_by_value.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_pass_by_value)]
-pub struct PassByValueDiag {
+pub(crate) struct PassByValueDiag {
     pub ty: String,
     #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
     pub suggestion: Span,
@@ -1534,14 +1534,14 @@ pub struct PassByValueDiag {
 // redundant_semicolon.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_redundant_semicolons)]
-pub struct RedundantSemicolonsDiag {
+pub(crate) struct RedundantSemicolonsDiag {
     pub multiple: bool,
     #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub suggestion: Span,
 }
 
 // traits.rs
-pub struct DropTraitConstraintsDiag<'a> {
+pub(crate) struct DropTraitConstraintsDiag<'a> {
     pub predicate: Clause<'a>,
     pub tcx: TyCtxt<'a>,
     pub def_id: DefId,
@@ -1556,7 +1556,7 @@ impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
     }
 }
 
-pub struct DropGlue<'a> {
+pub(crate) struct DropGlue<'a> {
     pub tcx: TyCtxt<'a>,
     pub def_id: DefId,
 }
@@ -1572,14 +1572,14 @@ impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
 // types.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_range_endpoint_out_of_range)]
-pub struct RangeEndpointOutOfRange<'a> {
+pub(crate) struct RangeEndpointOutOfRange<'a> {
     pub ty: &'a str,
     #[subdiagnostic]
     pub sub: UseInclusiveRange<'a>,
 }
 
 #[derive(Subdiagnostic)]
-pub enum UseInclusiveRange<'a> {
+pub(crate) enum UseInclusiveRange<'a> {
     #[suggestion(
         lint_range_use_inclusive_range,
         code = "{start}..={literal}{suffix}",
@@ -1605,7 +1605,7 @@ pub enum UseInclusiveRange<'a> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_overflowing_bin_hex)]
-pub struct OverflowingBinHex<'a> {
+pub(crate) struct OverflowingBinHex<'a> {
     pub ty: &'a str,
     pub lit: String,
     pub dec: u128,
@@ -1618,7 +1618,7 @@ pub struct OverflowingBinHex<'a> {
     pub sign_bit_sub: Option<OverflowingBinHexSignBitSub<'a>>,
 }
 
-pub enum OverflowingBinHexSign {
+pub(crate) enum OverflowingBinHexSign {
     Positive,
     Negative,
 }
@@ -1642,7 +1642,7 @@ impl Subdiagnostic for OverflowingBinHexSign {
 }
 
 #[derive(Subdiagnostic)]
-pub enum OverflowingBinHexSub<'a> {
+pub(crate) enum OverflowingBinHexSub<'a> {
     #[suggestion(
         lint_suggestion,
         code = "{sans_suffix}{suggestion_ty}",
@@ -1664,7 +1664,7 @@ pub enum OverflowingBinHexSub<'a> {
     code = "{lit_no_suffix}{uint_ty} as {int_ty}",
     applicability = "maybe-incorrect"
 )]
-pub struct OverflowingBinHexSignBitSub<'a> {
+pub(crate) struct OverflowingBinHexSignBitSub<'a> {
     #[primary_span]
     pub span: Span,
     pub lit_no_suffix: &'a str,
@@ -1676,7 +1676,7 @@ pub struct OverflowingBinHexSignBitSub<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_overflowing_int)]
 #[note]
-pub struct OverflowingInt<'a> {
+pub(crate) struct OverflowingInt<'a> {
     pub ty: &'a str,
     pub lit: String,
     pub min: i128,
@@ -1687,13 +1687,13 @@ pub struct OverflowingInt<'a> {
 
 #[derive(Subdiagnostic)]
 #[help(lint_help)]
-pub struct OverflowingIntHelp<'a> {
+pub(crate) struct OverflowingIntHelp<'a> {
     pub suggestion_ty: &'a str,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_only_cast_u8_to_char)]
-pub struct OnlyCastu8ToChar {
+pub(crate) struct OnlyCastu8ToChar {
     #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
     pub span: Span,
     pub literal: u128,
@@ -1702,7 +1702,7 @@ pub struct OnlyCastu8ToChar {
 #[derive(LintDiagnostic)]
 #[diag(lint_overflowing_uint)]
 #[note]
-pub struct OverflowingUInt<'a> {
+pub(crate) struct OverflowingUInt<'a> {
     pub ty: &'a str,
     pub lit: String,
     pub min: u128,
@@ -1712,17 +1712,17 @@ pub struct OverflowingUInt<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_overflowing_literal)]
 #[note]
-pub struct OverflowingLiteral<'a> {
+pub(crate) struct OverflowingLiteral<'a> {
     pub ty: &'a str,
     pub lit: String,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_comparisons)]
-pub struct UnusedComparisons;
+pub(crate) struct UnusedComparisons;
 
 #[derive(LintDiagnostic)]
-pub enum InvalidNanComparisons {
+pub(crate) enum InvalidNanComparisons {
     #[diag(lint_invalid_nan_comparisons_eq_ne)]
     EqNe {
         #[subdiagnostic]
@@ -1733,7 +1733,7 @@ pub enum InvalidNanComparisons {
 }
 
 #[derive(Subdiagnostic)]
-pub enum InvalidNanComparisonsSuggestion {
+pub(crate) enum InvalidNanComparisonsSuggestion {
     #[multipart_suggestion(
         lint_suggestion,
         style = "verbose",
@@ -1752,7 +1752,7 @@ pub enum InvalidNanComparisonsSuggestion {
 }
 
 #[derive(LintDiagnostic)]
-pub enum AmbiguousWidePointerComparisons<'a> {
+pub(crate) enum AmbiguousWidePointerComparisons<'a> {
     #[diag(lint_ambiguous_wide_pointer_comparisons)]
     Spanful {
         #[subdiagnostic]
@@ -1773,7 +1773,7 @@ pub enum AmbiguousWidePointerComparisons<'a> {
     // FIXME(#53934): make machine-applicable again
     applicability = "maybe-incorrect"
 )]
-pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
+pub(crate) struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
     pub ne: &'a str,
     pub deref_left: &'a str,
     pub deref_right: &'a str,
@@ -1788,7 +1788,7 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
+pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
     #[multipart_suggestion(
         lint_addr_suggestion,
         style = "verbose",
@@ -1832,7 +1832,7 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
     },
 }
 
-pub struct ImproperCTypes<'a> {
+pub(crate) struct ImproperCTypes<'a> {
     pub ty: Ty<'a>,
     pub desc: &'a str,
     pub label: Span,
@@ -1860,29 +1860,29 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_variant_size_differences)]
-pub struct VariantSizeDifferencesDiag {
+pub(crate) struct VariantSizeDifferencesDiag {
     pub largest: u64,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_atomic_ordering_load)]
 #[help]
-pub struct AtomicOrderingLoad;
+pub(crate) struct AtomicOrderingLoad;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_atomic_ordering_store)]
 #[help]
-pub struct AtomicOrderingStore;
+pub(crate) struct AtomicOrderingStore;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_atomic_ordering_fence)]
 #[help]
-pub struct AtomicOrderingFence;
+pub(crate) struct AtomicOrderingFence;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_atomic_ordering_invalid)]
 #[help]
-pub struct InvalidAtomicOrderingDiag {
+pub(crate) struct InvalidAtomicOrderingDiag {
     pub method: Symbol,
     #[label]
     pub fail_order_arg_span: Span,
@@ -1891,7 +1891,7 @@ pub struct InvalidAtomicOrderingDiag {
 // unused.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_op)]
-pub struct UnusedOp<'a> {
+pub(crate) struct UnusedOp<'a> {
     pub op: &'a str,
     #[label]
     pub label: Span,
@@ -1900,7 +1900,7 @@ pub struct UnusedOp<'a> {
 }
 
 #[derive(Subdiagnostic)]
-pub enum UnusedOpSuggestion {
+pub(crate) enum UnusedOpSuggestion {
     #[suggestion(
         lint_suggestion,
         style = "verbose",
@@ -1922,7 +1922,7 @@ pub enum UnusedOpSuggestion {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_result)]
-pub struct UnusedResult<'a> {
+pub(crate) struct UnusedResult<'a> {
     pub ty: Ty<'a>,
 }
 
@@ -1931,7 +1931,7 @@ pub struct UnusedResult<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_closure)]
 #[note]
-pub struct UnusedClosure<'a> {
+pub(crate) struct UnusedClosure<'a> {
     pub count: usize,
     pub pre: &'a str,
     pub post: &'a str,
@@ -1942,7 +1942,7 @@ pub struct UnusedClosure<'a> {
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_coroutine)]
 #[note]
-pub struct UnusedCoroutine<'a> {
+pub(crate) struct UnusedCoroutine<'a> {
     pub count: usize,
     pub pre: &'a str,
     pub post: &'a str,
@@ -1950,7 +1950,7 @@ pub struct UnusedCoroutine<'a> {
 
 // FIXME(davidtwco): this isn't properly translatable because of the pre/post
 // strings
-pub struct UnusedDef<'a, 'b> {
+pub(crate) struct UnusedDef<'a, 'b> {
     pub pre: &'a str,
     pub post: &'a str,
     pub cx: &'a LateContext<'b>,
@@ -1961,7 +1961,7 @@ pub struct UnusedDef<'a, 'b> {
 
 #[derive(Subdiagnostic)]
 
-pub enum UnusedDefSuggestion {
+pub(crate) enum UnusedDefSuggestion {
     #[suggestion(
         lint_suggestion,
         style = "verbose",
@@ -2000,13 +2000,13 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_path_statement_drop)]
-pub struct PathStatementDrop {
+pub(crate) struct PathStatementDrop {
     #[subdiagnostic]
     pub sub: PathStatementDropSub,
 }
 
 #[derive(Subdiagnostic)]
-pub enum PathStatementDropSub {
+pub(crate) enum PathStatementDropSub {
     #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
     Suggestion {
         #[primary_span]
@@ -2022,11 +2022,11 @@ pub enum PathStatementDropSub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_path_statement_no_effect)]
-pub struct PathStatementNoEffect;
+pub(crate) struct PathStatementNoEffect;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_delim)]
-pub struct UnusedDelim<'a> {
+pub(crate) struct UnusedDelim<'a> {
     pub delim: &'static str,
     pub item: &'a str,
     #[subdiagnostic]
@@ -2035,7 +2035,7 @@ pub struct UnusedDelim<'a> {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
-pub struct UnusedDelimSuggestion {
+pub(crate) struct UnusedDelimSuggestion {
     #[suggestion_part(code = "{start_replace}")]
     pub start_span: Span,
     pub start_replace: &'static str,
@@ -2046,19 +2046,19 @@ pub struct UnusedDelimSuggestion {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_import_braces)]
-pub struct UnusedImportBracesDiag {
+pub(crate) struct UnusedImportBracesDiag {
     pub node: Symbol,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_allocation)]
-pub struct UnusedAllocationDiag;
+pub(crate) struct UnusedAllocationDiag;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_allocation_mut)]
-pub struct UnusedAllocationMutDiag;
+pub(crate) struct UnusedAllocationMutDiag;
 
-pub struct AsyncFnInTraitDiag {
+pub(crate) struct AsyncFnInTraitDiag {
     pub sugg: Option<Vec<(Span, String)>>,
 }
 
@@ -2074,13 +2074,13 @@ impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unit_bindings)]
-pub struct UnitBindingsDiag {
+pub(crate) struct UnitBindingsDiag {
     #[label]
     pub label: Span,
 }
 
 #[derive(LintDiagnostic)]
-pub enum InvalidAsmLabel {
+pub(crate) enum InvalidAsmLabel {
     #[diag(lint_invalid_asm_label_named)]
     #[help]
     #[note]
@@ -2110,7 +2110,7 @@ pub enum InvalidAsmLabel {
 }
 
 #[derive(Subdiagnostic)]
-pub enum UnexpectedCfgCargoHelp {
+pub(crate) enum UnexpectedCfgCargoHelp {
     #[help(lint_unexpected_cfg_add_cargo_feature)]
     #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
     LintCfg { cargo_toml_lint_cfg: String },
@@ -2127,13 +2127,13 @@ impl UnexpectedCfgCargoHelp {
         )
     }
 
-    pub fn lint_cfg(unescaped: &str) -> Self {
+    pub(crate) fn lint_cfg(unescaped: &str) -> Self {
         UnexpectedCfgCargoHelp::LintCfg {
             cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
         }
     }
 
-    pub fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
+    pub(crate) fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
         UnexpectedCfgCargoHelp::LintCfgAndBuildRs {
             cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
             build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"),
@@ -2143,19 +2143,19 @@ impl UnexpectedCfgCargoHelp {
 
 #[derive(Subdiagnostic)]
 #[help(lint_unexpected_cfg_add_cmdline_arg)]
-pub struct UnexpectedCfgRustcHelp {
+pub(crate) struct UnexpectedCfgRustcHelp {
     pub cmdline_arg: String,
 }
 
 impl UnexpectedCfgRustcHelp {
-    pub fn new(unescaped: &str) -> Self {
+    pub(crate) fn new(unescaped: &str) -> Self {
         Self { cmdline_arg: format!("--check-cfg={unescaped}") }
     }
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unexpected_cfg_name)]
-pub struct UnexpectedCfgName {
+pub(crate) struct UnexpectedCfgName {
     #[subdiagnostic]
     pub code_sugg: unexpected_cfg_name::CodeSuggestion,
     #[subdiagnostic]
@@ -2164,13 +2164,13 @@ pub struct UnexpectedCfgName {
     pub name: Symbol,
 }
 
-pub mod unexpected_cfg_name {
+pub(crate) mod unexpected_cfg_name {
     use rustc_errors::DiagSymbolList;
     use rustc_macros::Subdiagnostic;
     use rustc_span::{Span, Symbol};
 
     #[derive(Subdiagnostic)]
-    pub enum CodeSuggestion {
+    pub(crate) enum CodeSuggestion {
         #[help(lint_unexpected_cfg_define_features)]
         DefineFeatures,
         #[suggestion(
@@ -2227,7 +2227,7 @@ pub mod unexpected_cfg_name {
 
     #[derive(Subdiagnostic)]
     #[help(lint_unexpected_cfg_name_expected_values)]
-    pub struct ExpectedValues {
+    pub(crate) struct ExpectedValues {
         pub best_match: Symbol,
         pub possibilities: DiagSymbolList,
     }
@@ -2238,7 +2238,7 @@ pub mod unexpected_cfg_name {
         applicability = "maybe-incorrect",
         code = "{code}"
     )]
-    pub struct FoundWithSimilarValue {
+    pub(crate) struct FoundWithSimilarValue {
         #[primary_span]
         pub span: Span,
         pub code: String,
@@ -2246,13 +2246,13 @@ pub mod unexpected_cfg_name {
 
     #[derive(Subdiagnostic)]
     #[help_once(lint_unexpected_cfg_name_expected_names)]
-    pub struct ExpectedNames {
+    pub(crate) struct ExpectedNames {
         pub possibilities: DiagSymbolList,
         pub and_more: usize,
     }
 
     #[derive(Subdiagnostic)]
-    pub enum InvocationHelp {
+    pub(crate) enum InvocationHelp {
         #[note(lint_unexpected_cfg_doc_cargo)]
         Cargo {
             #[subdiagnostic]
@@ -2265,7 +2265,7 @@ pub mod unexpected_cfg_name {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unexpected_cfg_value)]
-pub struct UnexpectedCfgValue {
+pub(crate) struct UnexpectedCfgValue {
     #[subdiagnostic]
     pub code_sugg: unexpected_cfg_value::CodeSuggestion,
     #[subdiagnostic]
@@ -2275,13 +2275,13 @@ pub struct UnexpectedCfgValue {
     pub value: String,
 }
 
-pub mod unexpected_cfg_value {
+pub(crate) mod unexpected_cfg_value {
     use rustc_errors::DiagSymbolList;
     use rustc_macros::Subdiagnostic;
     use rustc_span::{Span, Symbol};
 
     #[derive(Subdiagnostic)]
-    pub enum CodeSuggestion {
+    pub(crate) enum CodeSuggestion {
         ChangeValue {
             #[subdiagnostic]
             expected_values: ExpectedValues,
@@ -2305,7 +2305,7 @@ pub mod unexpected_cfg_value {
     }
 
     #[derive(Subdiagnostic)]
-    pub enum ChangeValueSuggestion {
+    pub(crate) enum ChangeValueSuggestion {
         #[suggestion(
             lint_unexpected_cfg_value_similar_name,
             code = r#""{best_match}""#,
@@ -2334,7 +2334,7 @@ pub mod unexpected_cfg_value {
         code = "",
         applicability = "maybe-incorrect"
     )]
-    pub struct RemoveValueSuggestion {
+    pub(crate) struct RemoveValueSuggestion {
         #[primary_span]
         pub span: Span,
     }
@@ -2345,14 +2345,14 @@ pub mod unexpected_cfg_value {
         code = "",
         applicability = "maybe-incorrect"
     )]
-    pub struct RemoveConditionSuggestion {
+    pub(crate) struct RemoveConditionSuggestion {
         #[primary_span]
         pub span: Span,
     }
 
     #[derive(Subdiagnostic)]
     #[note(lint_unexpected_cfg_value_expected_values)]
-    pub struct ExpectedValues {
+    pub(crate) struct ExpectedValues {
         pub name: Symbol,
         pub have_none_possibility: bool,
         pub possibilities: DiagSymbolList,
@@ -2360,7 +2360,7 @@ pub mod unexpected_cfg_value {
     }
 
     #[derive(Subdiagnostic)]
-    pub enum InvocationHelp {
+    pub(crate) enum InvocationHelp {
         #[note(lint_unexpected_cfg_doc_cargo)]
         Cargo(#[subdiagnostic] Option<CargoHelp>),
         #[note(lint_unexpected_cfg_doc_rustc)]
@@ -2368,7 +2368,7 @@ pub mod unexpected_cfg_value {
     }
 
     #[derive(Subdiagnostic)]
-    pub enum CargoHelp {
+    pub(crate) enum CargoHelp {
         #[help(lint_unexpected_cfg_value_add_feature)]
         AddFeature {
             value: Symbol,
@@ -2383,7 +2383,7 @@ pub mod unexpected_cfg_value {
 #[diag(lint_unexpected_builtin_cfg)]
 #[note(lint_controlled_by)]
 #[note(lint_incoherent)]
-pub struct UnexpectedBuiltinCfg {
+pub(crate) struct UnexpectedBuiltinCfg {
     pub(crate) cfg: String,
     pub(crate) cfg_name: Symbol,
     pub(crate) controlled_by: &'static str,
@@ -2392,15 +2392,15 @@ pub struct UnexpectedBuiltinCfg {
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_use_deprecated)]
 #[help]
-pub struct MacroUseDeprecated;
+pub(crate) struct MacroUseDeprecated;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_macro_use)]
-pub struct UnusedMacroUse;
+pub(crate) struct UnusedMacroUse;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_private_extern_crate_reexport, code = E0365)]
-pub struct PrivateExternCrateReexport {
+pub(crate) struct PrivateExternCrateReexport {
     pub ident: Ident,
     #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")]
     pub sugg: Span,
@@ -2408,28 +2408,28 @@ pub struct PrivateExternCrateReexport {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_label)]
-pub struct UnusedLabel;
+pub(crate) struct UnusedLabel;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_is_private)]
-pub struct MacroIsPrivate {
+pub(crate) struct MacroIsPrivate {
     pub ident: Ident,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_macro_definition)]
-pub struct UnusedMacroDefinition {
+pub(crate) struct UnusedMacroDefinition {
     pub name: Symbol,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_rule_never_used)]
-pub struct MacroRuleNeverUsed {
+pub(crate) struct MacroRuleNeverUsed {
     pub n: usize,
     pub name: Symbol,
 }
 
-pub struct UnstableFeature {
+pub(crate) struct UnstableFeature {
     pub msg: DiagMessage,
 }
 
@@ -2441,81 +2441,81 @@ impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_avoid_intel_syntax)]
-pub struct AvoidIntelSyntax;
+pub(crate) struct AvoidIntelSyntax;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_avoid_att_syntax)]
-pub struct AvoidAttSyntax;
+pub(crate) struct AvoidAttSyntax;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_incomplete_include)]
-pub struct IncompleteInclude;
+pub(crate) struct IncompleteInclude;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unnameable_test_items)]
-pub struct UnnameableTestItems;
+pub(crate) struct UnnameableTestItems;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_duplicate_macro_attribute)]
-pub struct DuplicateMacroAttribute;
+pub(crate) struct DuplicateMacroAttribute;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_cfg_attr_no_attributes)]
-pub struct CfgAttrNoAttributes;
+pub(crate) struct CfgAttrNoAttributes;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_crate_type_in_cfg_attr_deprecated)]
-pub struct CrateTypeInCfgAttr;
+pub(crate) struct CrateTypeInCfgAttr;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_crate_name_in_cfg_attr_deprecated)]
-pub struct CrateNameInCfgAttr;
+pub(crate) struct CrateNameInCfgAttr;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_missing_fragment_specifier)]
-pub struct MissingFragmentSpecifier;
+pub(crate) struct MissingFragmentSpecifier;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_metavariable_still_repeating)]
-pub struct MetaVariableStillRepeating {
+pub(crate) struct MetaVariableStillRepeating {
     pub name: MacroRulesNormalizedIdent,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_metavariable_wrong_operator)]
-pub struct MetaVariableWrongOperator;
+pub(crate) struct MetaVariableWrongOperator;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_duplicate_matcher_binding)]
-pub struct DuplicateMatcherBinding;
+pub(crate) struct DuplicateMatcherBinding;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unknown_macro_variable)]
-pub struct UnknownMacroVariable {
+pub(crate) struct UnknownMacroVariable {
     pub name: MacroRulesNormalizedIdent,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_crate_dependency)]
 #[help]
-pub struct UnusedCrateDependency {
+pub(crate) struct UnusedCrateDependency {
     pub extern_crate: Symbol,
     pub local_crate: Symbol,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_wasm_c_abi)]
-pub struct WasmCAbi;
+pub(crate) struct WasmCAbi;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_ill_formed_attribute_input)]
-pub struct IllFormedAttributeInput {
+pub(crate) struct IllFormedAttributeInput {
     pub num_suggestions: usize,
     pub suggestions: DiagArgValue,
 }
 
 #[derive(LintDiagnostic)]
-pub enum InnerAttributeUnstable {
+pub(crate) enum InnerAttributeUnstable {
     #[diag(lint_inner_macro_attribute_unstable)]
     InnerMacroAttribute,
     #[diag(lint_custom_inner_attribute_unstable)]
@@ -2524,7 +2524,7 @@ pub enum InnerAttributeUnstable {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unknown_diagnostic_attribute)]
-pub struct UnknownDiagnosticAttribute {
+pub(crate) struct UnknownDiagnosticAttribute {
     #[subdiagnostic]
     pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
 }
@@ -2536,7 +2536,7 @@ pub struct UnknownDiagnosticAttribute {
     code = "{typo_name}",
     applicability = "machine-applicable"
 )]
-pub struct UnknownDiagnosticAttributeTypoSugg {
+pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
     #[primary_span]
     pub span: Span,
     pub typo_name: Symbol,
@@ -2545,7 +2545,7 @@ pub struct UnknownDiagnosticAttributeTypoSugg {
 #[derive(LintDiagnostic)]
 #[diag(lint_unicode_text_flow)]
 #[note]
-pub struct UnicodeTextFlow {
+pub(crate) struct UnicodeTextFlow {
     #[label]
     pub comment_span: Span,
     #[subdiagnostic]
@@ -2558,7 +2558,7 @@ pub struct UnicodeTextFlow {
 
 #[derive(Subdiagnostic)]
 #[label(lint_label_comment_char)]
-pub struct UnicodeCharNoteSub {
+pub(crate) struct UnicodeCharNoteSub {
     #[primary_span]
     pub span: Span,
     pub c_debug: String,
@@ -2566,21 +2566,21 @@ pub struct UnicodeCharNoteSub {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable", style = "hidden")]
-pub struct UnicodeTextFlowSuggestion {
+pub(crate) struct UnicodeTextFlowSuggestion {
     #[suggestion_part(code = "")]
     pub spans: Vec<Span>,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_abs_path_with_module)]
-pub struct AbsPathWithModule {
+pub(crate) struct AbsPathWithModule {
     #[subdiagnostic]
     pub sugg: AbsPathWithModuleSugg,
 }
 
 #[derive(Subdiagnostic)]
 #[suggestion(lint_suggestion, code = "{replacement}")]
-pub struct AbsPathWithModuleSugg {
+pub(crate) struct AbsPathWithModuleSugg {
     #[primary_span]
     pub span: Span,
     #[applicability]
@@ -2590,7 +2590,7 @@ pub struct AbsPathWithModuleSugg {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_proc_macro_derive_resolution_fallback)]
-pub struct ProcMacroDeriveResolutionFallback {
+pub(crate) struct ProcMacroDeriveResolutionFallback {
     #[label]
     pub span: Span,
     pub ns: Namespace,
@@ -2599,28 +2599,28 @@ pub struct ProcMacroDeriveResolutionFallback {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_macro_expanded_macro_exports_accessed_by_absolute_paths)]
-pub struct MacroExpandedMacroExportsAccessedByAbsolutePaths {
+pub(crate) struct MacroExpandedMacroExportsAccessedByAbsolutePaths {
     #[note]
     pub definition: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_lifetime_parameters)]
-pub struct ElidedLifetimesInPaths {
+pub(crate) struct ElidedLifetimesInPaths {
     #[subdiagnostic]
     pub subdiag: ElidedLifetimeInPathSubdiag,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_invalid_crate_type_value)]
-pub struct UnknownCrateTypes {
+pub(crate) struct UnknownCrateTypes {
     #[subdiagnostic]
     pub sugg: Option<UnknownCrateTypesSub>,
 }
 
 #[derive(Subdiagnostic)]
 #[suggestion(lint_suggestion, code = r#""{candidate}""#, applicability = "maybe-incorrect")]
-pub struct UnknownCrateTypesSub {
+pub(crate) struct UnknownCrateTypesSub {
     #[primary_span]
     pub span: Span,
     pub candidate: Symbol,
@@ -2628,7 +2628,7 @@ pub struct UnknownCrateTypesSub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_imports)]
-pub struct UnusedImports {
+pub(crate) struct UnusedImports {
     #[subdiagnostic]
     pub sugg: UnusedImportsSugg,
     #[help]
@@ -2639,7 +2639,7 @@ pub struct UnusedImports {
 }
 
 #[derive(Subdiagnostic)]
-pub enum UnusedImportsSugg {
+pub(crate) enum UnusedImportsSugg {
     #[suggestion(
         lint_suggestion_remove_whole_use,
         applicability = "machine-applicable",
@@ -2664,7 +2664,7 @@ pub enum UnusedImportsSugg {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_redundant_import)]
-pub struct RedundantImport {
+pub(crate) struct RedundantImport {
     #[subdiagnostic]
     pub subs: Vec<RedundantImportSub>,
 
@@ -2672,7 +2672,7 @@ pub struct RedundantImport {
 }
 
 #[derive(Subdiagnostic)]
-pub enum RedundantImportSub {
+pub(crate) enum RedundantImportSub {
     #[label(lint_label_imported_here)]
     ImportedHere(#[primary_span] Span),
     #[label(lint_label_defined_here)]
@@ -2686,13 +2686,13 @@ pub enum RedundantImportSub {
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_doc_comment)]
 #[help]
-pub struct UnusedDocComment {
+pub(crate) struct UnusedDocComment {
     #[label]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-pub enum PatternsInFnsWithoutBody {
+pub(crate) enum PatternsInFnsWithoutBody {
     #[diag(lint_pattern_in_foreign)]
     Foreign {
         #[subdiagnostic]
@@ -2707,7 +2707,7 @@ pub enum PatternsInFnsWithoutBody {
 
 #[derive(Subdiagnostic)]
 #[suggestion(lint_remove_mut_from_pattern, code = "{ident}", applicability = "machine-applicable")]
-pub struct PatternsInFnsWithoutBodySub {
+pub(crate) struct PatternsInFnsWithoutBodySub {
     #[primary_span]
     pub span: Span,
 
@@ -2717,7 +2717,7 @@ pub struct PatternsInFnsWithoutBodySub {
 #[derive(LintDiagnostic)]
 #[diag(lint_extern_without_abi)]
 #[help]
-pub struct MissingAbi {
+pub(crate) struct MissingAbi {
     #[label]
     pub span: Span,
 
@@ -2726,14 +2726,14 @@ pub struct MissingAbi {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_legacy_derive_helpers)]
-pub struct LegacyDeriveHelpers {
+pub(crate) struct LegacyDeriveHelpers {
     #[label]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_or_patterns_back_compat)]
-pub struct OrPatternsBackCompat {
+pub(crate) struct OrPatternsBackCompat {
     #[suggestion(code = "{suggestion}", applicability = "machine-applicable")]
     pub span: Span,
     pub suggestion: String,
@@ -2741,7 +2741,7 @@ pub struct OrPatternsBackCompat {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_reserved_prefix)]
-pub struct ReservedPrefix {
+pub(crate) struct ReservedPrefix {
     #[label]
     pub label: Span,
     #[suggestion(code = " ", applicability = "machine-applicable")]
@@ -2752,7 +2752,7 @@ pub struct ReservedPrefix {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_builtin_attribute)]
-pub struct UnusedBuiltinAttribute {
+pub(crate) struct UnusedBuiltinAttribute {
     #[note]
     pub invoc_span: Span,
 
@@ -2762,7 +2762,7 @@ pub struct UnusedBuiltinAttribute {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_trailing_semi_macro)]
-pub struct TrailingMacro {
+pub(crate) struct TrailingMacro {
     #[note(lint_note1)]
     #[note(lint_note2)]
     pub is_trailing: bool,
@@ -2772,14 +2772,14 @@ pub struct TrailingMacro {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_break_with_label_and_loop)]
-pub struct BreakWithLabelAndLoop {
+pub(crate) struct BreakWithLabelAndLoop {
     #[subdiagnostic]
     pub sub: BreakWithLabelAndLoopSub,
 }
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
-pub struct BreakWithLabelAndLoopSub {
+pub(crate) struct BreakWithLabelAndLoopSub {
     #[suggestion_part(code = "(")]
     pub left: Span,
     #[suggestion_part(code = ")")]
@@ -2789,13 +2789,13 @@ pub struct BreakWithLabelAndLoopSub {
 #[derive(LintDiagnostic)]
 #[diag(lint_deprecated_where_clause_location)]
 #[note]
-pub struct DeprecatedWhereClauseLocation {
+pub(crate) struct DeprecatedWhereClauseLocation {
     #[subdiagnostic]
     pub suggestion: DeprecatedWhereClauseLocationSugg,
 }
 
 #[derive(Subdiagnostic)]
-pub enum DeprecatedWhereClauseLocationSugg {
+pub(crate) enum DeprecatedWhereClauseLocationSugg {
     #[multipart_suggestion(lint_suggestion_move_to_end, applicability = "machine-applicable")]
     MoveToEnd {
         #[suggestion_part(code = "")]
@@ -2814,14 +2814,14 @@ pub enum DeprecatedWhereClauseLocationSugg {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_missing_unsafe_on_extern)]
-pub struct MissingUnsafeOnExtern {
+pub(crate) struct MissingUnsafeOnExtern {
     #[suggestion(code = "unsafe ", applicability = "machine-applicable")]
     pub suggestion: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_single_use_lifetime)]
-pub struct SingleUseLifetime {
+pub(crate) struct SingleUseLifetime {
     #[label(lint_label_param)]
     pub param_span: Span,
     #[label(lint_label_use)]
@@ -2834,7 +2834,7 @@ pub struct SingleUseLifetime {
 
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
-pub struct SingleUseLifetimeSugg {
+pub(crate) struct SingleUseLifetimeSugg {
     #[suggestion_part(code = "")]
     pub deletion_span: Option<Span>,
     #[suggestion_part(code = "{replace_lt}")]
@@ -2845,7 +2845,7 @@ pub struct SingleUseLifetimeSugg {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_lifetime)]
-pub struct UnusedLifetime {
+pub(crate) struct UnusedLifetime {
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub deletion_span: Option<Span>,
 
@@ -2854,7 +2854,7 @@ pub struct UnusedLifetime {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_named_argument_used_positionally)]
-pub struct NamedArgumentUsedPositionally {
+pub(crate) struct NamedArgumentUsedPositionally {
     #[label(lint_label_named_arg)]
     pub named_arg_sp: Span,
     #[label(lint_label_position_arg)]
@@ -2869,21 +2869,21 @@ pub struct NamedArgumentUsedPositionally {
 #[derive(LintDiagnostic)]
 #[diag(lint_byte_slice_in_packed_struct_with_derive)]
 #[help]
-pub struct ByteSliceInPackedStructWithDerive {
+pub(crate) struct ByteSliceInPackedStructWithDerive {
     // FIXME: make this translatable
     pub ty: String,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unused_extern_crate)]
-pub struct UnusedExternCrate {
+pub(crate) struct UnusedExternCrate {
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub removal_span: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_extern_crate_not_idiomatic)]
-pub struct ExternCrateNotIdiomatic {
+pub(crate) struct ExternCrateNotIdiomatic {
     #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
     pub span: Span,
 
@@ -2891,7 +2891,7 @@ pub struct ExternCrateNotIdiomatic {
 }
 
 // FIXME: make this translatable
-pub struct AmbiguousGlobImports {
+pub(crate) struct AmbiguousGlobImports {
     pub ambiguity: AmbiguityErrorDiag,
 }
 
@@ -2904,7 +2904,7 @@ impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_ambiguous_glob_reexport)]
-pub struct AmbiguousGlobReexports {
+pub(crate) struct AmbiguousGlobReexports {
     #[label(lint_label_first_reexport)]
     pub first_reexport: Span,
     #[label(lint_label_duplicate_reexport)]
@@ -2917,7 +2917,7 @@ pub struct AmbiguousGlobReexports {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_glob_reexport)]
-pub struct HiddenGlobReexports {
+pub(crate) struct HiddenGlobReexports {
     #[note(lint_note_glob_reexport)]
     pub glob_reexport: Span,
     #[note(lint_note_private_item)]
@@ -2930,14 +2930,14 @@ pub struct HiddenGlobReexports {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unnecessary_qualification)]
-pub struct UnusedQualifications {
+pub(crate) struct UnusedQualifications {
     #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
     pub removal_span: Span,
 }
 
 #[derive(LintDiagnostic)]
 #[diag(lint_associated_const_elided_lifetime)]
-pub struct AssociatedConstElidedLifetime {
+pub(crate) struct AssociatedConstElidedLifetime {
     #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
     pub span: Span,
 
@@ -2949,7 +2949,7 @@ pub struct AssociatedConstElidedLifetime {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_redundant_import_visibility)]
-pub struct RedundantImportVisibility {
+pub(crate) struct RedundantImportVisibility {
     #[note]
     pub span: Span,
     #[help]
@@ -2961,7 +2961,7 @@ pub struct RedundantImportVisibility {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_unsafe_attr_outside_unsafe)]
-pub struct UnsafeAttrOutsideUnsafe {
+pub(crate) struct UnsafeAttrOutsideUnsafe {
     #[label]
     pub span: Span,
     #[subdiagnostic]
@@ -2973,7 +2973,7 @@ pub struct UnsafeAttrOutsideUnsafe {
     lint_unsafe_attr_outside_unsafe_suggestion,
     applicability = "machine-applicable"
 )]
-pub struct UnsafeAttrOutsideUnsafeSuggestion {
+pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
     #[suggestion_part(code = "unsafe(")]
     pub left: Span,
     #[suggestion_part(code = ")")]
@@ -2983,6 +2983,6 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion {
 #[derive(LintDiagnostic)]
 #[diag(lint_out_of_scope_macro_calls)]
 #[help]
-pub struct OutOfScopeMacroCalls {
+pub(crate) struct OutOfScopeMacroCalls {
     pub path: String,
 }
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 5ad677995da..13a3c741fe3 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -55,7 +55,7 @@ declare_lint! {
 }
 
 #[derive(Default)]
-pub struct NonLocalDefinitions {
+pub(crate) struct NonLocalDefinitions {
     body_depth: u32,
 }
 
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index d7fd41c0ad7..d81052b5e24 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -17,13 +17,13 @@ use crate::lints::{
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
 #[derive(PartialEq)]
-pub enum MethodLateContext {
+pub(crate) enum MethodLateContext {
     TraitAutoImpl,
     TraitImpl,
     PlainImpl,
 }
 
-pub fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext {
+pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext {
     let item = cx.tcx.associated_item(id);
     match item.container {
         ty::TraitContainer => MethodLateContext::TraitAutoImpl,
diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs
index 4fe35a6a0a3..bb9c7d85c2e 100644
--- a/compiler/rustc_lint/src/shadowed_into_iter.rs
+++ b/compiler/rustc_lint/src/shadowed_into_iter.rs
@@ -65,7 +65,7 @@ declare_lint! {
 }
 
 #[derive(Copy, Clone)]
-pub struct ShadowedIntoIter;
+pub(crate) struct ShadowedIntoIter;
 
 impl_lint_pass!(ShadowedIntoIter => [ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER]);
 
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index f1da14bb1f3..f2f7c0eaa4d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -165,7 +165,7 @@ declare_lint! {
 }
 
 #[derive(Copy, Clone)]
-pub struct TypeLimits {
+pub(crate) struct TypeLimits {
     /// Id of the last visited negated expression
     negated_expr_id: Option<hir::HirId>,
     /// Span of the last visited negated expression
@@ -180,7 +180,7 @@ impl_lint_pass!(TypeLimits => [
 ]);
 
 impl TypeLimits {
-    pub fn new() -> TypeLimits {
+    pub(crate) fn new() -> TypeLimits {
         TypeLimits { negated_expr_id: None, negated_expr_span: None }
     }
 }
@@ -1008,7 +1008,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>(
 
 /// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that
 /// field.
-pub fn transparent_newtype_field<'a, 'tcx>(
+pub(crate) fn transparent_newtype_field<'a, 'tcx>(
     tcx: TyCtxt<'tcx>,
     variant: &'a ty::VariantDef,
 ) -> Option<&'a ty::FieldDef> {
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 553d9db12c5..c3b80e01c36 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1019,7 +1019,7 @@ declare_lint! {
     "`if`, `match`, `while` and `return` do not need parentheses"
 }
 
-pub struct UnusedParens {
+pub(crate) struct UnusedParens {
     with_self_ty_parens: bool,
     /// `1 as (i32) < 2` parses to ExprKind::Lt
     /// `1 as i32 < 2` parses to i32::<2[missing angle bracket]
@@ -1027,7 +1027,7 @@ pub struct UnusedParens {
 }
 
 impl UnusedParens {
-    pub fn new() -> Self {
+    pub(crate) fn new() -> Self {
         Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() }
     }
 }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 0f07de43e80..c17b85db3b0 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,3 +1,7 @@
+// tidy-alphabetical-start
+#![warn(unreachable_pub)]
+// tidy-alphabetical-end
+
 use rustc_ast::node_id::NodeId;
 use rustc_ast::{AttrId, Attribute};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 79a68b2ff0e..ed12318c88d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -913,14 +913,19 @@ extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
                             size_t FilenameLen, const char *Directory,
                             size_t DirectoryLen, LLVMRustChecksumKind CSKind,
-                            const char *Checksum, size_t ChecksumLen) {
+                            const char *Checksum, size_t ChecksumLen,
+                            const char *Source, size_t SourceLen) {
 
   std::optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
   std::optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
   if (llvmCSKind)
     CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
+  std::optional<StringRef> oSource{};
+  if (Source)
+    oSource = StringRef(Source, SourceLen);
   return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
-                                  StringRef(Directory, DirectoryLen), CSInfo));
+                                  StringRef(Directory, DirectoryLen), CSInfo,
+                                  oSource));
 }
 
 extern "C" LLVMMetadataRef
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 939e5e4dbd4..3532d50c64e 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,8 +1,10 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
+#![cfg_attr(bootstrap, feature(unsafe_attributes, unsafe_extern_blocks))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
+#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // NOTE: This crate only exists to allow linking on mingw targets.
@@ -28,7 +30,7 @@ impl RustString {
 }
 
 /// Appending to a Rust string -- used by RawRustStringOstream.
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn LLVMRustStringWriteImpl(
     sr: &RustString,
     ptr: *const c_char,
@@ -46,7 +48,7 @@ pub fn initialize_available_targets() {
         ($cfg:meta, $($method:ident),*) => { {
             #[cfg($cfg)]
             fn init() {
-                extern "C" {
+                unsafe extern "C" {
                     $(fn $method();)*
                 }
                 unsafe {
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index c59f86b0a9b..929bc2df6f6 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -1,7 +1,5 @@
 // tidy-alphabetical-start
-#![allow(internal_features)]
 #![allow(rustc::default_hash_types)]
-#![feature(allow_internal_unstable)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(never_type)]
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 0d83f8c6c5c..9c93726ca37 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -872,7 +872,8 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::OpaqueTy
         | DefKind::Field
         | DefKind::Impl { .. }
-        | DefKind::Closure => true,
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => true,
         DefKind::ForeignMod | DefKind::GlobalAsm => false,
     }
 }
@@ -902,6 +903,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
         // https://github.com/model-checking/kani and is not a performance
         // or maintenance issue for us.
         DefKind::Closure => true,
+        DefKind::SyntheticCoroutineBody => false,
         DefKind::TyParam
         | DefKind::ConstParam
         | DefKind::Ctor(..)
@@ -948,7 +950,8 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
         | DefKind::Field
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::Closure => false,
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -984,7 +987,8 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
         | DefKind::GlobalAsm
         | DefKind::Impl { .. }
         | DefKind::Closure
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -1019,7 +1023,8 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
         | DefKind::InlineConst
         | DefKind::GlobalAsm
         | DefKind::Closure
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -1061,6 +1066,7 @@ fn should_encode_mir(
         }
         // Coroutines require optimized MIR to compute layout.
         DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true),
+        DefKind::SyntheticCoroutineBody => (false, true),
         // Full-fledged functions + closures
         DefKind::AssocFn | DefKind::Fn | DefKind::Closure => {
             let generics = tcx.generics_of(def_id);
@@ -1109,7 +1115,8 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
         | DefKind::InlineConst
         | DefKind::GlobalAsm
         | DefKind::Closure
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
         DefKind::TyAlias => tcx.type_alias_is_lazy(def_id),
     }
 }
@@ -1137,7 +1144,8 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
         | DefKind::Impl { .. }
         | DefKind::Field
         | DefKind::TyParam
-        | DefKind::Closure => true,
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => true,
         DefKind::Mod
         | DefKind::ForeignMod
         | DefKind::ConstParam
@@ -1168,7 +1176,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::Closure
         | DefKind::ConstParam
         | DefKind::AnonConst
-        | DefKind::InlineConst => true,
+        | DefKind::InlineConst
+        | DefKind::SyntheticCoroutineBody => true,
 
         DefKind::OpaqueTy => {
             let origin = tcx.opaque_type_origin(def_id);
@@ -1240,7 +1249,8 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
         | DefKind::Use
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -1277,7 +1287,8 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
         | DefKind::Use
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -1310,7 +1321,8 @@ fn should_encode_const(def_kind: DefKind) -> bool {
         | DefKind::Use
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::ExternCrate => false,
+        | DefKind::ExternCrate
+        | DefKind::SyntheticCoroutineBody => false,
     }
 }
 
@@ -1458,7 +1470,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     record!(self.tables.associated_type_for_effects[def_id] <- assoc_def_id);
                 }
             }
-            if def_kind == DefKind::Closure
+            if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind
                 && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id)
             {
                 self.tables.coroutine_kind.set(def_id.index, Some(coroutine_kind))
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 617372a97b5..3a6f3543317 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -171,6 +171,7 @@ fixed_size_enum! {
         ( Macro(MacroKind::Bang)                   )
         ( Macro(MacroKind::Attr)                   )
         ( Macro(MacroKind::Derive)                 )
+        ( SyntheticCoroutineBody                   )
     }
 }
 
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 0f85998204c..3d346b9cc5d 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -307,7 +307,7 @@ impl<'hir> Map<'hir> {
             }
             DefKind::InlineConst => BodyOwnerKind::Const { inline: true },
             DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn,
-            DefKind::Closure => BodyOwnerKind::Closure,
+            DefKind::Closure | DefKind::SyntheticCoroutineBody => BodyOwnerKind::Closure,
             DefKind::Static { safety: _, mutability, nested: false } => {
                 BodyOwnerKind::Static(mutability)
             }
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 6886562d9b7..ce330b4744b 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -28,7 +28,7 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::potential_query_instability)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))]
+#![cfg_attr(bootstrap, feature(min_exhaustive_patterns, unsafe_extern_blocks))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(allocator_api)]
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 5b2aac781eb..7b901915037 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -267,18 +267,6 @@ pub struct CoroutineInfo<'tcx> {
     /// Coroutine drop glue. This field is populated after the state transform pass.
     pub coroutine_drop: Option<Body<'tcx>>,
 
-    /// The body of the coroutine, modified to take its upvars by move rather than by ref.
-    ///
-    /// This is used by coroutine-closures, which must return a different flavor of coroutine
-    /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which
-    /// is run right after building the initial MIR, and will only be populated for coroutines
-    /// which come out of the async closure desugaring.
-    ///
-    /// This body should be processed in lockstep with the containing body -- any optimization
-    /// passes, etc, should be applied to this body as well. This is done automatically if
-    /// using `run_passes`.
-    pub by_move_body: Option<Body<'tcx>>,
-
     /// The layout of a coroutine. This field is populated after the state transform pass.
     pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
 
@@ -298,7 +286,6 @@ impl<'tcx> CoroutineInfo<'tcx> {
             coroutine_kind,
             yield_ty: Some(yield_ty),
             resume_ty: Some(resume_ty),
-            by_move_body: None,
             coroutine_drop: None,
             coroutine_layout: None,
         }
@@ -665,10 +652,6 @@ impl<'tcx> Body<'tcx> {
         self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop.as_ref())
     }
 
-    pub fn coroutine_by_move_body(&self) -> Option<&Body<'tcx>> {
-        self.coroutine.as_ref()?.by_move_body.as_ref()
-    }
-
     #[inline]
     pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
         self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 336a9388a56..1d94c364ae3 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -415,7 +415,6 @@ impl<'tcx> CodegenUnit<'tcx> {
                             | InstanceKind::Virtual(..)
                             | InstanceKind::ClosureOnceShim { .. }
                             | InstanceKind::ConstructCoroutineInClosureShim { .. }
-                            | InstanceKind::CoroutineKindShim { .. }
                             | InstanceKind::DropGlue(..)
                             | InstanceKind::CloneShim(..)
                             | InstanceKind::ThreadLocalShim(..)
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index bfb129495ce..64898a8495e 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -349,7 +349,6 @@ macro_rules! make_mir_visitor {
                             coroutine_closure_def_id: _def_id,
                             receiver_by_ref: _,
                         } |
-                        ty::InstanceKind::CoroutineKindShim { coroutine_def_id: _def_id } |
                         ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) |
                         ty::InstanceKind::DropGlue(_def_id, None) => {}
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 75166624f95..b748f85253f 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -326,6 +326,7 @@ rustc_queries! {
     query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
         desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
+        feedable
     }
 
     query opaque_types_defined_by(
@@ -498,6 +499,7 @@ rustc_queries! {
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html
     query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
         desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) }
+        feedable
     }
 
     /// Try to build an abstract representation of the given constant.
@@ -742,6 +744,7 @@ rustc_queries! {
     query constness(key: DefId) -> hir::Constness {
         desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) }
         separate_provide_extern
+        feedable
     }
 
     query asyncness(key: DefId) -> ty::Asyncness {
@@ -760,10 +763,22 @@ rustc_queries! {
         desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) }
     }
 
+    /// The body of the coroutine, modified to take its upvars by move rather than by ref.
+    ///
+    /// This is used by coroutine-closures, which must return a different flavor of coroutine
+    /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` pass which
+    /// is run right after building the initial MIR, and will only be populated for coroutines
+    /// which come out of the async closure desugaring.
+    query coroutine_by_move_body_def_id(def_id: DefId) -> DefId {
+        desc { |tcx| "looking up the coroutine by-move body for `{}`", tcx.def_path_str(def_id) }
+        separate_provide_extern
+    }
+
     /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine.
     query coroutine_kind(def_id: DefId) -> Option<hir::CoroutineKind> {
         desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) }
         separate_provide_extern
+        feedable
     }
 
     query coroutine_for_closure(def_id: DefId) -> DefId {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index cad3515f068..8effb67a1f6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1579,6 +1579,12 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
+    // Whether the body owner is synthetic, which in this case means it does not correspond to
+    // meaningful HIR. This is currently used to skip over MIR borrowck.
+    pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool {
+        matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody)
+    }
+
     /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
     /// This means it is neither an `async` or `gen` construct.
     pub fn is_general_coroutine(self, def_id: DefId) -> bool {
@@ -3168,6 +3174,18 @@ impl<'tcx> TyCtxt<'tcx> {
         self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
     }
 
+    pub fn needs_coroutine_by_move_body_def_id(self, def_id: LocalDefId) -> bool {
+        if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
+            self.coroutine_kind(def_id)
+            && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
+            && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce)
+        {
+            true
+        } else {
+            false
+        }
+    }
+
     /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
     pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
         matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true })
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index ecb3943e788..7d5f0f1e9c4 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -141,14 +141,6 @@ pub enum InstanceKind<'tcx> {
         receiver_by_ref: bool,
     },
 
-    /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce`
-    /// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or
-    /// similarly for `AsyncFnMut`.
-    ///
-    /// This will select the body that is produced by the `ByMoveBody` transform, and thus
-    /// take and use all of its upvars by-move rather than by-ref.
-    CoroutineKindShim { coroutine_def_id: DefId },
-
     /// Compiler-generated accessor for thread locals which returns a reference to the thread local
     /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking
     /// native support.
@@ -248,7 +240,6 @@ impl<'tcx> InstanceKind<'tcx> {
                 coroutine_closure_def_id: def_id,
                 receiver_by_ref: _,
             }
-            | ty::InstanceKind::CoroutineKindShim { coroutine_def_id: def_id }
             | InstanceKind::DropGlue(def_id, _)
             | InstanceKind::CloneShim(def_id, _)
             | InstanceKind::FnPtrAddrShim(def_id, _)
@@ -270,7 +261,6 @@ impl<'tcx> InstanceKind<'tcx> {
             | InstanceKind::Intrinsic(..)
             | InstanceKind::ClosureOnceShim { .. }
             | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceKind::CoroutineKindShim { .. }
             | InstanceKind::DropGlue(..)
             | InstanceKind::AsyncDropGlueCtorShim(..)
             | InstanceKind::CloneShim(..)
@@ -377,7 +367,6 @@ impl<'tcx> InstanceKind<'tcx> {
             | InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false,
             InstanceKind::ClosureOnceShim { .. }
             | InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | InstanceKind::CoroutineKindShim { .. }
             | InstanceKind::DropGlue(..)
             | InstanceKind::AsyncDropGlueCtorShim(..)
             | InstanceKind::Item(_)
@@ -452,7 +441,6 @@ pub fn fmt_instance(
         InstanceKind::FnPtrShim(_, ty) => write!(f, " - shim({ty})"),
         InstanceKind::ClosureOnceShim { .. } => write!(f, " - shim"),
         InstanceKind::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"),
-        InstanceKind::CoroutineKindShim { .. } => write!(f, " - shim"),
         InstanceKind::DropGlue(_, None) => write!(f, " - shim(None)"),
         InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
         InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"),
@@ -850,7 +838,9 @@ impl<'tcx> Instance<'tcx> {
                 Some(Instance { def: ty::InstanceKind::Item(coroutine_def_id), args })
             } else {
                 Some(Instance {
-                    def: ty::InstanceKind::CoroutineKindShim { coroutine_def_id },
+                    def: ty::InstanceKind::Item(
+                        tcx.coroutine_by_move_body_def_id(coroutine_def_id),
+                    ),
                     args,
                 })
             }
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 1a1acf36d77..af76d5b7d92 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -58,7 +58,7 @@ impl<T> Default for &List<T> {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     /// A dummy type used to force `List` to be unsized while not requiring
     /// references to it be wide pointers.
     type OpaqueListContents;
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 1e3b5800cba..e41ea7507ef 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1756,7 +1756,6 @@ impl<'tcx> TyCtxt<'tcx> {
             | ty::InstanceKind::Virtual(..)
             | ty::InstanceKind::ClosureOnceShim { .. }
             | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceKind::CoroutineKindShim { .. }
             | ty::InstanceKind::DropGlue(..)
             | ty::InstanceKind::CloneShim(..)
             | ty::InstanceKind::ThreadLocalShim(..)
@@ -1874,7 +1873,8 @@ impl<'tcx> TyCtxt<'tcx> {
                     identity_kind_ty.to_opt_closure_kind(),
                     Some(ClosureKind::Fn | ClosureKind::FnMut)
                 );
-                mir.coroutine_by_move_body().unwrap().coroutine_layout_raw()
+                self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
+                    .coroutine_layout_raw()
             }
         }
     }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 703339bf5bc..d9d2abc554a 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -53,7 +53,7 @@
 mod by_move_body;
 use std::{iter, ops};
 
-pub use by_move_body::ByMoveBody;
+pub use by_move_body::coroutine_by_move_body_def_id;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::pluralize;
 use rustc_hir as hir;
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 7ea36f08232..ebe8d2eff4f 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -69,161 +69,167 @@
 //! in case precise captures (edition 2021 closure capture rules) caused the inner coroutine
 //! to split one field capture into two.
 
+use rustc_data_structures::steal::Steal;
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::bug;
 use rustc_middle::hir::place::{Projection, ProjectionKind};
 use rustc_middle::mir::visit::MutVisitor;
-use rustc_middle::mir::{self, dump_mir, MirPass};
+use rustc_middle::mir::{self, dump_mir};
 use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_span::symbol::kw;
 use rustc_target::abi::{FieldIdx, VariantIdx};
 
-use crate::pass_manager::validate_body;
-
-pub struct ByMoveBody;
+pub fn coroutine_by_move_body_def_id<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    coroutine_def_id: LocalDefId,
+) -> DefId {
+    let body = tcx.mir_built(coroutine_def_id).borrow();
 
-impl<'tcx> MirPass<'tcx> for ByMoveBody {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
-        // We only need to generate by-move coroutine bodies for coroutines that come
-        // from coroutine-closures.
-        let Some(coroutine_def_id) = body.source.def_id().as_local() else {
-            return;
-        };
-        let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
-            tcx.coroutine_kind(coroutine_def_id)
-        else {
-            return;
-        };
+    let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
+        tcx.coroutine_kind(coroutine_def_id)
+    else {
+        bug!("should only be invoked on coroutine-closures");
+    };
 
-        // Also, let's skip processing any bodies with errors, since there's no guarantee
-        // the MIR body will be constructed well.
-        let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
-        if coroutine_ty.references_error() {
-            return;
-        }
+    // Also, let's skip processing any bodies with errors, since there's no guarantee
+    // the MIR body will be constructed well.
+    let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
 
-        // We don't need to generate a by-move coroutine if the coroutine body was
-        // produced by the `CoroutineKindShim`, since it's already by-move.
-        if matches!(body.source.instance, ty::InstanceKind::CoroutineKindShim { .. }) {
-            return;
-        }
+    let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
+    let args = args.as_coroutine();
 
-        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
-        let args = args.as_coroutine();
+    let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();
 
-        let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();
+    let parent_def_id = tcx.local_parent(coroutine_def_id);
+    let ty::CoroutineClosure(_, parent_args) =
+        *tcx.type_of(parent_def_id).instantiate_identity().kind()
+    else {
+        bug!();
+    };
+    if parent_args.references_error() {
+        return coroutine_def_id.to_def_id();
+    }
 
-        let parent_def_id = tcx.local_parent(coroutine_def_id);
-        let ty::CoroutineClosure(_, parent_args) =
-            *tcx.type_of(parent_def_id).instantiate_identity().kind()
-        else {
-            bug!();
-        };
-        let parent_closure_args = parent_args.as_coroutine_closure();
-        let num_args = parent_closure_args
-            .coroutine_closure_sig()
-            .skip_binder()
-            .tupled_inputs_ty
-            .tuple_fields()
-            .len();
+    let parent_closure_args = parent_args.as_coroutine_closure();
+    let num_args = parent_closure_args
+        .coroutine_closure_sig()
+        .skip_binder()
+        .tupled_inputs_ty
+        .tuple_fields()
+        .len();
 
-        let field_remapping: UnordMap<_, _> = ty::analyze_coroutine_closure_captures(
-            tcx.closure_captures(parent_def_id).iter().copied(),
-            tcx.closure_captures(coroutine_def_id).iter().skip(num_args).copied(),
-            |(parent_field_idx, parent_capture), (child_field_idx, child_capture)| {
-                // Store this set of additional projections (fields and derefs).
-                // We need to re-apply them later.
-                let mut child_precise_captures = child_capture.place.projections
-                    [parent_capture.place.projections.len()..]
-                    .to_vec();
+    let field_remapping: UnordMap<_, _> = ty::analyze_coroutine_closure_captures(
+        tcx.closure_captures(parent_def_id).iter().copied(),
+        tcx.closure_captures(coroutine_def_id).iter().skip(num_args).copied(),
+        |(parent_field_idx, parent_capture), (child_field_idx, child_capture)| {
+            // Store this set of additional projections (fields and derefs).
+            // We need to re-apply them later.
+            let mut child_precise_captures =
+                child_capture.place.projections[parent_capture.place.projections.len()..].to_vec();
 
-                // If the parent capture is by-ref, then we need to apply an additional
-                // deref before applying any further projections to this place.
-                if parent_capture.is_by_ref() {
-                    child_precise_captures.insert(
-                        0,
-                        Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref },
-                    );
-                }
-                // If the child capture is by-ref, then we need to apply a "ref"
-                // projection (i.e. `&`) at the end. But wait! We don't have that
-                // as a projection kind. So instead, we can apply its dual and
-                // *peel* a deref off of the place when it shows up in the MIR body.
-                // Luckily, by construction this is always possible.
-                let peel_deref = if child_capture.is_by_ref() {
-                    assert!(
-                        parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce,
-                        "`FnOnce` coroutine-closures return coroutines that capture from \
+            // If the parent capture is by-ref, then we need to apply an additional
+            // deref before applying any further projections to this place.
+            if parent_capture.is_by_ref() {
+                child_precise_captures.insert(
+                    0,
+                    Projection { ty: parent_capture.place.ty(), kind: ProjectionKind::Deref },
+                );
+            }
+            // If the child capture is by-ref, then we need to apply a "ref"
+            // projection (i.e. `&`) at the end. But wait! We don't have that
+            // as a projection kind. So instead, we can apply its dual and
+            // *peel* a deref off of the place when it shows up in the MIR body.
+            // Luckily, by construction this is always possible.
+            let peel_deref = if child_capture.is_by_ref() {
+                assert!(
+                    parent_capture.is_by_ref() || coroutine_kind != ty::ClosureKind::FnOnce,
+                    "`FnOnce` coroutine-closures return coroutines that capture from \
                         their body; it will always result in a borrowck error!"
-                    );
-                    true
-                } else {
-                    false
-                };
+                );
+                true
+            } else {
+                false
+            };
 
-                // Regarding the behavior above, you may think that it's redundant to both
-                // insert a deref and then peel a deref if the parent and child are both
-                // captured by-ref. This would be correct, except for the case where we have
-                // precise capturing projections, since the inserted deref is to the *beginning*
-                // and the peeled deref is at the *end*. I cannot seem to actually find a
-                // case where this happens, though, but let's keep this code flexible.
+            // Regarding the behavior above, you may think that it's redundant to both
+            // insert a deref and then peel a deref if the parent and child are both
+            // captured by-ref. This would be correct, except for the case where we have
+            // precise capturing projections, since the inserted deref is to the *beginning*
+            // and the peeled deref is at the *end*. I cannot seem to actually find a
+            // case where this happens, though, but let's keep this code flexible.
 
-                // Finally, store the type of the parent's captured place. We need
-                // this when building the field projection in the MIR body later on.
-                let mut parent_capture_ty = parent_capture.place.ty();
-                parent_capture_ty = match parent_capture.info.capture_kind {
-                    ty::UpvarCapture::ByValue => parent_capture_ty,
-                    ty::UpvarCapture::ByRef(kind) => Ty::new_ref(
-                        tcx,
-                        tcx.lifetimes.re_erased,
-                        parent_capture_ty,
-                        kind.to_mutbl_lossy(),
-                    ),
-                };
+            // Finally, store the type of the parent's captured place. We need
+            // this when building the field projection in the MIR body later on.
+            let mut parent_capture_ty = parent_capture.place.ty();
+            parent_capture_ty = match parent_capture.info.capture_kind {
+                ty::UpvarCapture::ByValue => parent_capture_ty,
+                ty::UpvarCapture::ByRef(kind) => Ty::new_ref(
+                    tcx,
+                    tcx.lifetimes.re_erased,
+                    parent_capture_ty,
+                    kind.to_mutbl_lossy(),
+                ),
+            };
 
+            (
+                FieldIdx::from_usize(child_field_idx + num_args),
                 (
-                    FieldIdx::from_usize(child_field_idx + num_args),
-                    (
-                        FieldIdx::from_usize(parent_field_idx + num_args),
-                        parent_capture_ty,
-                        peel_deref,
-                        child_precise_captures,
-                    ),
-                )
-            },
-        )
-        .collect();
+                    FieldIdx::from_usize(parent_field_idx + num_args),
+                    parent_capture_ty,
+                    peel_deref,
+                    child_precise_captures,
+                ),
+            )
+        },
+    )
+    .collect();
 
-        if coroutine_kind == ty::ClosureKind::FnOnce {
-            assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len());
-            return;
-        }
+    if coroutine_kind == ty::ClosureKind::FnOnce {
+        assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len());
+        // The by-move body is just the body :)
+        return coroutine_def_id.to_def_id();
+    }
 
-        let by_move_coroutine_ty = tcx
-            .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig())
-            .to_coroutine_given_kind_and_upvars(
-                tcx,
-                parent_closure_args.parent_args(),
-                coroutine_def_id.to_def_id(),
-                ty::ClosureKind::FnOnce,
-                tcx.lifetimes.re_erased,
-                parent_closure_args.tupled_upvars_ty(),
-                parent_closure_args.coroutine_captures_by_ref_ty(),
-            );
+    let by_move_coroutine_ty = tcx
+        .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig())
+        .to_coroutine_given_kind_and_upvars(
+            tcx,
+            parent_closure_args.parent_args(),
+            coroutine_def_id.to_def_id(),
+            ty::ClosureKind::FnOnce,
+            tcx.lifetimes.re_erased,
+            parent_closure_args.tupled_upvars_ty(),
+            parent_closure_args.coroutine_captures_by_ref_ty(),
+        );
 
-        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 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's just always validate this body.
-        validate_body(tcx, &mut by_move_body, "Initial coroutine_by_move body".to_string());
+    let body_def = tcx.create_def(coroutine_def_id, kw::Empty, DefKind::SyntheticCoroutineBody);
+    by_move_body.source =
+        mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
 
-        // FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body.
-        by_move_body.source = mir::MirSource::from_instance(InstanceKind::CoroutineKindShim {
-            coroutine_def_id: coroutine_def_id.to_def_id(),
-        });
-        body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body);
-    }
+    // Inherited from the by-ref coroutine.
+    body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
+    body_def.constness(tcx.constness(coroutine_def_id).clone());
+    body_def.coroutine_kind(tcx.coroutine_kind(coroutine_def_id).clone());
+    body_def.def_ident_span(tcx.def_ident_span(coroutine_def_id));
+    body_def.def_span(tcx.def_span(coroutine_def_id));
+    body_def.explicit_predicates_of(tcx.explicit_predicates_of(coroutine_def_id).clone());
+    body_def.generics_of(tcx.generics_of(coroutine_def_id).clone());
+    body_def.param_env(tcx.param_env(coroutine_def_id).clone());
+    body_def.predicates_of(tcx.predicates_of(coroutine_def_id).clone());
+
+    // The type of the coroutine is the `by_move_coroutine_ty`.
+    body_def.type_of(ty::EarlyBinder::bind(by_move_coroutine_ty));
+
+    body_def.mir_built(tcx.arena.alloc(Steal::new(by_move_body)));
+
+    body_def.def_id().to_def_id()
 }
 
 struct MakeByMoveBody<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 61fc5fc8816..2d6950be55d 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -341,7 +341,6 @@ impl<'tcx> Inliner<'tcx> {
             | InstanceKind::FnPtrShim(..)
             | InstanceKind::ClosureOnceShim { .. }
             | InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | InstanceKind::CoroutineKindShim { .. }
             | InstanceKind::DropGlue(..)
             | InstanceKind::CloneShim(..)
             | InstanceKind::ThreadLocalShim(..)
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index f5274c664cf..56e8905bead 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -88,7 +88,6 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
                 | InstanceKind::FnPtrShim(..)
                 | InstanceKind::ClosureOnceShim { .. }
                 | InstanceKind::ConstructCoroutineInClosureShim { .. }
-                | InstanceKind::CoroutineKindShim { .. }
                 | InstanceKind::ThreadLocalShim { .. }
                 | InstanceKind::CloneShim(..) => {}
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 1f214bc42cb..88094b44edf 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -135,6 +135,7 @@ pub fn provide(providers: &mut Providers) {
         mir_inliner_callees: inline::cycle::mir_inliner_callees,
         promoted_mir,
         deduced_param_attrs: deduce_param_attrs::deduced_param_attrs,
+        coroutine_by_move_body_def_id: coroutine::coroutine_by_move_body_def_id,
         ..providers.queries
     };
 }
@@ -293,10 +294,6 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
             &Lint(check_packed_ref::CheckPackedRef),
             &Lint(check_const_item_mutation::CheckConstItemMutation),
             &Lint(function_item_references::FunctionItemReferences),
-            // If this is an async closure's output coroutine, generate
-            // by-move and by-mut bodies if needed. We do this first so
-            // they can be optimized in lockstep with their parent bodies.
-            &coroutine::ByMoveBody,
             // What we need to do constant evaluation.
             &simplify::SimplifyCfg::Initial,
             &rustc_peek::SanityCheck, // Just a lint
@@ -329,8 +326,15 @@ fn mir_promoted(
         | DefKind::AnonConst => tcx.mir_const_qualif(def),
         _ => ConstQualifs::default(),
     };
-    // has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
+
+    // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
     tcx.ensure_with_value().has_ffi_unwind_calls(def);
+
+    // the `by_move_body` query uses the raw mir, so make sure it is run.
+    if tcx.needs_coroutine_by_move_body_def_id(def) {
+        tcx.ensure_with_value().coroutine_by_move_body_def_id(def);
+    }
+
     let mut body = tcx.mir_built(def).steal();
     if let Some(error_reported) = const_qualifs.tainted_by_errors {
         body.tainted_by_errors = Some(error_reported);
@@ -339,14 +343,6 @@ fn mir_promoted(
     // Collect `required_consts` *before* promotion, so if there are any consts being promoted
     // we still add them to the list in the outer MIR body.
     RequiredConstsVisitor::compute_required_consts(&mut body);
-    // If this has an associated by-move async closure body, that doesn't get run through these
-    // passes itself, it gets "tagged along" by the pass manager. `RequiredConstsVisitor` is not
-    // a regular pass so we have to also apply it manually to the other body.
-    if let Some(coroutine) = body.coroutine.as_mut() {
-        if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
-            RequiredConstsVisitor::compute_required_consts(by_move_body);
-        }
-    }
 
     // What we need to run borrowck etc.
     let promote_pass = promote_consts::PromoteTemps::default();
@@ -398,7 +394,10 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     if tcx.is_coroutine(def.to_def_id()) {
         tcx.ensure_with_value().mir_coroutine_witnesses(def);
     }
-    let mir_borrowck = tcx.mir_borrowck(def);
+
+    // We only need to borrowck non-synthetic MIR.
+    let tainted_by_errors =
+        if !tcx.is_synthetic_mir(def) { tcx.mir_borrowck(def).tainted_by_errors } else { None };
 
     let is_fn_like = tcx.def_kind(def).is_fn_like();
     if is_fn_like {
@@ -410,7 +409,8 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
 
     let (body, _) = tcx.mir_promoted(def);
     let mut body = body.steal();
-    if let Some(error_reported) = mir_borrowck.tainted_by_errors {
+
+    if let Some(error_reported) = tainted_by_errors {
         body.tainted_by_errors = Some(error_reported);
     }
 
@@ -660,14 +660,6 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
     // visited does not depend on the optimization level.
     // We do not use `run_passes` for this as that might skip the pass if `injection_phase` is set.
     mentioned_items::MentionedItems.run_pass(tcx, &mut body);
-    // If this has an associated by-move async closure body, that doesn't get run through these
-    // passes itself, it gets "tagged along" by the pass manager. Since we're not using the pass
-    // manager we have to do this by hand.
-    if let Some(coroutine) = body.coroutine.as_mut() {
-        if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
-            mentioned_items::MentionedItems.run_pass(tcx, by_move_body);
-        }
-    }
 
     // If `mir_drops_elaborated_and_const_checked` found that the current body has unsatisfiable
     // predicates, it will shrink the MIR to a single `unreachable` terminator.
@@ -690,7 +682,9 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
         return tcx.arena.alloc(IndexVec::new());
     }
 
-    tcx.ensure_with_value().mir_borrowck(def);
+    if !tcx.is_synthetic_mir(def) {
+        tcx.ensure_with_value().mir_borrowck(def);
+    }
     let mut promoted = tcx.mir_promoted(def).1.steal();
 
     for body in &mut promoted {
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 824a4b2f2df..d092477e340 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -182,12 +182,6 @@ fn run_passes_inner<'tcx>(
 
         body.pass_count = 1;
     }
-
-    if let Some(coroutine) = body.coroutine.as_mut() {
-        if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
-            run_passes_inner(tcx, by_move_body, passes, phase_change, validate_each);
-        }
-    }
 }
 
 pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 09b4e5e0711..86eada0183f 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -78,15 +78,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
             receiver_by_ref,
         } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref),
 
-        ty::InstanceKind::CoroutineKindShim { coroutine_def_id } => {
-            return tcx.optimized_mir(coroutine_def_id).coroutine_by_move_body().unwrap().clone();
-        }
-
         ty::InstanceKind::DropGlue(def_id, ty) => {
             // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end
             // of this function. Is this intentional?
-            if let Some(ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) {
-                let coroutine_body = tcx.optimized_mir(*coroutine_def_id);
+            if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) {
+                let coroutine_body = tcx.optimized_mir(coroutine_def_id);
 
                 let ty::Coroutine(_, id_args) = *tcx.type_of(coroutine_def_id).skip_binder().kind()
                 else {
@@ -105,7 +101,9 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
                         args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
                         ty::ClosureKind::FnOnce
                     );
-                    coroutine_body.coroutine_by_move_body().unwrap().coroutine_drop().unwrap()
+                    tcx.optimized_mir(tcx.coroutine_by_move_body_def_id(coroutine_def_id))
+                        .coroutine_drop()
+                        .unwrap()
                 };
 
                 let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 36908036796..99e06f59dd0 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -102,25 +102,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
                 }
             }
         }
-
-        // Enforce that coroutine-closure layouts are identical.
-        if let Some(layout) = body.coroutine_layout_raw()
-            && let Some(by_move_body) = body.coroutine_by_move_body()
-            && let Some(by_move_layout) = by_move_body.coroutine_layout_raw()
-        {
-            // FIXME(async_closures): We could do other validation here?
-            if layout.variant_fields.len() != by_move_layout.variant_fields.len() {
-                cfg_checker.fail(
-                    Location::START,
-                    format!(
-                        "Coroutine layout has different number of variant fields from \
-                        by-move coroutine layout:\n\
-                        layout: {layout:#?}\n\
-                        by_move_layout: {by_move_layout:#?}",
-                    ),
-                );
-            }
-        }
     }
 }
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index ff4207fbefd..36fb2e89af1 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -920,7 +920,6 @@ fn visit_instance_use<'tcx>(
         | ty::InstanceKind::ReifyShim(..)
         | ty::InstanceKind::ClosureOnceShim { .. }
         | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-        | ty::InstanceKind::CoroutineKindShim { .. }
         | ty::InstanceKind::Item(..)
         | ty::InstanceKind::FnPtrShim(..)
         | ty::InstanceKind::CloneShim(..)
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 610ad41ce52..2f0088fb34f 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -626,7 +626,6 @@ fn characteristic_def_id_of_mono_item<'tcx>(
                 | ty::InstanceKind::FnPtrShim(..)
                 | ty::InstanceKind::ClosureOnceShim { .. }
                 | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-                | ty::InstanceKind::CoroutineKindShim { .. }
                 | ty::InstanceKind::Intrinsic(..)
                 | ty::InstanceKind::DropGlue(..)
                 | ty::InstanceKind::Virtual(..)
@@ -796,7 +795,6 @@ fn mono_item_visibility<'tcx>(
         | InstanceKind::Intrinsic(..)
         | InstanceKind::ClosureOnceShim { .. }
         | InstanceKind::ConstructCoroutineInClosureShim { .. }
-        | InstanceKind::CoroutineKindShim { .. }
         | InstanceKind::DropGlue(..)
         | InstanceKind::AsyncDropGlueCtorShim(..)
         | InstanceKind::CloneShim(..)
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 5a24202db65..b59c7bcffa9 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -127,7 +127,7 @@ fn mark_used_by_default_parameters<'tcx>(
     unused_parameters: &mut UnusedGenericParams,
 ) {
     match tcx.def_kind(def_id) {
-        DefKind::Closure => {
+        DefKind::Closure | DefKind::SyntheticCoroutineBody => {
             for param in &generics.own_params {
                 debug!(?param, "(closure/gen)");
                 unused_parameters.mark_used(param.index);
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index d1d1e5e901f..9f78215bfd1 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -626,7 +626,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             | DefKind::Field
             | DefKind::GlobalAsm
             | DefKind::Impl { .. }
-            | DefKind::Closure => (),
+            | DefKind::Closure
+            | DefKind::SyntheticCoroutineBody => (),
         }
     }
 }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index fee42ba87c9..3ea782b62f1 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -197,8 +197,78 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
         for child in self.tcx.module_children(module.def_id()) {
             let parent_scope = ParentScope::module(module, self);
-            BuildReducedGraphVisitor { r: self, parent_scope }
-                .build_reduced_graph_for_external_crate_res(child);
+            self.build_reduced_graph_for_external_crate_res(child, parent_scope)
+        }
+    }
+
+    /// Builds the reduced graph for a single item in an external crate.
+    fn build_reduced_graph_for_external_crate_res(
+        &mut self,
+        child: &ModChild,
+        parent_scope: ParentScope<'a>,
+    ) {
+        let parent = parent_scope.module;
+        let ModChild { ident, res, vis, ref reexport_chain } = *child;
+        let span = self.def_span(
+            reexport_chain
+                .first()
+                .and_then(|reexport| reexport.id())
+                .unwrap_or_else(|| res.def_id()),
+        );
+        let res = res.expect_non_local();
+        let expansion = parent_scope.expansion;
+        // Record primary definitions.
+        match res {
+            Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => {
+                let module = self.expect_module(def_id);
+                self.define(parent, ident, TypeNS, (module, vis, span, expansion));
+            }
+            Res::Def(
+                DefKind::Struct
+                | DefKind::Union
+                | DefKind::Variant
+                | DefKind::TyAlias
+                | DefKind::ForeignTy
+                | DefKind::OpaqueTy
+                | DefKind::TraitAlias
+                | DefKind::AssocTy,
+                _,
+            )
+            | Res::PrimTy(..)
+            | Res::ToolMod => self.define(parent, ident, TypeNS, (res, vis, span, expansion)),
+            Res::Def(
+                DefKind::Fn
+                | DefKind::AssocFn
+                | DefKind::Static { .. }
+                | DefKind::Const
+                | DefKind::AssocConst
+                | DefKind::Ctor(..),
+                _,
+            ) => self.define(parent, ident, ValueNS, (res, vis, span, expansion)),
+            Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
+                self.define(parent, ident, MacroNS, (res, vis, span, expansion))
+            }
+            Res::Def(
+                DefKind::TyParam
+                | DefKind::ConstParam
+                | DefKind::ExternCrate
+                | DefKind::Use
+                | DefKind::ForeignMod
+                | DefKind::AnonConst
+                | DefKind::InlineConst
+                | DefKind::Field
+                | DefKind::LifetimeParam
+                | DefKind::GlobalAsm
+                | DefKind::Closure
+                | DefKind::SyntheticCoroutineBody
+                | DefKind::Impl { .. },
+                _,
+            )
+            | Res::Local(..)
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
+            | Res::SelfCtor(..)
+            | Res::Err => bug!("unexpected resolution: {:?}", res),
         }
     }
 }
@@ -967,72 +1037,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) {
-        let parent = self.parent_scope.module;
-        let ModChild { ident, res, vis, ref reexport_chain } = *child;
-        let span = self.r.def_span(
-            reexport_chain
-                .first()
-                .and_then(|reexport| reexport.id())
-                .unwrap_or_else(|| res.def_id()),
-        );
-        let res = res.expect_non_local();
-        let expansion = self.parent_scope.expansion;
-        // Record primary definitions.
-        match res {
-            Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => {
-                let module = self.r.expect_module(def_id);
-                self.r.define(parent, ident, TypeNS, (module, vis, span, expansion));
-            }
-            Res::Def(
-                DefKind::Struct
-                | DefKind::Union
-                | DefKind::Variant
-                | DefKind::TyAlias
-                | DefKind::ForeignTy
-                | DefKind::OpaqueTy
-                | DefKind::TraitAlias
-                | DefKind::AssocTy,
-                _,
-            )
-            | Res::PrimTy(..)
-            | Res::ToolMod => self.r.define(parent, ident, TypeNS, (res, vis, span, expansion)),
-            Res::Def(
-                DefKind::Fn
-                | DefKind::AssocFn
-                | DefKind::Static { .. }
-                | DefKind::Const
-                | DefKind::AssocConst
-                | DefKind::Ctor(..),
-                _,
-            ) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)),
-            Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
-                self.r.define(parent, ident, MacroNS, (res, vis, span, expansion))
-            }
-            Res::Def(
-                DefKind::TyParam
-                | DefKind::ConstParam
-                | DefKind::ExternCrate
-                | DefKind::Use
-                | DefKind::ForeignMod
-                | DefKind::AnonConst
-                | DefKind::InlineConst
-                | DefKind::Field
-                | DefKind::LifetimeParam
-                | DefKind::GlobalAsm
-                | DefKind::Closure
-                | DefKind::Impl { .. },
-                _,
-            )
-            | Res::Local(..)
-            | Res::SelfTyParam { .. }
-            | Res::SelfTyAlias { .. }
-            | Res::SelfCtor(..)
-            | Res::Err => bug!("unexpected resolution: {:?}", res),
-        }
-    }
-
     fn add_macro_use_binding(
         &mut self,
         name: Symbol,
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index b84280a3ccf..01c371ee498 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -14,6 +14,10 @@ session_crate_name_empty = crate name must not be empty
 
 session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen
 
+session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version}
+
+session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled
+
 session_expr_parentheses_needed = parentheses are required to parse this as an expression
 
 session_failed_to_create_profiler = failed to create profiler: {$err}
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 5cc54a5855b..15bbd4ff7bf 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -166,6 +166,16 @@ pub(crate) struct UnsupportedDwarfVersion {
 }
 
 #[derive(Diagnostic)]
+#[diag(session_embed_source_insufficient_dwarf_version)]
+pub(crate) struct EmbedSourceInsufficientDwarfVersion {
+    pub(crate) dwarf_version: u32,
+}
+
+#[derive(Diagnostic)]
+#[diag(session_embed_source_requires_debug_info)]
+pub(crate) struct EmbedSourceRequiresDebugInfo;
+
+#[derive(Diagnostic)]
 #[diag(session_target_stack_protector_not_supported)]
 pub(crate) struct StackProtectorNotSupportedForTarget<'a> {
     pub(crate) stack_protector: StackProtector,
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 63ca5fefd9f..d78f4a78de7 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -5,14 +5,11 @@ use std::{env, fs};
 
 use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use smallvec::{smallvec, SmallVec};
-use tracing::debug;
 
 use crate::search_paths::{PathKind, SearchPath};
 
 #[derive(Clone)]
 pub struct FileSearch<'a> {
-    sysroot: &'a Path,
-    triple: &'a str,
     cli_search_paths: &'a [SearchPath],
     tlib_path: &'a SearchPath,
     kind: PathKind,
@@ -32,23 +29,12 @@ impl<'a> FileSearch<'a> {
             .chain(std::iter::once(self.tlib_path))
     }
 
-    pub fn get_lib_path(&self) -> PathBuf {
-        make_target_lib_path(self.sysroot, self.triple)
-    }
-
-    pub fn get_self_contained_lib_path(&self) -> PathBuf {
-        self.get_lib_path().join("self-contained")
-    }
-
     pub fn new(
-        sysroot: &'a Path,
-        triple: &'a str,
         cli_search_paths: &'a [SearchPath],
         tlib_path: &'a SearchPath,
         kind: PathKind,
     ) -> FileSearch<'a> {
-        debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
-        FileSearch { sysroot, triple, cli_search_paths, tlib_path, kind }
+        FileSearch { cli_search_paths, tlib_path, kind }
     }
 }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index df72e2430fd..23231fbffbf 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1701,6 +1701,8 @@ options! {
         them only if an error has not been emitted"),
     ehcont_guard: bool = (false, parse_bool, [TRACKED],
         "generate Windows EHCont Guard tables"),
+    embed_source: bool = (false, parse_bool, [TRACKED],
+        "embed source text in DWARF debug sections (default: no)"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
         "emit a section containing stack size metadata (default: no)"),
     emit_thin_lto: bool = (true, parse_bool, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 693867c3853..70430d82ab5 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -37,8 +37,9 @@ use rustc_target::spec::{
 use crate::code_stats::CodeStats;
 pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use crate::config::{
-    self, CoverageLevel, CrateType, ErrorOutputType, FunctionReturn, Input, InstrumentCoverage,
-    OptLevel, OutFileName, OutputType, RemapPathScopeComponents, SwitchWithOptPath,
+    self, CoverageLevel, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, Input,
+    InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents,
+    SwitchWithOptPath,
 };
 use crate::parse::{add_feature_diagnostics, ParseSess};
 use crate::search_paths::{PathKind, SearchPath};
@@ -439,22 +440,10 @@ impl Session {
     }
 
     pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
-        filesearch::FileSearch::new(
-            &self.sysroot,
-            self.opts.target_triple.triple(),
-            &self.opts.search_paths,
-            &self.target_tlib_path,
-            kind,
-        )
+        filesearch::FileSearch::new(&self.opts.search_paths, &self.target_tlib_path, kind)
     }
     pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
-        filesearch::FileSearch::new(
-            &self.sysroot,
-            config::host_triple(),
-            &self.opts.search_paths,
-            &self.host_tlib_path,
-            kind,
-        )
+        filesearch::FileSearch::new(&self.opts.search_paths, &self.host_tlib_path, kind)
     }
 
     /// Returns a list of directories where target-specific tool binaries are located. Some fallback
@@ -1306,6 +1295,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
             .emit_err(errors::SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
     }
 
+    if sess.opts.unstable_opts.embed_source {
+        let dwarf_version =
+            sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version);
+
+        if dwarf_version < 5 {
+            sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version });
+        }
+
+        if sess.opts.debuginfo == DebugInfo::None {
+            sess.dcx().emit_warn(errors::EmbedSourceRequiresDebugInfo);
+        }
+    }
+
     if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
         sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 332fe22d869..9afd732486c 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -851,7 +851,6 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
             | ty::InstanceKind::FnPtrAddrShim(..)
             | ty::InstanceKind::ClosureOnceShim { .. }
             | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceKind::CoroutineKindShim { .. }
             | ty::InstanceKind::ThreadLocalShim(..)
             | ty::InstanceKind::DropGlue(..)
             | ty::InstanceKind::CloneShim(..)
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 41e9698242b..9b27b94fb5a 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -114,7 +114,9 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind {
         | DefKind::GlobalAsm => {
             unreachable!("Not a valid item kind: {kind:?}");
         }
-        DefKind::Closure | DefKind::AssocFn | DefKind::Fn => ItemKind::Fn,
+        DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
+            ItemKind::Fn
+        }
         DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
             ItemKind::Const
         }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 0f91684a3a4..59ccd6dff85 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -92,9 +92,6 @@ pub(super) fn mangle<'tcx>(
                 .write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" })
                 .unwrap();
         }
-        ty::InstanceKind::CoroutineKindShim { .. } => {
-            printer.write_str("{{by-move-body-shim}}").unwrap();
-        }
         _ => {}
     }
 
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 3a606f244e3..75f4499352b 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -56,7 +56,6 @@ pub(super) fn mangle<'tcx>(
         ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => {
             Some("by_ref")
         }
-        ty::InstanceKind::CoroutineKindShim { .. } => Some("by_move_body"),
 
         _ => None,
     };
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index c1ddfcb2f90..082c169b210 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -745,10 +745,25 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
 
     /// Checks if these two `ArgAbi` are equal enough to be considered "the same for all
     /// function call ABIs".
-    pub fn eq_abi(&self, other: &Self) -> bool {
+    pub fn eq_abi(&self, other: &Self) -> bool
+    where
+        Ty: PartialEq,
+    {
         // Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look
         // at the type.
-        self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode)
+        self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode) && {
+            // `fn_arg_sanity_check` accepts `PassMode::Direct` for some aggregates.
+            // That elevates any type difference to an ABI difference since we just use the
+            // full Rust type as the LLVM argument/return type.
+            if matches!(self.mode, PassMode::Direct(..))
+                && matches!(self.layout.abi, Abi::Aggregate { .. })
+            {
+                // For aggregates in `Direct` mode to be compatible, the types need to be equal.
+                self.layout.ty == other.layout.ty
+            } else {
+                true
+            }
+        }
     }
 }
 
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index 358efb4174d..daf5162e8ac 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -59,11 +59,11 @@ impl AArch64InlineAsmRegClass {
         _arch: InlineAsmArch,
     ) -> &'static [(InlineAsmType, Option<Symbol>)] {
         match self {
-            Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
+            Self::reg => types! { _: I8, I16, I32, I64, F16, F32, F64; },
             Self::vreg | Self::vreg_low16 => types! {
-                neon: I8, I16, I32, I64, F32, F64,
-                    VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
-                    VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
+                neon: I8, I16, I32, I64, F16, F32, F64, F128,
+                    VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1),
+                    VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2);
             },
             Self::preg => &[],
         }
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index 0d61345a70e..cc383f88fbc 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -53,6 +53,8 @@ pub enum Abi {
     },
     RustIntrinsic,
     RustCall,
+    /// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
+    /// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
     Unadjusted,
     /// For things unlikely to be called, where reducing register pressure in
     /// `extern "Rust"` callers is worth paying extra cost in the callee.
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 80f89a0ab2b..d5f227a84a4 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1750,6 +1750,9 @@ supported_targets! {
 
     ("x86_64-unikraft-linux-musl", x86_64_unikraft_linux_musl),
 
+    ("armv7-unknown-trusty", armv7_unknown_trusty),
+    ("aarch64-unknown-trusty", aarch64_unknown_trusty),
+
     ("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
     ("riscv32im-risc0-zkvm-elf", riscv32im_risc0_zkvm_elf),
     ("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs
new file mode 100644
index 00000000000..1525faf9b7e
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs
@@ -0,0 +1,34 @@
+// Trusty OS target for AArch64.
+
+use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "aarch64-unknown-unknown-musl".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("ARM64 Trusty".into()),
+            tier: Some(2),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 64,
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+reserve-x18".into(),
+            executables: true,
+            max_atomic_width: Some(128),
+            panic_strategy: PanicStrategy::Abort,
+            os: "trusty".into(),
+            position_independent_executables: true,
+            static_position_independent_executables: true,
+            crt_static_default: true,
+            crt_static_respected: true,
+            dynamic_linking: false,
+            link_self_contained: LinkSelfContainedDefault::InferredForMusl,
+            relro_level: RelroLevel::Full,
+            mcount: "\u{1}_mcount".into(),
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
new file mode 100644
index 00000000000..ae73de5e64d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs
@@ -0,0 +1,37 @@
+use crate::spec::{LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetOptions};
+
+pub 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
+        // support the "musleabi" value.
+        llvm_target: "armv7-unknown-unknown-gnueabi".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Armv7-A Trusty".into()),
+            tier: Some(2),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        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 {
+            abi: "eabi".into(),
+            features: "+v7,+thumb2,+soft-float,-neon".into(),
+            max_atomic_width: Some(64),
+            mcount: "\u{1}mcount".into(),
+            os: "trusty".into(),
+            link_self_contained: LinkSelfContainedDefault::InferredForMusl,
+            dynamic_linking: false,
+            executables: true,
+            crt_static_default: true,
+            crt_static_respected: true,
+            relro_level: RelroLevel::Full,
+            panic_strategy: PanicStrategy::Abort,
+            position_independent_executables: true,
+            static_position_independent_executables: true,
+
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 7e3c30f2383..16cd147b7d4 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -169,39 +169,6 @@ fn fn_sig_for_fn_abi<'tcx>(
                 kind: ty::BoundRegionKind::BrEnv,
             };
 
-            let mut ty = ty;
-            // When this `Closure` comes from a `CoroutineKindShim`,
-            // make sure we respect the `target_kind` in that shim.
-            // FIXME(async_closures): This shouldn't be needed, and we should be populating
-            // a separate def-id for these bodies.
-            if let InstanceKind::CoroutineKindShim { .. } = instance.def {
-                // Grab the parent coroutine-closure. It has the same args for the purposes
-                // of instantiation, so this will be okay to do.
-                let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx
-                    .instantiate_and_normalize_erasing_regions(
-                        args,
-                        param_env,
-                        tcx.type_of(tcx.parent(did)),
-                    )
-                    .kind()
-                else {
-                    bug!("CoroutineKindShim comes from calling a coroutine-closure");
-                };
-                let coroutine_closure_args = coroutine_closure_args.as_coroutine_closure();
-                ty = tcx.instantiate_bound_regions_with_erased(
-                    coroutine_closure_args.coroutine_closure_sig().map_bound(|sig| {
-                        sig.to_coroutine_given_kind_and_upvars(
-                            tcx,
-                            coroutine_closure_args.parent_args(),
-                            did,
-                            ty::ClosureKind::FnOnce,
-                            tcx.lifetimes.re_erased,
-                            coroutine_closure_args.tupled_upvars_ty(),
-                            coroutine_closure_args.coroutine_captures_by_ref_ty(),
-                        )
-                    }),
-                );
-            }
             let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty);
 
             let pin_did = tcx.require_lang_item(LangItem::Pin, None);
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 8812260b3af..70321a071a2 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -144,7 +144,8 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
         | DefKind::Field
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::Closure => ty::List::empty(),
+        | DefKind::Closure
+        | DefKind::SyntheticCoroutineBody => ty::List::empty(),
     }
 }
 
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index c7ed6e6110f..d77c3a277bf 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -363,6 +363,11 @@ fn resolve_associated_item<'tcx>(
                         tcx.item_name(trait_item_id)
                     ),
                 }
+            } else if tcx.is_lang_item(trait_ref.def_id, LangItem::TransmuteTrait) {
+                let name = tcx.item_name(trait_item_id);
+                assert_eq!(name, sym::transmute);
+                let args = tcx.erase_regions(rcvr_args);
+                Some(ty::Instance::new(trait_item_id, args))
             } else {
                 Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args)
             }
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 6680b451b7c..e899284674c 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -348,7 +348,8 @@ fn opaque_types_defined_by<'tcx>(
         | DefKind::Field
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
-        | DefKind::Impl { .. } => {}
+        | DefKind::Impl { .. }
+        | DefKind::SyntheticCoroutineBody => {}
         // Closures and coroutines are type checked with their parent, so we need to allow all
         // opaques from the closure signature *and* from the parent body.
         DefKind::Closure | DefKind::InlineConst => {
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 568b9383ffb..6f1cbb0fee7 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -87,7 +87,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // These are not part of a public API, they can only appear as hidden types, and there
         // the interesting parts are solely in the signature of the containing item's opaque type
         // or dyn type.
-        DefKind::InlineConst | DefKind::Closure => {}
+        DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {}
         DefKind::Impl { of_trait } => {
             if of_trait {
                 let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 6cc91849e1d..cac00b37d1f 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -1,9 +1,6 @@
 #![doc = include_str!("error.md")]
 #![stable(feature = "error_in_core", since = "1.81.0")]
 
-#[cfg(test)]
-mod tests;
-
 use crate::any::TypeId;
 use crate::fmt::{Debug, Display, Formatter, Result};
 
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 221724d7b4a..59828198099 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -232,7 +232,7 @@ extern "rust-intrinsic" {
     ///
     /// `T` must be a vector.
     ///
-    /// `U` must be a **const** array of `i32`s. This means it must either refer to a named
+    /// `U` must be a **const** array or vector of `u32`s. This means it must either refer to a named
     /// const or be given as an inline const expression (`const { ... }`).
     ///
     /// `V` must be a vector with the same element type as `T` and the same length as `U`.
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index ea73c5b80ba..62d454a5289 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -1,10 +1,88 @@
 use crate::marker::{ConstParamTy_, UnsizedConstParamTy};
 
-/// Are values of a type transmutable into values of another type?
+/// Marks that `Src` is transmutable into `Self`.
 ///
-/// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of
-/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
-/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
+/// # Implementation
+///
+/// This trait cannot be implemented explicitly. It is implemented on-the-fly by
+/// the compiler for all types `Src` and `Self` such that, given a set of safety
+/// obligations on the programmer (see [`Assume`]), the compiler has proved that
+/// the bits of a value of type `Src` can be soundly reinterpreted as a `Self`.
+///
+/// # Safety
+///
+/// If `Dst: BikeshedIntrinsicFrom<Src, ASSUMPTIONS>`, the compiler guarantees
+/// that `Src` is soundly *union-transmutable* into a value of type `Dst`,
+/// provided that the programmer has guaranteed that the given
+/// [`ASSUMPTIONS`](Assume) are satisfied.
+///
+/// A union-transmute is any bit-reinterpretation conversion in the form of:
+///
+/// ```rust
+/// pub unsafe fn transmute_via_union<Src, Dst>(src: Src) -> Dst {
+///     use core::mem::ManuallyDrop;
+///
+///     #[repr(C)]
+///     union Transmute<Src, Dst> {
+///         src: ManuallyDrop<Src>,
+///         dst: ManuallyDrop<Dst>,
+///     }
+///
+///     let transmute = Transmute {
+///         src: ManuallyDrop::new(src),
+///     };
+///
+///     let dst = transmute.dst;
+///
+///     ManuallyDrop::into_inner(dst)
+/// }
+/// ```
+///
+/// Note that this construction is more permissive than
+/// [`mem::transmute_copy`](super::transmute_copy); union-transmutes permit
+/// conversions that extend the bits of `Src` with trailing padding to fill
+/// trailing uninitialized bytes of `Self`; e.g.:
+///
+#[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+#[cfg_attr(not(bootstrap), doc = "```rust")]
+/// #![feature(transmutability)]
+///
+/// use core::mem::{Assume, BikeshedIntrinsicFrom};
+///
+/// let src = 42u8; // size = 1
+///
+/// #[repr(C, align(2))]
+/// struct Dst(u8); // size = 2
+//
+/// let _ = unsafe {
+///     <Dst as BikeshedIntrinsicFrom<u8, { Assume::SAFETY }>>::transmute(src)
+/// };
+/// ```
+///
+/// # Caveats
+///
+/// ## Portability
+///
+/// Implementations of this trait do not provide any guarantee of portability
+/// across toolchains, targets or compilations. This trait may be implemented
+/// for certain combinations of `Src`, `Self` and `ASSUME` on some toolchains,
+/// targets or compilations, but not others. For example, if the layouts of
+/// `Src` or `Self` are non-deterministic, the presence or absence of an
+/// implementation of this trait may also be non-deterministic. Even if `Src`
+/// and `Self` have deterministic layouts (e.g., they are `repr(C)` structs),
+/// Rust does not specify the alignments of its primitive integer types, and
+/// layouts that involve these types may vary across toolchains, targets or
+/// compilations.
+///
+/// ## Stability
+///
+/// Implementations of this trait do not provide any guarantee of SemVer
+/// stability across the crate versions that define the `Src` and `Self` types.
+/// If SemVer stability is crucial to your application, you must consult the
+/// documentation of `Src` and `Self`s' defining crates. Note that the presence
+/// of `repr(C)`, alone, does not carry a safety invariant of SemVer stability.
+/// Furthermore, stability does not imply portability. For example, the size of
+/// `usize` is stable, but not portable.
 #[unstable(feature = "transmutability", issue = "99571")]
 #[lang = "transmute_trait"]
 #[rustc_deny_explicit_impl(implement_via_object = false)]
@@ -13,28 +91,207 @@ pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOT
 where
     Src: ?Sized,
 {
+    /// Transmutes a `Src` value into a `Self`.
+    ///
+    /// # Safety
+    ///
+    /// The safety obligations of the caller depend on the value of `ASSUME`:
+    /// - If [`ASSUME.alignment`](Assume::alignment), the caller must guarantee
+    ///   that the addresses of references in the returned `Self` satisfy the
+    ///   alignment requirements of their referent types.
+    /// - If [`ASSUME.lifetimes`](Assume::lifetimes), the caller must guarantee
+    ///   that references in the returned `Self` will not outlive their
+    ///   referents.
+    /// - If [`ASSUME.safety`](Assume::safety), the returned value might not
+    ///   satisfy the library safety invariants of `Self`, and the caller must
+    ///   guarantee that undefined behavior does not arise from uses of the
+    ///   returned value.
+    /// - If [`ASSUME.validity`](Assume::validity), the caller must guarantee
+    ///   that `src` is a bit-valid instance of `Self`.
+    ///
+    /// When satisfying the above obligations (if any), the caller must *not*
+    /// assume that this trait provides any inherent guarantee of layout
+    /// [portability](#portability) or [stability](#stability).
+    unsafe fn transmute(src: Src) -> Self
+    where
+        Src: Sized,
+        Self: Sized,
+    {
+        use super::ManuallyDrop;
+
+        #[repr(C)]
+        union Transmute<Src, Dst> {
+            src: ManuallyDrop<Src>,
+            dst: ManuallyDrop<Dst>,
+        }
+
+        let transmute = Transmute { src: ManuallyDrop::new(src) };
+
+        // SAFETY: It is safe to reinterpret the bits of `src` as a value of
+        // type `Self`, because, by combination of invariant on this trait and
+        // contract on the caller, `src` has been proven to satisfy both the
+        // language and library invariants of `Self`. For all invariants not
+        // `ASSUME`'d by the caller, the safety obligation is supplied by the
+        // compiler. Conversely, for all invariants `ASSUME`'d by the caller,
+        // the safety obligation is supplied by contract on the caller.
+        let dst = unsafe { transmute.dst };
+
+        ManuallyDrop::into_inner(dst)
+    }
 }
 
-/// What transmutation safety conditions shall the compiler assume that *you* are checking?
+/// Configurable proof assumptions of [`BikeshedIntrinsicFrom`].
+///
+/// When `false`, the respective proof obligation belongs to the compiler. When
+/// `true`, the onus of the safety proof belongs to the programmer.
+/// [`BikeshedIntrinsicFrom`].
 #[unstable(feature = "transmutability", issue = "99571")]
 #[lang = "transmute_opts"]
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct Assume {
-    /// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that
-    /// destination referents do not have stricter alignment requirements than source referents.
+    /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for
+    /// transmutations that might violate the 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")]
+    /// #![feature(transmutability)]
+    /// use core::mem::{align_of, BikeshedIntrinsicFrom};
+    ///
+    /// assert_eq!(align_of::<[u8; 2]>(), 1);
+    /// assert_eq!(align_of::<u16>(), 2);
+    ///
+    /// let src: &[u8; 2] = &[0xFF, 0xFF];
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let dst: &u16 = unsafe {
+    ///     <_ as BikeshedIntrinsicFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured
+    /// that references in the transmuted value satisfy the alignment
+    /// requirements of their referent types; e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```rust")]
+    /// #![feature(pointer_is_aligned_to, transmutability)]
+    /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom};
+    ///
+    /// let src: &[u8; 2] = &[0xFF, 0xFF];
+    ///
+    /// let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::<u16>()) {
+    ///     // SAFETY: We have checked above that the address of `src` satisfies the
+    ///     // alignment requirements of `u16`.
+    ///     Some(unsafe {
+    ///         <_ as BikeshedIntrinsicFrom<_, { Assume::ALIGNMENT }>>::transmute(src)
+    ///     })
+    /// } else {
+    ///     None
+    /// };
+    ///
+    /// assert!(matches!(maybe_dst, Some(&u16::MAX) | None));
+    /// ```
     pub alignment: bool,
 
-    /// When `true`, the compiler assume that *you* are ensuring that lifetimes are not extended in a manner
-    /// that violates Rust's memory model.
+    /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for
+    /// transmutations that extend the lifetimes of references.
+    ///
+    /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured
+    /// that references in the transmuted value do not outlive their referents.
     pub lifetimes: bool,
 
-    /// When `true`, the compiler assumes that *you* have ensured that no
-    /// unsoundness will arise from violating the safety invariants of the
-    /// destination type (and sometimes of the source type, too).
+    /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for
+    /// transmutations that might violate the library safety invariants of the
+    /// destination type; e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")]
+    /// #![feature(transmutability)]
+    /// use core::mem::BikeshedIntrinsicFrom;
+    ///
+    /// let src: u8 = 3;
+    ///
+    /// struct EvenU8 {
+    ///     // SAFETY: `val` must be an even number.
+    ///     val: u8,
+    /// }
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let dst: EvenU8 = unsafe {
+    ///     <_ as BikeshedIntrinsicFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured
+    /// that undefined behavior does not arise from using the transmuted value;
+    /// e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```rust")]
+    /// #![feature(transmutability)]
+    /// use core::mem::{Assume, BikeshedIntrinsicFrom};
+    ///
+    /// let src: u8 = 42;
+    ///
+    /// struct EvenU8 {
+    ///     // SAFETY: `val` must be an even number.
+    ///     val: u8,
+    /// }
+    ///
+    /// let maybe_dst: Option<EvenU8> = if src % 2 == 0 {
+    ///     // SAFETY: We have checked above that the value of `src` is even.
+    ///     Some(unsafe {
+    ///         <_ as BikeshedIntrinsicFrom<_, { Assume::SAFETY }>>::transmute(src)
+    ///     })
+    /// } else {
+    ///     None
+    /// };
+    ///
+    /// assert!(matches!(maybe_dst, Some(EvenU8 { val: 42 })));
+    /// ```
     pub safety: bool,
 
-    /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid
-    /// instance of the destination type.
+    /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for
+    /// transmutations that might violate the language-level bit-validity
+    /// invariant of the destination type; e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")]
+    /// #![feature(transmutability)]
+    /// use core::mem::BikeshedIntrinsicFrom;
+    ///
+    /// let src: u8 = 3;
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let dst: bool = unsafe {
+    ///     <_ as BikeshedIntrinsicFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured
+    /// that the value being transmuted is a bit-valid instance of the
+    /// transmuted value; e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```rust")]
+    /// #![feature(transmutability)]
+    /// use core::mem::{Assume, BikeshedIntrinsicFrom};
+    ///
+    /// let src: u8 = 1;
+    ///
+    /// let maybe_dst: Option<bool> = if src == 0 || src == 1 {
+    ///     // SAFETY: We have checked above that the value of `src` is a bit-valid
+    ///     // instance of `bool`.
+    ///     Some(unsafe {
+    ///         <_ as BikeshedIntrinsicFrom<_, { Assume::VALIDITY }>>::transmute(src)
+    ///     })
+    /// } else {
+    ///     None
+    /// };
+    ///
+    /// assert_eq!(maybe_dst, Some(true));
+    /// ```
     pub validity: bool,
 }
 
@@ -44,29 +301,87 @@ impl ConstParamTy_ for Assume {}
 impl UnsizedConstParamTy for Assume {}
 
 impl Assume {
-    /// Do not assume that *you* have ensured any safety properties are met.
+    /// With this, [`BikeshedIntrinsicFrom`] does not assume you have ensured
+    /// any safety obligations are met, and relies only upon its own analysis to
+    /// (dis)prove transmutability.
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const NOTHING: Self =
         Self { alignment: false, lifetimes: false, safety: false, validity: false };
 
-    /// Assume only that alignment conditions are met.
+    /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured
+    /// that references in the transmuted value satisfy the alignment
+    /// requirements of their referent types. See [`Assume::alignment`] for
+    /// examples.
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING };
 
-    /// Assume only that lifetime conditions are met.
+    /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured
+    /// that references in the transmuted value do not outlive their referents.
+    /// See [`Assume::lifetimes`] for examples.
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING };
 
-    /// Assume only that safety conditions are met.
+    /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured
+    /// that undefined behavior does not arise from using the transmuted value.
+    /// See [`Assume::safety`] for examples.
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING };
 
-    /// Assume only that dynamically-satisfiable validity conditions are met.
+    /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured
+    /// that the value being transmuted is a bit-valid instance of the
+    /// transmuted value. See [`Assume::validity`] for examples.
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING };
 
-    /// Assume both `self` and `other_assumptions`.
+    /// Combine the assumptions of `self` and `other_assumptions`.
+    ///
+    /// This is especially useful for extending [`Assume`] in generic contexts;
+    /// e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```rust")]
     #[unstable(feature = "transmutability", issue = "99571")]
+    /// #![feature(
+    ///     adt_const_params,
+    ///     generic_const_exprs,
+    ///     pointer_is_aligned_to,
+    ///     transmutability,
+    /// )]
+    /// #![allow(incomplete_features)]
+    /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom};
+    ///
+    /// /// Attempts to transmute `src` to `&Dst`.
+    /// ///
+    /// /// Returns `None` if `src` violates the alignment requirements of `&Dst`.
+    /// ///
+    /// /// # Safety
+    /// ///
+    /// /// The caller guarantees that the obligations required by `ASSUME`, except
+    /// /// alignment, are satisfied.
+    /// unsafe fn try_transmute_ref<'a, Src, Dst, const ASSUME: Assume>(src: &'a Src) -> Option<&'a Dst>
+    /// where
+    ///     &'a Dst: BikeshedIntrinsicFrom<&'a Src, { ASSUME.and(Assume::ALIGNMENT) }>,
+    /// {
+    ///     if <*const _>::is_aligned_to(src, align_of::<Dst>()) {
+    ///         // SAFETY: By the above dynamic check, we have ensured that the address
+    ///         // of `src` satisfies the alignment requirements of `&Dst`. By contract
+    ///         // on the caller, the safety obligations required by `ASSUME` have also
+    ///         // been satisfied.
+    ///         Some(unsafe {
+    ///             <_ as BikeshedIntrinsicFrom<_, { ASSUME.and(Assume::ALIGNMENT) }>>::transmute(src)
+    ///         })
+    ///     } else {
+    ///         None
+    ///     }
+    /// }
+    ///
+    /// let src: &[u8; 2] = &[0xFF, 0xFF];
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let maybe_dst: Option<&u16> = unsafe {
+    ///     try_transmute_ref::<_, _, { Assume::NOTHING }>(src)
+    /// };
+    ///```
     pub const fn and(self, other_assumptions: Self) -> Self {
         Self {
             alignment: self.alignment || other_assumptions.alignment,
@@ -76,7 +391,21 @@ impl Assume {
         }
     }
 
-    /// Assume `self`, excepting `other_assumptions`.
+    /// Remove `other_assumptions` the obligations of `self`; e.g.:
+    ///
+    #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")]
+    #[cfg_attr(not(bootstrap), doc = "```rust")]
+    /// #![feature(transmutability)]
+    /// use core::mem::Assume;
+    ///
+    /// let assumptions = Assume::ALIGNMENT.and(Assume::SAFETY);
+    /// let to_be_removed = Assume::SAFETY.and(Assume::VALIDITY);
+    ///
+    /// assert_eq!(
+    ///     assumptions.but_not(to_be_removed),
+    ///     Assume::ALIGNMENT,
+    /// );
+    /// ```
     #[unstable(feature = "transmutability", issue = "99571")]
     pub const fn but_not(self, other_assumptions: Self) -> Self {
         Self {
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 38e69e7641a..d4236e47bfe 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -454,11 +454,14 @@ impl f128 {
     }
 
     /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
-    /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
-    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
-    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
-    /// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
-    /// See [explanation of NaN as a special value](f128) for more info.
+    /// positive sign bit and positive infinity.
+    ///
+    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
+    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
+    /// conserved over arithmetic operations, the result of `is_sign_positive` on
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// #![feature(f128)]
@@ -477,11 +480,14 @@ impl f128 {
     }
 
     /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
-    /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
-    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
-    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
-    /// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
-    /// See [explanation of NaN as a special value](f128) for more info.
+    /// negative sign bit and negative infinity.
+    ///
+    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
+    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
+    /// conserved over arithmetic operations, the result of `is_sign_negative` on
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// #![feature(f128)]
@@ -750,7 +756,7 @@ impl f128 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f128) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
@@ -791,7 +797,7 @@ impl f128 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f128) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index bb0cc1c60ba..1e2f841aca7 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -464,11 +464,14 @@ impl f16 {
     }
 
     /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
-    /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
-    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
-    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
-    /// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
-    /// See [explanation of NaN as a special value](f16) for more info.
+    /// positive sign bit and positive infinity.
+    ///
+    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
+    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
+    /// conserved over arithmetic operations, the result of `is_sign_positive` on
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// #![feature(f16)]
@@ -490,11 +493,14 @@ impl f16 {
     }
 
     /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
-    /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
-    /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
-    /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
-    /// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
-    /// See [explanation of NaN as a special value](f16) for more info.
+    /// negative sign bit and negative infinity.
+    ///
+    /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
+    /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
+    /// conserved over arithmetic operations, the result of `is_sign_negative` on
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// #![feature(f16)]
@@ -762,7 +768,7 @@ impl f16 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f16) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
@@ -802,7 +808,7 @@ impl f16 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f16) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
     // #[unstable(feature = "float_minimum_maximum", issue = "91079")]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 719727e2f1e..c1adcc753f2 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -700,8 +700,9 @@ impl f32 {
     /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
     /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
     /// conserved over arithmetic operations, the result of `is_sign_positive` on
-    /// a NaN might produce an unexpected result in some cases. See [explanation
-    /// of NaN as a special value](f32) for more info.
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// let f = 7.0_f32;
@@ -724,8 +725,9 @@ impl f32 {
     /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
     /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
     /// conserved over arithmetic operations, the result of `is_sign_negative` on
-    /// a NaN might produce an unexpected result in some cases. See [explanation
-    /// of NaN as a special value](f32) for more info.
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// let f = 7.0f32;
@@ -954,7 +956,7 @@ impl f32 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
@@ -989,7 +991,7 @@ impl f32 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 85eb152ad1f..e6406771ad3 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -695,8 +695,9 @@ impl f64 {
     /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
     /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
     /// conserved over arithmetic operations, the result of `is_sign_positive` on
-    /// a NaN might produce an unexpected result in some cases. See [explanation
-    /// of NaN as a special value](f32) for more info.
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == 1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// let f = 7.0_f64;
@@ -728,8 +729,9 @@ impl f64 {
     /// Note that IEEE 754 doesn't assign any meaning to the sign bit in case of
     /// a NaN, and as Rust doesn't guarantee that the bit pattern of NaNs are
     /// conserved over arithmetic operations, the result of `is_sign_negative` on
-    /// a NaN might produce an unexpected result in some cases. See [explanation
-    /// of NaN as a special value](f32) for more info.
+    /// a NaN might produce an unexpected or non-portable result. See the [specification
+    /// of NaN bit patterns](f32#nan-bit-patterns) for more info. Use `self.signum() == -1.0`
+    /// if you need fully portable behavior (will return `false` for all NaNs).
     ///
     /// ```
     /// let f = 7.0_f64;
@@ -968,7 +970,7 @@ impl f64 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
@@ -1003,7 +1005,7 @@ impl f64 {
     /// Note that this follows the semantics specified in IEEE 754-2019.
     ///
     /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
-    /// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
+    /// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[unstable(feature = "float_minimum_maximum", issue = "91079")]
     #[inline]
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 17cf2a7b261..229cd89bea3 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1312,6 +1312,34 @@ macro_rules! int_impl {
             }
         }
 
+        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        ///
+        /// If `rhs` is larger or equal to the number of bits in `self`,
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(unbounded_shifts)]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
+            if rhs < Self::BITS {
+                // SAFETY:
+                // rhs is just checked to be in-range above
+                unsafe { self.unchecked_shl(rhs) }
+            } else {
+                0
+            }
+        }
+
         /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
         /// larger than or equal to the number of bits in `self`.
         ///
@@ -1410,6 +1438,40 @@ macro_rules! int_impl {
             }
         }
 
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        ///
+        /// If `rhs` is larger or equal to the number of bits in `self`,
+        /// the entire value is shifted out, which yields `0` for a positive number,
+        /// and `-1` for a negative number.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(unbounded_shifts)]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
+            if rhs < Self::BITS {
+                // SAFETY:
+                // rhs is just checked to be in-range above
+                unsafe { self.unchecked_shr(rhs) }
+            } else {
+                // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
+
+                // SAFETY:
+                // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
+                unsafe { self.unchecked_shr(Self::BITS - 1) }
+            }
+        }
+
         /// Checked absolute value. Computes `self.abs()`, returning `None` if
         /// `self == MIN`.
         ///
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 719a6a55940..0d0bbc5256f 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1501,6 +1501,34 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        ///
+        /// If `rhs` is larger or equal to the number of bits in `self`,
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(unbounded_shifts)]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
+            if rhs < Self::BITS {
+                // SAFETY:
+                // rhs is just checked to be in-range above
+                unsafe { self.unchecked_shl(rhs) }
+            } else {
+                0
+            }
+        }
+
         /// Checked shift right. Computes `self >> rhs`, returning `None`
         /// if `rhs` is larger than or equal to the number of bits in `self`.
         ///
@@ -1599,6 +1627,34 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        ///
+        /// If `rhs` is larger or equal to the number of bits in `self`,
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(unbounded_shifts)]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
+            if rhs < Self::BITS {
+                // SAFETY:
+                // rhs is just checked to be in-range above
+                unsafe { self.unchecked_shr(rhs) }
+            } else {
+                0
+            }
+        }
+
         /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
         /// overflow occurred.
         ///
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 09ebef89fb0..fe6ed7e0cf3 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1130,8 +1130,8 @@ impl<T> (T,) {}
 /// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008).
 ///
 /// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many
-/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on
-/// half-precision values][wikipedia] for more information.
+/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on half-precision
+/// values][wikipedia] for more information.
 ///
 /// Note that most common platforms will not support `f16` in hardware without enabling extra target
 /// features, with the notable exception of Apple Silicon (also known as M1, M2, etc.) processors.
@@ -1190,6 +1190,11 @@ mod prim_f16 {}
 ///     portable or even fully deterministic! This means that there may be some
 ///     surprising results upon inspecting the bit patterns,
 ///     as the same calculations might produce NaNs with different bit patterns.
+///     This also affects the sign of the NaN: checking `is_sign_positive` or `is_sign_negative` on
+///     a NaN is the most common way to run into these surprising results.
+///     (Checking `x >= 0.0` or `x <= 0.0` avoids those surprises, but also how negative/positive
+///     zero are treated.)
+///     See the section below for what exactly is guaranteed about the bit pattern of a NaN.
 ///
 /// When a primitive operation (addition, subtraction, multiplication, or
 /// division) is performed on this type, the result is rounded according to the
@@ -1211,6 +1216,79 @@ mod prim_f16 {}
 /// *[See also the `std::f32::consts` module](crate::f32::consts).*
 ///
 /// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
+///
+/// # NaN bit patterns
+///
+/// This section defines the possible NaN bit patterns returned by non-"bitwise" floating point
+/// operations. The bitwise operations are unary `-`, `abs`, `copysign`; those are guaranteed to
+/// exactly preserve the bit pattern of their input except for possibly changing the sign bit.
+///
+/// A floating-point NaN value consists of:
+/// - a sign bit
+/// - a quiet/signaling bit
+/// - a payload, which makes up the rest of the significand (i.e., the mantissa) except for the
+///   quiet/signaling bit.
+///
+/// Rust assumes that the quiet/signaling bit being set to `1` indicates a quiet NaN (QNaN), and a
+/// value of `0` indicates a signaling NaN (SNaN). In the following we will hence just call it the
+/// "quiet bit".
+///
+/// The following rules apply when a NaN value is returned: the result has a non-deterministic sign.
+/// The quiet bit and payload are non-deterministically chosen from the following set of options:
+///
+/// - **Preferred NaN**: The quiet bit is set and the payload is all-zero.
+/// - **Quieting NaN propagation**: The quiet bit is set and the payload is copied from any input
+///   operand that is a NaN. If the inputs and outputs do not have the same payload size (i.e., for
+///   `as` casts), then
+///   - If the output is smaller than the input, low-order bits of the payload get dropped.
+///   - If the output is larger than the input, the payload gets filled up with 0s in the low-order
+///     bits.
+/// - **Unchanged NaN propagation**: The quiet bit and payload are copied from any input operand
+///   that is a NaN. If the inputs and outputs do not have the same size (i.e., for `as` casts), the
+///   same rules as for "quieting NaN propagation" apply, with one caveat: if the output is smaller
+///   than the input, droppig the low-order bits may result in a payload of 0; a payload of 0 is not
+///   possible with a signaling NaN (the all-0 significand encodes an infinity) so unchanged NaN
+///   propagation cannot occur with some inputs.
+/// - **Target-specific NaN**: The quiet bit is set and the payload is picked from a target-specific
+///   set of "extra" possible NaN payloads. The set can depend on the input operand values.
+///   See the table below for the concrete NaNs this set contains on various targets.
+///
+/// In particular, if all input NaNs are quiet (or if there are no input NaNs), then the output NaN
+/// is definitely quiet. Signaling NaN outputs can only occur if they are provided as an input
+/// value. Similarly, if all input NaNs are preferred (or if there are no input NaNs) and the target
+/// does not have any "extra" NaN payloads, then the output NaN is guaranteed to be preferred.
+///
+/// The non-deterministic choice happens when the operation is executed; i.e., the result of a
+/// NaN-producing floating point operation is a stable bit pattern (looking at these bits multiple
+/// times will yield consistent results), but running the same operation twice with the same inputs
+/// can produce different results.
+///
+/// These guarantees are neither stronger nor weaker than those of IEEE 754: IEEE 754 guarantees
+/// that an operation never returns a signaling NaN, whereas it is possible for operations like
+/// `SNAN * 1.0` to return a signaling NaN in Rust. Conversely, IEEE 754 makes no statement at all
+/// about which quiet NaN is returned, whereas Rust restricts the set of possible results to the
+/// ones listed above.
+///
+/// Unless noted otherwise, the same rules also apply to NaNs returned by other library functions
+/// (e.g. `min`, `minimum`, `max`, `maximum`); other aspects of their semantics and which IEEE 754
+/// operation they correspond to are documented with the respective functions.
+///
+/// When a floating-point operation is executed in `const` context, the same rules apply: no
+/// guarantee is made about which of the NaN bit patterns described above will be returned. The
+/// result does not have to match what happens when executing the same code at runtime, and the
+/// result can vary depending on factors such as compiler version and flags.
+///
+/// ### Target-specific "extra" NaN values
+// FIXME: Is there a better place to put this?
+///
+/// | `target_arch` | Extra payloads possible on this platform |
+/// |---------------|---------|
+/// | `x86`, `x86_64`, `arm`, `aarch64`, `riscv32`, `riscv64` | None |
+/// | `sparc`, `sparc64` | The all-one payload |
+/// | `wasm32`, `wasm64` | If all input NaNs are quiet with all-zero payload: None.<br> Otherwise: all possible payloads. |
+///
+/// For targets not in this table, all payloads are possible.
+
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_f32 {}
 
@@ -1218,14 +1296,12 @@ mod prim_f32 {}
 #[doc(alias = "double")]
 /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
 ///
-/// This type is very similar to [`f32`], but has increased
-/// precision by using twice as many bits. Please see [the documentation for
-/// `f32`][`f32`] or [Wikipedia on double precision
+/// This type is very similar to [`prim@f32`], but has increased precision by using twice as many
+/// bits. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on double-precision
 /// values][wikipedia] for more information.
 ///
 /// *[See also the `std::f64::consts` module](crate::f64::consts).*
 ///
-/// [`f32`]: prim@f32
 /// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_f64 {}
@@ -1235,12 +1311,12 @@ mod prim_f64 {}
 /// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008).
 ///
 /// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice
-/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on
+/// as many bits as `f64`. Please see [the documentation for `f32`](prim@f32) or [Wikipedia on
 /// quad-precision values][wikipedia] for more information.
 ///
 /// Note that no platforms have hardware support for `f128` without enabling target specific features,
 /// as for all instruction set architectures `f128` is considered an optional feature.
-/// Only Power ISA ("PowerPC") and RISCV specify it, and only certain microarchitectures
+/// Only Power ISA ("PowerPC") and RISC-V specify it, and only certain microarchitectures
 /// actually implement it. For x86-64 and AArch64, ISA support is not even specified,
 /// so it will always be a software implementation significantly slower than `f64`.
 ///
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 93bbd92593f..3b635e2a4aa 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -239,24 +239,7 @@ impl<T: ?Sized> *const T {
     /// # Safety
     ///
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -302,24 +285,8 @@ impl<T: ?Sized> *const T {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -350,20 +317,7 @@ impl<T: ?Sized> *const T {
     /// # Safety
     ///
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 65e473d99b3..d7ed4edcc00 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -56,6 +56,44 @@
 //! has size 0, i.e., even if memory is not actually touched. Consider using
 //! [`NonNull::dangling`] in such cases.
 //!
+//! ## Pointer to reference conversion
+//!
+//! When converting a pointer to a reference (e.g. via `&*ptr` or `&mut *ptr`),
+//! there are several rules that must be followed:
+//!
+//! * The pointer must be properly aligned.
+//!
+//! * It must be non-null.
+//!
+//! * It must be "dereferenceable" in the sense defined above.
+//!
+//! * The pointer must point to a [valid value] of type `T`.
+//!
+//! * You must enforce Rust's aliasing rules. The exact aliasing rules are not decided yet, so we
+//!   only give a rough overview here. The rules also depend on whether a mutable or a shared
+//!   reference is being created.
+//!   * When creating a mutable reference, then while this reference exists, the memory it points to
+//!     must not get accessed (read or written) through any other pointer or reference not derived
+//!     from this reference.
+//!   * When creating a shared reference, then while this reference exists, the memory it points to
+//!     must not get mutated (except inside `UnsafeCell`).
+//!
+//! If a pointer follows all of these rules, it is said to be
+//! *convertible to a (mutable or shared) reference*.
+// ^ we use this term instead of saying that the produced reference must
+// be valid, as the validity of a reference is easily confused for the
+// validity of the thing it refers to, and while the two concepts are
+// closly related, they are not identical.
+//!
+//! These rules apply even if the result is unused!
+//! (The part about being initialized is not yet fully decided, but until
+//! it is, the only safe approach is to ensure that they are indeed initialized.)
+//!
+//! An example of the implications of the above rules is that an expression such
+//! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior.
+//!
+//! [valid value]: ../../reference/behavior-considered-undefined.html#invalid-values
+//!
 //! ## Allocated object
 //!
 //! An *allocated object* is a subset of program memory which is addressable
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index bcf9b889182..42975cc927b 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -247,24 +247,7 @@ impl<T: ?Sized> *mut T {
     /// # Safety
     ///
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -313,24 +296,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// When calling this method, you have to ensure that the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -364,20 +330,9 @@ impl<T: ?Sized> *mut T {
     /// # Safety
     ///
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+    /// Note that because the created reference is to `MaybeUninit<T>`, the
+    /// source pointer can point to uninitialized memory.
     ///
     /// # Examples
     ///
@@ -609,25 +564,10 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
+    /// When calling this method, you have to ensure that *either*
+    /// the pointer is null *or*
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get accessed (read or written) through any other pointer.
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
     ///
     /// # Examples
     ///
@@ -675,24 +615,8 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -727,20 +651,7 @@ impl<T: ?Sized> *mut T {
     /// # Safety
     ///
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get accessed (read or written) through any other pointer.
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index d6be37a76bb..b1429fff744 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -126,20 +126,10 @@ impl<T: Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+    /// Note that because the created reference is to `MaybeUninit<T>`, the
+    /// source pointer can point to uninitialized memory.
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
@@ -160,20 +150,10 @@ impl<T: Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get accessed (read or written) through any other pointer.
-    ///
-    /// This applies even if the result of this method is unused!
-    ///
-    /// [the module documentation]: crate::ptr#safety
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+    /// Note that because the created reference is to `MaybeUninit<T>`, the
+    /// source pointer can point to uninitialized memory.
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
@@ -359,22 +339,8 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get mutated (except inside `UnsafeCell`).
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     ///
     /// # Examples
     ///
@@ -410,22 +376,8 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// When calling this method, you have to ensure that all of the following is true:
-    ///
-    /// * The pointer must be properly aligned.
-    ///
-    /// * It must be "dereferenceable" in the sense defined in [the module documentation].
-    ///
-    /// * The pointer must point to an initialized instance of `T`.
-    ///
-    /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
-    ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
-    ///   In particular, while this reference exists, the memory the pointer points to must
-    ///   not get accessed (read or written) through any other pointer.
-    ///
-    /// This applies even if the result of this method is unused!
-    /// (The part about being initialized is not yet fully decided, but until
-    /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    /// When calling this method, you have to ensure that
+    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     /// # Examples
     ///
     /// ```
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index bfa1cf096e2..6aab22177ab 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -5,6 +5,8 @@ use crate::ops::{self, ControlFlow};
 
 /// Indicates whether a value is available or if the current task has been
 /// scheduled to receive a wakeup instead.
+///
+/// This is returned by [`Future::poll`](core::future::Future::poll).
 #[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
 #[lang = "Poll"]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 073429c7628..c205f028dd3 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -141,7 +141,6 @@ mod intrinsics;
 mod io;
 mod iter;
 mod lazy;
-#[cfg(test)]
 mod macros;
 mod manually_drop;
 mod mem;
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 165d9a29617..7cd3b54e3f3 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -1,427 +1,424 @@
 macro_rules! int_module {
     ($T:ident) => {
-        #[cfg(test)]
-        mod tests {
-            use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
-            use core::$T::*;
-
-            use crate::num;
-
-            #[test]
-            fn test_overflows() {
-                assert!(MAX > 0);
-                assert!(MIN <= 0);
-                assert_eq!(MIN + MAX + 1, 0);
-            }
+        use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+        use core::$T::*;
 
-            #[test]
-            fn test_num() {
-                num::test_num(10 as $T, 2 as $T);
-            }
+        use crate::num;
 
-            #[test]
-            fn test_rem_euclid() {
-                assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
-            }
+        #[test]
+        fn test_overflows() {
+            assert!(MAX > 0);
+            assert!(MIN <= 0);
+            assert_eq!(MIN + MAX + 1, 0);
+        }
 
-            #[test]
-            pub fn test_abs() {
-                assert_eq!((1 as $T).abs(), 1 as $T);
-                assert_eq!((0 as $T).abs(), 0 as $T);
-                assert_eq!((-1 as $T).abs(), 1 as $T);
-            }
+        #[test]
+        fn test_num() {
+            num::test_num(10 as $T, 2 as $T);
+        }
 
-            #[test]
-            fn test_signum() {
-                assert_eq!((1 as $T).signum(), 1 as $T);
-                assert_eq!((0 as $T).signum(), 0 as $T);
-                assert_eq!((-0 as $T).signum(), 0 as $T);
-                assert_eq!((-1 as $T).signum(), -1 as $T);
-            }
+        #[test]
+        fn test_rem_euclid() {
+            assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
+        }
 
-            #[test]
-            fn test_is_positive() {
-                assert!((1 as $T).is_positive());
-                assert!(!(0 as $T).is_positive());
-                assert!(!(-0 as $T).is_positive());
-                assert!(!(-1 as $T).is_positive());
-            }
+        #[test]
+        pub fn test_abs() {
+            assert_eq!((1 as $T).abs(), 1 as $T);
+            assert_eq!((0 as $T).abs(), 0 as $T);
+            assert_eq!((-1 as $T).abs(), 1 as $T);
+        }
 
-            #[test]
-            fn test_is_negative() {
-                assert!(!(1 as $T).is_negative());
-                assert!(!(0 as $T).is_negative());
-                assert!(!(-0 as $T).is_negative());
-                assert!((-1 as $T).is_negative());
-            }
+        #[test]
+        fn test_signum() {
+            assert_eq!((1 as $T).signum(), 1 as $T);
+            assert_eq!((0 as $T).signum(), 0 as $T);
+            assert_eq!((-0 as $T).signum(), 0 as $T);
+            assert_eq!((-1 as $T).signum(), -1 as $T);
+        }
 
-            #[test]
-            fn test_bitwise_operators() {
-                assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
-                assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
-                assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
-                assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
-                assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
-                assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
-            }
+        #[test]
+        fn test_is_positive() {
+            assert!((1 as $T).is_positive());
+            assert!(!(0 as $T).is_positive());
+            assert!(!(-0 as $T).is_positive());
+            assert!(!(-1 as $T).is_positive());
+        }
 
-            const A: $T = 0b0101100;
-            const B: $T = 0b0100001;
-            const C: $T = 0b1111001;
+        #[test]
+        fn test_is_negative() {
+            assert!(!(1 as $T).is_negative());
+            assert!(!(0 as $T).is_negative());
+            assert!(!(-0 as $T).is_negative());
+            assert!((-1 as $T).is_negative());
+        }
 
-            const _0: $T = 0;
-            const _1: $T = !0;
+        #[test]
+        fn test_bitwise_operators() {
+            assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
+            assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
+            assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
+            assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
+            assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
+            assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
+        }
 
-            #[test]
-            fn test_count_ones() {
-                assert_eq!(A.count_ones(), 3);
-                assert_eq!(B.count_ones(), 2);
-                assert_eq!(C.count_ones(), 5);
-            }
+        const A: $T = 0b0101100;
+        const B: $T = 0b0100001;
+        const C: $T = 0b1111001;
 
-            #[test]
-            fn test_count_zeros() {
-                assert_eq!(A.count_zeros(), $T::BITS - 3);
-                assert_eq!(B.count_zeros(), $T::BITS - 2);
-                assert_eq!(C.count_zeros(), $T::BITS - 5);
-            }
+        const _0: $T = 0;
+        const _1: $T = !0;
 
-            #[test]
-            fn test_leading_trailing_ones() {
-                let a: $T = 0b0101_1111;
-                assert_eq!(a.trailing_ones(), 5);
-                assert_eq!((!a).leading_ones(), $T::BITS - 7);
+        #[test]
+        fn test_count_ones() {
+            assert_eq!(A.count_ones(), 3);
+            assert_eq!(B.count_ones(), 2);
+            assert_eq!(C.count_ones(), 5);
+        }
 
-                assert_eq!(a.reverse_bits().leading_ones(), 5);
+        #[test]
+        fn test_count_zeros() {
+            assert_eq!(A.count_zeros(), $T::BITS - 3);
+            assert_eq!(B.count_zeros(), $T::BITS - 2);
+            assert_eq!(C.count_zeros(), $T::BITS - 5);
+        }
 
-                assert_eq!(_1.leading_ones(), $T::BITS);
-                assert_eq!(_1.trailing_ones(), $T::BITS);
+        #[test]
+        fn test_leading_trailing_ones() {
+            let a: $T = 0b0101_1111;
+            assert_eq!(a.trailing_ones(), 5);
+            assert_eq!((!a).leading_ones(), $T::BITS - 7);
 
-                assert_eq!((_1 << 1).trailing_ones(), 0);
-                assert_eq!(MAX.leading_ones(), 0);
+            assert_eq!(a.reverse_bits().leading_ones(), 5);
 
-                assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1);
-                assert_eq!(MAX.trailing_ones(), $T::BITS - 1);
+            assert_eq!(_1.leading_ones(), $T::BITS);
+            assert_eq!(_1.trailing_ones(), $T::BITS);
 
-                assert_eq!(_0.leading_ones(), 0);
-                assert_eq!(_0.trailing_ones(), 0);
+            assert_eq!((_1 << 1).trailing_ones(), 0);
+            assert_eq!(MAX.leading_ones(), 0);
 
-                let x: $T = 0b0010_1100;
-                assert_eq!(x.leading_ones(), 0);
-                assert_eq!(x.trailing_ones(), 0);
-            }
+            assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1);
+            assert_eq!(MAX.trailing_ones(), $T::BITS - 1);
 
-            #[test]
-            fn test_rotate() {
-                assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-                assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-                assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
-
-                // Rotating these should make no difference
-                //
-                // We test using 124 bits because to ensure that overlong bit shifts do
-                // not cause undefined behaviour. See #10183.
-                assert_eq!(_0.rotate_left(124), _0);
-                assert_eq!(_1.rotate_left(124), _1);
-                assert_eq!(_0.rotate_right(124), _0);
-                assert_eq!(_1.rotate_right(124), _1);
-
-                // Rotating by 0 should have no effect
-                assert_eq!(A.rotate_left(0), A);
-                assert_eq!(B.rotate_left(0), B);
-                assert_eq!(C.rotate_left(0), C);
-                // Rotating by a multiple of word size should also have no effect
-                assert_eq!(A.rotate_left(128), A);
-                assert_eq!(B.rotate_left(128), B);
-                assert_eq!(C.rotate_left(128), C);
-            }
+            assert_eq!(_0.leading_ones(), 0);
+            assert_eq!(_0.trailing_ones(), 0);
 
-            #[test]
-            fn test_swap_bytes() {
-                assert_eq!(A.swap_bytes().swap_bytes(), A);
-                assert_eq!(B.swap_bytes().swap_bytes(), B);
-                assert_eq!(C.swap_bytes().swap_bytes(), C);
+            let x: $T = 0b0010_1100;
+            assert_eq!(x.leading_ones(), 0);
+            assert_eq!(x.trailing_ones(), 0);
+        }
 
-                // Swapping these should make no difference
-                assert_eq!(_0.swap_bytes(), _0);
-                assert_eq!(_1.swap_bytes(), _1);
-            }
+        #[test]
+        fn test_rotate() {
+            assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+            assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+            assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+            // Rotating these should make no difference
+            //
+            // We test using 124 bits because to ensure that overlong bit shifts do
+            // not cause undefined behaviour. See #10183.
+            assert_eq!(_0.rotate_left(124), _0);
+            assert_eq!(_1.rotate_left(124), _1);
+            assert_eq!(_0.rotate_right(124), _0);
+            assert_eq!(_1.rotate_right(124), _1);
+
+            // Rotating by 0 should have no effect
+            assert_eq!(A.rotate_left(0), A);
+            assert_eq!(B.rotate_left(0), B);
+            assert_eq!(C.rotate_left(0), C);
+            // Rotating by a multiple of word size should also have no effect
+            assert_eq!(A.rotate_left(128), A);
+            assert_eq!(B.rotate_left(128), B);
+            assert_eq!(C.rotate_left(128), C);
+        }
 
-            #[test]
-            fn test_le() {
-                assert_eq!($T::from_le(A.to_le()), A);
-                assert_eq!($T::from_le(B.to_le()), B);
-                assert_eq!($T::from_le(C.to_le()), C);
-                assert_eq!($T::from_le(_0), _0);
-                assert_eq!($T::from_le(_1), _1);
-                assert_eq!(_0.to_le(), _0);
-                assert_eq!(_1.to_le(), _1);
-            }
+        #[test]
+        fn test_swap_bytes() {
+            assert_eq!(A.swap_bytes().swap_bytes(), A);
+            assert_eq!(B.swap_bytes().swap_bytes(), B);
+            assert_eq!(C.swap_bytes().swap_bytes(), C);
 
-            #[test]
-            fn test_be() {
-                assert_eq!($T::from_be(A.to_be()), A);
-                assert_eq!($T::from_be(B.to_be()), B);
-                assert_eq!($T::from_be(C.to_be()), C);
-                assert_eq!($T::from_be(_0), _0);
-                assert_eq!($T::from_be(_1), _1);
-                assert_eq!(_0.to_be(), _0);
-                assert_eq!(_1.to_be(), _1);
-            }
+            // Swapping these should make no difference
+            assert_eq!(_0.swap_bytes(), _0);
+            assert_eq!(_1.swap_bytes(), _1);
+        }
 
-            #[test]
-            fn test_signed_checked_div() {
-                assert_eq!((10 as $T).checked_div(2), Some(5));
-                assert_eq!((5 as $T).checked_div(0), None);
-                assert_eq!(isize::MIN.checked_div(-1), None);
-            }
+        #[test]
+        fn test_le() {
+            assert_eq!($T::from_le(A.to_le()), A);
+            assert_eq!($T::from_le(B.to_le()), B);
+            assert_eq!($T::from_le(C.to_le()), C);
+            assert_eq!($T::from_le(_0), _0);
+            assert_eq!($T::from_le(_1), _1);
+            assert_eq!(_0.to_le(), _0);
+            assert_eq!(_1.to_le(), _1);
+        }
 
-            #[test]
-            fn test_saturating_abs() {
-                assert_eq!((0 as $T).saturating_abs(), 0);
-                assert_eq!((123 as $T).saturating_abs(), 123);
-                assert_eq!((-123 as $T).saturating_abs(), 123);
-                assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
-                assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
-                assert_eq!(MAX.saturating_abs(), MAX);
-                assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
-                assert_eq!((MIN + 1).saturating_abs(), MAX);
-                assert_eq!(MIN.saturating_abs(), MAX);
-            }
+        #[test]
+        fn test_be() {
+            assert_eq!($T::from_be(A.to_be()), A);
+            assert_eq!($T::from_be(B.to_be()), B);
+            assert_eq!($T::from_be(C.to_be()), C);
+            assert_eq!($T::from_be(_0), _0);
+            assert_eq!($T::from_be(_1), _1);
+            assert_eq!(_0.to_be(), _0);
+            assert_eq!(_1.to_be(), _1);
+        }
 
-            #[test]
-            fn test_saturating_neg() {
-                assert_eq!((0 as $T).saturating_neg(), 0);
-                assert_eq!((123 as $T).saturating_neg(), -123);
-                assert_eq!((-123 as $T).saturating_neg(), 123);
-                assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
-                assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
-                assert_eq!(MAX.saturating_neg(), MIN + 1);
-                assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
-                assert_eq!((MIN + 1).saturating_neg(), MAX);
-                assert_eq!(MIN.saturating_neg(), MAX);
-            }
+        #[test]
+        fn test_signed_checked_div() {
+            assert_eq!((10 as $T).checked_div(2), Some(5));
+            assert_eq!((5 as $T).checked_div(0), None);
+            assert_eq!(isize::MIN.checked_div(-1), None);
+        }
 
-            #[test]
-            fn test_from_str() {
-                fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
-                    std::str::FromStr::from_str(t).ok()
-                }
-                assert_eq!(from_str::<$T>("0"), Some(0 as $T));
-                assert_eq!(from_str::<$T>("3"), Some(3 as $T));
-                assert_eq!(from_str::<$T>("10"), Some(10 as $T));
-                assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
-                assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
-                assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
-                assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
-                assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
-                assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
-                assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
-
-                assert_eq!(from_str::<$T>(""), None);
-                assert_eq!(from_str::<$T>(" "), None);
-                assert_eq!(from_str::<$T>("x"), None);
-            }
+        #[test]
+        fn test_saturating_abs() {
+            assert_eq!((0 as $T).saturating_abs(), 0);
+            assert_eq!((123 as $T).saturating_abs(), 123);
+            assert_eq!((-123 as $T).saturating_abs(), 123);
+            assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
+            assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
+            assert_eq!(MAX.saturating_abs(), MAX);
+            assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
+            assert_eq!((MIN + 1).saturating_abs(), MAX);
+            assert_eq!(MIN.saturating_abs(), MAX);
+        }
 
-            #[test]
-            fn test_from_str_radix() {
-                assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
-                assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
-                assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
-                assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
-                assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
-                assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
-                assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
-                assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
-
-                assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
-                assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
-                assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
-                assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
-                assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
-                assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
-                assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
-                assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
-
-                assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
-                assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
-            }
+        #[test]
+        fn test_saturating_neg() {
+            assert_eq!((0 as $T).saturating_neg(), 0);
+            assert_eq!((123 as $T).saturating_neg(), -123);
+            assert_eq!((-123 as $T).saturating_neg(), 123);
+            assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
+            assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
+            assert_eq!(MAX.saturating_neg(), MIN + 1);
+            assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
+            assert_eq!((MIN + 1).saturating_neg(), MAX);
+            assert_eq!(MIN.saturating_neg(), MAX);
+        }
 
-            #[test]
-            fn test_pow() {
-                let mut r = 2 as $T;
-                assert_eq!(r.pow(2), 4 as $T);
-                assert_eq!(r.pow(0), 1 as $T);
-                assert_eq!(r.wrapping_pow(2), 4 as $T);
-                assert_eq!(r.wrapping_pow(0), 1 as $T);
-                assert_eq!(r.checked_pow(2), Some(4 as $T));
-                assert_eq!(r.checked_pow(0), Some(1 as $T));
-                assert_eq!(r.overflowing_pow(2), (4 as $T, false));
-                assert_eq!(r.overflowing_pow(0), (1 as $T, false));
-                assert_eq!(r.saturating_pow(2), 4 as $T);
-                assert_eq!(r.saturating_pow(0), 1 as $T);
-
-                r = MAX;
-                // use `^` to represent .pow() with no overflow.
-                // if itest::MAX == 2^j-1, then itest is a `j` bit int,
-                // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
-                // thussaturating_pow the overflowing result is exactly 1.
-                assert_eq!(r.wrapping_pow(2), 1 as $T);
-                assert_eq!(r.checked_pow(2), None);
-                assert_eq!(r.overflowing_pow(2), (1 as $T, true));
-                assert_eq!(r.saturating_pow(2), MAX);
-                //test for negative exponent.
-                r = -2 as $T;
-                assert_eq!(r.pow(2), 4 as $T);
-                assert_eq!(r.pow(3), -8 as $T);
-                assert_eq!(r.pow(0), 1 as $T);
-                assert_eq!(r.wrapping_pow(2), 4 as $T);
-                assert_eq!(r.wrapping_pow(3), -8 as $T);
-                assert_eq!(r.wrapping_pow(0), 1 as $T);
-                assert_eq!(r.checked_pow(2), Some(4 as $T));
-                assert_eq!(r.checked_pow(3), Some(-8 as $T));
-                assert_eq!(r.checked_pow(0), Some(1 as $T));
-                assert_eq!(r.overflowing_pow(2), (4 as $T, false));
-                assert_eq!(r.overflowing_pow(3), (-8 as $T, false));
-                assert_eq!(r.overflowing_pow(0), (1 as $T, false));
-                assert_eq!(r.saturating_pow(2), 4 as $T);
-                assert_eq!(r.saturating_pow(3), -8 as $T);
-                assert_eq!(r.saturating_pow(0), 1 as $T);
+        #[test]
+        fn test_from_str() {
+            fn from_str<T: std::str::FromStr>(t: &str) -> Option<T> {
+                std::str::FromStr::from_str(t).ok()
             }
+            assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+            assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+            assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+            assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
+            assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+            assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
+            assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
+            assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
+            assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
+            assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
+
+            assert_eq!(from_str::<$T>(""), None);
+            assert_eq!(from_str::<$T>(" "), None);
+            assert_eq!(from_str::<$T>("x"), None);
+        }
 
-            #[test]
-            fn test_isqrt() {
-                assert_eq!($T::MIN.checked_isqrt(), None);
-                assert_eq!((-1 as $T).checked_isqrt(), None);
-                assert_eq!((0 as $T).isqrt(), 0 as $T);
-                assert_eq!((1 as $T).isqrt(), 1 as $T);
-                assert_eq!((2 as $T).isqrt(), 1 as $T);
-                assert_eq!((99 as $T).isqrt(), 9 as $T);
-                assert_eq!((100 as $T).isqrt(), 10 as $T);
-            }
+        #[test]
+        fn test_from_str_radix() {
+            assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+            assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+            assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+            assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
+            assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
+            assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
+            assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+            assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
+
+            assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
+            assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
+            assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
+            assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
+            assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+            assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+            assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
+            assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
+
+            assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
+            assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
+        }
 
-            #[cfg(not(miri))] // Miri is too slow
-            #[test]
-            fn test_lots_of_isqrt() {
-                let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
-                for n in 0..=n_max {
-                    let isqrt: $T = n.isqrt();
-
-                    assert!(isqrt.pow(2) <= n);
-                    let (square, overflow) = (isqrt + 1).overflowing_pow(2);
-                    assert!(overflow || square > n);
-                }
-
-                for n in ($T::MAX - 127)..=$T::MAX {
-                    let isqrt: $T = n.isqrt();
-
-                    assert!(isqrt.pow(2) <= n);
-                    let (square, overflow) = (isqrt + 1).overflowing_pow(2);
-                    assert!(overflow || square > n);
-                }
-            }
+        #[test]
+        fn test_pow() {
+            let mut r = 2 as $T;
+            assert_eq!(r.pow(2), 4 as $T);
+            assert_eq!(r.pow(0), 1 as $T);
+            assert_eq!(r.wrapping_pow(2), 4 as $T);
+            assert_eq!(r.wrapping_pow(0), 1 as $T);
+            assert_eq!(r.checked_pow(2), Some(4 as $T));
+            assert_eq!(r.checked_pow(0), Some(1 as $T));
+            assert_eq!(r.overflowing_pow(2), (4 as $T, false));
+            assert_eq!(r.overflowing_pow(0), (1 as $T, false));
+            assert_eq!(r.saturating_pow(2), 4 as $T);
+            assert_eq!(r.saturating_pow(0), 1 as $T);
+
+            r = MAX;
+            // use `^` to represent .pow() with no overflow.
+            // if itest::MAX == 2^j-1, then itest is a `j` bit int,
+            // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
+            // thussaturating_pow the overflowing result is exactly 1.
+            assert_eq!(r.wrapping_pow(2), 1 as $T);
+            assert_eq!(r.checked_pow(2), None);
+            assert_eq!(r.overflowing_pow(2), (1 as $T, true));
+            assert_eq!(r.saturating_pow(2), MAX);
+            //test for negative exponent.
+            r = -2 as $T;
+            assert_eq!(r.pow(2), 4 as $T);
+            assert_eq!(r.pow(3), -8 as $T);
+            assert_eq!(r.pow(0), 1 as $T);
+            assert_eq!(r.wrapping_pow(2), 4 as $T);
+            assert_eq!(r.wrapping_pow(3), -8 as $T);
+            assert_eq!(r.wrapping_pow(0), 1 as $T);
+            assert_eq!(r.checked_pow(2), Some(4 as $T));
+            assert_eq!(r.checked_pow(3), Some(-8 as $T));
+            assert_eq!(r.checked_pow(0), Some(1 as $T));
+            assert_eq!(r.overflowing_pow(2), (4 as $T, false));
+            assert_eq!(r.overflowing_pow(3), (-8 as $T, false));
+            assert_eq!(r.overflowing_pow(0), (1 as $T, false));
+            assert_eq!(r.saturating_pow(2), 4 as $T);
+            assert_eq!(r.saturating_pow(3), -8 as $T);
+            assert_eq!(r.saturating_pow(0), 1 as $T);
+        }
 
-            #[test]
-            fn test_div_floor() {
-                let a: $T = 8;
-                let b = 3;
-                assert_eq!(a.div_floor(b), 2);
-                assert_eq!(a.div_floor(-b), -3);
-                assert_eq!((-a).div_floor(b), -3);
-                assert_eq!((-a).div_floor(-b), 2);
-            }
+        #[test]
+        fn test_isqrt() {
+            assert_eq!($T::MIN.checked_isqrt(), None);
+            assert_eq!((-1 as $T).checked_isqrt(), None);
+            assert_eq!((0 as $T).isqrt(), 0 as $T);
+            assert_eq!((1 as $T).isqrt(), 1 as $T);
+            assert_eq!((2 as $T).isqrt(), 1 as $T);
+            assert_eq!((99 as $T).isqrt(), 9 as $T);
+            assert_eq!((100 as $T).isqrt(), 10 as $T);
+        }
 
-            #[test]
-            fn test_div_ceil() {
-                let a: $T = 8;
-                let b = 3;
-                assert_eq!(a.div_ceil(b), 3);
-                assert_eq!(a.div_ceil(-b), -2);
-                assert_eq!((-a).div_ceil(b), -2);
-                assert_eq!((-a).div_ceil(-b), 3);
-            }
+        #[cfg(not(miri))] // Miri is too slow
+        #[test]
+        fn test_lots_of_isqrt() {
+            let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
+            for n in 0..=n_max {
+                let isqrt: $T = n.isqrt();
 
-            #[test]
-            fn test_next_multiple_of() {
-                assert_eq!((16 as $T).next_multiple_of(8), 16);
-                assert_eq!((23 as $T).next_multiple_of(8), 24);
-                assert_eq!((16 as $T).next_multiple_of(-8), 16);
-                assert_eq!((23 as $T).next_multiple_of(-8), 16);
-                assert_eq!((-16 as $T).next_multiple_of(8), -16);
-                assert_eq!((-23 as $T).next_multiple_of(8), -16);
-                assert_eq!((-16 as $T).next_multiple_of(-8), -16);
-                assert_eq!((-23 as $T).next_multiple_of(-8), -24);
-                assert_eq!(MIN.next_multiple_of(-1), MIN);
+                assert!(isqrt.pow(2) <= n);
+                let (square, overflow) = (isqrt + 1).overflowing_pow(2);
+                assert!(overflow || square > n);
             }
 
-            #[test]
-            fn test_checked_next_multiple_of() {
-                assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16));
-                assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24));
-                assert_eq!((16 as $T).checked_next_multiple_of(-8), Some(16));
-                assert_eq!((23 as $T).checked_next_multiple_of(-8), Some(16));
-                assert_eq!((-16 as $T).checked_next_multiple_of(8), Some(-16));
-                assert_eq!((-23 as $T).checked_next_multiple_of(8), Some(-16));
-                assert_eq!((-16 as $T).checked_next_multiple_of(-8), Some(-16));
-                assert_eq!((-23 as $T).checked_next_multiple_of(-8), Some(-24));
-                assert_eq!((1 as $T).checked_next_multiple_of(0), None);
-                assert_eq!(MAX.checked_next_multiple_of(2), None);
-                assert_eq!(MIN.checked_next_multiple_of(-3), None);
-                assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN));
-            }
+            for n in ($T::MAX - 127)..=$T::MAX {
+                let isqrt: $T = n.isqrt();
 
-            #[test]
-            fn test_carrying_add() {
-                assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true));
-                assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true));
-                assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true));
-                assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false));
-                assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow
-                assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true));
-                assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow
-                assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true));
-                assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false));
+                assert!(isqrt.pow(2) <= n);
+                let (square, overflow) = (isqrt + 1).overflowing_pow(2);
+                assert!(overflow || square > n);
             }
+        }
 
-            #[test]
-            fn test_borrowing_sub() {
-                assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
-                assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
-                assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
-                assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false));
-                assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow
-                assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true));
-                assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow
-                assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true));
-                assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false));
-            }
+        #[test]
+        fn test_div_floor() {
+            let a: $T = 8;
+            let b = 3;
+            assert_eq!(a.div_floor(b), 2);
+            assert_eq!(a.div_floor(-b), -3);
+            assert_eq!((-a).div_floor(b), -3);
+            assert_eq!((-a).div_floor(-b), 2);
+        }
 
-            #[test]
-            fn test_midpoint() {
-                assert_eq!(<$T>::midpoint(1, 3), 2);
-                assert_eq!(<$T>::midpoint(3, 1), 2);
-
-                assert_eq!(<$T>::midpoint(0, 0), 0);
-                assert_eq!(<$T>::midpoint(0, 2), 1);
-                assert_eq!(<$T>::midpoint(2, 0), 1);
-                assert_eq!(<$T>::midpoint(2, 2), 2);
-
-                assert_eq!(<$T>::midpoint(1, 4), 2);
-                assert_eq!(<$T>::midpoint(4, 1), 2);
-                assert_eq!(<$T>::midpoint(3, 4), 3);
-                assert_eq!(<$T>::midpoint(4, 3), 3);
-
-                assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1);
-                assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
-
-                assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
-                assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
-                assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
-            }
+        #[test]
+        fn test_div_ceil() {
+            let a: $T = 8;
+            let b = 3;
+            assert_eq!(a.div_ceil(b), 3);
+            assert_eq!(a.div_ceil(-b), -2);
+            assert_eq!((-a).div_ceil(b), -2);
+            assert_eq!((-a).div_ceil(-b), 3);
+        }
+
+        #[test]
+        fn test_next_multiple_of() {
+            assert_eq!((16 as $T).next_multiple_of(8), 16);
+            assert_eq!((23 as $T).next_multiple_of(8), 24);
+            assert_eq!((16 as $T).next_multiple_of(-8), 16);
+            assert_eq!((23 as $T).next_multiple_of(-8), 16);
+            assert_eq!((-16 as $T).next_multiple_of(8), -16);
+            assert_eq!((-23 as $T).next_multiple_of(8), -16);
+            assert_eq!((-16 as $T).next_multiple_of(-8), -16);
+            assert_eq!((-23 as $T).next_multiple_of(-8), -24);
+            assert_eq!(MIN.next_multiple_of(-1), MIN);
+        }
+
+        #[test]
+        fn test_checked_next_multiple_of() {
+            assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16));
+            assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24));
+            assert_eq!((16 as $T).checked_next_multiple_of(-8), Some(16));
+            assert_eq!((23 as $T).checked_next_multiple_of(-8), Some(16));
+            assert_eq!((-16 as $T).checked_next_multiple_of(8), Some(-16));
+            assert_eq!((-23 as $T).checked_next_multiple_of(8), Some(-16));
+            assert_eq!((-16 as $T).checked_next_multiple_of(-8), Some(-16));
+            assert_eq!((-23 as $T).checked_next_multiple_of(-8), Some(-24));
+            assert_eq!((1 as $T).checked_next_multiple_of(0), None);
+            assert_eq!(MAX.checked_next_multiple_of(2), None);
+            assert_eq!(MIN.checked_next_multiple_of(-3), None);
+            assert_eq!(MIN.checked_next_multiple_of(-1), Some(MIN));
+        }
+
+        #[test]
+        fn test_carrying_add() {
+            assert_eq!($T::MAX.carrying_add(1, false), ($T::MIN, true));
+            assert_eq!($T::MAX.carrying_add(0, true), ($T::MIN, true));
+            assert_eq!($T::MAX.carrying_add(1, true), ($T::MIN + 1, true));
+            assert_eq!($T::MAX.carrying_add(-1, false), ($T::MAX - 1, false));
+            assert_eq!($T::MAX.carrying_add(-1, true), ($T::MAX, false)); // no intermediate overflow
+            assert_eq!($T::MIN.carrying_add(-1, false), ($T::MAX, true));
+            assert_eq!($T::MIN.carrying_add(-1, true), ($T::MIN, false)); // no intermediate overflow
+            assert_eq!((0 as $T).carrying_add($T::MAX, true), ($T::MIN, true));
+            assert_eq!((0 as $T).carrying_add($T::MIN, true), ($T::MIN + 1, false));
+        }
+
+        #[test]
+        fn test_borrowing_sub() {
+            assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
+            assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
+            assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+            assert_eq!($T::MIN.borrowing_sub(-1, false), ($T::MIN + 1, false));
+            assert_eq!($T::MIN.borrowing_sub(-1, true), ($T::MIN, false)); // no intermediate overflow
+            assert_eq!($T::MAX.borrowing_sub(-1, false), ($T::MIN, true));
+            assert_eq!($T::MAX.borrowing_sub(-1, true), ($T::MAX, false)); // no intermediate overflow
+            assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true));
+            assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false));
+        }
+
+        #[test]
+        fn test_midpoint() {
+            assert_eq!(<$T>::midpoint(1, 3), 2);
+            assert_eq!(<$T>::midpoint(3, 1), 2);
+
+            assert_eq!(<$T>::midpoint(0, 0), 0);
+            assert_eq!(<$T>::midpoint(0, 2), 1);
+            assert_eq!(<$T>::midpoint(2, 0), 1);
+            assert_eq!(<$T>::midpoint(2, 2), 2);
+
+            assert_eq!(<$T>::midpoint(1, 4), 2);
+            assert_eq!(<$T>::midpoint(4, 1), 2);
+            assert_eq!(<$T>::midpoint(3, 4), 3);
+            assert_eq!(<$T>::midpoint(4, 3), 3);
+
+            assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1);
+            assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+
+            assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+            assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3);
+            assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3);
         }
     };
 }
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index 53ff5ab1ced..dad46ad88fe 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -178,7 +178,7 @@ fn test_can_not_overflow() {
 
     // Check u128 separately:
     for base in 2..=36 {
-        let num = u128::MAX as u128;
+        let num = <u128>::MAX;
         let max_len_string = format_radix(num, base as u128);
         // base 16 fits perfectly for u128 and won't overflow:
         assert_eq!(can_overflow::<u128>(base, &max_len_string), base != 16);
diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
index d009ad89d5c..f4fa789461e 100644
--- a/library/core/tests/num/uint_macros.rs
+++ b/library/core/tests/num/uint_macros.rs
@@ -1,320 +1,317 @@
 macro_rules! uint_module {
     ($T:ident) => {
-        #[cfg(test)]
-        mod tests {
-            use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
-            use core::$T::*;
-            use std::str::FromStr;
-
-            use crate::num;
-
-            #[test]
-            fn test_overflows() {
-                assert!(MAX > 0);
-                assert!(MIN <= 0);
-                assert!((MIN + MAX).wrapping_add(1) == 0);
-            }
+        use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+        use core::$T::*;
+        use std::str::FromStr;
 
-            #[test]
-            fn test_num() {
-                num::test_num(10 as $T, 2 as $T);
-            }
+        use crate::num;
 
-            #[test]
-            fn test_bitwise_operators() {
-                assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
-                assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
-                assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
-                assert!(0b1110 as $T == (0b0111 as $T).shl(1));
-                assert!(0b0111 as $T == (0b1110 as $T).shr(1));
-                assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
-            }
+        #[test]
+        fn test_overflows() {
+            assert!(MAX > 0);
+            assert!(MIN <= 0);
+            assert!((MIN + MAX).wrapping_add(1) == 0);
+        }
 
-            const A: $T = 0b0101100;
-            const B: $T = 0b0100001;
-            const C: $T = 0b1111001;
+        #[test]
+        fn test_num() {
+            num::test_num(10 as $T, 2 as $T);
+        }
 
-            const _0: $T = 0;
-            const _1: $T = !0;
+        #[test]
+        fn test_bitwise_operators() {
+            assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+            assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+            assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+            assert!(0b1110 as $T == (0b0111 as $T).shl(1));
+            assert!(0b0111 as $T == (0b1110 as $T).shr(1));
+            assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
+        }
 
-            #[test]
-            fn test_count_ones() {
-                assert!(A.count_ones() == 3);
-                assert!(B.count_ones() == 2);
-                assert!(C.count_ones() == 5);
-            }
+        const A: $T = 0b0101100;
+        const B: $T = 0b0100001;
+        const C: $T = 0b1111001;
 
-            #[test]
-            fn test_count_zeros() {
-                assert!(A.count_zeros() == $T::BITS - 3);
-                assert!(B.count_zeros() == $T::BITS - 2);
-                assert!(C.count_zeros() == $T::BITS - 5);
-            }
+        const _0: $T = 0;
+        const _1: $T = !0;
 
-            #[test]
-            fn test_leading_trailing_ones() {
-                let a: $T = 0b0101_1111;
-                assert_eq!(a.trailing_ones(), 5);
-                assert_eq!((!a).leading_ones(), $T::BITS - 7);
+        #[test]
+        fn test_count_ones() {
+            assert!(A.count_ones() == 3);
+            assert!(B.count_ones() == 2);
+            assert!(C.count_ones() == 5);
+        }
 
-                assert_eq!(a.reverse_bits().leading_ones(), 5);
+        #[test]
+        fn test_count_zeros() {
+            assert!(A.count_zeros() == $T::BITS - 3);
+            assert!(B.count_zeros() == $T::BITS - 2);
+            assert!(C.count_zeros() == $T::BITS - 5);
+        }
 
-                assert_eq!(_1.leading_ones(), $T::BITS);
-                assert_eq!(_1.trailing_ones(), $T::BITS);
+        #[test]
+        fn test_leading_trailing_ones() {
+            let a: $T = 0b0101_1111;
+            assert_eq!(a.trailing_ones(), 5);
+            assert_eq!((!a).leading_ones(), $T::BITS - 7);
 
-                assert_eq!((_1 << 1).trailing_ones(), 0);
-                assert_eq!((_1 >> 1).leading_ones(), 0);
+            assert_eq!(a.reverse_bits().leading_ones(), 5);
 
-                assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1);
-                assert_eq!((_1 >> 1).trailing_ones(), $T::BITS - 1);
+            assert_eq!(_1.leading_ones(), $T::BITS);
+            assert_eq!(_1.trailing_ones(), $T::BITS);
 
-                assert_eq!(_0.leading_ones(), 0);
-                assert_eq!(_0.trailing_ones(), 0);
+            assert_eq!((_1 << 1).trailing_ones(), 0);
+            assert_eq!((_1 >> 1).leading_ones(), 0);
 
-                let x: $T = 0b0010_1100;
-                assert_eq!(x.leading_ones(), 0);
-                assert_eq!(x.trailing_ones(), 0);
-            }
+            assert_eq!((_1 << 1).leading_ones(), $T::BITS - 1);
+            assert_eq!((_1 >> 1).trailing_ones(), $T::BITS - 1);
 
-            #[test]
-            fn test_rotate() {
-                assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-                assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-                assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
-
-                // Rotating these should make no difference
-                //
-                // We test using 124 bits because to ensure that overlong bit shifts do
-                // not cause undefined behaviour. See #10183.
-                assert_eq!(_0.rotate_left(124), _0);
-                assert_eq!(_1.rotate_left(124), _1);
-                assert_eq!(_0.rotate_right(124), _0);
-                assert_eq!(_1.rotate_right(124), _1);
-
-                // Rotating by 0 should have no effect
-                assert_eq!(A.rotate_left(0), A);
-                assert_eq!(B.rotate_left(0), B);
-                assert_eq!(C.rotate_left(0), C);
-                // Rotating by a multiple of word size should also have no effect
-                assert_eq!(A.rotate_left(128), A);
-                assert_eq!(B.rotate_left(128), B);
-                assert_eq!(C.rotate_left(128), C);
-            }
+            assert_eq!(_0.leading_ones(), 0);
+            assert_eq!(_0.trailing_ones(), 0);
 
-            #[test]
-            fn test_swap_bytes() {
-                assert_eq!(A.swap_bytes().swap_bytes(), A);
-                assert_eq!(B.swap_bytes().swap_bytes(), B);
-                assert_eq!(C.swap_bytes().swap_bytes(), C);
+            let x: $T = 0b0010_1100;
+            assert_eq!(x.leading_ones(), 0);
+            assert_eq!(x.trailing_ones(), 0);
+        }
 
-                // Swapping these should make no difference
-                assert_eq!(_0.swap_bytes(), _0);
-                assert_eq!(_1.swap_bytes(), _1);
-            }
+        #[test]
+        fn test_rotate() {
+            assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+            assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+            assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+            // Rotating these should make no difference
+            //
+            // We test using 124 bits because to ensure that overlong bit shifts do
+            // not cause undefined behaviour. See #10183.
+            assert_eq!(_0.rotate_left(124), _0);
+            assert_eq!(_1.rotate_left(124), _1);
+            assert_eq!(_0.rotate_right(124), _0);
+            assert_eq!(_1.rotate_right(124), _1);
+
+            // Rotating by 0 should have no effect
+            assert_eq!(A.rotate_left(0), A);
+            assert_eq!(B.rotate_left(0), B);
+            assert_eq!(C.rotate_left(0), C);
+            // Rotating by a multiple of word size should also have no effect
+            assert_eq!(A.rotate_left(128), A);
+            assert_eq!(B.rotate_left(128), B);
+            assert_eq!(C.rotate_left(128), C);
+        }
 
-            #[test]
-            fn test_reverse_bits() {
-                assert_eq!(A.reverse_bits().reverse_bits(), A);
-                assert_eq!(B.reverse_bits().reverse_bits(), B);
-                assert_eq!(C.reverse_bits().reverse_bits(), C);
+        #[test]
+        fn test_swap_bytes() {
+            assert_eq!(A.swap_bytes().swap_bytes(), A);
+            assert_eq!(B.swap_bytes().swap_bytes(), B);
+            assert_eq!(C.swap_bytes().swap_bytes(), C);
 
-                // Swapping these should make no difference
-                assert_eq!(_0.reverse_bits(), _0);
-                assert_eq!(_1.reverse_bits(), _1);
-            }
+            // Swapping these should make no difference
+            assert_eq!(_0.swap_bytes(), _0);
+            assert_eq!(_1.swap_bytes(), _1);
+        }
 
-            #[test]
-            fn test_le() {
-                assert_eq!($T::from_le(A.to_le()), A);
-                assert_eq!($T::from_le(B.to_le()), B);
-                assert_eq!($T::from_le(C.to_le()), C);
-                assert_eq!($T::from_le(_0), _0);
-                assert_eq!($T::from_le(_1), _1);
-                assert_eq!(_0.to_le(), _0);
-                assert_eq!(_1.to_le(), _1);
-            }
+        #[test]
+        fn test_reverse_bits() {
+            assert_eq!(A.reverse_bits().reverse_bits(), A);
+            assert_eq!(B.reverse_bits().reverse_bits(), B);
+            assert_eq!(C.reverse_bits().reverse_bits(), C);
 
-            #[test]
-            fn test_be() {
-                assert_eq!($T::from_be(A.to_be()), A);
-                assert_eq!($T::from_be(B.to_be()), B);
-                assert_eq!($T::from_be(C.to_be()), C);
-                assert_eq!($T::from_be(_0), _0);
-                assert_eq!($T::from_be(_1), _1);
-                assert_eq!(_0.to_be(), _0);
-                assert_eq!(_1.to_be(), _1);
-            }
+            // Swapping these should make no difference
+            assert_eq!(_0.reverse_bits(), _0);
+            assert_eq!(_1.reverse_bits(), _1);
+        }
 
-            #[test]
-            fn test_unsigned_checked_div() {
-                assert!((10 as $T).checked_div(2) == Some(5));
-                assert!((5 as $T).checked_div(0) == None);
-            }
+        #[test]
+        fn test_le() {
+            assert_eq!($T::from_le(A.to_le()), A);
+            assert_eq!($T::from_le(B.to_le()), B);
+            assert_eq!($T::from_le(C.to_le()), C);
+            assert_eq!($T::from_le(_0), _0);
+            assert_eq!($T::from_le(_1), _1);
+            assert_eq!(_0.to_le(), _0);
+            assert_eq!(_1.to_le(), _1);
+        }
 
-            fn from_str<T: FromStr>(t: &str) -> Option<T> {
-                FromStr::from_str(t).ok()
-            }
+        #[test]
+        fn test_be() {
+            assert_eq!($T::from_be(A.to_be()), A);
+            assert_eq!($T::from_be(B.to_be()), B);
+            assert_eq!($T::from_be(C.to_be()), C);
+            assert_eq!($T::from_be(_0), _0);
+            assert_eq!($T::from_be(_1), _1);
+            assert_eq!(_0.to_be(), _0);
+            assert_eq!(_1.to_be(), _1);
+        }
 
-            #[test]
-            pub fn test_from_str() {
-                assert_eq!(from_str::<$T>("0"), Some(0 as $T));
-                assert_eq!(from_str::<$T>("3"), Some(3 as $T));
-                assert_eq!(from_str::<$T>("10"), Some(10 as $T));
-                assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
-                assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
-                assert_eq!(from_str::<$T>(""), None);
-                assert_eq!(from_str::<$T>(" "), None);
-                assert_eq!(from_str::<$T>("x"), None);
-            }
+        #[test]
+        fn test_unsigned_checked_div() {
+            assert!((10 as $T).checked_div(2) == Some(5));
+            assert!((5 as $T).checked_div(0) == None);
+        }
 
-            #[test]
-            pub fn test_parse_bytes() {
-                assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
-                assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
-                assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
-                assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
-                assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
-                assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
-
-                assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
-                assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
-            }
+        fn from_str<T: FromStr>(t: &str) -> Option<T> {
+            FromStr::from_str(t).ok()
+        }
 
-            #[test]
-            fn test_pow() {
-                let mut r = 2 as $T;
-                assert_eq!(r.pow(2), 4 as $T);
-                assert_eq!(r.pow(0), 1 as $T);
-                assert_eq!(r.wrapping_pow(2), 4 as $T);
-                assert_eq!(r.wrapping_pow(0), 1 as $T);
-                assert_eq!(r.checked_pow(2), Some(4 as $T));
-                assert_eq!(r.checked_pow(0), Some(1 as $T));
-                assert_eq!(r.overflowing_pow(2), (4 as $T, false));
-                assert_eq!(r.overflowing_pow(0), (1 as $T, false));
-                assert_eq!(r.saturating_pow(2), 4 as $T);
-                assert_eq!(r.saturating_pow(0), 1 as $T);
-
-                r = MAX;
-                // use `^` to represent .pow() with no overflow.
-                // if itest::MAX == 2^j-1, then itest is a `j` bit int,
-                // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
-                // thussaturating_pow the overflowing result is exactly 1.
-                assert_eq!(r.wrapping_pow(2), 1 as $T);
-                assert_eq!(r.checked_pow(2), None);
-                assert_eq!(r.overflowing_pow(2), (1 as $T, true));
-                assert_eq!(r.saturating_pow(2), MAX);
-            }
+        #[test]
+        pub fn test_from_str() {
+            assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+            assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+            assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+            assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
+            assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+            assert_eq!(from_str::<$T>(""), None);
+            assert_eq!(from_str::<$T>(" "), None);
+            assert_eq!(from_str::<$T>("x"), None);
+        }
 
-            #[test]
-            fn test_isqrt() {
-                assert_eq!((0 as $T).isqrt(), 0 as $T);
-                assert_eq!((1 as $T).isqrt(), 1 as $T);
-                assert_eq!((2 as $T).isqrt(), 1 as $T);
-                assert_eq!((99 as $T).isqrt(), 9 as $T);
-                assert_eq!((100 as $T).isqrt(), 10 as $T);
-                assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
-            }
+        #[test]
+        pub fn test_parse_bytes() {
+            assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+            assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+            assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+            assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
+            assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
+            assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+
+            assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
+            assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
+        }
 
-            #[cfg(not(miri))] // Miri is too slow
-            #[test]
-            fn test_lots_of_isqrt() {
-                let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
-                for n in 0..=n_max {
-                    let isqrt: $T = n.isqrt();
+        #[test]
+        fn test_pow() {
+            let mut r = 2 as $T;
+            assert_eq!(r.pow(2), 4 as $T);
+            assert_eq!(r.pow(0), 1 as $T);
+            assert_eq!(r.wrapping_pow(2), 4 as $T);
+            assert_eq!(r.wrapping_pow(0), 1 as $T);
+            assert_eq!(r.checked_pow(2), Some(4 as $T));
+            assert_eq!(r.checked_pow(0), Some(1 as $T));
+            assert_eq!(r.overflowing_pow(2), (4 as $T, false));
+            assert_eq!(r.overflowing_pow(0), (1 as $T, false));
+            assert_eq!(r.saturating_pow(2), 4 as $T);
+            assert_eq!(r.saturating_pow(0), 1 as $T);
+
+            r = MAX;
+            // use `^` to represent .pow() with no overflow.
+            // if itest::MAX == 2^j-1, then itest is a `j` bit int,
+            // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
+            // thussaturating_pow the overflowing result is exactly 1.
+            assert_eq!(r.wrapping_pow(2), 1 as $T);
+            assert_eq!(r.checked_pow(2), None);
+            assert_eq!(r.overflowing_pow(2), (1 as $T, true));
+            assert_eq!(r.saturating_pow(2), MAX);
+        }
 
-                    assert!(isqrt.pow(2) <= n);
-                    assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
-                }
+        #[test]
+        fn test_isqrt() {
+            assert_eq!((0 as $T).isqrt(), 0 as $T);
+            assert_eq!((1 as $T).isqrt(), 1 as $T);
+            assert_eq!((2 as $T).isqrt(), 1 as $T);
+            assert_eq!((99 as $T).isqrt(), 9 as $T);
+            assert_eq!((100 as $T).isqrt(), 10 as $T);
+            assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
+        }
 
-                for n in ($T::MAX - 255)..=$T::MAX {
-                    let isqrt: $T = n.isqrt();
+        #[cfg(not(miri))] // Miri is too slow
+        #[test]
+        fn test_lots_of_isqrt() {
+            let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
+            for n in 0..=n_max {
+                let isqrt: $T = n.isqrt();
 
-                    assert!(isqrt.pow(2) <= n);
-                    assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
-                }
+                assert!(isqrt.pow(2) <= n);
+                assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
             }
 
-            #[test]
-            fn test_div_floor() {
-                assert_eq!((8 as $T).div_floor(3), 2);
-            }
+            for n in ($T::MAX - 255)..=$T::MAX {
+                let isqrt: $T = n.isqrt();
 
-            #[test]
-            fn test_div_ceil() {
-                assert_eq!((8 as $T).div_ceil(3), 3);
+                assert!(isqrt.pow(2) <= n);
+                assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
             }
+        }
 
-            #[test]
-            fn test_next_multiple_of() {
-                assert_eq!((16 as $T).next_multiple_of(8), 16);
-                assert_eq!((23 as $T).next_multiple_of(8), 24);
-                assert_eq!(MAX.next_multiple_of(1), MAX);
-            }
+        #[test]
+        fn test_div_floor() {
+            assert_eq!((8 as $T).div_floor(3), 2);
+        }
 
-            #[test]
-            fn test_checked_next_multiple_of() {
-                assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16));
-                assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24));
-                assert_eq!((1 as $T).checked_next_multiple_of(0), None);
-                assert_eq!(MAX.checked_next_multiple_of(2), None);
-            }
+        #[test]
+        fn test_div_ceil() {
+            assert_eq!((8 as $T).div_ceil(3), 3);
+        }
 
-            #[test]
-            fn test_is_next_multiple_of() {
-                assert!((12 as $T).is_multiple_of(4));
-                assert!(!(12 as $T).is_multiple_of(5));
-                assert!((0 as $T).is_multiple_of(0));
-                assert!(!(12 as $T).is_multiple_of(0));
-            }
+        #[test]
+        fn test_next_multiple_of() {
+            assert_eq!((16 as $T).next_multiple_of(8), 16);
+            assert_eq!((23 as $T).next_multiple_of(8), 24);
+            assert_eq!(MAX.next_multiple_of(1), MAX);
+        }
 
-            #[test]
-            fn test_carrying_add() {
-                assert_eq!($T::MAX.carrying_add(1, false), (0, true));
-                assert_eq!($T::MAX.carrying_add(0, true), (0, true));
-                assert_eq!($T::MAX.carrying_add(1, true), (1, true));
+        #[test]
+        fn test_checked_next_multiple_of() {
+            assert_eq!((16 as $T).checked_next_multiple_of(8), Some(16));
+            assert_eq!((23 as $T).checked_next_multiple_of(8), Some(24));
+            assert_eq!((1 as $T).checked_next_multiple_of(0), None);
+            assert_eq!(MAX.checked_next_multiple_of(2), None);
+        }
 
-                assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
-                assert_eq!($T::MIN.carrying_add(0, true), (1, false));
-                assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true));
-            }
+        #[test]
+        fn test_is_next_multiple_of() {
+            assert!((12 as $T).is_multiple_of(4));
+            assert!(!(12 as $T).is_multiple_of(5));
+            assert!((0 as $T).is_multiple_of(0));
+            assert!(!(12 as $T).is_multiple_of(0));
+        }
 
-            #[test]
-            fn test_borrowing_sub() {
-                assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
-                assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
-                assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+        #[test]
+        fn test_carrying_add() {
+            assert_eq!($T::MAX.carrying_add(1, false), (0, true));
+            assert_eq!($T::MAX.carrying_add(0, true), (0, true));
+            assert_eq!($T::MAX.carrying_add(1, true), (1, true));
 
-                assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false));
-                assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
-                assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
-            }
+            assert_eq!($T::MIN.carrying_add($T::MAX, false), ($T::MAX, false));
+            assert_eq!($T::MIN.carrying_add(0, true), (1, false));
+            assert_eq!($T::MIN.carrying_add($T::MAX, true), (0, true));
+        }
 
-            #[test]
-            fn test_midpoint() {
-                assert_eq!(<$T>::midpoint(1, 3), 2);
-                assert_eq!(<$T>::midpoint(3, 1), 2);
-
-                assert_eq!(<$T>::midpoint(0, 0), 0);
-                assert_eq!(<$T>::midpoint(0, 2), 1);
-                assert_eq!(<$T>::midpoint(2, 0), 1);
-                assert_eq!(<$T>::midpoint(2, 2), 2);
-
-                assert_eq!(<$T>::midpoint(1, 4), 2);
-                assert_eq!(<$T>::midpoint(4, 1), 2);
-                assert_eq!(<$T>::midpoint(3, 4), 3);
-                assert_eq!(<$T>::midpoint(4, 3), 3);
-
-                assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
-                assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
-
-                assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
-                assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
-                assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
-                assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
-            }
+        #[test]
+        fn test_borrowing_sub() {
+            assert_eq!($T::MIN.borrowing_sub(1, false), ($T::MAX, true));
+            assert_eq!($T::MIN.borrowing_sub(0, true), ($T::MAX, true));
+            assert_eq!($T::MIN.borrowing_sub(1, true), ($T::MAX - 1, true));
+
+            assert_eq!($T::MAX.borrowing_sub($T::MAX, false), (0, false));
+            assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false));
+            assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true));
+        }
+
+        #[test]
+        fn test_midpoint() {
+            assert_eq!(<$T>::midpoint(1, 3), 2);
+            assert_eq!(<$T>::midpoint(3, 1), 2);
+
+            assert_eq!(<$T>::midpoint(0, 0), 0);
+            assert_eq!(<$T>::midpoint(0, 2), 1);
+            assert_eq!(<$T>::midpoint(2, 0), 1);
+            assert_eq!(<$T>::midpoint(2, 2), 2);
+
+            assert_eq!(<$T>::midpoint(1, 4), 2);
+            assert_eq!(<$T>::midpoint(4, 1), 2);
+            assert_eq!(<$T>::midpoint(3, 4), 3);
+            assert_eq!(<$T>::midpoint(4, 3), 3);
+
+            assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2);
+            assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX);
+
+            assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3);
+            assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3);
+            assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3);
+            assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3);
         }
     };
 }
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index f6df6259137..b436fe9929c 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -248,11 +248,16 @@ impl f128 {
     /// Returns a number composed of the magnitude of `self` and the sign of
     /// `sign`.
     ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
-    /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
-    /// `sign` is returned. Note, however, that conserving the sign bit on NaN
-    /// across arithmetical operations is not generally guaranteed.
-    /// See [explanation of NaN as a special value](primitive@f128) for more info.
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index 10908332762..b2cd5fae9d0 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -247,11 +247,16 @@ impl f16 {
     /// Returns a number composed of the magnitude of `self` and the sign of
     /// `sign`.
     ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
-    /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
-    /// `sign` is returned. Note, however, that conserving the sign bit on NaN
-    /// across arithmetical operations is not generally guaranteed.
-    /// See [explanation of NaN as a special value](primitive@f16) for more info.
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 12433d25bfa..cafbe9761da 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -226,11 +226,16 @@ impl f32 {
     /// Returns a number composed of the magnitude of `self` and the sign of
     /// `sign`.
     ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
-    /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
-    /// `sign` is returned. Note, however, that conserving the sign bit on NaN
-    /// across arithmetical operations is not generally guaranteed.
-    /// See [explanation of NaN as a special value](primitive@f32) for more info.
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index a343e19173e..fba283e3a44 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -226,11 +226,16 @@ impl f64 {
     /// Returns a number composed of the magnitude of `self` and the sign of
     /// `sign`.
     ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
-    /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
-    /// `sign` is returned. Note, however, that conserving the sign bit on NaN
-    /// across arithmetical operations is not generally guaranteed.
-    /// See [explanation of NaN as a special value](primitive@f32) for more info.
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 9ffdebe1b6f..bbea27ebc10 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2296,6 +2296,15 @@ impl Child {
 /// }
 /// ```
 ///
+/// In its current implementation, this function will execute exit handlers registered with `atexit`
+/// as well as other platform-specific exit handlers (e.g. `fini` sections of ELF shared objects).
+/// This means that Rust requires that all exit handlers are safe to execute at any time. In
+/// particular, if an exit handler cleans up some state that might be concurrently accessed by other
+/// threads, it is required that the exit handler performs suitable synchronization with those
+/// threads. (The alternative to this requirement would be to not run exit handlers at all, which is
+/// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an
+/// unsafe operation is not an option.)
+///
 /// ## Platform-specific behavior
 ///
 /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
diff --git a/library/std/src/sys/pal/hermit/alloc.rs b/library/std/src/sys/alloc/hermit.rs
index f10d5f9227e..77f8200a70a 100644
--- a/library/std/src/sys/pal/hermit/alloc.rs
+++ b/library/std/src/sys/alloc/hermit.rs
@@ -1,4 +1,3 @@
-use super::hermit_abi;
 use crate::alloc::{GlobalAlloc, Layout, System};
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
diff --git a/library/std/src/sys/pal/common/alloc.rs b/library/std/src/sys/alloc/mod.rs
index 1b465f95d1b..2c0b533a570 100644
--- a/library/std/src/sys/pal/common/alloc.rs
+++ b/library/std/src/sys/alloc/mod.rs
@@ -1,10 +1,18 @@
 #![forbid(unsafe_op_in_unsafe_fn)]
+
 use crate::alloc::{GlobalAlloc, Layout, System};
-use crate::{cmp, ptr};
+use crate::ptr;
 
 // The minimum alignment guaranteed by the architecture. This value is used to
 // add fast paths for low alignment values.
-#[cfg(any(
+#[allow(dead_code)]
+const MIN_ALIGN: usize = if cfg!(any(
+    all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
+    all(target_arch = "xtensa", target_os = "espidf"),
+)) {
+    // The allocator on the esp-idf and zkvm platforms guarantees 4 byte alignment.
+    4
+} else if cfg!(any(
     target_arch = "x86",
     target_arch = "arm",
     target_arch = "m68k",
@@ -16,11 +24,11 @@ use crate::{cmp, ptr};
     target_arch = "sparc",
     target_arch = "wasm32",
     target_arch = "hexagon",
-    all(target_arch = "riscv32", not(any(target_os = "espidf", target_os = "zkvm"))),
-    all(target_arch = "xtensa", not(target_os = "espidf")),
-))]
-pub const MIN_ALIGN: usize = 8;
-#[cfg(any(
+    target_arch = "riscv32",
+    target_arch = "xtensa",
+)) {
+    8
+} else if cfg!(any(
     target_arch = "x86_64",
     target_arch = "aarch64",
     target_arch = "arm64ec",
@@ -31,16 +39,14 @@ pub const MIN_ALIGN: usize = 8;
     target_arch = "sparc64",
     target_arch = "riscv64",
     target_arch = "wasm64",
-))]
-pub const MIN_ALIGN: usize = 16;
-// The allocator on the esp-idf and zkvm platforms guarantee 4 byte alignment.
-#[cfg(all(any(
-    all(target_arch = "riscv32", any(target_os = "espidf", target_os = "zkvm")),
-    all(target_arch = "xtensa", target_os = "espidf"),
-)))]
-pub const MIN_ALIGN: usize = 4;
+)) {
+    16
+} else {
+    panic!("add a value for MIN_ALIGN")
+};
 
-pub unsafe fn realloc_fallback(
+#[allow(dead_code)]
+unsafe fn realloc_fallback(
     alloc: &System,
     ptr: *mut u8,
     old_layout: Layout,
@@ -52,10 +58,37 @@ pub unsafe fn realloc_fallback(
 
         let new_ptr = GlobalAlloc::alloc(alloc, new_layout);
         if !new_ptr.is_null() {
-            let size = cmp::min(old_layout.size(), new_size);
+            let size = usize::min(old_layout.size(), new_size);
             ptr::copy_nonoverlapping(ptr, new_ptr, size);
             GlobalAlloc::dealloc(alloc, ptr, old_layout);
         }
+
         new_ptr
     }
 }
+
+cfg_if::cfg_if! {
+    if #[cfg(any(
+        target_family = "unix",
+        target_os = "wasi",
+        target_os = "teeos",
+    ))] {
+        mod unix;
+    } else if #[cfg(target_os = "windows")] {
+        mod windows;
+    } else if #[cfg(target_os = "hermit")] {
+        mod hermit;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+        mod sgx;
+    } else if #[cfg(target_os = "solid_asp3")] {
+        mod solid;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+    } else if #[cfg(target_family = "wasm")] {
+        mod wasm;
+    } else if #[cfg(target_os = "xous")] {
+        mod xous;
+    } else if #[cfg(target_os = "zkvm")] {
+        mod zkvm;
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/alloc.rs b/library/std/src/sys/alloc/sgx.rs
index f68ede9fcf0..fca9d087e5b 100644
--- a/library/std/src/sys/pal/sgx/alloc.rs
+++ b/library/std/src/sys/alloc/sgx.rs
@@ -1,9 +1,8 @@
-use core::sync::atomic::{AtomicBool, Ordering};
-
-use super::abi::mem as sgx_mem;
-use super::waitqueue::SpinMutex;
 use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::ptr;
+use crate::sync::atomic::{AtomicBool, Ordering};
+use crate::sys::pal::abi::mem as sgx_mem;
+use crate::sys::pal::waitqueue::SpinMutex;
 
 // Using a SpinMutex because we never want to exit the enclave waiting for the
 // allocator.
diff --git a/library/std/src/sys/pal/solid/alloc.rs b/library/std/src/sys/alloc/solid.rs
index 4cf60ac9b2e..abb534a1c5c 100644
--- a/library/std/src/sys/pal/solid/alloc.rs
+++ b/library/std/src/sys/alloc/solid.rs
@@ -1,5 +1,5 @@
+use super::{realloc_fallback, MIN_ALIGN};
 use crate::alloc::{GlobalAlloc, Layout, System};
-use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
diff --git a/library/std/src/sys/pal/uefi/alloc.rs b/library/std/src/sys/alloc/uefi.rs
index 15404ac3ea6..5221876e908 100644
--- a/library/std/src/sys/pal/uefi/alloc.rs
+++ b/library/std/src/sys/alloc/uefi.rs
@@ -3,9 +3,9 @@
 
 use r_efi::protocols::loaded_image;
 
-use super::helpers;
 use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::sync::OnceLock;
+use crate::sys::pal::helpers;
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/alloc/unix.rs
index 625ba5247f1..46ed7de7162 100644
--- a/library/std/src/sys/pal/unix/alloc.rs
+++ b/library/std/src/sys/alloc/unix.rs
@@ -1,6 +1,6 @@
+use super::{realloc_fallback, MIN_ALIGN};
 use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::ptr;
-use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
@@ -11,7 +11,7 @@ unsafe impl GlobalAlloc for System {
         // Also see <https://github.com/rust-lang/rust/issues/45955> and
         // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::malloc(layout.size()) as *mut u8
+            unsafe { libc::malloc(layout.size()) as *mut u8 }
         } else {
             // `posix_memalign` returns a non-aligned value if supplied a very
             // large alignment on older versions of Apple's platforms (unknown
@@ -25,7 +25,7 @@ unsafe impl GlobalAlloc for System {
                     return ptr::null_mut();
                 }
             }
-            aligned_malloc(&layout)
+            unsafe { aligned_malloc(&layout) }
         }
     }
 
@@ -33,11 +33,11 @@ unsafe impl GlobalAlloc for System {
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
         // See the comment above in `alloc` for why this check looks the way it does.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::calloc(layout.size(), 1) as *mut u8
+            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
         } else {
-            let ptr = self.alloc(layout);
+            let ptr = unsafe { self.alloc(layout) };
             if !ptr.is_null() {
-                ptr::write_bytes(ptr, 0, layout.size());
+                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
             }
             ptr
         }
@@ -45,15 +45,15 @@ unsafe impl GlobalAlloc for System {
 
     #[inline]
     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-        libc::free(ptr as *mut libc::c_void)
+        unsafe { libc::free(ptr as *mut libc::c_void) }
     }
 
     #[inline]
     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
         if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
-            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
+            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
         } else {
-            realloc_fallback(self, ptr, layout, new_size)
+            unsafe { realloc_fallback(self, ptr, layout, new_size) }
         }
     }
 }
@@ -81,7 +81,7 @@ cfg_if::cfg_if! {
             // posix_memalign only has one, clear requirement: that the alignment be a multiple of
             // `sizeof(void*)`. Since these are all powers of 2, we can just use max.
             let align = layout.align().max(crate::mem::size_of::<usize>());
-            let ret = libc::posix_memalign(&mut out, align, layout.size());
+            let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
             if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
         }
     }
diff --git a/library/std/src/sys/pal/wasm/alloc.rs b/library/std/src/sys/alloc/wasm.rs
index ef9d753d7f8..ef9d753d7f8 100644
--- a/library/std/src/sys/pal/wasm/alloc.rs
+++ b/library/std/src/sys/alloc/wasm.rs
diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/alloc/windows.rs
index 2205885687d..e91956966aa 100644
--- a/library/std/src/sys/pal/windows/alloc.rs
+++ b/library/std/src/sys/alloc/windows.rs
@@ -1,11 +1,10 @@
-use core::mem::MaybeUninit;
-
+use super::{realloc_fallback, MIN_ALIGN};
 use crate::alloc::{GlobalAlloc, Layout, System};
 use crate::ffi::c_void;
+use crate::mem::MaybeUninit;
 use crate::ptr;
 use crate::sync::atomic::{AtomicPtr, Ordering};
 use crate::sys::c;
-use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
 
 #[cfg(test)]
 mod tests;
@@ -113,28 +112,28 @@ fn init_or_get_process_heap() -> c::HANDLE {
 extern "C" fn process_heap_init_and_alloc(
     _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
     flags: u32,
-    dwBytes: usize,
+    bytes: usize,
 ) -> *mut c_void {
     let heap = init_or_get_process_heap();
     if core::intrinsics::unlikely(heap.is_null()) {
         return ptr::null_mut();
     }
     // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
-    unsafe { HeapAlloc(heap, flags, dwBytes) }
+    unsafe { HeapAlloc(heap, flags, bytes) }
 }
 
 #[inline(never)]
 fn process_heap_alloc(
     _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
     flags: u32,
-    dwBytes: usize,
+    bytes: usize,
 ) -> *mut c_void {
     let heap = HEAP.load(Ordering::Relaxed);
     if core::intrinsics::likely(!heap.is_null()) {
         // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
-        unsafe { HeapAlloc(heap, flags, dwBytes) }
+        unsafe { HeapAlloc(heap, flags, bytes) }
     } else {
-        process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes)
+        process_heap_init_and_alloc(MaybeUninit::uninit(), flags, bytes)
     }
 }
 
diff --git a/library/std/src/sys/pal/windows/alloc/tests.rs b/library/std/src/sys/alloc/windows/tests.rs
index 674a3e1d92d..674a3e1d92d 100644
--- a/library/std/src/sys/pal/windows/alloc/tests.rs
+++ b/library/std/src/sys/alloc/windows/tests.rs
diff --git a/library/std/src/sys/pal/xous/alloc.rs b/library/std/src/sys/alloc/xous.rs
index 9ea43445d02..9ea43445d02 100644
--- a/library/std/src/sys/pal/xous/alloc.rs
+++ b/library/std/src/sys/alloc/xous.rs
diff --git a/library/std/src/sys/pal/zkvm/alloc.rs b/library/std/src/sys/alloc/zkvm.rs
index 2fdca223524..a600cfa2220 100644
--- a/library/std/src/sys/pal/zkvm/alloc.rs
+++ b/library/std/src/sys/alloc/zkvm.rs
@@ -1,5 +1,5 @@
-use super::abi;
 use crate::alloc::{GlobalAlloc, Layout, System};
+use crate::sys::pal::abi;
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index a86b3628f24..1ef17dd530f 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -5,6 +5,7 @@
 /// descriptors.
 mod pal;
 
+mod alloc;
 mod personality;
 
 pub mod anonymous_pipe;
diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs
index 29fc0835d76..9af4dee401c 100644
--- a/library/std/src/sys/pal/common/mod.rs
+++ b/library/std/src/sys/pal/common/mod.rs
@@ -10,7 +10,6 @@
 
 #![allow(dead_code)]
 
-pub mod alloc;
 pub mod small_c_string;
 
 #[cfg(test)]
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index ef406b9ec7f..1f2e5d9469f 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -18,7 +18,6 @@
 
 use crate::os::raw::c_char;
 
-pub mod alloc;
 pub mod args;
 pub mod env;
 pub mod fd;
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 6321f92e3d9..4c0c0919f47 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -77,8 +77,11 @@ impl Thread {
 
     #[inline]
     pub fn sleep(dur: Duration) {
+        let micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
+        let micros = u64::try_from(micros).unwrap_or(u64::MAX);
+
         unsafe {
-            hermit_abi::usleep(dur.as_micros() as u64);
+            hermit_abi::usleep(micros);
         }
     }
 
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 851ab9b9f97..8d29b2ec619 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -9,7 +9,6 @@ use crate::io::ErrorKind;
 use crate::sync::atomic::{AtomicBool, Ordering};
 
 pub mod abi;
-pub mod alloc;
 pub mod args;
 pub mod env;
 pub mod fd;
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
index cbf34286878..6ebcf5b7c48 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -16,7 +16,6 @@ pub mod itron {
     use super::unsupported;
 }
 
-pub mod alloc;
 #[path = "../unsupported/args.rs"]
 pub mod args;
 pub mod env;
diff --git a/library/std/src/sys/pal/teeos/alloc.rs b/library/std/src/sys/pal/teeos/alloc.rs
deleted file mode 100644
index b280d1dd76f..00000000000
--- a/library/std/src/sys/pal/teeos/alloc.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-use crate::alloc::{GlobalAlloc, Layout, System};
-use crate::ptr;
-use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
-
-#[stable(feature = "alloc_system_type", since = "1.28.0")]
-unsafe impl GlobalAlloc for System {
-    #[inline]
-    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
-        // jemalloc provides alignment less than MIN_ALIGN for small allocations.
-        // So only rely on MIN_ALIGN if size >= align.
-        // Also see <https://github.com/rust-lang/rust/issues/45955> and
-        // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
-        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            unsafe { libc::malloc(layout.size()) as *mut u8 }
-        } else {
-            unsafe { aligned_malloc(&layout) }
-        }
-    }
-
-    #[inline]
-    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
-        // See the comment above in `alloc` for why this check looks the way it does.
-        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
-        } else {
-            let ptr = unsafe { self.alloc(layout) };
-            if !ptr.is_null() {
-                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
-            }
-            ptr
-        }
-    }
-
-    #[inline]
-    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-        unsafe { libc::free(ptr as *mut libc::c_void) }
-    }
-
-    #[inline]
-    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
-        if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
-            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
-        } else {
-            unsafe { realloc_fallback(self, ptr, layout, new_size) }
-        }
-    }
-}
-
-#[inline]
-unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
-    let mut out = ptr::null_mut();
-    // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
-    // Since these are all powers of 2, we can just use max.
-    let align = layout.align().max(crate::mem::size_of::<usize>());
-    let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
-    if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
-}
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index adefd1bb42c..00e38604240 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -8,7 +8,6 @@
 
 pub use self::rand::hashmap_random_keys;
 
-pub mod alloc;
 #[path = "../unsupported/args.rs"]
 pub mod args;
 #[path = "../unsupported/env.rs"]
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 851bcea4c1e..ac22f4ded88 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -13,11 +13,11 @@
 //! [`OsString`]: crate::ffi::OsString
 #![forbid(unsafe_op_in_unsafe_fn)]
 
-pub mod alloc;
 pub mod args;
 pub mod env;
 #[path = "../unsupported/fs.rs"]
 pub mod fs;
+pub mod helpers;
 #[path = "../unsupported/io.rs"]
 pub mod io;
 #[path = "../unsupported/net.rs"]
@@ -30,8 +30,6 @@ pub mod stdio;
 pub mod thread;
 pub mod time;
 
-mod helpers;
-
 #[cfg(test)]
 mod tests;
 
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 10df3306f92..ba2f58f9c10 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -7,7 +7,6 @@ use crate::io::ErrorKind;
 #[macro_use]
 pub mod weak;
 
-pub mod alloc;
 pub mod args;
 pub mod env;
 pub mod fd;
diff --git a/library/std/src/sys/pal/unsupported/alloc.rs b/library/std/src/sys/pal/unsupported/alloc.rs
deleted file mode 100644
index d715ae45401..00000000000
--- a/library/std/src/sys/pal/unsupported/alloc.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use crate::alloc::{GlobalAlloc, Layout, System};
-use crate::ptr::null_mut;
-
-#[stable(feature = "alloc_system_type", since = "1.28.0")]
-unsafe impl GlobalAlloc for System {
-    #[inline]
-    unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
-        null_mut()
-    }
-
-    #[inline]
-    unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
-        null_mut()
-    }
-
-    #[inline]
-    unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
-
-    #[inline]
-    unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
-        null_mut()
-    }
-}
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs
index 442e6042ad5..01d516f7568 100644
--- a/library/std/src/sys/pal/unsupported/mod.rs
+++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -1,6 +1,5 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
-pub mod alloc;
 pub mod args;
 pub mod env;
 pub mod fs;
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index f4dc3ebd414..8051021a588 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -14,8 +14,6 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
-#[path = "../unix/alloc.rs"]
-pub mod alloc;
 pub mod args;
 pub mod env;
 pub mod fd;
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index f20630e10cf..546fadbe501 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -6,8 +6,6 @@
 //! To begin with, this target mirrors the wasi target 1 to 1, but over
 //! time this will change significantly.
 
-#[path = "../unix/alloc.rs"]
-pub mod alloc;
 #[path = "../wasi/args.rs"]
 pub mod args;
 #[path = "../wasi/env.rs"]
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 4c34859e918..8141bfac49a 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -16,7 +16,6 @@
 
 #![deny(unsafe_op_in_unsafe_fn)]
 
-pub mod alloc;
 #[path = "../unsupported/args.rs"]
 pub mod args;
 pub mod env;
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 6ed77fbc3d4..272fadd9150 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -15,7 +15,6 @@ pub mod compat;
 
 mod api;
 
-pub mod alloc;
 pub mod args;
 pub mod c;
 pub mod env;
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index 961d45c5e83..b211e94db65 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -1,6 +1,5 @@
 #![forbid(unsafe_op_in_unsafe_fn)]
 
-pub mod alloc;
 #[path = "../unsupported/args.rs"]
 pub mod args;
 #[path = "../unsupported/env.rs"]
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index 651f25d6623..20fdb7468a4 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -10,7 +10,7 @@
 
 const WORD_SIZE: usize = core::mem::size_of::<u32>();
 
-pub mod alloc;
+pub mod abi;
 #[path = "../zkvm/args.rs"]
 pub mod args;
 pub mod env;
@@ -26,13 +26,10 @@ pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
 pub mod stdio;
-#[path = "../unsupported/time.rs"]
-pub mod time;
-
 #[path = "../unsupported/thread.rs"]
 pub mod thread;
-
-mod abi;
+#[path = "../unsupported/time.rs"]
+pub mod time;
 
 use crate::io as std_io;
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index ce23b7735f8..bdfee55d8d1 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1885,6 +1885,22 @@ impl Config {
                     warn("link-shared");
                 }
 
+                // FIXME(#129153): instead of all the ad-hoc `download-ci-llvm` checks that follow,
+                // use the `builder-config` present in tarballs since #128822 to compare the local
+                // config to the ones used to build the LLVM artifacts on CI, and only notify users
+                // if they've chosen a different value.
+
+                if libzstd.is_some() {
+                    println!(
+                        "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
+                        like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
+                        artifacts builder config."
+                    );
+                    println!(
+                        "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
+                    );
+                }
+
                 // None of the LLVM options, except assertions, are supported
                 // when using downloaded LLVM. We could just ignore these but
                 // that's potentially confusing, so force them to not be
@@ -1894,7 +1910,6 @@ impl Config {
                 check_ci_llvm!(optimize_toml);
                 check_ci_llvm!(thin_lto);
                 check_ci_llvm!(release_debuginfo);
-                check_ci_llvm!(libzstd);
                 check_ci_llvm!(targets);
                 check_ci_llvm!(experimental_targets);
                 check_ci_llvm!(clang_cl);
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 61e9694f1e2..e857f38e68a 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -62,9 +62,9 @@ COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/
 RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
-# rustc's LLVM needs zstd.
-COPY scripts/zstd.sh /tmp/
-RUN ./zstd.sh
+# Build zstd to enable `llvm.libzstd`.
+COPY host-x86_64/dist-x86_64-linux/build-zstd.sh /tmp/
+RUN ./build-zstd.sh
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/scripts/zstd.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh
index a3d37ccc311..a3d37ccc311 100755
--- a/src/ci/docker/scripts/zstd.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-zstd.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
index 19683317126..83c2aa8cfb3 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
@@ -28,5 +28,6 @@ ENV RUST_CONFIGURE_ARGS \
  --build=x86_64-unknown-linux-gnu \
  --enable-sanitizers \
  --enable-profiler \
- --enable-compiler-docs
+ --enable-compiler-docs \
+ --set llvm.libzstd=true
 ENV SCRIPT python3 ../x.py --stage 2 test
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 4e34e2667cf..b3a74a7716b 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -49,6 +49,7 @@
     - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md)
     - [\*-espidf](platform-support/esp-idf.md)
     - [\*-unknown-fuchsia](platform-support/fuchsia.md)
+    - [\*-unknown-trusty](platform-support/trusty.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
     - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md)
     - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index dd478e9df37..0d79e5f4114 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -264,6 +264,7 @@ target | std | host | notes
 [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD
 [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
 [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ |  | ARM64 Redox OS
+[`aarch64-unknown-trusty`](platform-support/trusty.md) | ? |  |
 `aarch64-uwp-windows-msvc` | ✓ |  |
 [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  | ARM64 VxWorks OS
 `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
@@ -283,6 +284,7 @@ target | std | host | notes
 [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
 `armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
 [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
+[`armv7-unknown-trusty`](platform-support/trusty.md) | ? |  |
 [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ |  | Armv7-A for VxWorks
 [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3
 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ |  | ARM SOLID with TOPPERS/ASP3, hardfloat
diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md
new file mode 100644
index 00000000000..dec3b96ff64
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/trusty.md
@@ -0,0 +1,51 @@
+# `aarch64-unknown-trusty` and `armv7-unknown-trusty`
+
+**Tier: 3**
+
+[Trusty] is a secure Operating System that provides a Trusted Execution
+Environment (TEE) for Android.
+
+## Target maintainers
+
+- Nicole LeGare (@randomPoison)
+- Stephen Crane (@rinon)
+- As a fallback trusty-dev-team@google.com can be contacted
+
+## Requirements
+
+These targets are cross-compiled. They have no special requirements for the host.
+
+Support for the standard library is work-in-progress. It is expected that
+they will support alloc with the default allocator, and partially support std.
+
+Trusty uses the ELF file format.
+
+## Building the target
+
+The targets can be built by enabling them for a `rustc` build, for example:
+
+```toml
+[build]
+build-stage = 1
+target = ["aarch64-unknown-trusty", "armv7-unknown-trusty"]
+```
+
+## Building Rust programs
+
+There is currently no supported way to build a Trusty app with Cargo. You can
+follow the [Trusty build instructions] to build the Trusty kernel along with any
+Rust apps that are setup in the project.
+
+## Testing
+
+See the [Trusty build instructions] for information on how to build Rust code
+within the main Trusty project. The main project also includes infrastructure
+for testing Rust applications within a QEMU emulator.
+
+## Cross-compilation toolchains and C code
+
+See the [Trusty build instructions] for information on how C code is built
+within Trusty.
+
+[Trusty]: https://source.android.com/docs/security/features/trusty
+[Trusty build instructions]: https://source.android.com/docs/security/features/trusty/download-and-build
diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md
index 8e1b1d80fb6..5ea8b6cd542 100644
--- a/src/doc/style-guide/src/items.md
+++ b/src/doc/style-guide/src/items.md
@@ -449,8 +449,8 @@ entries, format it across multiple lines as with a type alias.
 ## extern items
 
 When writing extern items (such as `extern "C" fn`), always specify the ABI.
-For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or
-`extern "C" { ... }`.
+For example, write `extern "C" fn foo ...` or `unsafe extern "C" { ...}`
+and avoid `extern fn foo ...` and `unsafe extern { ... }`.
 
 ## Imports (`use` statements)
 
diff --git a/src/doc/unstable-book/src/compiler-flags/embed-source.md b/src/doc/unstable-book/src/compiler-flags/embed-source.md
new file mode 100644
index 00000000000..01a11e37797
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/embed-source.md
@@ -0,0 +1,12 @@
+# `embed-source`
+
+This flag controls whether the compiler embeds the program source code text into
+the object debug information section. It takes one of the following values:
+
+* `y`, `yes`, `on` or `true`: put source code in debug info.
+* `n`, `no`, `off`, `false` or no value: omit source code from debug info (the default).
+
+This flag is ignored in configurations that don't emit DWARF debug information
+and is ignored on non-LLVM backends. `-Z embed-source` requires DWARFv5. Use
+`-Z dwarf-version=5` to control the compiler's DWARF target version and `-g` to
+enable debug info generation.
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index 3dcef15b552..9754e1e6f74 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -162,7 +162,8 @@ impl ItemType {
             | DefKind::LifetimeParam
             | DefKind::GlobalAsm
             | DefKind::Impl { .. }
-            | DefKind::Closure => Self::ForeignType,
+            | DefKind::Closure
+            | DefKind::SyntheticCoroutineBody => Self::ForeignType,
         }
     }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index c1b2ee7d8ae..47f321a4c4a 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1730,6 +1730,7 @@ fn render_impl(
                 let source_id = format!("{item_type}.{name}");
                 let id = cx.derive_id(&source_id);
                 write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
+                render_rightside(w, cx, item, render_mode);
                 if trait_.is_some() {
                     // Anchors are only used on trait impls.
                     write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>");
@@ -1751,6 +1752,7 @@ fn render_impl(
                 let source_id = format!("{item_type}.{name}");
                 let id = cx.derive_id(&source_id);
                 write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");
+                render_rightside(w, cx, item, render_mode);
                 if trait_.is_some() {
                     // Anchors are only used on trait impls.
                     write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>");
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index ab03f620230..eae12b84839 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1950,7 +1950,9 @@ fn resolution_failure(
                             | TraitAlias
                             | TyParam
                             | Static { .. } => "associated item",
-                            Impl { .. } | GlobalAsm => unreachable!("not a path"),
+                            Impl { .. } | GlobalAsm | SyntheticCoroutineBody => {
+                                unreachable!("not a path")
+                            }
                         }
                     } else {
                         "associated item"
diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs
index 7f8080235c8..a559d6f81a2 100644
--- a/src/tools/compiletest/src/command-list.rs
+++ b/src/tools/compiletest/src/command-list.rs
@@ -141,6 +141,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "needs-force-clang-based-tests",
     "needs-git-hash",
     "needs-llvm-components",
+    "needs-llvm-zstd",
     "needs-profiler-support",
     "needs-relocation-model-pic",
     "needs-run-enabled",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 1fc24301c85..933913eb47c 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -1203,6 +1203,107 @@ pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<u32> {
     None
 }
 
+/// For tests using the `needs-llvm-zstd` directive:
+/// - for local LLVM builds, try to find the static zstd library in the llvm-config system libs.
+/// - for `download-ci-llvm`, see if `lld` was built with zstd support.
+pub fn llvm_has_libzstd(config: &Config) -> bool {
+    // Strategy 1: works for local builds but not with `download-ci-llvm`.
+    //
+    // We check whether `llvm-config` returns the zstd library. Bootstrap's `llvm.libzstd` will only
+    // ask to statically link it when building LLVM, so we only check if the list of system libs
+    // contains a path to that static lib, and that it exists.
+    //
+    // See compiler/rustc_llvm/build.rs for more details and similar expectations.
+    fn is_zstd_in_config(llvm_bin_dir: &Path) -> Option<()> {
+        let llvm_config_path = llvm_bin_dir.join("llvm-config");
+        let output = Command::new(llvm_config_path).arg("--system-libs").output().ok()?;
+        assert!(output.status.success(), "running llvm-config --system-libs failed");
+
+        let libs = String::from_utf8(output.stdout).ok()?;
+        for lib in libs.split_whitespace() {
+            if lib.ends_with("libzstd.a") && Path::new(lib).exists() {
+                return Some(());
+            }
+        }
+
+        None
+    }
+
+    // Strategy 2: `download-ci-llvm`'s `llvm-config --system-libs` will not return any libs to
+    // use.
+    //
+    // The CI artifacts also don't contain the bootstrap config used to build them: otherwise we
+    // could have looked at the `llvm.libzstd` config.
+    //
+    // We infer whether `LLVM_ENABLE_ZSTD` was used to build LLVM as a byproduct of testing whether
+    // `lld` supports it. If not, an error will be emitted: "LLVM was not built with
+    // LLVM_ENABLE_ZSTD or did not find zstd at build time".
+    #[cfg(unix)]
+    fn is_lld_built_with_zstd(llvm_bin_dir: &Path) -> Option<()> {
+        let lld_path = llvm_bin_dir.join("lld");
+        if lld_path.exists() {
+            // We can't call `lld` as-is, it expects to be invoked by a compiler driver using a
+            // different name. Prepare a temporary symlink to do that.
+            let lld_symlink_path = llvm_bin_dir.join("ld.lld");
+            if !lld_symlink_path.exists() {
+                std::os::unix::fs::symlink(lld_path, &lld_symlink_path).ok()?;
+            }
+
+            // Run `lld` with a zstd flag. We expect this command to always error here, we don't
+            // want to link actual files and don't pass any.
+            let output = Command::new(&lld_symlink_path)
+                .arg("--compress-debug-sections=zstd")
+                .output()
+                .ok()?;
+            assert!(!output.status.success());
+
+            // Look for a specific error caused by LLVM not being built with zstd support. We could
+            // also look for the "no input files" message, indicating the zstd flag was accepted.
+            let stderr = String::from_utf8(output.stderr).ok()?;
+            let zstd_available = !stderr.contains("LLVM was not built with LLVM_ENABLE_ZSTD");
+
+            // We don't particularly need to clean the link up (so the previous commands could fail
+            // in theory but won't in practice), but we can try.
+            std::fs::remove_file(lld_symlink_path).ok()?;
+
+            if zstd_available {
+                return Some(());
+            }
+        }
+
+        None
+    }
+
+    #[cfg(not(unix))]
+    fn is_lld_built_with_zstd(_llvm_bin_dir: &Path) -> Option<()> {
+        None
+    }
+
+    if let Some(llvm_bin_dir) = &config.llvm_bin_dir {
+        // Strategy 1: for local LLVM builds.
+        if is_zstd_in_config(llvm_bin_dir).is_some() {
+            return true;
+        }
+
+        // Strategy 2: for LLVM artifacts built on CI via `download-ci-llvm`.
+        //
+        // It doesn't work for cases where the artifacts don't contain the linker, but it's
+        // best-effort: CI has `llvm.libzstd` and `lld` enabled on the x64 linux artifacts, so it
+        // will at least work there.
+        //
+        // If this can be improved and expanded to less common cases in the future, it should.
+        if config.target == "x86_64-unknown-linux-gnu"
+            && config.host == config.target
+            && is_lld_built_with_zstd(llvm_bin_dir).is_some()
+        {
+            return true;
+        }
+    }
+
+    // Otherwise, all hope is lost.
+    false
+}
+
 /// Takes a directive of the form "<version1> [- <version2>]",
 /// returns the numeric representation of <version1> and <version2> as
 /// tuple: (<version1> as u32, <version2> as u32)
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 8f935d5b744..72b1b9c6d48 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -1,5 +1,5 @@
 use crate::common::{Config, Sanitizer};
-use crate::header::IgnoreDecision;
+use crate::header::{llvm_has_libzstd, IgnoreDecision};
 
 pub(super) fn handle_needs(
     cache: &CachedNeedsConditions,
@@ -144,6 +144,11 @@ pub(super) fn handle_needs(
             condition: cache.symlinks,
             ignore_reason: "ignored if symlinks are unavailable",
         },
+        Need {
+            name: "needs-llvm-zstd",
+            condition: cache.llvm_zstd,
+            ignore_reason: "ignored if LLVM wasn't build with zstd for ELF section compression",
+        },
     ];
 
     let (name, comment) = match ln.split_once([':', ' ']) {
@@ -169,7 +174,7 @@ pub(super) fn handle_needs(
             } else {
                 return IgnoreDecision::Ignore {
                     reason: if let Some(comment) = comment {
-                        format!("{} ({comment})", need.ignore_reason)
+                        format!("{} ({})", need.ignore_reason, comment.trim())
                     } else {
                         need.ignore_reason.into()
                     },
@@ -210,6 +215,8 @@ pub(super) struct CachedNeedsConditions {
     rust_lld: bool,
     dlltool: bool,
     symlinks: bool,
+    /// Whether LLVM built with zstd, for the `needs-llvm-zstd` directive.
+    llvm_zstd: bool,
 }
 
 impl CachedNeedsConditions {
@@ -253,6 +260,7 @@ impl CachedNeedsConditions {
                 .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
                 .exists(),
 
+            llvm_zstd: llvm_has_libzstd(&config),
             dlltool: find_dlltool(&config),
             symlinks: has_symlinks(),
         }
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 9df0d95f1f2..6fd207c92b9 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -617,9 +617,10 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
         // the *value* (including the associated provenance if this is an AtomicPtr) at this location.
         // Only metadata on the location itself is used.
         let scalar = this.allow_data_races_ref(move |this| this.read_scalar(place))?;
-        this.buffered_atomic_read(place, atomic, scalar, || {
+        let buffered_scalar = this.buffered_atomic_read(place, atomic, scalar, || {
             this.validate_atomic_load(place, atomic)
-        })
+        })?;
+        Ok(buffered_scalar.ok_or_else(|| err_ub!(InvalidUninitBytes(None)))?)
     }
 
     /// Perform an atomic write operation at the memory location.
@@ -632,14 +633,14 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
         this.atomic_access_check(dest, AtomicAccessType::Store)?;
 
+        // Read the previous value so we can put it in the store buffer later.
+        // The program didn't actually do a read, so suppress the memory access hooks.
+        // This is also a very special exception where we just ignore an error -- if this read
+        // was UB e.g. because the memory is uninitialized, we don't want to know!
+        let old_val = this.run_for_validation(|| this.read_scalar(dest)).ok();
         this.allow_data_races_mut(move |this| this.write_scalar(val, dest))?;
         this.validate_atomic_store(dest, atomic)?;
-        // FIXME: it's not possible to get the value before write_scalar. A read_scalar will cause
-        // side effects from a read the program did not perform. So we have to initialise
-        // the store buffer with the value currently being written
-        // ONCE this is fixed please remove the hack in buffered_atomic_write() in weak_memory.rs
-        // https://github.com/rust-lang/miri/issues/2164
-        this.buffered_atomic_write(val, dest, atomic, val)
+        this.buffered_atomic_write(val, dest, atomic, old_val)
     }
 
     /// Perform an atomic RMW operation on a memory location.
@@ -768,7 +769,7 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
             // in the modification order.
             // Since `old` is only a value and not the store element, we need to separately
             // find it in our store buffer and perform load_impl on it.
-            this.perform_read_on_buffered_latest(place, fail, old.to_scalar())?;
+            this.perform_read_on_buffered_latest(place, fail)?;
         }
 
         // Return the old value.
diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs
index 6f4171584a8..0605b744e6a 100644
--- a/src/tools/miri/src/concurrency/weak_memory.rs
+++ b/src/tools/miri/src/concurrency/weak_memory.rs
@@ -39,11 +39,10 @@
 //! to attach store buffers to atomic objects. However, Rust follows LLVM in that it only has
 //! 'atomic accesses'. Therefore Miri cannot know when and where atomic 'objects' are being
 //! created or destroyed, to manage its store buffers. Instead, we hence lazily create an
-//! atomic object on the first atomic access to a given region, and we destroy that object
-//! on the next non-atomic or imperfectly overlapping atomic access to that region.
+//! atomic object on the first atomic write to a given region, and we destroy that object
+//! on the next non-atomic or imperfectly overlapping atomic write to that region.
 //! These lazy (de)allocations happen in memory_accessed() on non-atomic accesses, and
-//! get_or_create_store_buffer() on atomic accesses. This mostly works well, but it does
-//! lead to some issues (<https://github.com/rust-lang/miri/issues/2164>).
+//! get_or_create_store_buffer_mut() on atomic writes.
 //!
 //! One consequence of this difference is that safe/sound Rust allows for more operations on atomic locations
 //! than the C++20 atomic API was intended to allow, such as non-atomically accessing
@@ -144,11 +143,9 @@ struct StoreElement {
 
     /// The timestamp of the storing thread when it performed the store
     timestamp: VTimestamp,
-    /// The value of this store
-    // FIXME: this means the store must be fully initialized;
-    // we will have to change this if we want to support atomics on
-    // (partially) uninitialized data.
-    val: Scalar,
+    /// The value of this store. `None` means uninitialized.
+    // FIXME: Currently, we cannot represent partial initialization.
+    val: Option<Scalar>,
 
     /// Metadata about loads from this store element,
     /// behind a RefCell to keep load op take &self
@@ -170,7 +167,7 @@ impl StoreBufferAlloc {
 
     /// When a non-atomic access happens on a location that has been atomically accessed
     /// before without data race, we can determine that the non-atomic access fully happens
-    /// after all the prior atomic accesses so the location no longer needs to exhibit
+    /// after all the prior atomic writes so the location no longer needs to exhibit
     /// any weak memory behaviours until further atomic accesses.
     pub fn memory_accessed(&self, range: AllocRange, global: &DataRaceState) {
         if !global.ongoing_action_data_race_free() {
@@ -192,37 +189,29 @@ impl StoreBufferAlloc {
         }
     }
 
-    /// Gets a store buffer associated with an atomic object in this allocation,
-    /// or creates one with the specified initial value if no atomic object exists yet.
-    fn get_or_create_store_buffer<'tcx>(
+    /// Gets a store buffer associated with an atomic object in this allocation.
+    /// Returns `None` if there is no store buffer.
+    fn get_store_buffer<'tcx>(
         &self,
         range: AllocRange,
-        init: Scalar,
-    ) -> InterpResult<'tcx, Ref<'_, StoreBuffer>> {
+    ) -> InterpResult<'tcx, Option<Ref<'_, StoreBuffer>>> {
         let access_type = self.store_buffers.borrow().access_type(range);
         let pos = match access_type {
             AccessType::PerfectlyOverlapping(pos) => pos,
-            AccessType::Empty(pos) => {
-                let mut buffers = self.store_buffers.borrow_mut();
-                buffers.insert_at_pos(pos, range, StoreBuffer::new(init));
-                pos
-            }
-            AccessType::ImperfectlyOverlapping(pos_range) => {
-                // Once we reach here we would've already checked that this access is not racy.
-                let mut buffers = self.store_buffers.borrow_mut();
-                buffers.remove_pos_range(pos_range.clone());
-                buffers.insert_at_pos(pos_range.start, range, StoreBuffer::new(init));
-                pos_range.start
-            }
+            // If there is nothing here yet, that means there wasn't an atomic write yet so
+            // we can't return anything outdated.
+            _ => return Ok(None),
         };
-        Ok(Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos]))
+        let store_buffer = Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos]);
+        Ok(Some(store_buffer))
     }
 
-    /// Gets a mutable store buffer associated with an atomic object in this allocation
+    /// Gets a mutable store buffer associated with an atomic object in this allocation,
+    /// or creates one with the specified initial value if no atomic object exists yet.
     fn get_or_create_store_buffer_mut<'tcx>(
         &mut self,
         range: AllocRange,
-        init: Scalar,
+        init: Option<Scalar>,
     ) -> InterpResult<'tcx, &mut StoreBuffer> {
         let buffers = self.store_buffers.get_mut();
         let access_type = buffers.access_type(range);
@@ -244,10 +233,8 @@ impl StoreBufferAlloc {
 }
 
 impl<'tcx> StoreBuffer {
-    fn new(init: Scalar) -> Self {
+    fn new(init: Option<Scalar>) -> Self {
         let mut buffer = VecDeque::new();
-        buffer.reserve(STORE_BUFFER_LIMIT);
-        let mut ret = Self { buffer };
         let store_elem = StoreElement {
             // The thread index and timestamp of the initialisation write
             // are never meaningfully used, so it's fine to leave them as 0
@@ -257,11 +244,11 @@ impl<'tcx> StoreBuffer {
             is_seqcst: false,
             load_info: RefCell::new(LoadInfo::default()),
         };
-        ret.buffer.push_back(store_elem);
-        ret
+        buffer.push_back(store_elem);
+        Self { buffer }
     }
 
-    /// Reads from the last store in modification order
+    /// Reads from the last store in modification order, if any.
     fn read_from_last_store(
         &self,
         global: &DataRaceState,
@@ -282,7 +269,7 @@ impl<'tcx> StoreBuffer {
         is_seqcst: bool,
         rng: &mut (impl rand::Rng + ?Sized),
         validate: impl FnOnce() -> InterpResult<'tcx>,
-    ) -> InterpResult<'tcx, (Scalar, LoadRecency)> {
+    ) -> InterpResult<'tcx, (Option<Scalar>, LoadRecency)> {
         // Having a live borrow to store_buffer while calling validate_atomic_load is fine
         // because the race detector doesn't touch store_buffer
 
@@ -419,15 +406,15 @@ impl<'tcx> StoreBuffer {
             // In the language provided in the paper, an atomic store takes the value from a
             // non-atomic memory location.
             // But we already have the immediate value here so we don't need to do the memory
-            // access
-            val,
+            // access.
+            val: Some(val),
             is_seqcst,
             load_info: RefCell::new(LoadInfo::default()),
         };
-        self.buffer.push_back(store_elem);
-        if self.buffer.len() > STORE_BUFFER_LIMIT {
+        if self.buffer.len() >= STORE_BUFFER_LIMIT {
             self.buffer.pop_front();
         }
+        self.buffer.push_back(store_elem);
         if is_seqcst {
             // Every store that happens before this needs to be marked as SC
             // so that in a later SC load, only the last SC store (i.e. this one) or stores that
@@ -450,7 +437,12 @@ impl StoreElement {
     /// buffer regardless of subsequent loads by the same thread; if the earliest load of another
     /// thread doesn't happen before the current one, then no subsequent load by the other thread
     /// can happen before the current one.
-    fn load_impl(&self, index: VectorIdx, clocks: &ThreadClockSet, is_seqcst: bool) -> Scalar {
+    fn load_impl(
+        &self,
+        index: VectorIdx,
+        clocks: &ThreadClockSet,
+        is_seqcst: bool,
+    ) -> Option<Scalar> {
         let mut load_info = self.load_info.borrow_mut();
         load_info.sc_loaded |= is_seqcst;
         let _ = load_info.timestamps.try_insert(index, clocks.clock[index]);
@@ -479,7 +471,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 global.sc_write(threads);
             }
             let range = alloc_range(base_offset, place.layout.size);
-            let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, init)?;
+            let buffer = alloc_buffers.get_or_create_store_buffer_mut(range, Some(init))?;
             buffer.read_from_last_store(global, threads, atomic == AtomicRwOrd::SeqCst);
             buffer.buffered_write(new_val, global, threads, atomic == AtomicRwOrd::SeqCst)?;
         }
@@ -492,47 +484,55 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         atomic: AtomicReadOrd,
         latest_in_mo: Scalar,
         validate: impl FnOnce() -> InterpResult<'tcx>,
-    ) -> InterpResult<'tcx, Scalar> {
+    ) -> InterpResult<'tcx, Option<Scalar>> {
         let this = self.eval_context_ref();
-        if let Some(global) = &this.machine.data_race {
-            let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
-            if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
-                if atomic == AtomicReadOrd::SeqCst {
-                    global.sc_read(&this.machine.threads);
-                }
-                let mut rng = this.machine.rng.borrow_mut();
-                let buffer = alloc_buffers.get_or_create_store_buffer(
-                    alloc_range(base_offset, place.layout.size),
-                    latest_in_mo,
-                )?;
-                let (loaded, recency) = buffer.buffered_read(
-                    global,
-                    &this.machine.threads,
-                    atomic == AtomicReadOrd::SeqCst,
-                    &mut *rng,
-                    validate,
-                )?;
-                if global.track_outdated_loads && recency == LoadRecency::Outdated {
-                    this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad {
-                        ptr: place.ptr(),
-                    });
+        'fallback: {
+            if let Some(global) = &this.machine.data_race {
+                let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
+                if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
+                    if atomic == AtomicReadOrd::SeqCst {
+                        global.sc_read(&this.machine.threads);
+                    }
+                    let mut rng = this.machine.rng.borrow_mut();
+                    let Some(buffer) = alloc_buffers
+                        .get_store_buffer(alloc_range(base_offset, place.layout.size))?
+                    else {
+                        // No old writes available, fall back to base case.
+                        break 'fallback;
+                    };
+                    let (loaded, recency) = buffer.buffered_read(
+                        global,
+                        &this.machine.threads,
+                        atomic == AtomicReadOrd::SeqCst,
+                        &mut *rng,
+                        validate,
+                    )?;
+                    if global.track_outdated_loads && recency == LoadRecency::Outdated {
+                        this.emit_diagnostic(NonHaltingDiagnostic::WeakMemoryOutdatedLoad {
+                            ptr: place.ptr(),
+                        });
+                    }
+
+                    return Ok(loaded);
                 }
-
-                return Ok(loaded);
             }
         }
 
         // Race detector or weak memory disabled, simply read the latest value
         validate()?;
-        Ok(latest_in_mo)
+        Ok(Some(latest_in_mo))
     }
 
+    /// Add the given write to the store buffer. (Does not change machine memory.)
+    ///
+    /// `init` says with which value to initialize the store buffer in case there wasn't a store
+    /// buffer for this memory range before.
     fn buffered_atomic_write(
         &mut self,
         val: Scalar,
         dest: &MPlaceTy<'tcx>,
         atomic: AtomicWriteOrd,
-        init: Scalar,
+        init: Option<Scalar>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr(), 0)?;
@@ -545,23 +545,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 global.sc_write(threads);
             }
 
-            // UGLY HACK: in write_scalar_atomic() we don't know the value before our write,
-            // so init == val always. If the buffer is fresh then we would've duplicated an entry,
-            // so we need to remove it.
-            // See https://github.com/rust-lang/miri/issues/2164
-            let was_empty = matches!(
-                alloc_buffers
-                    .store_buffers
-                    .borrow()
-                    .access_type(alloc_range(base_offset, dest.layout.size)),
-                AccessType::Empty(_)
-            );
             let buffer = alloc_buffers
                 .get_or_create_store_buffer_mut(alloc_range(base_offset, dest.layout.size), init)?;
-            if was_empty {
-                buffer.buffer.pop_front();
-            }
-
             buffer.buffered_write(val, global, threads, atomic == AtomicWriteOrd::SeqCst)?;
         }
 
@@ -576,7 +561,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &self,
         place: &MPlaceTy<'tcx>,
         atomic: AtomicReadOrd,
-        init: Scalar,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_ref();
 
@@ -587,8 +571,12 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             let size = place.layout.size;
             let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
             if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
-                let buffer = alloc_buffers
-                    .get_or_create_store_buffer(alloc_range(base_offset, size), init)?;
+                let Some(buffer) =
+                    alloc_buffers.get_store_buffer(alloc_range(base_offset, size))?
+                else {
+                    // No store buffer, nothing to do.
+                    return Ok(());
+                };
                 buffer.read_from_last_store(
                     global,
                     &this.machine.threads,
diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
index 804aa13660b..bbf069b7a2d 100644
--- a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
+++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs
@@ -4,7 +4,9 @@
 
 //@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation"
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
-//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^}]*\};" -> "FREE();"
+//@normalize-stderr-test: "unsafe \{ libc::free\([^()]*\) \}|unsafe \{ HeapFree\([^}]*\};" -> "FREE();"
+//@normalize-stderr-test: "alloc::[A-Za-z]+::" -> "alloc::PLATFORM::"
+//@normalize-stderr-test: "alloc/[A-Za-z]+.rs" -> "alloc/PLATFORM.rs"
 
 #![feature(allocator_api, slice_ptr_get)]
 
diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr
index 77909564149..287a1f1a3e3 100644
--- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr
+++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr
@@ -1,5 +1,5 @@
 error: Undefined Behavior: deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/alloc.rs:LL:CC
+  --> RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC
    |
 LL |         FREE();
    | ^ deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation
@@ -7,7 +7,7 @@ LL |         FREE();
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::alloc::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/pal/PLATFORM/alloc.rs:LL:CC
+   = note: inside `std::sys::alloc::PLATFORM::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC
    = note: inside `<std::alloc::System as std::alloc::Allocator>::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC
 note: inside `main`
   --> $DIR/global_system_mixup.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs
new file mode 100644
index 00000000000..54bea6c6908
--- /dev/null
+++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.rs
@@ -0,0 +1,43 @@
+//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0
+
+// Tests showing weak memory behaviours are exhibited. All tests
+// return true when the desired behaviour is seen.
+// This is scheduler and pseudo-RNG dependent, so each test is
+// run multiple times until one try returns true.
+// Spurious failure is possible, if you are really unlucky with
+// the RNG and always read the latest value from the store buffer.
+#![feature(new_uninit)]
+
+use std::sync::atomic::*;
+use std::thread::spawn;
+
+#[allow(dead_code)]
+#[derive(Copy, Clone)]
+struct EvilSend<T>(pub T);
+
+unsafe impl<T> Send for EvilSend<T> {}
+unsafe impl<T> Sync for EvilSend<T> {}
+
+// We can't create static items because we need to run each test multiple times.
+fn static_uninit_atomic() -> &'static AtomicUsize {
+    unsafe { Box::leak(Box::new_uninit()).assume_init_ref() }
+}
+
+fn relaxed() {
+    let x = static_uninit_atomic();
+    let j1 = spawn(move || {
+        x.store(1, Ordering::Relaxed);
+    });
+
+    let j2 = spawn(move || x.load(Ordering::Relaxed)); //~ERROR: using uninitialized data
+
+    j1.join().unwrap();
+    j2.join().unwrap();
+}
+
+pub fn main() {
+    // If we try often enough, we should hit UB.
+    for _ in 0..100 {
+        relaxed();
+    }
+}
diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr
new file mode 100644
index 00000000000..9aa5bc2fa76
--- /dev/null
+++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
+  --> $DIR/weak_uninit.rs:LL:CC
+   |
+LL |     let j2 = spawn(move || x.load(Ordering::Relaxed));
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE on thread `unnamed-ID`:
+   = note: inside closure at $DIR/weak_uninit.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs
index dac63eeeb0b..1b5c98cd518 100644
--- a/src/tools/miri/tests/pass/weak_memory/weak.rs
+++ b/src/tools/miri/tests/pass/weak_memory/weak.rs
@@ -18,11 +18,9 @@ struct EvilSend<T>(pub T);
 unsafe impl<T> Send for EvilSend<T> {}
 unsafe impl<T> Sync for EvilSend<T> {}
 
-// We can't create static items because we need to run each test
-// multiple times
+// We can't create static items because we need to run each test multiple times.
 fn static_atomic(val: usize) -> &'static AtomicUsize {
-    let ret = Box::leak(Box::new(AtomicUsize::new(val)));
-    ret
+    Box::leak(Box::new(AtomicUsize::new(val)))
 }
 
 // Spins until it reads the given value
@@ -33,7 +31,7 @@ fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
     val
 }
 
-fn relaxed() -> bool {
+fn relaxed(initial_read: bool) -> bool {
     let x = static_atomic(0);
     let j1 = spawn(move || {
         x.store(1, Relaxed);
@@ -47,7 +45,9 @@ fn relaxed() -> bool {
     j1.join().unwrap();
     let r2 = j2.join().unwrap();
 
-    r2 == 1
+    // There are three possible values here: 0 (from the initial read), 1 (from the first relaxed
+    // read), and 2 (the last read). The last case is boring and we cover the other two.
+    r2 == if initial_read { 0 } else { 1 }
 }
 
 // https://www.doc.ic.ac.uk/~afd/homepages/papers/pdfs/2017/POPL.pdf Figure 8
@@ -74,7 +74,6 @@ fn seq_cst() -> bool {
 
 fn initialization_write(add_fence: bool) -> bool {
     let x = static_atomic(11);
-    assert_eq!(x.load(Relaxed), 11); // work around https://github.com/rust-lang/miri/issues/2164
 
     let wait = static_atomic(0);
 
@@ -112,11 +111,8 @@ fn faa_replaced_by_load() -> bool {
     }
 
     let x = static_atomic(0);
-    assert_eq!(x.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164
     let y = static_atomic(0);
-    assert_eq!(y.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164
     let z = static_atomic(0);
-    assert_eq!(z.load(Relaxed), 0); // work around https://github.com/rust-lang/miri/issues/2164
 
     // Since each thread is so short, we need to make sure that they truely run at the same time
     // Otherwise t1 will finish before t2 even starts
@@ -146,7 +142,8 @@ fn assert_once(f: fn() -> bool) {
 }
 
 pub fn main() {
-    assert_once(relaxed);
+    assert_once(|| relaxed(false));
+    assert_once(|| relaxed(true));
     assert_once(seq_cst);
     assert_once(|| initialization_write(false));
     assert_once(|| initialization_write(true));
diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs
index 6a58d58dbde..08f6a3909f8 100644
--- a/src/tools/tidy/src/edition.rs
+++ b/src/tools/tidy/src/edition.rs
@@ -1,4 +1,4 @@
-//! Tidy check to ensure that crate `edition` is '2018' or '2021'.
+//! Tidy check to ensure that crate `edition` is '2021' or '2024'.
 
 use std::path::Path;
 
@@ -12,7 +12,9 @@ pub fn check(path: &Path, bad: &mut bool) {
             return;
         }
 
-        let is_2021 = contents.lines().any(|line| line.trim() == "edition = \"2021\"");
+        let is_current_edition = contents
+            .lines()
+            .any(|line| line.trim() == "edition = \"2021\"" || line.trim() == "edition = \"2024\"");
 
         let is_workspace = contents.lines().any(|line| line.trim() == "[workspace]");
         let is_package = contents.lines().any(|line| line.trim() == "[package]");
@@ -20,10 +22,10 @@ pub fn check(path: &Path, bad: &mut bool) {
 
         // Check that all packages use the 2021 edition. Virtual workspaces don't allow setting an
         // edition, so these shouldn't be checked.
-        if is_package && !is_2021 {
+        if is_package && !is_current_edition {
             tidy_error!(
                 bad,
-                "{} doesn't have `edition = \"2021\"` on a separate line",
+                "{} doesn't have `edition = \"2021\"` or `edition = \"2024\"` on a separate line",
                 file.display()
             );
         }
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index 3e2a4773703..f36345670e3 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -5,10 +5,12 @@
 //@ [arm64ec] compile-flags: --target arm64ec-pc-windows-msvc
 //@ [arm64ec] needs-llvm-components: aarch64
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16, f128)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
+// FIXME(f16_f128): Only needed for FIXME in check! and check_reg!
+#![feature(auto_traits)]
 
 #[rustc_builtin_macro]
 macro_rules! asm {
@@ -39,6 +41,8 @@ pub struct i32x2(i32, i32);
 #[repr(simd)]
 pub struct i64x1(i64);
 #[repr(simd)]
+pub struct f16x4(f16, f16, f16, f16);
+#[repr(simd)]
 pub struct f32x2(f32, f32);
 #[repr(simd)]
 pub struct f64x1(f64);
@@ -51,30 +55,42 @@ pub struct i32x4(i32, i32, i32, i32);
 #[repr(simd)]
 pub struct i64x2(i64, i64);
 #[repr(simd)]
+pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16);
+#[repr(simd)]
 pub struct f32x4(f32, f32, f32, f32);
 #[repr(simd)]
 pub struct f64x2(f64, f64);
 
 impl Copy for i8 {}
 impl Copy for i16 {}
+impl Copy for f16 {}
 impl Copy for i32 {}
 impl Copy for f32 {}
 impl Copy for i64 {}
 impl Copy for f64 {}
+impl Copy for f128 {}
 impl Copy for ptr {}
 impl Copy for i8x8 {}
 impl Copy for i16x4 {}
 impl Copy for i32x2 {}
 impl Copy for i64x1 {}
+impl Copy for f16x4 {}
 impl Copy for f32x2 {}
 impl Copy for f64x1 {}
 impl Copy for i8x16 {}
 impl Copy for i16x8 {}
 impl Copy for i32x4 {}
 impl Copy for i64x2 {}
+impl Copy for f16x8 {}
 impl Copy for f32x4 {}
 impl Copy for f64x2 {}
 
+// FIXME(f16_f128): Only needed for FIXME in check! and check_reg!
+#[lang = "freeze"]
+unsafe auto trait Freeze {}
+#[lang = "unpin"]
+auto trait Unpin {}
+
 extern "C" {
     fn extern_func();
     static extern_static: u8;
@@ -111,38 +127,44 @@ pub unsafe fn issue_75761() {
 
 macro_rules! check {
     ($func:ident $ty:ident $class:ident $mov:literal $modifier:literal) => {
+        // FIXME(f16_f128): Change back to `$func(x: $ty) -> $ty` once arm64ec can pass and return
+        // `f16` and `f128` without LLVM erroring.
+        // LLVM issue: <https://github.com/llvm/llvm-project/issues/94434>
         #[no_mangle]
-        pub unsafe fn $func(x: $ty) -> $ty {
+        pub unsafe fn $func(inp: &$ty, out: &mut $ty) {
             // Hack to avoid function merging
             extern "Rust" {
                 fn dont_merge(s: &str);
             }
             dont_merge(stringify!($func));
 
+            let x = *inp;
             let y;
             asm!(
                 concat!($mov, " {:", $modifier, "}, {:", $modifier, "}"),
                 out($class) y,
                 in($class) x
             );
-            y
+            *out = y;
         }
     };
 }
 
 macro_rules! check_reg {
     ($func:ident $ty:ident $reg:tt $mov:literal) => {
+        // FIXME(f16_f128): See FIXME in `check!`
         #[no_mangle]
-        pub unsafe fn $func(x: $ty) -> $ty {
+        pub unsafe fn $func(inp: &$ty, out: &mut $ty) {
             // Hack to avoid function merging
             extern "Rust" {
                 fn dont_merge(s: &str);
             }
             dont_merge(stringify!($func));
 
+            let x = *inp;
             let y;
             asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
-            y
+            *out = y;
         }
     };
 }
@@ -159,6 +181,12 @@ check!(reg_i8 i8 reg "mov" "");
 // CHECK: //NO_APP
 check!(reg_i16 i16 reg "mov" "");
 
+// CHECK-LABEL: {{("#)?}}reg_f16{{"?}}
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check!(reg_f16 f16 reg "mov" "");
+
 // CHECK-LABEL: {{("#)?}}reg_i32{{"?}}
 // CHECK: //APP
 // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
@@ -201,6 +229,12 @@ check!(vreg_i8 i8 vreg "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_i16 i16 vreg "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_f16{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_f16 f16 vreg "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_i32{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -225,6 +259,12 @@ check!(vreg_i64 i64 vreg "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_f64 f64 vreg "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_f128{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_f128 f128 vreg "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_ptr{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -255,6 +295,12 @@ check!(vreg_i32x2 i32x2 vreg "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_i64x1 i64x1 vreg "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_f16x4{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_f16x4 f16x4 vreg "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_f32x2{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -291,6 +337,12 @@ check!(vreg_i32x4 i32x4 vreg "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_i64x2 i64x2 vreg "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_f16x8{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_f16x8 f16x8 vreg "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_f32x4{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -315,6 +367,12 @@ check!(vreg_low16_i8 i8 vreg_low16 "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_low16_i16 i16 vreg_low16 "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_low16_f16{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_low16_f16 f16 vreg_low16 "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_low16_f32{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -333,6 +391,12 @@ check!(vreg_low16_i64 i64 vreg_low16 "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_low16_f64 f64 vreg_low16 "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_low16_f128{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_low16_f128 f128 vreg_low16 "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_low16_ptr{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -363,6 +427,12 @@ check!(vreg_low16_i32x2 i32x2 vreg_low16 "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_low16_i64x1 i64x1 vreg_low16 "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_low16_f16x4{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_low16_f16x4 f16x4 vreg_low16 "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_low16_f32x2{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -399,6 +469,12 @@ check!(vreg_low16_i32x4 i32x4 vreg_low16 "fmov" "s");
 // CHECK: //NO_APP
 check!(vreg_low16_i64x2 i64x2 vreg_low16 "fmov" "s");
 
+// CHECK-LABEL: {{("#)?}}vreg_low16_f16x8{{"?}}
+// CHECK: //APP
+// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: //NO_APP
+check!(vreg_low16_f16x8 f16x8 vreg_low16 "fmov" "s");
+
 // CHECK-LABEL: {{("#)?}}vreg_low16_f32x4{{"?}}
 // CHECK: //APP
 // CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
@@ -423,6 +499,12 @@ check_reg!(x0_i8 i8 "x0" "mov");
 // CHECK: //NO_APP
 check_reg!(x0_i16 i16 "x0" "mov");
 
+// CHECK-LABEL: {{("#)?}}x0_f16{{"?}}
+// CHECK: //APP
+// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
+// CHECK: //NO_APP
+check_reg!(x0_f16 f16 "x0" "mov");
+
 // CHECK-LABEL: {{("#)?}}x0_i32{{"?}}
 // CHECK: //APP
 // CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
@@ -465,6 +547,12 @@ check_reg!(v0_i8 i8 "s0" "fmov");
 // CHECK: //NO_APP
 check_reg!(v0_i16 i16 "s0" "fmov");
 
+// CHECK-LABEL: {{("#)?}}v0_f16{{"?}}
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f16 f16 "s0" "fmov");
+
 // CHECK-LABEL: {{("#)?}}v0_i32{{"?}}
 // CHECK: //APP
 // CHECK: fmov s0, s0
@@ -489,6 +577,12 @@ check_reg!(v0_i64 i64 "s0" "fmov");
 // CHECK: //NO_APP
 check_reg!(v0_f64 f64 "s0" "fmov");
 
+// CHECK-LABEL: {{("#)?}}v0_f128{{"?}}
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f128 f128 "s0" "fmov");
+
 // CHECK-LABEL: {{("#)?}}v0_ptr{{"?}}
 // CHECK: //APP
 // CHECK: fmov s0, s0
@@ -519,6 +613,12 @@ check_reg!(v0_i32x2 i32x2 "s0" "fmov");
 // CHECK: //NO_APP
 check_reg!(v0_i64x1 i64x1 "s0" "fmov");
 
+// CHECK-LABEL: {{("#)?}}v0_f16x4{{"?}}
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f16x4 f16x4 "s0" "fmov");
+
 // CHECK-LABEL: {{("#)?}}v0_f32x2{{"?}}
 // CHECK: //APP
 // CHECK: fmov s0, s0
@@ -555,6 +655,12 @@ check_reg!(v0_i32x4 i32x4 "s0" "fmov");
 // CHECK: //NO_APP
 check_reg!(v0_i64x2 i64x2 "s0" "fmov");
 
+// CHECK-LABEL: {{("#)?}}v0_f16x8{{"?}}
+// CHECK: //APP
+// CHECK: fmov s0, s0
+// CHECK: //NO_APP
+check_reg!(v0_f16x8 f16x8 "s0" "fmov");
+
 // CHECK-LABEL: {{("#)?}}v0_f32x4{{"?}}
 // CHECK: //APP
 // CHECK: fmov s0, s0
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index c3a083321e2..6f0a200a08c 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -66,6 +66,9 @@
 //@ revisions: aarch64_unknown_teeos
 //@ [aarch64_unknown_teeos] compile-flags: --target aarch64-unknown-teeos
 //@ [aarch64_unknown_teeos] needs-llvm-components: aarch64
+//@ revisions: aarch64_unknown_trusty
+//@ [aarch64_unknown_trusty] compile-flags: --target aarch64-unknown-trusty
+//@ [aarch64_unknown_trusty] needs-llvm-components: aarch64
 //@ revisions: aarch64_wrs_vxworks
 //@ [aarch64_wrs_vxworks] compile-flags: --target aarch64-wrs-vxworks
 //@ [aarch64_wrs_vxworks] needs-llvm-components: aarch64
@@ -153,6 +156,9 @@
 //@ revisions: armv7_unknown_netbsd_eabihf
 //@ [armv7_unknown_netbsd_eabihf] compile-flags: --target armv7-unknown-netbsd-eabihf
 //@ [armv7_unknown_netbsd_eabihf] needs-llvm-components: arm
+//@ revisions: armv7_unknown_trusty
+//@ [armv7_unknown_trusty] compile-flags: --target armv7-unknown-trusty
+//@ [armv7_unknown_trusty] needs-llvm-components: arm
 //@ revisions: armv7_wrs_vxworks_eabihf
 //@ [armv7_wrs_vxworks_eabihf] compile-flags: --target armv7-wrs-vxworks-eabihf
 //@ [armv7_wrs_vxworks_eabihf] needs-llvm-components: arm
diff --git a/tests/crashes/129205.rs b/tests/crashes/129205.rs
deleted file mode 100644
index f328fca247a..00000000000
--- a/tests/crashes/129205.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: rust-lang/rust#129205
-
-fn x<T: Copy>() {
-    T::try_from();
-}
diff --git a/tests/crashes/129216.rs b/tests/crashes/129216.rs
deleted file mode 100644
index 0ad6bc5c71b..00000000000
--- a/tests/crashes/129216.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: rust-lang/rust#129216
-//@ only-linux
-
-trait Mirror {
-    type Assoc;
-}
-
-struct Foo;
-
-fn main() {
-    <Foo as Mirror>::Assoc::new();
-}
diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir
index e8ad5cd8d16..293aa37944d 100644
--- a/tests/mir-opt/issue_72181_1.main.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.main.built.after.mir
@@ -19,7 +19,7 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = ();
-        _2 = transmute::<(), Void>(move _3) -> bb4;
+        _2 = std::intrinsics::transmute::<(), Void>(move _3) -> bb4;
     }
 
     bb1: {
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
index 71e84fdd881..b1104c70e46 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<std::cmp::Ordering, i8>(move _2) -> [return: bb1, unwind unreachable];
+-         _0 = std::intrinsics::transmute::<std::cmp::Ordering, i8>(move _2) -> [return: bb1, unwind unreachable];
 +         _0 = move _2 as i8 (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
index 71e84fdd881..b1104c70e46 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<std::cmp::Ordering, i8>(move _2) -> [return: bb1, unwind unreachable];
+-         _0 = std::intrinsics::transmute::<std::cmp::Ordering, i8>(move _2) -> [return: bb1, unwind unreachable];
 +         _0 = move _2 as i8 (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
index 37232b826c1..169e48a31dd 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable];
+-         _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable];
 +         _0 = move _2 as *const T (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
index 37232b826c1..169e48a31dd 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable];
+-         _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable];
 +         _0 = move _2 as *const T (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
index 8ac70f99ad2..7098b4d3168 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -11,7 +11,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
index 8ac70f99ad2..7098b4d3168 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -11,7 +11,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
index c2c4ec0003c..06225fffd7c 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as &mut Never (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
index c2c4ec0003c..06225fffd7c 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as &mut Never (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
index 1b516a1f53b..dd6ab3a9c97 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as &Never (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
index 1b516a1f53b..dd6ab3a9c97 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -10,7 +10,7 @@
   
       bb0: {
           StorageLive(_1);
--         _1 = transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable];
+-         _1 = std::intrinsics::transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable];
 +         _1 = const 1_usize as &Never (Transmute);
 +         goto -> bb1;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
index eab969e9fe5..6571f3d9db8 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<(), Never>(move _2) -> unwind unreachable;
+-         _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable;
 +         _0 = move _2 as Never (Transmute);
 +         unreachable;
       }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
index eab969e9fe5..6571f3d9db8 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -9,7 +9,7 @@
       bb0: {
           StorageLive(_2);
           _2 = copy _1;
--         _0 = transmute::<(), Never>(move _2) -> unwind unreachable;
+-         _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable;
 +         _0 = move _2 as Never (Transmute);
 +         unreachable;
       }
diff --git a/tests/run-make/rust-lld-compress-debug-sections/main.rs b/tests/run-make/compressed-debuginfo-zstd/main.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/rust-lld-compress-debug-sections/main.rs
+++ b/tests/run-make/compressed-debuginfo-zstd/main.rs
diff --git a/tests/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs
new file mode 100644
index 00000000000..8356373e949
--- /dev/null
+++ b/tests/run-make/compressed-debuginfo-zstd/rmake.rs
@@ -0,0 +1,42 @@
+// Checks debuginfo compression both for the always-enabled zlib, and when the optional zstd is
+// enabled:
+// - via rustc's `debuginfo-compression`,
+// - and via rust-lld's `compress-debug-sections`
+
+//@ needs-llvm-zstd: we want LLVM/LLD to be built with zstd support
+//@ needs-rust-lld: the system linker will most likely not support zstd
+//@ only-linux
+//@ ignore-cross-compile
+
+use run_make_support::{llvm_readobj, run_in_tmpdir, Rustc};
+
+fn check_compression(compression: &str, to_find: &str) {
+    // check compressed debug sections via rustc flag
+    prepare_and_check(to_find, |rustc| {
+        rustc.arg(&format!("-Zdebuginfo-compression={compression}"))
+    });
+
+    // check compressed debug sections via rust-lld flag
+    prepare_and_check(to_find, |rustc| {
+        rustc.link_arg(&format!("-Wl,--compress-debug-sections={compression}"))
+    });
+}
+
+fn prepare_and_check<F: FnOnce(&mut Rustc) -> &mut Rustc>(to_find: &str, prepare_rustc: F) {
+    run_in_tmpdir(|| {
+        let mut rustc = Rustc::new();
+        rustc
+            .arg("-Zlinker-features=+lld")
+            .arg("-Clink-self-contained=+linker")
+            .arg("-Zunstable-options")
+            .arg("-Cdebuginfo=full")
+            .input("main.rs");
+        prepare_rustc(&mut rustc).run();
+        llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find);
+    });
+}
+
+fn main() {
+    check_compression("zlib", "ZLIB");
+    check_compression("zstd", "ZSTD");
+}
diff --git a/tests/run-make/embed-source-dwarf/main.rs b/tests/run-make/embed-source-dwarf/main.rs
new file mode 100644
index 00000000000..c80af84f414
--- /dev/null
+++ b/tests/run-make/embed-source-dwarf/main.rs
@@ -0,0 +1,2 @@
+// hello
+fn main() {}
diff --git a/tests/run-make/embed-source-dwarf/rmake.rs b/tests/run-make/embed-source-dwarf/rmake.rs
new file mode 100644
index 00000000000..06d550121b0
--- /dev/null
+++ b/tests/run-make/embed-source-dwarf/rmake.rs
@@ -0,0 +1,70 @@
+//@ ignore-windows
+//@ ignore-apple
+
+// LLVM 17's embed-source implementation requires that source code is attached
+// for all files in the output DWARF debug info. This restriction was lifted in
+// LLVM 18 (87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d).
+//@ min-llvm-version: 18
+
+// This test should be replaced with one in tests/debuginfo once we can easily
+// tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB
+// like setting an invalid source map path don't appear to work, maybe this'll
+// become easier once GDB supports DWARFv6?
+
+use std::collections::HashMap;
+use std::path::PathBuf;
+use std::rc::Rc;
+
+use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian};
+use object::{Object, ObjectSection};
+use run_make_support::{gimli, object, rfs, rustc};
+
+fn main() {
+    let output = PathBuf::from("embed-source-main");
+    rustc()
+        .input("main.rs")
+        .output(&output)
+        .arg("-g")
+        .arg("-Zembed-source=yes")
+        .arg("-Zdwarf-version=5")
+        .run();
+    let output = rfs::read(output);
+    let obj = object::File::parse(output.as_slice()).unwrap();
+    let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big };
+    let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> {
+        let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap());
+        Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian))
+    })
+    .unwrap();
+
+    let mut sources = HashMap::new();
+
+    let mut iter = dwarf.units();
+    while let Some(header) = iter.next().unwrap() {
+        let unit = dwarf.unit(header).unwrap();
+        let unit = unit.unit_ref(&dwarf);
+
+        if let Some(program) = &unit.line_program {
+            let header = program.header();
+            for file in header.file_names() {
+                if let Some(source) = file.source() {
+                    let path = unit
+                        .attr_string(file.path_name())
+                        .unwrap()
+                        .to_string_lossy()
+                        .unwrap()
+                        .to_string();
+                    let source =
+                        unit.attr_string(source).unwrap().to_string_lossy().unwrap().to_string();
+                    if !source.is_empty() {
+                        sources.insert(path, source);
+                    }
+                }
+            }
+        }
+    }
+
+    dbg!(&sources);
+    assert_eq!(sources.len(), 1);
+    assert_eq!(sources.get("main.rs").unwrap(), "// hello\nfn main() {}\n");
+}
diff --git a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs b/tests/run-make/rust-lld-compress-debug-sections/rmake.rs
deleted file mode 100644
index ea4997fab80..00000000000
--- a/tests/run-make/rust-lld-compress-debug-sections/rmake.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Checks the `compress-debug-sections` option on rust-lld.
-
-//@ needs-rust-lld
-//@ only-linux
-//@ ignore-cross-compile
-
-// FIXME: This test isn't comprehensive and isn't covering all possible combinations.
-
-use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc};
-
-fn check_compression(compression: &str, to_find: &str) {
-    run_in_tmpdir(|| {
-        let out = rustc()
-            .arg("-Zlinker-features=+lld")
-            .arg("-Clink-self-contained=+linker")
-            .arg("-Zunstable-options")
-            .arg("-Cdebuginfo=full")
-            .link_arg(&format!("-Wl,--compress-debug-sections={compression}"))
-            .input("main.rs")
-            .run_unchecked();
-        let stderr = out.stderr_utf8();
-        if stderr.is_empty() {
-            llvm_readobj().arg("-t").arg("main").run().assert_stdout_contains(to_find);
-        } else {
-            assert_contains(
-                stderr,
-                format!(
-                    "LLVM was not built with LLVM_ENABLE_{to_find} \
-                     or did not find {compression} at build time"
-                ),
-            );
-        }
-    });
-}
-
-fn main() {
-    check_compression("zlib", "ZLIB");
-    check_compression("zstd", "ZSTD");
-}
diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors.no_type_anchor2.html
index 71e93990e29..9127104ded4 100644
--- a/tests/rustdoc/anchors.no_type_anchor2.html
+++ b/tests/rustdoc/anchors.no_type_anchor2.html
@@ -1 +1 @@
-<section id="associatedtype.Y" class="associatedtype"><h4 class="code-header">pub type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
+<section id="associatedtype.Y" class="associatedtype"><a class="src rightside" href="../src/foo/anchors.rs.html#45">source</a><h4 class="code-header">pub type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/assoc-type-source-link.rs b/tests/rustdoc/assoc-type-source-link.rs
new file mode 100644
index 00000000000..34b156b9649
--- /dev/null
+++ b/tests/rustdoc/assoc-type-source-link.rs
@@ -0,0 +1,26 @@
+// This test ensures that the source links are generated for impl associated types.
+
+#![crate_name = "foo"]
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+//@ has 'foo/struct.Bar.html'
+pub struct Bar;
+
+impl Bar {
+    //@ has - '//*[@id="implementations-list"]//*[@id="associatedtype.Y"]/a' 'source'
+    //@ has - '//*[@id="implementations-list"]//*[@id="associatedtype.Y"]/a/@href' \
+    // '../src/foo/assoc-type-source-link.rs.html#14'
+    pub type Y = u8;
+}
+
+pub trait Foo {
+    type Z;
+}
+
+impl Foo for Bar {
+    //@ has - '//*[@id="trait-implementations-list"]//*[@id="associatedtype.Z"]/a' 'source'
+    //@ has - '//*[@id="trait-implementations-list"]//*[@id="associatedtype.Z"]/a/@href' \
+    // '../src/foo/assoc-type-source-link.rs.html#25'
+    type Z = u8;
+}
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index ca78604edd8..d37e793d989 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -40,9 +40,10 @@
 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64] needs-llvm-components: loongarch
 //@[loongarch64] min-llvm-version: 18
-//@ revisions: wasm
-//@[wasm] compile-flags: --target wasm32-unknown-unknown
-//@[wasm] needs-llvm-components: webassembly
+//FIXME: wasm is disabled due to <https://github.com/rust-lang/rust/issues/115666>.
+//FIXME @ revisions: wasm
+//FIXME @[wasm] compile-flags: --target wasm32-unknown-unknown
+//FIXME @[wasm] needs-llvm-components: webassembly
 //@ revisions: wasip1
 //@[wasip1] compile-flags: --target wasm32-wasip1
 //@[wasip1] needs-llvm-components: webassembly
diff --git a/tests/ui/asm/aarch64/type-check-3.stderr b/tests/ui/asm/aarch64/type-check-3.stderr
index 9e37bb4c203..9d84d2666b3 100644
--- a/tests/ui/asm/aarch64/type-check-3.stderr
+++ b/tests/ui/asm/aarch64/type-check-3.stderr
@@ -95,7 +95,7 @@ error: type `i128` cannot be used with this register class
 LL |         asm!("{}", in(reg) 0i128);
    |                            ^^^^^
    |
-   = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
+   = note: register class `reg` supports these types: i8, i16, i32, i64, f16, f32, f64
 
 error: type `float64x2_t` cannot be used with this register class
   --> $DIR/type-check-3.rs:75:28
@@ -103,7 +103,7 @@ error: type `float64x2_t` cannot be used with this register class
 LL |         asm!("{}", in(reg) f64x2);
    |                            ^^^^^
    |
-   = note: register class `reg` supports these types: i8, i16, i32, i64, f32, f64
+   = note: register class `reg` supports these types: i8, i16, i32, i64, f16, f32, f64
 
 error: type `Simd256bit` cannot be used with this register class
   --> $DIR/type-check-3.rs:77:29
@@ -111,7 +111,7 @@ error: type `Simd256bit` cannot be used with this register class
 LL |         asm!("{}", in(vreg) f64x4);
    |                             ^^^^^
    |
-   = note: register class `vreg` supports these types: i8, i16, i32, i64, f32, f64, i8x8, i16x4, i32x2, i64x1, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2
+   = note: register class `vreg` supports these types: i8, i16, i32, i64, f16, f32, f64, f128, i8x8, i16x4, i32x2, i64x1, f16x4, f32x2, f64x1, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2
 
 error: incompatible types for asm inout argument
   --> $DIR/type-check-3.rs:88:33
diff --git a/tests/ui/asm/aarch64/type-f16.rs b/tests/ui/asm/aarch64/type-f16.rs
new file mode 100644
index 00000000000..e62d8130c93
--- /dev/null
+++ b/tests/ui/asm/aarch64/type-f16.rs
@@ -0,0 +1,25 @@
+//@ only-aarch64
+//@ run-pass
+//@ needs-asm-support
+
+#![feature(f16)]
+
+use std::arch::asm;
+
+#[inline(never)]
+pub fn f32_to_f16_asm(a: f32) -> f16 {
+    let ret: f16;
+    unsafe {
+        asm!(
+            "fcvt {ret:h}, {a:s}",
+            a = in(vreg) a,
+            ret = lateout(vreg) ret,
+            options(nomem, nostack),
+        );
+    }
+    ret
+}
+
+fn main() {
+    assert_eq!(f32_to_f16_asm(1.0 as f32), 1.0);
+}
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index d780e04e729..103a7564a0f 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -201,7 +201,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`, `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`, `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`
@@ -285,7 +285,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`, `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`, `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: 29 warnings emitted
diff --git a/tests/ui/closures/coerce-unsafe-to-closure.stderr b/tests/ui/closures/coerce-unsafe-to-closure.stderr
index cb718ca160f..2538fc0361c 100644
--- a/tests/ui/closures/coerce-unsafe-to-closure.stderr
+++ b/tests/ui/closures/coerce-unsafe-to-closure.stderr
@@ -1,4 +1,4 @@
-error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
   --> $DIR/coerce-unsafe-to-closure.rs:2:44
    |
 LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
@@ -6,7 +6,7 @@ LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
    |                                        |
    |                                        required by a bound introduced by this call
    |
-   = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+   = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
    = note: unsafe function cannot be called generically without an unsafe block
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs
index 45e8ea570ed..3a526c54dc3 100644
--- a/tests/ui/consts/const-float-bits-conv.rs
+++ b/tests/ui/consts/const-float-bits-conv.rs
@@ -3,8 +3,9 @@
 
 #![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
+#![feature(f16)]
+#![feature(f128)]
 #![allow(unused_macro_rules)]
-
 // Don't promote
 const fn nop<T>(x: T) -> T { x }
 
@@ -28,6 +29,37 @@ fn has_broken_floats() -> bool {
     std::env::var("TARGET").is_ok_and(|v| v.contains("i586"))
 }
 
+#[cfg(target_arch = "x86_64")]
+fn f16(){
+    const_assert!((1f16).to_bits(), 0x3c00);
+    const_assert!(u16::from_be_bytes(1f16.to_be_bytes()), 0x3c00);
+    const_assert!((12.5f16).to_bits(), 0x4a40);
+    const_assert!(u16::from_le_bytes(12.5f16.to_le_bytes()), 0x4a40);
+    const_assert!((1337f16).to_bits(), 0x6539);
+    const_assert!(u16::from_ne_bytes(1337f16.to_ne_bytes()), 0x6539);
+    const_assert!((-14.25f16).to_bits(), 0xcb20);
+    const_assert!(f16::from_bits(0x3c00), 1.0);
+    const_assert!(f16::from_be_bytes(0x3c00u16.to_be_bytes()), 1.0);
+    const_assert!(f16::from_bits(0x4a40), 12.5);
+    const_assert!(f16::from_le_bytes(0x4a40u16.to_le_bytes()), 12.5);
+    const_assert!(f16::from_bits(0x5be0), 252.0);
+    const_assert!(f16::from_ne_bytes(0x5be0u16.to_ne_bytes()), 252.0);
+    const_assert!(f16::from_bits(0xcb20), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u16 = f16::NAN.to_bits() ^ 0x0155;
+    const SIGNALING_NAN: u16 = f16::NAN.to_bits() ^ 0x02AA;
+
+    const_assert!(f16::from_bits(QUIET_NAN).is_nan());
+    const_assert!(f16::from_bits(SIGNALING_NAN).is_nan());
+    const_assert!(f16::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        const_assert!(f16::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
 fn f32() {
     const_assert!((1f32).to_bits(), 0x3f800000);
     const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000);
@@ -88,7 +120,43 @@ fn f64() {
     }
 }
 
+#[cfg(target_arch = "x86_64")]
+fn f128() {
+    const_assert!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
+    const_assert!(u128::from_be_bytes(1f128.to_be_bytes()), 0x3fff0000000000000000000000000000);
+    const_assert!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
+    const_assert!(u128::from_le_bytes(12.5f128.to_le_bytes()), 0x40029000000000000000000000000000);
+    const_assert!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
+    const_assert!(u128::from_ne_bytes(1337f128.to_ne_bytes()), 0x40094e40000000000000000000000000);
+    const_assert!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
+    const_assert!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
+    const_assert!(f128::from_be_bytes(0x3fff0000000000000000000000000000u128.to_be_bytes()), 1.0);
+    const_assert!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
+    const_assert!(f128::from_le_bytes(0x40029000000000000000000000000000u128.to_le_bytes()), 12.5);
+    const_assert!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
+    assert_eq!(f128::from_ne_bytes(0x40094e40000000000000000000000000u128.to_ne_bytes()), 1337.0);
+    const_assert!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
+
+    // Check that NaNs roundtrip their bits regardless of signalingness
+    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
+    // NOTE: These names assume `f{BITS}::NAN` is a quiet NAN and IEEE754-2008's NaN rules apply!
+    const QUIET_NAN: u128 = f128::NAN.to_bits() | 0x0000_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA_AAAA;
+    const SIGNALING_NAN: u128 = f128::NAN.to_bits() ^ 0x0000_5555_5555_5555_5555_5555_5555_5555;
+
+    const_assert!(f128::from_bits(QUIET_NAN).is_nan());
+    const_assert!(f128::from_bits(SIGNALING_NAN).is_nan());
+    const_assert!(f128::from_bits(QUIET_NAN).to_bits(), QUIET_NAN);
+    if !has_broken_floats() {
+        const_assert!(f128::from_bits(SIGNALING_NAN).to_bits(), SIGNALING_NAN);
+    }
+}
+
 fn main() {
+    #[cfg(target_arch = "x86_64")]
+    {
+        f16();
+        f128();
+    }
     f32();
     f64();
 }
diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr
new file mode 100644
index 00000000000..6038c6d332f
--- /dev/null
+++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.not_allow.stderr
@@ -0,0 +1,12 @@
+error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
+  --> $DIR/precise-drop-allow-const-fn-unstable.rs:11:24
+   |
+LL | pub const fn unwrap<T>(this: Option<T>) -> T {
+   |                        ^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs
new file mode 100644
index 00000000000..56155e519dc
--- /dev/null
+++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs
@@ -0,0 +1,17 @@
+//@ revisions: allow not_allow
+//@ compile-flags: --crate-type=lib -Cinstrument-coverage  -Zno-profiler-runtime
+//@[allow] check-pass
+
+#![feature(staged_api, rustc_allow_const_fn_unstable)]
+#![stable(feature = "rust_test", since = "1.0.0")]
+
+#[stable(feature = "rust_test", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust_test", since = "1.0.0")]
+#[cfg_attr(allow, rustc_allow_const_fn_unstable(const_precise_live_drops))]
+pub const fn unwrap<T>(this: Option<T>) -> T {
+//[not_allow]~^ ERROR: cannot be evaluated
+    match this {
+        Some(x) => x,
+        None => panic!(),
+    }
+}
diff --git a/tests/ui/duplicate-label-E0381-issue-129274.rs b/tests/ui/duplicate-label-E0381-issue-129274.rs
new file mode 100644
index 00000000000..b2156e630c8
--- /dev/null
+++ b/tests/ui/duplicate-label-E0381-issue-129274.rs
@@ -0,0 +1,13 @@
+fn main() {
+    fn test() {
+        loop {
+            let blah: Option<String>;
+            if true {
+                blah = Some("".to_string());
+            }
+            if let Some(blah) = blah.as_ref() { //~ ERROR E0381
+            }
+        }
+    }
+    println!("{:?}", test())
+}
diff --git a/tests/ui/duplicate-label-E0381-issue-129274.stderr b/tests/ui/duplicate-label-E0381-issue-129274.stderr
new file mode 100644
index 00000000000..7f8bddb17c5
--- /dev/null
+++ b/tests/ui/duplicate-label-E0381-issue-129274.stderr
@@ -0,0 +1,15 @@
+error[E0381]: used binding `blah` is possibly-uninitialized
+  --> $DIR/duplicate-label-E0381-issue-129274.rs:8:33
+   |
+LL |             let blah: Option<String>;
+   |                 ---- binding declared here but left uninitialized
+LL |             if true {
+LL |                 blah = Some("".to_string());
+   |                 ---- binding initialized here in some conditions
+LL |             }
+LL |             if let Some(blah) = blah.as_ref() {
+   |                                 ^^^^ `blah` used here but it is possibly-uninitialized
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
index 6bca8ef12ec..89a3f3136c8 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
@@ -5,14 +5,17 @@
 
 fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x }
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 fn implicit(x: &i32) -> impl Sized + use<> { *x }
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 struct W;
 impl W {
     fn hello(&self, x: &i32) -> impl Sized + '_ + use<'_> { self }
     //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
+    //~| WARN this changes meaning in Rust 2024
 }
 
 trait Higher<'a> {
@@ -24,5 +27,6 @@ impl Higher<'_> for () {
 
 fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized + use<>> {}
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
index 5b6726b49e0..18c04f9f799 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
@@ -5,14 +5,17 @@
 
 fn named<'a>(x: &'a i32) -> impl Sized { *x }
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 fn implicit(x: &i32) -> impl Sized { *x }
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 struct W;
 impl W {
     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
     //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
+    //~| WARN this changes meaning in Rust 2024
 }
 
 trait Higher<'a> {
@@ -24,5 +27,6 @@ impl Higher<'_> for () {
 
 fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
index fec640aa83a..94dafb04d64 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
@@ -4,6 +4,8 @@ error: `impl Sized` will capture more lifetimes than possibly intended in editio
 LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
    |                             ^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
   --> $DIR/overcaptures-2024.rs:6:10
    |
@@ -21,13 +23,15 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x }
    |                                        +++++++
 
 error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:9:25
+  --> $DIR/overcaptures-2024.rs:10:25
    |
 LL | fn implicit(x: &i32) -> impl Sized { *x }
    |                         ^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:9:16
+  --> $DIR/overcaptures-2024.rs:10:16
    |
 LL | fn implicit(x: &i32) -> impl Sized { *x }
    |                ^
@@ -38,13 +42,15 @@ LL | fn implicit(x: &i32) -> impl Sized + use<> { *x }
    |                                    +++++++
 
 error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:14:33
+  --> $DIR/overcaptures-2024.rs:16:33
    |
 LL |     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
    |                                 ^^^^^^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:14:24
+  --> $DIR/overcaptures-2024.rs:16:24
    |
 LL |     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
    |                        ^
@@ -55,13 +61,15 @@ LL |     fn hello(&self, x: &i32) -> impl Sized + '_ + use<'_> { self }
    |                                                 +++++++++
 
 error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:25:47
+  --> $DIR/overcaptures-2024.rs:28:47
    |
 LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
    |                                               ^^^^^^^^^^
    |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:25:23
+  --> $DIR/overcaptures-2024.rs:28:23
    |
 LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
    |                       ^^
diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr
index 0119a1a6650..21b7bf4e1cb 100644
--- a/tests/ui/intrinsics/reify-intrinsic.stderr
+++ b/tests/ui/intrinsics/reify-intrinsic.stderr
@@ -7,9 +7,9 @@ LL |     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr
    |            expected due to this
    |
    = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize`
-                 found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+                 found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
 
-error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
+error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
   --> $DIR/reify-intrinsic.rs:11:13
    |
 LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr
index 09729eeba79..ef590d85aef 100644
--- a/tests/ui/lint/unused/lint-unused-variables.stderr
+++ b/tests/ui/lint/unused/lint-unused-variables.stderr
@@ -16,6 +16,12 @@ error: unused variable: `a`
 LL |         a: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_a`
 
+error: unused variable: `a`
+  --> $DIR/lint-unused-variables.rs:68:9
+   |
+LL |         a: i32,
+   |         ^ help: if this is intentional, prefix it with an underscore: `_a`
+
 error: unused variable: `b`
   --> $DIR/lint-unused-variables.rs:14:5
    |
@@ -58,12 +64,6 @@ error: unused variable: `b`
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
-error: unused variable: `a`
-  --> $DIR/lint-unused-variables.rs:68:9
-   |
-LL |         a: i32,
-   |         ^ help: if this is intentional, prefix it with an underscore: `_a`
-
 error: unused variable: `b`
   --> $DIR/lint-unused-variables.rs:74:9
    |
diff --git a/tests/ui/methods/missing-method-on-type-parameter.rs b/tests/ui/methods/missing-method-on-type-parameter.rs
new file mode 100644
index 00000000000..cbcbeea4d4c
--- /dev/null
+++ b/tests/ui/methods/missing-method-on-type-parameter.rs
@@ -0,0 +1,6 @@
+// Regression test for https://github.com/rust-lang/rust/issues/129205
+fn x<T: Copy>() {
+    T::try_from(); //~ ERROR E0599
+}
+
+fn main() {}
diff --git a/tests/ui/methods/missing-method-on-type-parameter.stderr b/tests/ui/methods/missing-method-on-type-parameter.stderr
new file mode 100644
index 00000000000..c53d7afe4e2
--- /dev/null
+++ b/tests/ui/methods/missing-method-on-type-parameter.stderr
@@ -0,0 +1,19 @@
+error[E0599]: no function or associated item named `try_from` found for type parameter `T` in the current scope
+  --> $DIR/missing-method-on-type-parameter.rs:3:8
+   |
+LL | fn x<T: Copy>() {
+   |      - function or associated item `try_from` not found for this type parameter
+LL |     T::try_from();
+   |        ^^^^^^^^ function or associated item not found in `T`
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: there is an associated function `from` with a similar name
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+help: trait `TryFrom` which provides `try_from` is implemented but not in scope; perhaps you want to import it
+   |
+LL + use std::convert::TryFrom;
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
index 16e1af46059..9b92166bcb7 100644
--- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -16,6 +16,12 @@ error: unused variable: `a`
 LL |         #[cfg(something)] a: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
 
+error: unused variable: `a`
+  --> $DIR/param-attrs-cfg.rs:107:27
+   |
+LL |         #[cfg(something)] a: i32,
+   |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
+
 error: unused variable: `b`
   --> $DIR/param-attrs-cfg.rs:30:23
    |
@@ -100,12 +106,6 @@ error: unused variable: `c`
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
-error: unused variable: `a`
-  --> $DIR/param-attrs-cfg.rs:107:27
-   |
-LL |         #[cfg(something)] a: i32,
-   |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
-
 error: unused variable: `b`
   --> $DIR/param-attrs-cfg.rs:113:27
    |
diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs
index 09926d95557..dc0d688284e 100644
--- a/tests/ui/simd/shuffle.rs
+++ b/tests/ui/simd/shuffle.rs
@@ -6,15 +6,20 @@
 #![allow(incomplete_features)]
 #![feature(adt_const_params)]
 
+use std::marker::ConstParamTy;
+
 extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, ConstParamTy, PartialEq, Eq)]
 #[repr(simd)]
 struct Simd<T, const N: usize>([T; N]);
 
-pub unsafe fn __shuffle_vector16<const IDX: [u32; 16], T, U>(x: T, y: T) -> U {
+unsafe fn __shuffle_vector16<const IDX: [u32; 16], T, U>(x: T, y: T) -> U {
+    simd_shuffle(x, y, IDX)
+}
+unsafe fn __shuffle_vector16_v2<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U {
     simd_shuffle(x, y, IDX)
 }
 
@@ -30,6 +35,17 @@ fn main() {
         let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
         assert_eq!(y.0, [1, 5]);
     }
+    // Test that we can also use a SIMD vector instead of a normal array for the shuffle.
+    const I1_SIMD: Simd<u32, 4> = Simd([0, 2, 4, 6]);
+    const I2_SIMD: Simd<u32, 2> = Simd([1, 5]);
+    unsafe {
+        let x: Simd<u8, 4> = simd_shuffle(a, b, I1_SIMD);
+        assert_eq!(x.0, [0, 2, 4, 6]);
+
+        let y: Simd<u8, 2> = simd_shuffle(a, b, I2_SIMD);
+        assert_eq!(y.0, [1, 5]);
+    }
+
     // Test that an indirection (via an unnamed constant)
     // through a const generic parameter also works.
     // See https://github.com/rust-lang/rust/issues/113500 for details.
@@ -42,4 +58,11 @@ fn main() {
             Simd<u8, 16>,
         >(a, b);
     }
+    unsafe {
+        __shuffle_vector16_v2::<
+            { Simd([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) },
+            Simd<u8, 16>,
+            Simd<u8, 16>,
+        >(a, b);
+    }
 }