about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/dependencies.yml7
-rw-r--r--.gitignore4
-rw-r--r--Cargo.lock31
-rw-r--r--RELEASES.md2
-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/ast.rs11
-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/asm.rs4
-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.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs12
-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.rs4
-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/places_conflict.rs2
-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.rs6
-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.rs33
-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.rs41
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs25
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs20
-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.rs122
-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/Cargo.toml4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs8
-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/codegen_attrs.rs125
-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/messages.ftl5
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs66
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs44
-rw-r--r--compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs10
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs8
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs9
-rw-r--r--compiler/rustc_const_eval/src/errors.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs45
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs32
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs21
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs67
-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.rs4
-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_errors/src/translation.rs2
-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/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs5
-rw-r--r--compiler/rustc_feature/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/unstable.rs7
-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.rs46
-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.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs7
-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.rs5
-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.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.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_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs65
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs31
-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/dump.rs32
-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.rs32
-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.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs42
-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.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs8
-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.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs4
-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/messages.ftl2
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs4
-rw-r--r--compiler/rustc_incremental/src/errors.rs89
-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.rs2
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/context.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/mod.rs10
-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/queries.rs2
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lexer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/messages.ftl5
-rw-r--r--compiler/rustc_lint/src/builtin.rs10
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs5
-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.rs17
-rw-r--r--compiler/rustc_lint/src/internal.rs152
-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.rs4
-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.rs60
-rw-r--r--compiler/rustc_lint/src/unused.rs4
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs37
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp11
-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/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs37
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs1
-rw-r--r--compiler/rustc_middle/src/arena.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs3
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs8
-rw-r--r--compiler/rustc_middle/src/middle/resolve_bound_vars.rs8
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs6
-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/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs41
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs32
-rw-r--r--compiler/rustc_middle/src/ty/context.rs36
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs16
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-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_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_mir_build/messages.ftl16
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs46
-rw-r--r--compiler/rustc_mir_build/src/errors.rs37
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs2
-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/coverage/mod.rs48
-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.rs5
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs38
-rw-r--r--compiler/rustc_parse/src/parser/item.rs4
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs5
-rw-r--r--compiler/rustc_passes/messages.ftl12
-rw-r--r--compiler/rustc_passes/src/check_attr.rs57
-rw-r--r--compiler/rustc_passes/src/errors.rs25
-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_resolve/src/def_collector.rs16
-rw-r--r--compiler/rustc_session/messages.ftl4
-rw-r--r--compiler/rustc_session/src/config.rs1
-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_span/src/hygiene.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs6
-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_target/src/target_features.rs78
-rw-r--r--compiler/rustc_trait_selection/messages.ftl2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs46
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs50
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs60
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs18
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/mod.rs13
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/query_context.rs6
-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/needs_drop.rs2
-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--compiler/rustc_type_ir/Cargo.toml4
-rw-r--r--compiler/rustc_type_ir/src/data_structures.rs15
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs2
-rw-r--r--compiler/rustc_type_ir/src/outlives.rs3
-rw-r--r--compiler/rustc_type_ir/src/search_graph/mod.rs2
-rw-r--r--compiler/stable_mir/src/mir/visit.rs16
-rw-r--r--config.example.toml1
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/src/boxed.rs98
-rw-r--r--library/alloc/src/rc.rs6
-rw-r--r--library/alloc/src/sync.rs10
-rw-r--r--library/alloc/src/vec/mod.rs3
-rw-r--r--library/alloc/tests/boxed.rs1
-rw-r--r--library/core/src/ascii/ascii_char.rs10
-rw-r--r--library/core/src/cell.rs3
-rw-r--r--library/core/src/cell/once.rs3
-rw-r--r--library/core/src/error.rs3
-rw-r--r--library/core/src/ffi/c_str.rs1
-rw-r--r--library/core/src/fmt/builders.rs224
-rw-r--r--library/core/src/intrinsics.rs4
-rw-r--r--library/core/src/intrinsics/simd.rs2
-rw-r--r--library/core/src/iter/traits/accum.rs4
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--library/core/src/mem/manually_drop.rs1
-rw-r--r--library/core/src/mem/maybe_uninit.rs1
-rw-r--r--library/core/src/mem/mod.rs2
-rw-r--r--library/core/src/mem/transmutability.rs370
-rw-r--r--library/core/src/num/f128.rs30
-rw-r--r--library/core/src/num/f16.rs56
-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.rs83
-rw-r--r--library/core/src/num/uint_macros.rs56
-rw-r--r--library/core/src/panic/location.rs1
-rw-r--r--library/core/src/pin.rs141
-rw-r--r--library/core/src/primitive_docs.rs92
-rw-r--r--library/core/src/ptr/alignment.rs2
-rw-r--r--library/core/src/ptr/const_ptr.rs54
-rw-r--r--library/core/src/ptr/mod.rs65
-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/slice/mod.rs4
-rw-r--r--library/core/src/slice/sort/shared/smallsort.rs3
-rw-r--r--library/core/src/str/iter.rs15
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/core/src/tuple.rs36
-rw-r--r--library/core/src/ub_checks.rs2
-rw-r--r--library/core/tests/fmt/builders.rs386
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/num/float_iter_sum_identity.rs27
-rw-r--r--library/core/tests/num/int_macros.rs759
-rw-r--r--library/core/tests/num/mod.rs3
-rw-r--r--library/core/tests/num/uint_macros.rs543
-rw-r--r--library/profiler_builtins/build.rs16
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/build.rs16
-rw-r--r--library/std/src/f128.rs10
-rw-r--r--library/std/src/f16.rs10
-rw-r--r--library/std/src/f32.rs10
-rw-r--r--library/std/src/f64.rs10
-rw-r--r--library/std/src/fs.rs2
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/wasi/fs.rs1
-rw-r--r--library/std/src/os/wasi/mod.rs2
-rw-r--r--library/std/src/os/wasip2/mod.rs1
-rw-r--r--library/std/src/panicking.rs2
-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/fs.rs23
-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/fs.rs49
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/thread.rs30
-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/args.rs2
-rw-r--r--library/std/src/sys/pal/wasi/env.rs2
-rw-r--r--library/std/src/sys/pal/wasi/fd.rs2
-rw-r--r--library/std/src/sys/pal/wasi/fs.rs22
-rw-r--r--library/std/src/sys/pal/wasi/helpers.rs2
-rw-r--r--library/std/src/sys/pal/wasi/io.rs2
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasi/net.rs2
-rw-r--r--library/std/src/sys/pal/wasi/os.rs2
-rw-r--r--library/std/src/sys/pal/wasi/stdio.rs2
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs18
-rw-r--r--library/std/src/sys/pal/wasi/time.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/fs.rs4
-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--library/std/src/sys_common/fs.rs21
-rw-r--r--library/std/src/sys_common/mod.rs8
-rw-r--r--library/std/tests/run-time-detect.rs34
-rw-r--r--src/bootstrap/bootstrap.py37
-rw-r--r--src/bootstrap/src/bin/rustdoc.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs44
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs37
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs19
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs2
-rw-r--r--src/bootstrap/src/core/builder.rs13
-rw-r--r--src/bootstrap/src/core/config/config.rs164
-rw-r--r--src/bootstrap/src/core/download.rs26
-rw-r--r--src/bootstrap/src/lib.rs117
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-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
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh4
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/platform-support.md4
-rw-r--r--src/doc/rustc/src/platform-support/trusty.md51
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md197
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md14
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip1.md6
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip2.md6
-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/doc/unstable-book/src/language-features/struct-target-features.md7
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/formats/item_type.rs3
-rw-r--r--src/librustdoc/html/format.rs114
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/html/render/search_index.rs36
-rw-r--r--src/librustdoc/html/render/write_shared.rs18
-rw-r--r--src/librustdoc/html/render/write_shared/tests.rs6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css13
-rw-r--r--src/librustdoc/html/static/js/search.js25
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs6
-rw-r--r--src/librustdoc/passes/strip_hidden.rs7
m---------src/llvm-project0
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.cargo/config.toml6
-rw-r--r--src/tools/clippy/.github/deploy.sh1
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml5
-rw-r--r--src/tools/clippy/CHANGELOG.md1
-rw-r--r--src/tools/clippy/Cargo.toml4
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md2
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md8
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs23
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs17
-rw-r--r--src/tools/clippy/clippy_dev/src/main.rs1
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_lints/src/absolute_paths.rs95
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cfg_not_test.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/collapsible_if.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/collection_is_never_read.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/create_dir.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/markdown.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs122
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs91
-rw-r--r--src/tools/clippy/clippy_lints/src/else_if_without_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_enum.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/float_literal.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/from_str_radix_10.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs91
-rw-r--r--src/tools/clippy/clippy_lints/src/if_not_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_return.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/indexing_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/infinite_iter.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/int_plus_one.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/item_name_repetitions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_statements.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_test_module.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_frames.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs48
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_representation.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_hash_one.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_range_patterns.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/mutex_atomic.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_continue.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_if.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs47
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/needless_bitwise_bool.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/reference.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/regex.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_unit.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs1078
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/visibility.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs8
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs38
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs22
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs21
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs101
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs25
-rw-r--r--src/tools/clippy/declare_clippy_lint/src/lib.rs25
-rw-r--r--src/tools/clippy/lintcheck/src/json.rs39
-rw-r--r--src/tools/clippy/lintcheck/src/output.rs14
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs385
-rw-r--r--src/tools/clippy/tests/config-metadata.rs78
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr45
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr80
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr71
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr98
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs178
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml0
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs15
-rw-r--r--src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr16
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.fixed20
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.rs20
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr2
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr26
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.fixed11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.stderr2
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs17
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr10
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed13
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs13
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr18
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.rs8
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.stderr16
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed12
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs12
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.stderr16
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.stderr26
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.stderr16
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed21
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs21
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr4
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr4
-rw-r--r--src/tools/clippy/tests/ui/string_slice.rs5
-rw-r--r--src/tools/clippy/tests/ui/string_slice.stderr14
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed9
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs8
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr20
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs53
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr566
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr35
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/index.html393
-rw-r--r--src/tools/clippy/util/gh-pages/script.js100
-rw-r--r--src/tools/clippy/util/gh-pages/style.css398
-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/linkchecker/main.rs6
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs104
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs15
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs19
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/concurrency/weak_memory.rs164
-rw-r--r--src/tools/miri/src/machine.rs46
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs16
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs6
-rw-r--r--src/tools/miri/src/shims/x86/sha.rs221
-rw-r--r--src/tools/miri/test_dependencies/Cargo.lock4
-rw-r--r--src/tools/miri/tests/fail/alloc/global_system_mixup.rs8
-rw-r--r--src/tools/miri/tests/fail/alloc/global_system_mixup.stderr6
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs19
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr15
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr36
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/bad_unwind.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.stderr2
-rw-r--r--src/tools/miri/tests/fail/terminate-terminator.stderr2
-rw-r--r--src/tools/miri/tests/fail/unwind-action-terminate.stderr2
-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/panic/alloc_error_handler_hook.stderr2
-rw-r--r--src/tools/miri/tests/panic/alloc_error_handler_panic.stderr2
-rw-r--r--src/tools/miri/tests/panic/div-by-zero-2.stderr2
-rw-r--r--src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr2
-rw-r--r--src/tools/miri/tests/panic/oob_subslice.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-lsh-neg.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-rsh-1.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-rsh-2.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic2.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic3.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic4.stderr2
-rw-r--r--src/tools/miri/tests/panic/target_feature_wasm.rs (renamed from src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs)4
-rw-r--r--src/tools/miri/tests/panic/transmute_fat2.stderr2
-rw-r--r--src/tools/miri/tests/panic/unsupported_foreign_function.stderr2
-rw-r--r--src/tools/miri/tests/panic/unsupported_syscall.stderr2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-epoll.rs28
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.stderr2
-rw-r--r--src/tools/miri/tests/pass/panic/concurrent-panic.stderr2
-rw-r--r--src/tools/miri/tests/pass/panic/nested_panic_caught.stderr2
-rw-r--r--src/tools/miri/tests/pass/panic/thread_panic.stderr2
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs270
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs19
-rw-r--r--src/tools/run-make-support/Cargo.toml1
-rw-r--r--src/tools/run-make-support/src/env.rs8
-rw-r--r--src/tools/run-make-support/src/lib.rs3
-rw-r--r--src/tools/run-make-support/src/path_helpers.rs1
-rw-r--r--src/tools/run-make-support/src/run.rs2
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt2
-rw-r--r--src/tools/tidy/src/edition.rs10
-rw-r--r--tests/assembly/asm/aarch64-types.rs116
-rw-r--r--tests/assembly/struct-target-features.rs37
-rw-r--r--tests/assembly/targets/targets-elf.rs6
-rw-r--r--tests/assembly/x86_64-cmp.rs42
-rw-r--r--tests/codegen/integer-cmp.rs21
-rw-r--r--tests/codegen/naked-fn/aligned.rs20
-rw-r--r--tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs10
-rw-r--r--tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs21
-rw-r--r--tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs21
-rw-r--r--tests/codegen/tied-features-strength.rs14
-rw-r--r--tests/crashes/123693.rs4
-rw-r--r--tests/crashes/124207.rs2
-rw-r--r--tests/crashes/125881.rs2
-rw-r--r--tests/crashes/126267.rs4
-rw-r--r--tests/crashes/126377.rs4
-rw-r--r--tests/crashes/126966.rs4
-rw-r--r--tests/crashes/127972.rs2
-rw-r--r--tests/crashes/128016.rs10
-rw-r--r--tests/crashes/129205.rs5
-rw-r--r--tests/crashes/129216.rs12
-rw-r--r--tests/incremental/decl_macro.rs34
-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/crate-loading/rmake.rs2
-rw-r--r--tests/run-make/debugger-visualizer-dep-info/foo.py1
-rw-r--r--tests/run-make/debugger-visualizer-dep-info/main.rs2
-rw-r--r--tests/run-make/debugger-visualizer-dep-info/my_gdb_script.py6
-rw-r--r--tests/run-make/debugger-visualizer-dep-info/rmake.rs2
-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/emit-shared-files/rmake.rs1
-rwxr-xr-xtests/run-make/libtest-junit/validate_junit.py10
-rw-r--r--tests/run-make/libtest-thread-limit/Makefile7
-rw-r--r--tests/run-make/libtest-thread-limit/rmake.rs64
-rw-r--r--tests/run-make/libtest-thread-limit/test.rs7
-rw-r--r--tests/run-make/msvc-wholearchive/c.c1
-rw-r--r--tests/run-make/msvc-wholearchive/dll.def4
-rw-r--r--tests/run-make/msvc-wholearchive/rmake.rs52
-rw-r--r--tests/run-make/msvc-wholearchive/static.rs9
-rw-r--r--tests/run-make/remove-dir-all-race/rmake.rs62
-rw-r--r--tests/run-make/rust-lld-compress-debug-sections/rmake.rs39
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile23
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs96
-rw-r--r--tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh69
-rw-r--r--tests/rustdoc-gui/target.goml2
-rw-r--r--tests/rustdoc-js-std/exact-case.js7
-rw-r--r--tests/rustdoc/anchors.no_type_anchor2.html2
-rw-r--r--tests/rustdoc/assoc-type-source-link.rs26
-rw-r--r--tests/rustdoc/doc-hidden-crate.rs27
-rw-r--r--tests/rustdoc/primitive-tuple-variadic.rs17
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.rs7
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.stderr42
-rw-r--r--tests/ui-fulldeps/stable-mir/check_instance.rs10
-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/asm/naked-with-invalid-repr-attr.rs48
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.stderr77
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr5
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr5
-rw-r--r--tests/ui/attributes/rustc_pub_transparent.rs25
-rw-r--r--tests/ui/attributes/rustc_pub_transparent.stderr23
-rw-r--r--tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr9
-rw-r--r--tests/ui/check-cfg/mix.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr6
-rw-r--r--tests/ui/closures/coerce-unsafe-to-closure.stderr4
-rw-r--r--tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs14
-rw-r--r--tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs2
-rw-r--r--tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr20
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs4
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr4
-rw-r--r--tests/ui/const-generics/bad-subst-const-kind.rs1
-rw-r--r--tests/ui/const-generics/bad-subst-const-kind.stderr11
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-nested.rs21
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-param.rs13
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-res-error.rs13
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro-res-error.stderr24
-rw-r--r--tests/ui/const-generics/early/trivial-const-arg-macro.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type_mismatch.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs10
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr4
-rw-r--r--tests/ui/const-generics/transmute-fail.rs126
-rw-r--r--tests/ui/const-generics/transmute-fail.stderr101
-rw-r--r--tests/ui/const-generics/type_mismatch.rs2
-rw-r--r--tests/ui/const-generics/type_mismatch.stderr20
-rw-r--r--tests/ui/consts/const-eval/const_fn_target_feature.rs4
-rw-r--r--tests/ui/consts/const-eval/const_fn_target_feature.stderr9
-rw-r--r--tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs4
-rw-r--r--tests/ui/consts/const-eval/ub-write-through-immutable.rs9
-rw-r--r--tests/ui/consts/const-eval/ub-write-through-immutable.stderr54
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs4
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr15
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn.rs17
-rw-r--r--tests/ui/consts/const-float-bits-conv.rs70
-rw-r--r--tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr8
-rw-r--r--tests/ui/consts/const_fn_floating_point_arithmetic.rs20
-rw-r--r--tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr53
-rw-r--r--tests/ui/consts/const_let_eq_float.rs2
-rw-r--r--tests/ui/consts/issue-36163.stderr6
-rw-r--r--tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs2
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs14
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr37
-rw-r--r--tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs8
-rw-r--r--tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr21
-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/consts/static-default-lifetime/elided-lifetime.stderr6
-rw-r--r--tests/ui/consts/static-default-lifetime/static-trait-impl.stderr6
-rw-r--r--tests/ui/delegation/inner-attr.stderr5
-rw-r--r--tests/ui/dst/dst-rvalue.stderr10
-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/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs14
-rw-r--r--tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr14
-rw-r--r--tests/ui/error-codes/E0208.rs2
-rw-r--r--tests/ui/error-codes/E0208.stderr2
-rw-r--r--tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr12
-rw-r--r--tests/ui/feature-gates/feature-gate-const-arg-path.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-repr-simd.stderr14
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-struct-target-features.stderr10
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path.base.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-76535.base.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-79422.base.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-79422.extended.stderr2
-rw-r--r--tests/ui/impl-trait/capture-lifetime-not-in-hir.rs4
-rw-r--r--tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr4
-rw-r--r--tests/ui/impl-trait/implicit-capture-late.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/refine-err.rs14
-rw-r--r--tests/ui/impl-trait/in-trait/refine-err.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr19
-rw-r--r--tests/ui/impl-trait/in-trait/variance.rs12
-rw-r--r--tests/ui/impl-trait/in-trait/variance.stderr12
-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/impl-trait/variance.e2024.stderr8
-rw-r--r--tests/ui/impl-trait/variance.new.stderr8
-rw-r--r--tests/ui/impl-trait/variance.old.stderr6
-rw-r--r--tests/ui/impl-trait/variance.rs14
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr4
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.rs8
-rw-r--r--tests/ui/inference/detect-old-time-version-format_description-parse.stderr11
-rw-r--r--tests/ui/internal/internal-unstable-const.rs13
-rw-r--r--tests/ui/internal/internal-unstable-const.stderr19
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs8
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr8
-rw-r--r--tests/ui/intrinsics/reify-intrinsic.stderr4
-rw-r--r--tests/ui/issues/issue-17651.stderr5
-rw-r--r--tests/ui/issues/issue-20831-debruijn.stderr4
-rw-r--r--tests/ui/issues/issue-37884.stderr5
-rw-r--r--tests/ui/issues/issue-47094.stderr25
-rw-r--r--tests/ui/lifetimes/issue-95023.rs7
-rw-r--r--tests/ui/lifetimes/issue-95023.stderr10
-rw-r--r--tests/ui/lint/dropping_copy_types-macros.fixed12
-rw-r--r--tests/ui/lint/dropping_copy_types-macros.rs12
-rw-r--r--tests/ui/lint/dropping_copy_types-macros.stderr21
-rw-r--r--tests/ui/lint/lint-ctypes-cstr.rs36
-rw-r--r--tests/ui/lint/lint-ctypes-cstr.stderr84
-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/parser/attribute/attr-stmt-expr-attr-bad.stderr15
-rw-r--r--tests/ui/parser/attribute/attr.stderr5
-rw-r--r--tests/ui/parser/inner-attr-after-doc-comment.stderr5
-rw-r--r--tests/ui/parser/inner-attr.stderr5
-rw-r--r--tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.rs10
-rw-r--r--tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.stderr12
-rw-r--r--tests/ui/parser/issues/issue-30318.fixed2
-rw-r--r--tests/ui/parser/issues/issue-30318.rs2
-rw-r--r--tests/ui/parser/issues/issue-30318.stderr8
-rw-r--r--tests/ui/regions/explicit-static-bound-on-trait.rs13
-rw-r--r--tests/ui/regions/explicit-static-bound-on-trait.stderr32
-rw-r--r--tests/ui/repr/conflicting-repr-hints.stderr22
-rw-r--r--tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs25
-rw-r--r--tests/ui/return/return-from-residual-sugg-issue-125997.fixed18
-rw-r--r--tests/ui/return/return-from-residual-sugg-issue-125997.stderr21
-rw-r--r--tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr11
-rw-r--r--tests/ui/simd/shuffle.rs27
-rw-r--r--tests/ui/sized/unsized-binding.stderr5
-rw-r--r--tests/ui/sized/unsized-str-in-return-expr-arg-and-local.rs30
-rw-r--r--tests/ui/sized/unsized-str-in-return-expr-arg-and-local.stderr74
-rw-r--r--tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs1
-rw-r--r--tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr14
-rw-r--r--tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs1
-rw-r--r--tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr14
-rw-r--r--tests/ui/suggestions/issue-84973-blacklist.stderr5
-rw-r--r--tests/ui/target-feature/gate.rs1
-rw-r--r--tests/ui/target-feature/gate.stderr2
-rw-r--r--tests/ui/target-feature/struct-target-features.rs98
-rw-r--r--tests/ui/target-feature/struct-target-features.stderr47
-rw-r--r--tests/ui/traits/object/pretty.rs7
-rw-r--r--tests/ui/traits/object/pretty.stderr50
-rw-r--r--tests/ui/transmutability/abstraction/abstracted_assume.rs4
-rw-r--r--tests/ui/transmutability/abstraction/const_generic_fn.rs6
-rw-r--r--tests/ui/transmutability/alignment/align-fail.rs4
-rw-r--r--tests/ui/transmutability/alignment/align-fail.stderr2
-rw-r--r--tests/ui/transmutability/alignment/align-pass.rs4
-rw-r--r--tests/ui/transmutability/arrays/huge-len.rs4
-rw-r--r--tests/ui/transmutability/arrays/huge-len.stderr12
-rw-r--r--tests/ui/transmutability/arrays/issue-103783-array-length.rs4
-rw-r--r--tests/ui/transmutability/arrays/should_have_correct_length.rs4
-rw-r--r--tests/ui/transmutability/arrays/should_inherit_alignment.rs4
-rw-r--r--tests/ui/transmutability/arrays/should_require_well_defined_layout.rs4
-rw-r--r--tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr12
-rw-r--r--tests/ui/transmutability/enums/niche_optimization.rs6
-rw-r--r--tests/ui/transmutability/enums/repr/padding_differences.rs6
-rw-r--r--tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs4
-rw-r--r--tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr40
-rw-r--r--tests/ui/transmutability/enums/repr/should_handle_all.rs4
-rw-r--r--tests/ui/transmutability/enums/should_order_correctly.rs4
-rw-r--r--tests/ui/transmutability/enums/should_pad_variants.rs4
-rw-r--r--tests/ui/transmutability/enums/should_pad_variants.stderr2
-rw-r--r--tests/ui/transmutability/enums/should_respect_endianness.rs4
-rw-r--r--tests/ui/transmutability/enums/should_respect_endianness.stderr2
-rw-r--r--tests/ui/transmutability/enums/uninhabited_optimization.rs2
-rw-r--r--tests/ui/transmutability/issue-101739-1.rs7
-rw-r--r--tests/ui/transmutability/issue-101739-1.stderr19
-rw-r--r--tests/ui/transmutability/issue-101739-2.rs26
-rw-r--r--tests/ui/transmutability/issue-101739-2.stderr29
-rw-r--r--tests/ui/transmutability/issue-110467.rs4
-rw-r--r--tests/ui/transmutability/issue-110892.rs4
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs2
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr4
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs4
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.rs26
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.stderr46
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs4
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs16
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr35
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs4
-rw-r--r--tests/ui/transmutability/maybeuninit.rs4
-rw-r--r--tests/ui/transmutability/maybeuninit.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool-mut.rs4
-rw-r--r--tests/ui/transmutability/primitives/bool-mut.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool.current.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool.next.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool.rs6
-rw-r--r--tests/ui/transmutability/primitives/numbers.current.stderr228
-rw-r--r--tests/ui/transmutability/primitives/numbers.next.stderr228
-rw-r--r--tests/ui/transmutability/primitives/numbers.rs4
-rw-r--r--tests/ui/transmutability/primitives/unit.current.stderr2
-rw-r--r--tests/ui/transmutability/primitives/unit.next.stderr2
-rw-r--r--tests/ui/transmutability/primitives/unit.rs4
-rw-r--r--tests/ui/transmutability/references/accept_assume_lifetime_extension.rs6
-rw-r--r--tests/ui/transmutability/references/accept_unexercised_lifetime_extension.rs4
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs4
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr2
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs4
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs4
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr2
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types.rs4
-rw-r--r--tests/ui/transmutability/references/reject_extension.rs4
-rw-r--r--tests/ui/transmutability/references/reject_extension.stderr2
-rw-r--r--tests/ui/transmutability/references/reject_lifetime_extension.rs6
-rw-r--r--tests/ui/transmutability/references/reject_lifetime_extension.stderr4
-rw-r--r--tests/ui/transmutability/references/u8-to-unit.rs4
-rw-r--r--tests/ui/transmutability/references/unit-to-itself.rs4
-rw-r--r--tests/ui/transmutability/references/unit-to-u8.rs4
-rw-r--r--tests/ui/transmutability/references/unit-to-u8.stderr2
-rw-r--r--tests/ui/transmutability/references/unsafecell.rs4
-rw-r--r--tests/ui/transmutability/references/unsafecell.stderr8
-rw-r--r--tests/ui/transmutability/region-infer.rs4
-rw-r--r--tests/ui/transmutability/region-infer.stderr2
-rw-r--r--tests/ui/transmutability/safety/assume/should_accept_if_dst_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/assume/should_accept_if_src_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/should_accept_if_src_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.stderr4
-rw-r--r--tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.rs4
-rw-r--r--tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.stderr4
-rw-r--r--tests/ui/transmutability/structs/repr/should_handle_align.rs4
-rw-r--r--tests/ui/transmutability/structs/repr/should_handle_all.rs4
-rw-r--r--tests/ui/transmutability/structs/repr/should_handle_packed.rs4
-rw-r--r--tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs5
-rw-r--r--tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr21
-rw-r--r--tests/ui/transmutability/structs/should_order_fields_correctly.rs4
-rw-r--r--tests/ui/transmutability/transmute-padding-ice.rs4
-rw-r--r--tests/ui/transmutability/uninhabited.rs4
-rw-r--r--tests/ui/transmutability/uninhabited.stderr8
-rw-r--r--tests/ui/transmutability/unions/boolish.rs4
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_align.rs4
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_all.rs4
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_packed.rs4
-rw-r--r--tests/ui/transmutability/unions/should_pad_variants.rs4
-rw-r--r--tests/ui/transmutability/unions/should_pad_variants.stderr2
-rw-r--r--tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs4
-rw-r--r--tests/ui/transmutability/unions/should_reject_contraction.rs4
-rw-r--r--tests/ui/transmutability/unions/should_reject_contraction.stderr4
-rw-r--r--tests/ui/transmutability/unions/should_reject_disjoint.rs4
-rw-r--r--tests/ui/transmutability/unions/should_reject_disjoint.stderr8
-rw-r--r--tests/ui/transmutability/unions/should_reject_intersecting.rs4
-rw-r--r--tests/ui/transmutability/unions/should_reject_intersecting.stderr8
-rw-r--r--tests/ui/try-trait/try-operator-on-main.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs32
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr32
-rw-r--r--tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs8
-rw-r--r--tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr20
-rw-r--r--tests/ui/unsized/unsized6.stderr10
-rw-r--r--tests/ui/variance/variance-associated-consts.rs2
-rw-r--r--tests/ui/variance/variance-associated-consts.stderr2
-rw-r--r--tests/ui/variance/variance-associated-types.rs4
-rw-r--r--tests/ui/variance/variance-associated-types.stderr4
-rw-r--r--tests/ui/variance/variance-object-types.rs2
-rw-r--r--tests/ui/variance/variance-object-types.stderr2
-rw-r--r--tests/ui/variance/variance-regions-direct.rs14
-rw-r--r--tests/ui/variance/variance-regions-direct.stderr14
-rw-r--r--tests/ui/variance/variance-regions-indirect.rs10
-rw-r--r--tests/ui/variance/variance-regions-indirect.stderr10
-rw-r--r--tests/ui/variance/variance-trait-bounds.rs8
-rw-r--r--tests/ui/variance/variance-trait-bounds.stderr8
-rw-r--r--tests/ui/variance/variance-trait-object-bound.rs2
-rw-r--r--tests/ui/variance/variance-trait-object-bound.stderr2
-rw-r--r--tests/ui/variance/variance-types-bounds.rs10
-rw-r--r--tests/ui/variance/variance-types-bounds.stderr10
-rw-r--r--tests/ui/variance/variance-types.rs12
-rw-r--r--tests/ui/variance/variance-types.stderr12
-rw-r--r--triagebot.toml3
1134 files changed, 13931 insertions, 8777 deletions
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index 5e54ceea3d7..83b92b7fa09 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -64,6 +64,10 @@ jobs:
       - name: cargo update
         # Remove first line that always just says "Updating crates.io index"
         run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
+      - name: cargo update library
+        run: |
+          echo -e "\nlibrary dependencies:" >> cargo_update.log
+          cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
       - name: cargo update rustbook
         run: |
           echo -e "\nrustbook dependencies:" >> cargo_update.log
@@ -74,6 +78,7 @@ jobs:
           name: Cargo-lock
           path: |
             Cargo.lock
+            library/Cargo.lock
             src/tools/rustbook/Cargo.lock
           retention-days: 1
       - name: upload cargo-update log artifact for use in PR
@@ -119,7 +124,7 @@ jobs:
           git config user.name github-actions
           git config user.email github-actions@github.com
           git switch --force-create cargo_update
-          git add ./Cargo.lock ./src/tools/rustbook/Cargo.lock
+          git add ./Cargo.lock ./library/Cargo.lock ./src/tools/rustbook/Cargo.lock
           git commit --no-verify --file=commit.txt
 
       - name: push
diff --git a/.gitignore b/.gitignore
index a36cb51de33..2e6499081a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,7 +56,9 @@ build/
 /src/tools/x/target
 # Created by default with `src/ci/docker/run.sh`
 /obj/
-/rustc-ice*
+
+## ICE reports
+rustc-ice-*.txt
 
 ## Temporary files
 *~
diff --git a/Cargo.lock b/Cargo.lock
index a18219b5683..6ea4cd8f5ac 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "ar_archive_writer"
-version = "0.4.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de11a9d32db3327f981143bdf699ade4d637c6887b13b97e6e91a9154666963c"
+checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
 dependencies = [
  "object 0.36.3",
 ]
@@ -410,12 +410,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.1.13"
+version = "1.0.105"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
-dependencies = [
- "shlex",
-]
+checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437"
 
 [[package]]
 name = "cfg-if"
@@ -539,6 +536,7 @@ name = "clippy"
 version = "0.1.82"
 dependencies = [
  "anstream",
+ "cargo_metadata 0.18.1",
  "clippy_config",
  "clippy_lints",
  "clippy_utils",
@@ -552,6 +550,7 @@ dependencies = [
  "regex",
  "rustc_tools_util",
  "serde",
+ "serde_json",
  "syn 2.0.75",
  "tempfile",
  "termize",
@@ -566,7 +565,6 @@ name = "clippy_config"
 version = "0.1.82"
 dependencies = [
  "itertools",
- "rustc-semver",
  "serde",
  "toml 0.7.8",
  "walkdir",
@@ -598,7 +596,6 @@ dependencies = [
  "quine-mc_cluskey",
  "regex",
  "regex-syntax 0.8.4",
- "rustc-semver",
  "semver",
  "serde",
  "serde_json",
@@ -617,7 +614,6 @@ dependencies = [
  "arrayvec",
  "clippy_config",
  "itertools",
- "rustc-semver",
  "rustc_apfloat",
 ]
 
@@ -2230,9 +2226,12 @@ dependencies = [
 
 [[package]]
 name = "minifier"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95bbbf96b9ac3482c2a25450b67a15ed851319bc5fabf3b40742ea9066e84282"
+checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437"
+dependencies = [
+ "clap",
+]
 
 [[package]]
 name = "minimal-lexical"
@@ -3129,6 +3128,7 @@ dependencies = [
  "bstr",
  "build_helper",
  "gimli 0.31.0",
+ "libc",
  "object 0.36.3",
  "regex",
  "serde_json",
@@ -3202,12 +3202,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc-semver"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5be1bdc7edf596692617627bbfeaba522131b18e06ca4df2b6b689e3c5d5ce84"
-
-[[package]]
 name = "rustc-stable-hash"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4542,6 +4536,7 @@ dependencies = [
  "bitflags 2.6.0",
  "derive-where",
  "indexmap",
+ "rustc-hash",
  "rustc_ast_ir",
  "rustc_data_structures",
  "rustc_index",
diff --git a/RELEASES.md b/RELEASES.md
index 2c91ddf7826..5e4827be4ec 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -143,6 +143,8 @@ Compatibility Notes
 - [Turn `proc_macro_back_compat` lint into a hard error.](https://github.com/rust-lang/rust/pull/125596/)
 - [Detect unused structs even when implementing private traits](https://github.com/rust-lang/rust/pull/122382/)
 - [`std::sync::ReentrantLockGuard<T>` is no longer `Sync` if `T: !Sync`](https://github.com/rust-lang/rust/pull/125527) which means [`std::io::StdoutLock` and `std::io::StderrLock` are no longer Sync](https://github.com/rust-lang/rust/issues/127340)
+- [Type inference will fail in some cases due to new implementations of `FromIterator for Box<str>`.](https://github.com/rust-lang/rust/pull/99969/)
+  Notably, this breaks versions of the `time` crate before 0.3.35, due to no longer inferring the implementation for `Box<[_]>`.
 
 <a id="1.80-Internal-Changes"></a>
 
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/ast.rs b/compiler/rustc_ast/src/ast.rs
index a44ed828504..85d38a0e28b 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2902,6 +2902,17 @@ pub struct AttrItem {
     pub tokens: Option<LazyAttrTokenStream>,
 }
 
+impl AttrItem {
+    pub fn is_valid_for_outer_style(&self) -> bool {
+        self.path == sym::cfg_attr
+            || self.path == sym::cfg
+            || self.path == sym::forbid
+            || self.path == sym::warn
+            || self.path == sym::allow
+            || self.path == sym::deny
+    }
+}
+
 /// `TraitRef`s appear in impls.
 ///
 /// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
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/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 51cbe808a3a..e077c544965 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -220,7 +220,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             let parent_def_id = self.current_def_id_parent;
                             let node_id = self.next_node_id();
                             // HACK(min_generic_const_args): see lower_anon_const
-                            if !expr.is_potential_trivial_const_arg() {
+                            if !self.tcx.features().const_arg_path
+                                || !expr.is_potential_trivial_const_arg()
+                            {
                                 self.create_def(
                                     parent_def_id,
                                     node_id,
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 b5d8a547a8f..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,
@@ -387,7 +387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let node_id = self.next_node_id();
 
                 // HACK(min_generic_const_args): see lower_anon_const
-                if !arg.is_potential_trivial_const_arg() {
+                if !self.tcx.features().const_arg_path || !arg.is_potential_trivial_const_arg() {
                     // Add a definition for the in-band const def.
                     self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
                 }
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 81d17a9dec2..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,
 }
@@ -2358,7 +2357,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         span: Span,
     ) -> &'hir hir::ConstArg<'hir> {
         let ct_kind = match res {
-            Res::Def(DefKind::ConstParam, _) => {
+            Res::Def(DefKind::ConstParam, _) if self.tcx.features().const_arg_path => {
                 let qpath = self.lower_qpath(
                     ty_id,
                     &None,
@@ -2433,7 +2432,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
         debug!("res={:?}", maybe_res);
         // FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
-        if let Some(res) = maybe_res
+        if self.tcx.features().const_arg_path
+            && let Some(res) = maybe_res
             && let Res::Def(DefKind::ConstParam, _) = res
             && let ExprKind::Path(qself, path) = &expr.kind
         {
@@ -2464,7 +2464,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// See [`hir::ConstArg`] for when to use this function vs
     /// [`Self::lower_anon_const_to_const_arg`].
     fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
-        if c.value.is_potential_trivial_const_arg() {
+        if self.tcx.features().const_arg_path && c.value.is_potential_trivial_const_arg() {
             // HACK(min_generic_const_args): see DefCollector::visit_anon_const
             // Over there, we guess if this is a bare param and only create a def if
             // we think it's not. However we may can guess wrong (see there for example)
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 76e39fe94af..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()
     }
 
@@ -290,7 +290,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         ty: Ty<'_>,
         is_index: Option<bool>,
     ) -> Diag<'infcx> {
-        let type_name = match (&ty.kind(), is_index) {
+        let type_name = match (ty.kind(), is_index) {
             (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
             (&ty::Slice(_), _) => "slice",
             _ => span_bug!(move_from_span, "this path should not cause illegal move"),
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/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 42d0c2038f8..311f17f15b9 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -201,7 +201,7 @@ fn place_components_conflict<'tcx>(
 
             let base_ty = base.ty(body, tcx).ty;
 
-            match (elem, &base_ty.kind(), access) {
+            match (elem, base_ty.kind(), access) {
                 (_, _, Shallow(Some(ArtificialField::ArrayLength)))
                 | (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
                     // The array length is like additional fields on the
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 6983cda6ddf..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;
@@ -2043,9 +2043,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
                         let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
 
-                        if let Err(terr) = self.eq_types(
-                            *ty,
+                        if let Err(terr) = self.sub_types(
                             ty_fn_ptr_from,
+                            *ty,
                             location.to_locations(),
                             ConstraintCategory::Cast { unsize_to: None },
                         ) {
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..92a857c2adc 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>,
@@ -521,13 +521,20 @@ pub fn llfn_attrs_from_instance<'ll, 'tcx>(
 
     let function_features = function_features
         .iter()
-        .flat_map(|feat| {
-            llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}"))
-        })
+        // Convert to LLVMFeatures and filter out unavailable ones
+        .flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat))
+        // Convert LLVMFeatures & dependencies to +<feats>s
+        .flat_map(|feat| feat.into_iter().map(|f| format!("+{f}")))
         .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
             InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
             InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
         }))
+        // HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled
+        // It only exists as a feature in LLVM 18, cannot be passed down for any other version
+        .chain(match &*cx.tcx.sess.target.arch {
+            "aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()],
+            _ => vec![],
+        })
         .collect::<Vec<String>>();
 
     if cx.tcx.sess.target.is_like_wasm {
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 8862f139aff..01aae24ab56 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::base_n::{ToBaseN, ALPHANUMERIC_ONLY};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_hir::def_id::DefId;
+use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
 use rustc_middle::mir::mono::CodegenUnit;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
@@ -39,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,
@@ -110,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,
@@ -226,6 +227,20 @@ pub unsafe fn create_module<'ll>(
         }
     }
 
+    // If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
+    // See https://github.com/llvm/llvm-project/pull/104826
+    if sess.is_sanitizer_cfi_normalize_integers_enabled() {
+        let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr().cast();
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                cfi_normalize_integers,
+                1,
+            );
+        }
+    }
+
     // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
         let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
@@ -245,6 +260,22 @@ pub unsafe fn create_module<'ll>(
         unsafe {
             llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
         }
+
+        // Add "kcfi-offset" module flag with -Z patchable-function-entry (See
+        // https://reviews.llvm.org/D141172).
+        let pfe =
+            PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
+        if pfe.prefix() > 0 {
+            let kcfi_offset = c"kcfi-offset".as_ptr().cast();
+            unsafe {
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Override,
+                    kcfi_offset,
+                    pfe.prefix().into(),
+                );
+            }
+        }
     }
 
     // Control Flow Guard is currently only supported by the MSVC linker on Windows.
@@ -531,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()
     }
 
@@ -1066,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..d7a4f105f3c 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -1,5 +1,5 @@
 use rustc_middle::mir::coverage::{
-    CodeRegion, ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind,
+    ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind, SourceRegion,
 };
 
 /// Must match the layout of `LLVMRustCounterKind`.
@@ -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 }
         }
     }
@@ -236,9 +236,10 @@ impl CounterMappingRegion {
     pub(crate) fn from_mapping(
         mapping_kind: &MappingKind,
         local_file_id: u32,
-        code_region: &CodeRegion,
+        source_region: &SourceRegion,
     ) -> Self {
-        let &CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region;
+        let &SourceRegion { file_name: _, start_line, start_col, end_line, end_col } =
+            source_region;
         match *mapping_kind {
             MappingKind::Code(term) => Self::code_region(
                 Counter::from_term(term),
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
index 9433385c23a..5ed640b840e 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
@@ -2,8 +2,8 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::coverage::{
-    CodeRegion, CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping,
-    MappingKind, Op,
+    CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, MappingKind, Op,
+    SourceRegion,
 };
 use rustc_middle::ty::Instance;
 use rustc_span::Symbol;
@@ -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,13 +195,13 @@ 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 }
     }
 
     /// Returns an iterator over all filenames used by this function's mappings.
     pub(crate) fn all_file_names(&self) -> impl Iterator<Item = Symbol> + Captures<'_> {
-        self.function_coverage_info.mappings.iter().map(|mapping| mapping.code_region.file_name)
+        self.function_coverage_info.mappings.iter().map(|mapping| mapping.source_region.file_name)
     }
 
     /// Convert this function's coverage expression data into a form that can be
@@ -230,12 +230,12 @@ impl<'tcx> FunctionCoverage<'tcx> {
     /// that will be used by `mapgen` when preparing for FFI.
     pub(crate) fn counter_regions(
         &self,
-    ) -> impl Iterator<Item = (MappingKind, &CodeRegion)> + ExactSizeIterator {
+    ) -> impl Iterator<Item = (MappingKind, &SourceRegion)> + ExactSizeIterator {
         self.function_coverage_info.mappings.iter().map(move |mapping| {
-            let Mapping { kind, code_region } = mapping;
+            let Mapping { kind, source_region } = mapping;
             let kind =
                 kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term });
-            (kind, code_region)
+            (kind, source_region)
         })
     }
 
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..618602ed70f 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) -> Option<LLVMFeature<'a>> {
     let arch = if sess.target.arch == "x86_64" {
         "x86"
     } else if sess.target.arch == "arm64ec" {
@@ -218,46 +218,65 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
         &*sess.target.arch
     };
     match (arch, s) {
-        ("x86", "sse4.2") => {
-            LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32"))
-        }
-        ("x86", "pclmulqdq") => LLVMFeature::new("pclmul"),
-        ("x86", "rdrand") => LLVMFeature::new("rdrnd"),
-        ("x86", "bmi1") => LLVMFeature::new("bmi"),
-        ("x86", "cmpxchg16b") => LLVMFeature::new("cx16"),
-        ("x86", "lahfsahf") => LLVMFeature::new("sahf"),
-        ("aarch64", "rcpc2") => LLVMFeature::new("rcpc-immo"),
-        ("aarch64", "dpb") => LLVMFeature::new("ccpp"),
-        ("aarch64", "dpb2") => LLVMFeature::new("ccdp"),
-        ("aarch64", "frintts") => LLVMFeature::new("fptoint"),
-        ("aarch64", "fcma") => LLVMFeature::new("complxnum"),
-        ("aarch64", "pmuv3") => LLVMFeature::new("perfmon"),
-        ("aarch64", "paca") => LLVMFeature::new("pauth"),
-        ("aarch64", "pacg") => LLVMFeature::new("pauth"),
+        ("x86", "sse4.2") => Some(LLVMFeature::with_dependency(
+            "sse4.2",
+            TargetFeatureFoldStrength::EnableOnly("crc32"),
+        )),
+        ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")),
+        ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")),
+        ("x86", "bmi1") => Some(LLVMFeature::new("bmi")),
+        ("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")),
+        ("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")),
+        ("aarch64", "rcpc2") => Some(LLVMFeature::new("rcpc-immo")),
+        ("aarch64", "dpb") => Some(LLVMFeature::new("ccpp")),
+        ("aarch64", "dpb2") => Some(LLVMFeature::new("ccdp")),
+        ("aarch64", "frintts") => Some(LLVMFeature::new("fptoint")),
+        ("aarch64", "fcma") => Some(LLVMFeature::new("complxnum")),
+        ("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
+        ("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
+        ("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
+        ("aarch64", "sve-b16b16") => Some(LLVMFeature::new("b16b16")),
+        ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
         // Rust ties fp and neon together.
         ("aarch64", "neon") => {
-            LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8"))
+            Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8")))
         }
         // In LLVM neon implicitly enables fp, but we manually enable
         // neon when a feature only implicitly enables fp
-        ("aarch64", "fhm") => LLVMFeature::new("fp16fml"),
-        ("aarch64", "fp16") => LLVMFeature::new("fullfp16"),
+        ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
+        ("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
+        // Filter out features that are not supported by the current LLVM version
+        ("aarch64", "faminmax") if get_version().0 < 18 => None,
+        ("aarch64", "fp8") if get_version().0 < 18 => None,
+        ("aarch64", "fp8dot2") if get_version().0 < 18 => None,
+        ("aarch64", "fp8dot4") if get_version().0 < 18 => None,
+        ("aarch64", "fp8fma") if get_version().0 < 18 => None,
+        ("aarch64", "fpmr") if get_version().0 != 18 => None,
+        ("aarch64", "lut") if get_version().0 < 18 => None,
+        ("aarch64", "sme-f8f16") if get_version().0 < 18 => None,
+        ("aarch64", "sme-f8f32") if get_version().0 < 18 => None,
+        ("aarch64", "sme-fa64") if get_version().0 < 18 => None,
+        ("aarch64", "sme-lutv2") if get_version().0 < 18 => None,
+        ("aarch64", "ssve-fp8dot2") if get_version().0 < 18 => None,
+        ("aarch64", "ssve-fp8dot4") if get_version().0 < 18 => None,
+        ("aarch64", "ssve-fp8fma") if get_version().0 < 18 => None,
+        ("aarch64", "v9.5a") if get_version().0 < 18 => None,
         // In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
         // `fast-unaligned-access`. In LLVM 19, it was split back out.
         ("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
-            LLVMFeature::new("fast-unaligned-access")
+            Some(LLVMFeature::new("fast-unaligned-access"))
         }
         // For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
         ("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
-            LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))
+            Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
         }
-        (_, s) => LLVMFeature::new(s),
+        (_, s) => Some(LLVMFeature::new(s)),
     }
 }
 
 /// 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]> {
@@ -291,13 +310,17 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
                     return true;
                 }
                 // check that all features in a given smallvec are enabled
-                for llvm_feature in to_llvm_features(sess, feature) {
-                    let cstr = SmallCStr::new(llvm_feature);
-                    if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
-                        return false;
+                if let Some(feat) = to_llvm_features(sess, feature) {
+                    for llvm_feature in feat {
+                        let cstr = SmallCStr::new(llvm_feature);
+                        if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
+                            return false;
+                        }
                     }
+                    true
+                } else {
+                    false
                 }
-                true
             })
             .map(|(feature, _, _)| Symbol::intern(feature)),
     );
@@ -337,19 +360,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();
@@ -386,9 +409,9 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
         .target
         .supported_target_features()
         .iter()
-        .map(|(feature, _gate, _implied)| {
+        .filter_map(|(feature, _gate, _implied)| {
             // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
-            let llvm_feature = to_llvm_features(sess, *feature).llvm_feature_name;
+            let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
             let desc =
                 match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
                     Some(index) => {
@@ -398,7 +421,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
                     None => "",
                 };
 
-            (*feature, desc)
+            Some((*feature, desc))
         })
         .collect::<Vec<_>>();
 
@@ -479,7 +502,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()),
@@ -595,7 +618,7 @@ pub(crate) fn global_llvm_features(
                     if feature_state.is_none() {
                         let rust_feature =
                             supported_features.iter().find_map(|&(rust_feature, _, _)| {
-                                let llvm_features = to_llvm_features(sess, rust_feature);
+                                let llvm_features = to_llvm_features(sess, rust_feature)?;
                                 if llvm_features.contains(feature)
                                     && !llvm_features.contains(rust_feature)
                                 {
@@ -641,7 +664,7 @@ pub(crate) fn global_llvm_features(
                 // passing requests down to LLVM. This means that all in-language
                 // features also work on the command line instead of having two
                 // different names when the LLVM name and the Rust name differ.
-                let llvm_feature = to_llvm_features(sess, feature);
+                let llvm_feature = to_llvm_features(sess, feature)?;
 
                 Some(
                     std::iter::once(format!(
@@ -691,6 +714,9 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
     let feature = s
         .strip_prefix(&['+', '-'][..])
         .unwrap_or_else(|| sess.dcx().emit_fatal(InvalidTargetFeaturePrefix { feature: s }));
+    if s.is_empty() {
+        return None;
+    }
     // Rustc-specific feature requests like `+crt-static` or `-crt-static`
     // are not passed down to LLVM.
     if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
@@ -699,7 +725,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/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index e3033b332ca..e78039bafd8 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -5,10 +5,10 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-ar_archive_writer = "0.4.0"
+ar_archive_writer = "0.4.2"
 arrayvec = { version = "0.7", default-features = false }
 bitflags = "2.4.1"
-cc = "1.0.90"
+cc = "=1.0.105" # FIXME(cc): pinned to keep support for VS2013
 either = "1.5.0"
 itertools = "0.12"
 jobserver = "0.1.28"
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 38a440a707a..76a94de5433 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -108,7 +108,11 @@ pub trait ArchiveBuilderBuilder {
                 &exports,
                 machine,
                 !sess.target.is_like_msvc,
-                /*comdat=*/ false,
+                // Enable compatibility with MSVC's `/WHOLEARCHIVE` flag.
+                // Without this flag a duplicate symbol error would be emitted
+                // when linking a rust staticlib using `/WHOLEARCHIVE`.
+                // See #129020
+                true,
             ) {
                 sess.dcx()
                     .emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() });
@@ -121,7 +125,7 @@ pub trait ArchiveBuilderBuilder {
         rlib: &'a Path,
         outdir: &Path,
         bundled_lib_file_names: &FxIndexSet<Symbol>,
-    ) -> Result<(), ExtractBundledLibsError<'_>> {
+    ) -> Result<(), ExtractBundledLibsError<'a>> {
         let archive_map = unsafe {
             Mmap::map(
                 File::open(rlib)
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/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 4ab20c154cc..209750d6ba6 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,5 +1,6 @@
 use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{struct_span_code_err, DiagMessage, SubdiagMessage};
 use rustc_hir as hir;
@@ -8,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
 use rustc_hir::{lang_items, LangItem};
 use rustc_middle::middle::codegen_fn_attrs::{
-    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
+    CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, TargetFeature,
 };
 use rustc_middle::mir::mono::Linkage;
 use rustc_middle::query::Providers;
@@ -17,6 +18,7 @@ use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span};
+use rustc_target::abi::VariantIdx;
 use rustc_target::spec::{abi, SanitizerSet};
 
 use crate::errors;
@@ -78,6 +80,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     let mut link_ordinal_span = None;
     let mut no_sanitize_span = None;
 
+    let fn_sig_outer = || {
+        use DefKind::*;
+
+        let def_kind = tcx.def_kind(did);
+        if let Fn | AssocFn | Variant | Ctor(..) = def_kind { Some(tcx.fn_sig(did)) } else { None }
+    };
+
     for attr in attrs.iter() {
         // In some cases, attribute are only valid on functions, but it's the `check_attr`
         // pass that check that they aren't used anywhere else, rather this module.
@@ -85,16 +94,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         // functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
         // report a delayed bug, just in case `check_attr` isn't doing its job.
         let fn_sig = || {
-            use DefKind::*;
-
-            let def_kind = tcx.def_kind(did);
-            if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
-                Some(tcx.fn_sig(did))
-            } else {
+            let sig = fn_sig_outer();
+            if sig.is_none() {
                 tcx.dcx()
                     .span_delayed_bug(attr.span, "this attribute can only be applied to functions");
-                None
             }
+            sig
         };
 
         let Some(Ident { name, .. }) = attr.ident() else {
@@ -613,7 +618,93 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         }
     }
 
-    // If a function uses #[target_feature] it can't be inlined into general
+    if let Some(sig) = fn_sig_outer() {
+        // Collect target features from types reachable from arguments.
+        // We define a type as "reachable" if:
+        //  - it is a function argument
+        //  - it is a field of a reachable struct
+        //  - there is a reachable reference to it
+        // FIXME(struct_target_features): we may want to cache the result of this computation.
+        let mut visited_types = FxHashSet::default();
+        let mut reachable_types: Vec<_> = sig.skip_binder().inputs().skip_binder().to_owned();
+        let mut additional_tf = vec![];
+
+        while let Some(ty) = reachable_types.pop() {
+            if visited_types.contains(&ty) {
+                continue;
+            }
+            visited_types.insert(ty);
+            match ty.kind() {
+                ty::Alias(..) => {
+                    if let Ok(t) =
+                        tcx.try_normalize_erasing_regions(tcx.param_env(did.to_def_id()), ty)
+                    {
+                        reachable_types.push(t)
+                    }
+                }
+
+                ty::Ref(_, inner, _) => reachable_types.push(*inner),
+                ty::Tuple(tys) => reachable_types.extend(tys.iter()),
+                ty::Adt(adt_def, args) => {
+                    additional_tf.extend_from_slice(tcx.struct_target_features(adt_def.did()));
+                    // This only recurses into structs as i.e. an Option<TargetFeature> is an ADT
+                    // that doesn't actually always contain a TargetFeature.
+                    if adt_def.is_struct() {
+                        reachable_types.extend(
+                            adt_def
+                                .variant(VariantIdx::from_usize(0))
+                                .fields
+                                .iter()
+                                .map(|field| field.ty(tcx, args)),
+                        );
+                    }
+                }
+                ty::Bool
+                | ty::Char
+                | ty::Int(..)
+                | ty::Uint(..)
+                | ty::Float(..)
+                | ty::Foreign(..)
+                | ty::Str
+                | ty::Array(..)
+                | ty::Pat(..)
+                | ty::Slice(..)
+                | ty::RawPtr(..)
+                | ty::FnDef(..)
+                | ty::FnPtr(..)
+                | ty::Dynamic(..)
+                | ty::Closure(..)
+                | ty::CoroutineClosure(..)
+                | ty::Coroutine(..)
+                | ty::CoroutineWitness(..)
+                | ty::Never
+                | ty::Param(..)
+                | ty::Bound(..)
+                | ty::Placeholder(..)
+                | ty::Infer(..)
+                | ty::Error(..) => (),
+            }
+        }
+
+        // FIXME(struct_target_features): is this really necessary?
+        if !additional_tf.is_empty() && sig.skip_binder().abi() != abi::Abi::Rust {
+            tcx.dcx().span_err(
+                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
+                "cannot use a struct with target features in a function with non-Rust ABI",
+            );
+        }
+        if !additional_tf.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
+            tcx.dcx().span_err(
+                tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
+                "cannot use a struct with target features in a #[inline(always)] function",
+            );
+        }
+        codegen_fn_attrs
+            .target_features
+            .extend(additional_tf.iter().map(|tf| TargetFeature { implied: true, ..*tf }));
+    }
+
+    // If a function uses non-default target_features it can't be inlined into general
     // purpose functions as they wouldn't have the right target features
     // enabled. For that reason we also forbid #[inline(always)] as it can't be
     // respected.
@@ -758,6 +849,20 @@ fn check_link_name_xor_ordinal(
     }
 }
 
+fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeature] {
+    let mut features = vec![];
+    let supported_features = tcx.supported_target_features(LOCAL_CRATE);
+    for attr in tcx.get_attrs(def_id, sym::target_feature) {
+        from_target_feature(tcx, attr, supported_features, &mut features);
+    }
+    tcx.arena.alloc_slice(&features)
+}
+
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
+    *providers = Providers {
+        codegen_fn_attrs,
+        should_inherit_track_caller,
+        struct_target_features,
+        ..*providers
+    };
 }
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/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 1442f1832b9..db788b6b151 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -402,9 +402,6 @@ const_eval_unallowed_mutable_refs =
 const_eval_unallowed_op_in_const_context =
     {$msg}
 
-const_eval_unavailable_target_features_for_fn =
-    calling a function that requires unavailable target features: {$unavailable_feats}
-
 const_eval_uninhabited_enum_variant_read =
     read discriminant of an uninhabited enum variant
 const_eval_uninhabited_enum_variant_written =
@@ -419,7 +416,7 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
 const_eval_unstable_in_stable =
     const-stable function cannot use `#[feature({$gate})]`
     .unstable_sugg = if it is not part of the public API, make this function unstably const
-    .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+    .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
 
 const_eval_unterminated_c_string =
     reading a null-terminated string starting at {$pointer} with no null found before end of allocation
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 86a5afa65ba..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);
@@ -575,10 +589,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
             Rvalue::UnaryOp(_, operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                if is_int_bool_or_char(ty) {
-                    // Int, bool, and char operations are fine.
-                } else if ty.is_floating_point() {
-                    self.check_op(ops::FloatingPointOp);
+                if is_int_bool_float_or_char(ty) {
+                    // Int, bool, float, and char operations are fine.
                 } else {
                     span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
                 }
@@ -588,8 +600,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 let lhs_ty = lhs.ty(self.body, self.tcx);
                 let rhs_ty = rhs.ty(self.body, self.tcx);
 
-                if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
-                    // Int, bool, and char operations are fine.
+                if is_int_bool_float_or_char(lhs_ty) && is_int_bool_float_or_char(rhs_ty) {
+                    // Int, bool, float, and char operations are fine.
                 } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
                     assert_matches!(
                         op,
@@ -603,8 +615,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     );
 
                     self.check_op(ops::RawPtrComparison);
-                } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
-                    self.check_op(ops::FloatingPointOp);
                 } else {
                     span_bug!(
                         self.span,
@@ -1009,8 +1019,8 @@ fn place_as_reborrow<'tcx>(
     }
 }
 
-fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
-    ty.is_bool() || ty.is_integral() || ty.is_char()
+fn is_int_bool_float_or_char(ty: Ty<'_>) -> bool {
+    ty.is_bool() || ty.is_integral() || ty.is_char() || ty.is_floating_point()
 }
 
 fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 259114dbdc2..93fafa60557 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -55,28 +55,6 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx>;
 }
 
-#[derive(Debug)]
-pub struct FloatingPointOp;
-impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
-    fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
-        if ccx.const_kind() == hir::ConstContext::ConstFn {
-            Status::Unstable(sym::const_fn_floating_point_arithmetic)
-        } else {
-            Status::Allowed
-        }
-    }
-
-    #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
-    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
-        feature_err(
-            &ccx.tcx.sess,
-            sym::const_fn_floating_point_arithmetic,
-            span,
-            format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
-        )
-    }
-}
-
 /// A function call where the callee is a pointer.
 #[derive(Debug)]
 pub struct FnCallIndirect;
@@ -440,22 +418,12 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
         DiagImportance::Secondary
     }
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
-        // FIXME: Maybe a more elegant solution to this if else case
-        if let hir::ConstContext::Static(_) = ccx.const_kind() {
-            ccx.dcx().create_err(errors::InteriorMutableDataRefer {
-                span,
-                opt_help: true,
-                kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(E0492),
-            })
-        } else {
-            ccx.dcx().create_err(errors::InteriorMutableDataRefer {
-                span,
-                opt_help: false,
-                kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(E0492),
-            })
-        }
+        ccx.dcx().create_err(errors::InteriorMutableDataRefer {
+            span,
+            opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)),
+            kind: ccx.const_kind(),
+            teach: ccx.tcx.sess.teach(E0492),
+        })
     }
 }
 
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/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 00bbd9337f7..25b32785b7d 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -22,6 +22,7 @@ pub enum ConstEvalErrKind {
     RecursiveStatic,
     AssertFailure(AssertKind<ConstInt>),
     Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
+    WriteThroughImmutablePointer,
 }
 
 impl MachineStopType for ConstEvalErrKind {
@@ -35,12 +36,16 @@ impl MachineStopType for ConstEvalErrKind {
             Panic { .. } => const_eval_panic,
             RecursiveStatic => const_eval_recursive_static,
             AssertFailure(x) => x.diagnostic_message(),
+            WriteThroughImmutablePointer => const_eval_write_through_immutable_pointer,
         }
     }
     fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) {
         use ConstEvalErrKind::*;
         match *self {
-            RecursiveStatic | ConstAccessesMutGlobal | ModifiedGlobal => {}
+            RecursiveStatic
+            | ConstAccessesMutGlobal
+            | ModifiedGlobal
+            | WriteThroughImmutablePointer => {}
             AssertFailure(kind) => kind.add_args(adder),
             Panic { msg, line, col, file } => {
                 adder("msg".into(), msg.into_diag_arg());
@@ -159,6 +164,7 @@ where
 
 /// Emit a lint from a const-eval situation, with a backtrace.
 // Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
+#[allow(unused)]
 pub(super) fn lint<'tcx, L>(
     tcx: TyCtxtAt<'tcx>,
     machine: &CompileTimeMachine<'tcx>,
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index c3d94ca0e59..9c1fef095f5 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -12,7 +12,6 @@ use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, mir};
-use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use rustc_target::abi::{Align, Size};
@@ -732,8 +731,8 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
     }
 
     fn before_memory_write(
-        tcx: TyCtxtAt<'tcx>,
-        machine: &mut Self,
+        _tcx: TyCtxtAt<'tcx>,
+        _machine: &mut Self,
         _alloc_extra: &mut Self::AllocExtra,
         (_alloc_id, immutable): (AllocId, bool),
         range: AllocRange,
@@ -744,9 +743,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
         }
         // Reject writes through immutable pointers.
         if immutable {
-            super::lint(tcx, machine, WRITES_THROUGH_IMMUTABLE_POINTER, |frames| {
-                crate::errors::WriteThroughImmutablePointer { frames }
-            });
+            return Err(ConstEvalErrKind::WriteThroughImmutablePointer.into());
         }
         // Everything else is fine.
         Ok(())
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 6075f3f84cd..0b366b43f95 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -407,13 +407,6 @@ pub struct ConstEvalError {
     pub frame_notes: Vec<FrameNote>,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(const_eval_write_through_immutable_pointer)]
-pub struct WriteThroughImmutablePointer {
-    #[subdiagnostic]
-    pub frames: Vec<FrameNote>,
-}
-
 #[derive(Diagnostic)]
 #[diag(const_eval_nullary_intrinsic_fail)]
 pub struct NullaryIntrinsicError {
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 917a2fa7c6d..61e8007e10e 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -311,34 +311,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         Ok(())
     }
 
-    fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> {
-        // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
-        let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
-        if !self.tcx.sess.target.is_like_wasm
-            && attrs
-                .target_features
-                .iter()
-                .any(|feature| !self.tcx.sess.target_features.contains(&feature.name))
-        {
-            throw_ub_custom!(
-                fluent::const_eval_unavailable_target_features_for_fn,
-                unavailable_feats = attrs
-                    .target_features
-                    .iter()
-                    .filter(|&feature| !feature.implied
-                        && !self.tcx.sess.target_features.contains(&feature.name))
-                    .fold(String::new(), |mut s, feature| {
-                        if !s.is_empty() {
-                            s.push_str(", ");
-                        }
-                        s.push_str(feature.name.as_str());
-                        s
-                    }),
-            );
-        }
-        Ok(())
-    }
-
     /// The main entry point for creating a new stack frame: performs ABI checks and initializes
     /// arguments.
     #[instrument(skip(self), level = "trace")]
@@ -360,20 +332,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             throw_unsup_format!("calling a c-variadic function is not supported");
         }
 
-        if M::enforce_abi(self) {
-            if caller_fn_abi.conv != callee_fn_abi.conv {
-                throw_ub_custom!(
-                    fluent::const_eval_incompatible_calling_conventions,
-                    callee_conv = format!("{:?}", callee_fn_abi.conv),
-                    caller_conv = format!("{:?}", caller_fn_abi.conv),
-                )
-            }
+        if caller_fn_abi.conv != callee_fn_abi.conv {
+            throw_ub_custom!(
+                fluent::const_eval_incompatible_calling_conventions,
+                callee_conv = format!("{:?}", callee_fn_abi.conv),
+                caller_conv = format!("{:?}", caller_fn_abi.conv),
+            )
         }
 
         // Check that all target features required by the callee (i.e., from
         // the attribute `#[target_feature(enable = ...)]`) are enabled at
         // compile time.
-        self.check_fn_target_features(instance)?;
+        M::check_fn_target_features(self, instance)?;
 
         if !callee_fn_abi.can_unwind {
             // The callee cannot unwind, so force the `Unreachable` unwind handling.
@@ -576,7 +546,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/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 4901e4b2a41..e8c9f145eea 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -388,7 +388,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         let (src_pointee_ty, dest_pointee_ty) =
             self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
 
-        match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
+        match (src_pointee_ty.kind(), dest_pointee_ty.kind()) {
             (&ty::Array(_, length), &ty::Slice(_)) => {
                 let ptr = self.read_pointer(src)?;
                 let val = Immediate::new_slice(
@@ -478,9 +478,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         dest: &PlaceTy<'tcx, M::Provenance>,
     ) -> InterpResult<'tcx> {
         trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty);
-        match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
+        match (src.layout.ty.kind(), cast_ty.ty.kind()) {
             (&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _))
-            | (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, *s, *c),
+            | (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c),
             (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
                 assert_eq!(def_a, def_b); // implies same number of fields
 
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index aef39b9af2f..bedc56de0da 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -684,19 +684,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         assert!(layout.is_sized());
 
         let get_bytes = |this: &InterpCx<'tcx, M>,
-                         op: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
-                         size|
+                         op: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>|
          -> InterpResult<'tcx, &[u8]> {
             let ptr = this.read_pointer(op)?;
-            let Some(alloc_ref) = self.get_ptr_alloc(ptr, size)? else {
+            this.check_ptr_align(ptr, layout.align.abi)?;
+            let Some(alloc_ref) = self.get_ptr_alloc(ptr, layout.size)? else {
                 // zero-sized access
                 return Ok(&[]);
             };
             alloc_ref.get_bytes_strip_provenance()
         };
 
-        let lhs_bytes = get_bytes(self, lhs, layout.size)?;
-        let rhs_bytes = get_bytes(self, rhs, layout.size)?;
+        let lhs_bytes = get_bytes(self, lhs)?;
+        let rhs_bytes = get_bytes(self, rhs)?;
         Ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 761ab81e228..88453245b84 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -173,11 +173,6 @@ pub trait Machine<'tcx>: Sized {
         false
     }
 
-    /// Whether function calls should be [ABI](CallAbi)-checked.
-    fn enforce_abi(_ecx: &InterpCx<'tcx, Self>) -> bool {
-        true
-    }
-
     /// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
     /// check for overflow.
     fn ignore_optional_overflow_checks(_ecx: &InterpCx<'tcx, Self>) -> bool;
@@ -238,6 +233,13 @@ pub trait Machine<'tcx>: Sized {
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>>;
 
+    /// Check whether the given function may be executed on the current machine, in terms of the
+    /// target features is requires.
+    fn check_fn_target_features(
+        _ecx: &InterpCx<'tcx, Self>,
+        _instance: ty::Instance<'tcx>,
+    ) -> InterpResult<'tcx>;
+
     /// Called to evaluate `Assert` MIR terminators that trigger a panic.
     fn assert_panic(
         ecx: &mut InterpCx<'tcx, Self>,
@@ -280,6 +282,9 @@ pub trait Machine<'tcx>: Sized {
         Ok(())
     }
 
+    /// Determines the result of a `NullaryOp::UbChecks` invocation.
+    fn ub_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
+
     /// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
     /// You can use this to detect long or endlessly running programs.
     #[inline]
@@ -615,6 +620,16 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
     }
 
     #[inline(always)]
+    fn check_fn_target_features(
+        _ecx: &InterpCx<$tcx, Self>,
+        _instance: ty::Instance<$tcx>,
+    ) -> InterpResult<$tcx> {
+        // For now we don't do any checking here. We can't use `tcx.sess` because that can differ
+        // between crates, and we need to ensure that const-eval always behaves the same.
+        Ok(())
+    }
+
+    #[inline(always)]
     fn call_extra_fn(
         _ecx: &mut InterpCx<$tcx, Self>,
         fn_val: !,
@@ -628,6 +643,13 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
     }
 
     #[inline(always)]
+    fn ub_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
+        // We can't look at `tcx.sess` here as that can differ across crates, which can lead to
+        // unsound differences in evaluating the same constant at different instantiation sites.
+        Ok(true)
+    }
+
+    #[inline(always)]
     fn adjust_global_allocation<'b>(
         _ecx: &InterpCx<$tcx, Self>,
         _id: AllocId,
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_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index ad87d6953d3..9a8ccaa7cc5 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -319,6 +319,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
             // some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
             // to detect those here and also give them no data
             _ if matches!(layout.abi, Abi::Aggregate { .. })
+                && matches!(layout.variants, abi::Variants::Single { .. })
                 && matches!(&layout.fields, abi::FieldsShape::Arbitrary { offsets, .. } if offsets.len() == 0) =>
             {
                 Immediate::Uninit
@@ -328,8 +329,9 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
                 assert_eq!(offset.bytes(), 0);
                 assert!(
                     match (self.layout.abi, layout.abi) {
-                        (Abi::Scalar(..), Abi::Scalar(..)) => true,
-                        (Abi::ScalarPair(..), Abi::ScalarPair(..)) => true,
+                        (Abi::Scalar(l), Abi::Scalar(r)) => l.size(cx) == r.size(cx),
+                        (Abi::ScalarPair(l1, l2), Abi::ScalarPair(r1, r2)) =>
+                            l1.size(cx) == r1.size(cx) && l2.size(cx) == r2.size(cx),
                         _ => false,
                     },
                     "cannot project into {} immediate with equally-sized field {}\nouter ABI: {:#?}\nfield ABI: {:#?}",
@@ -344,16 +346,23 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
             (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
                 assert_matches!(layout.abi, Abi::Scalar(..));
                 Immediate::from(if offset.bytes() == 0 {
-                    debug_assert_eq!(layout.size, a.size(cx));
+                    // It is "okay" to transmute from `usize` to a pointer (GVN relies on that).
+                    // So only compare the size.
+                    assert_eq!(layout.size, a.size(cx));
                     a_val
                 } else {
-                    debug_assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi));
-                    debug_assert_eq!(layout.size, b.size(cx));
+                    assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi));
+                    assert_eq!(layout.size, b.size(cx));
                     b_val
                 })
             }
             // everything else is a bug
-            _ => bug!("invalid field access on immediate {}, layout {:#?}", self, self.layout),
+            _ => bug!(
+                "invalid field access on immediate {} at offset {}, original layout {:#?}",
+                self,
+                offset.bytes(),
+                self.layout
+            ),
         };
 
         ImmTy::from_immediate(inner_val, layout)
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 2f860f9f942..e9ba12dbcc4 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -512,7 +512,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                     self.tcx.offset_of_subfield(self.param_env, layout, fields.iter()).bytes();
                 ImmTy::from_uint(val, usize_layout())
             }
-            UbChecks => ImmTy::from_bool(self.tcx.sess.ub_checks(), *self.tcx),
+            UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),
         })
     }
 }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 2b7dc040f64..e49ae60e890 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;
@@ -391,13 +393,17 @@ fn run_compiler(
 
         let linker = compiler.enter(|queries| {
             let early_exit = || early_exit().map(|_| None);
+
+            // Parse the crate root source code (doesn't parse submodules yet)
+            // Everything else is parsed during macro expansion.
             queries.parse()?;
 
-            if let Some(ppm) = &sess.opts.pretty {
-                if ppm.needs_ast_map() {
+            // If pretty printing is requested: Figure out the representation, print it and exit
+            if let Some(pp_mode) = sess.opts.pretty {
+                if pp_mode.needs_ast_map() {
                     queries.global_ctxt()?.enter(|tcx| {
                         tcx.ensure().early_lint_checks(());
-                        pretty::print(sess, *ppm, pretty::PrintExtra::NeedsAstMap { tcx });
+                        pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
                         Ok(())
                     })?;
 
@@ -408,7 +414,7 @@ fn run_compiler(
                     let krate = queries.parse()?;
                     pretty::print(
                         sess,
-                        *ppm,
+                        pp_mode,
                         pretty::PrintExtra::AfterParsing { krate: &*krate.borrow() },
                     );
                 }
@@ -463,12 +469,8 @@ fn run_compiler(
             linker.link(sess, codegen_backend)?
         }
 
-        if sess.opts.unstable_opts.print_fuel.is_some() {
-            eprintln!(
-                "Fuel used by {}: {}",
-                sess.opts.unstable_opts.print_fuel.as_ref().unwrap(),
-                sess.print_fuel.load(Ordering::SeqCst)
-            );
+        if let Some(fuel) = sess.opts.unstable_opts.print_fuel.as_deref() {
+            eprintln!("Fuel used by {}: {}", fuel, sess.print_fuel.load(Ordering::SeqCst));
         }
 
         Ok(())
@@ -485,36 +487,43 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileNa
     (odir, ofile)
 }
 
-// Extract input (string or file and optional path) from matches.
+/// Extract input (string or file and optional path) from matches.
+/// This handles reading from stdin if `-` is provided.
 fn make_input(
     early_dcx: &EarlyDiagCtxt,
     free_matches: &[String],
 ) -> Result<Option<Input>, ErrorGuaranteed> {
-    let [ifile] = free_matches else { return Ok(None) };
-    if ifile == "-" {
-        let mut src = String::new();
-        if io::stdin().read_to_string(&mut src).is_err() {
-            // Immediately stop compilation if there was an issue reading
-            // the input (for example if the input stream is not UTF-8).
-            let reported =
-                early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8");
-            return Err(reported);
-        }
-        if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
+    let [input_file] = free_matches else { return Ok(None) };
+
+    if input_file != "-" {
+        // Normal `Input::File`
+        return Ok(Some(Input::File(PathBuf::from(input_file))));
+    }
+
+    // read from stdin as `Input::Str`
+    let mut input = String::new();
+    if io::stdin().read_to_string(&mut input).is_err() {
+        // Immediately stop compilation if there was an issue reading
+        // the input (for example if the input stream is not UTF-8).
+        let reported =
+            early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8");
+        return Err(reported);
+    }
+
+    let name = match env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
+        Ok(path) => {
             let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
                 "when UNSTABLE_RUSTDOC_TEST_PATH is set \
                                     UNSTABLE_RUSTDOC_TEST_LINE also needs to be set",
             );
             let line = isize::from_str_radix(&line, 10)
                 .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
-            let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
-            Ok(Some(Input::Str { name: file_name, input: src }))
-        } else {
-            Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src }))
+            FileName::doc_test_source_code(PathBuf::from(path), line)
         }
-    } else {
-        Ok(Some(Input::File(PathBuf::from(ifile))))
-    }
+        Err(_) => FileName::anon_source_code(&input),
+    };
+
+    Ok(Some(Input::Str { name, input }))
 }
 
 /// Whether to stop or continue compilation.
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 c44f136120a..b1db44dd215 100644
--- a/compiler/rustc_errors/src/markdown/parse.rs
+++ b/compiler/rustc_errors/src/markdown/parse.rs
@@ -74,13 +74,13 @@ 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())
 }
 
 /// Parse a buffer with specified context
-fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'_> {
+fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'a> {
     use ParseOpt as Po;
     use Prev::{Escape, Newline, Whitespace};
 
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_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index a44e794ee12..e0b64b276eb 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -59,7 +59,7 @@ pub trait Translate {
         &'a self,
         message: &'a DiagMessage,
         args: &'a FluentArgs<'_>,
-    ) -> Result<Cow<'_, str>, TranslateError<'_>> {
+    ) -> Result<Cow<'a, str>, TranslateError<'a>> {
         trace!(?message, ?args);
         let (identifier, attr) = match message {
             DiagMessage::Str(msg) | DiagMessage::Translated(msg) => {
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/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index a4a2028e26e..9223c3c322a 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -115,6 +115,8 @@ declare_features! (
     (accepted, conservative_impl_trait, "1.26.0", Some(34511)),
     /// Allows calling constructor functions in `const fn`.
     (accepted, const_constructor, "1.40.0", Some(61456)),
+    /// Allows basic arithmetic on floating point types in a `const fn`.
+    (accepted, const_fn_floating_point_arithmetic, "CURRENT_RUSTC_VERSION", Some(57241)),
     /// Allows using and casting function pointers in a `const fn`.
     (accepted, const_fn_fn_ptr_basics, "1.61.0", Some(57563)),
     /// Allows trait bounds in `const fn`.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index d4c54b67f24..2747a14d60a 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -641,6 +641,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         ErrorFollowing, EncodeCrossCrate::Yes,
         "rustc_deprecated_safe_2024 is supposed to be used in libstd only",
     ),
+    rustc_attr!(
+        rustc_pub_transparent, Normal, template!(Word),
+        WarnFollowing, EncodeCrossCrate::Yes,
+        "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
+    ),
 
 
     // ==========================================================================
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_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index a1741ac33ca..f7ddc3e2c56 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -193,6 +193,8 @@ declare_features! (
     (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
     /// Allows identifying the `compiler_builtins` crate.
     (internal, compiler_builtins, "1.13.0", None),
+    /// Gating for a new desugaring of const arguments of usages of const parameters
+    (internal, const_arg_path, "1.81.0", None),
     /// Allows writing custom MIR
     (internal, custom_mir, "1.65.0", None),
     /// Outputs useful `assert!` messages
@@ -300,6 +302,7 @@ declare_features! (
     // FIXME: Document these and merge with the list below.
 
     // Unstable `#[target_feature]` directives.
+    (unstable, aarch64_unstable_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
     (unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
     (unstable, arm_target_feature, "1.27.0", Some(44839)),
     (unstable, avx512_target_feature, "1.27.0", Some(44839)),
@@ -400,8 +403,6 @@ declare_features! (
     (incomplete, const_closures, "1.68.0", Some(106003)),
     /// Allows the definition of `const extern fn` and `const unsafe extern fn`.
     (unstable, const_extern_fn, "1.40.0", Some(64926)),
-    /// Allows basic arithmetic on floating point types in a `const fn`.
-    (unstable, const_fn_floating_point_arithmetic, "1.48.0", Some(57241)),
     /// Allows `for _ in _` loops in const contexts.
     (unstable, const_for, "1.56.0", Some(87575)),
     /// Allows using `&mut` in constant functions.
@@ -594,6 +595,8 @@ declare_features! (
     (unstable, strict_provenance, "1.61.0", Some(95228)),
     /// Allows string patterns to dereference values to match them.
     (unstable, string_deref_patterns, "1.67.0", Some(87121)),
+    /// Allows structs to carry target_feature information.
+    (incomplete, struct_target_features, "CURRENT_RUSTC_VERSION", Some(129107)),
     /// Allows the use of `#[target_feature]` on safe functions.
     (unstable, target_feature_11, "1.45.0", Some(69098)),
     /// Allows using `#[thread_local]` on `static` items.
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..36e29d2dcb2 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
@@ -319,6 +326,41 @@ impl DefKind {
             | DefKind::ExternCrate => false,
         }
     }
+
+    /// Whether `query struct_target_features` should be used with this definition.
+    pub fn has_struct_target_features(self) -> bool {
+        match self {
+            DefKind::Struct | DefKind::Union | DefKind::Enum => true,
+            DefKind::Fn
+            | DefKind::AssocFn
+            | DefKind::Ctor(..)
+            | DefKind::Closure
+            | DefKind::Static { .. }
+            | DefKind::Mod
+            | DefKind::Variant
+            | DefKind::Trait
+            | DefKind::TyAlias
+            | DefKind::ForeignTy
+            | DefKind::TraitAlias
+            | DefKind::AssocTy
+            | DefKind::Const
+            | DefKind::AssocConst
+            | DefKind::Macro(..)
+            | DefKind::Use
+            | DefKind::ForeignMod
+            | DefKind::OpaqueTy
+            | DefKind::Impl { .. }
+            | DefKind::Field
+            | DefKind::TyParam
+            | DefKind::ConstParam
+            | DefKind::LifetimeParam
+            | DefKind::AnonConst
+            | DefKind::InlineConst
+            | DefKind::SyntheticCoroutineBody
+            | DefKind::GlobalAsm
+            | DefKind::ExternCrate => false,
+        }
+    }
 }
 
 /// The resolution of a path or export.
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 16eeb57b2b9..d414bcdb95b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -529,7 +529,7 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
 
         match tcx.named_bound_var(hir_id) {
             Some(ResolvedArg::EarlyBound(def_id)) => {
-                expected_captures.insert(def_id);
+                expected_captures.insert(def_id.to_def_id());
 
                 // Make sure we allow capturing these lifetimes through `Self` and
                 // `T::Assoc` projection syntax, too. These will occur when we only
@@ -538,7 +538,7 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
                 // feature -- see <https://github.com/rust-lang/rust/pull/115659>.
                 if let DefKind::LifetimeParam = tcx.def_kind(def_id)
                     && let Some(def_id) = tcx
-                        .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
+                        .map_opaque_lifetime_to_parent_lifetime(def_id)
                         .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
                 {
                     shadowed_captures.insert(def_id);
@@ -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()
@@ -1259,7 +1259,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
                 ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
                 ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
                 ty::Adt(def, args) => {
-                    if !def.did().is_local() {
+                    if !def.did().is_local() && !tcx.has_attr(def.did(), sym::rustc_pub_transparent)
+                    {
                         let non_exhaustive = def.is_variant_list_non_exhaustive()
                             || def
                                 .variants()
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 80daaa60324..d2b7ede6523 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -7,7 +7,8 @@ use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT
 use rustc_middle::span_bug;
 use rustc_middle::traits::{ObligationCause, Reveal};
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
+    TypeVisitableExt, TypeVisitor,
 };
 use rustc_span::Span;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -177,6 +178,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         return;
     };
 
+    if trait_bounds.references_error() || impl_bounds.references_error() {
+        return;
+    }
+
     // For quicker lookup, use an `IndexSet` (we don't use one earlier because
     // it's not foldable..).
     // Also, We have to anonymize binders in these types because they may contain
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 d4b2c3f8a87..cb66179ec80 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -747,7 +747,7 @@ fn region_known_to_outlive<'tcx>(
     region_b: ty::Region<'tcx>,
 ) -> bool {
     test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
-        infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP), region_b, region_a);
+        infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP, None), region_b, region_a);
     })
 }
 
@@ -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.rs b/compiler/rustc_hir_analysis/src/collect.rs
index f75954c9edf..3acf2c63145 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -34,7 +34,7 @@ use rustc_infer::traits::ObligationCause;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
-use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, Upcast};
+use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -70,7 +70,6 @@ pub fn provide(providers: &mut Providers) {
         impl_super_outlives: item_bounds::impl_super_outlives,
         generics_of: generics_of::generics_of,
         predicates_of: predicates_of::predicates_of,
-        predicates_defined_on,
         explicit_predicates_of: predicates_of::explicit_predicates_of,
         explicit_super_predicates_of: predicates_of::explicit_super_predicates_of,
         explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
@@ -392,7 +391,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
     }
 
     fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
-        if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
+        if let RegionInferReason::ObjectLifetimeDefault = reason {
             let e = struct_span_code_err!(
                 self.dcx(),
                 span,
@@ -1775,34 +1774,6 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
     })
 }
 
-/// Returns a list of type predicates for the definition with ID `def_id`, including inferred
-/// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
-/// inferred constraints concerning which regions outlive other regions.
-#[instrument(level = "debug", skip(tcx))]
-fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    let mut result = tcx.explicit_predicates_of(def_id);
-    debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result);
-    let inferred_outlives = tcx.inferred_outlives_of(def_id);
-    if !inferred_outlives.is_empty() {
-        debug!(
-            "predicates_defined_on: inferred_outlives_of({:?}) = {:?}",
-            def_id, inferred_outlives,
-        );
-        let inferred_outlives_iter =
-            inferred_outlives.iter().map(|(clause, span)| ((*clause).upcast(tcx), *span));
-        if result.predicates.is_empty() {
-            result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter);
-        } else {
-            result.predicates = tcx.arena.alloc_from_iter(
-                result.predicates.into_iter().copied().chain(inferred_outlives_iter),
-            );
-        }
-    }
-
-    debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
-    result
-}
-
 fn compute_sig_of_foreign_fn_decl<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 6ac4802b195..bba8b0497be 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -18,10 +18,26 @@ use crate::delegation::inherit_predicates_for_delegation_item;
 use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
 
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
-/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
-/// `Self: Trait` predicates for traits.
+/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
+/// inferred constraints concerning which regions outlive other regions.
+#[instrument(level = "debug", skip(tcx))]
 pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    let mut result = tcx.predicates_defined_on(def_id);
+    let mut result = tcx.explicit_predicates_of(def_id);
+    debug!("predicates_of: explicit_predicates_of({:?}) = {:?}", def_id, result);
+
+    let inferred_outlives = tcx.inferred_outlives_of(def_id);
+    if !inferred_outlives.is_empty() {
+        debug!("predicates_of: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives,);
+        let inferred_outlives_iter =
+            inferred_outlives.iter().map(|(clause, span)| ((*clause).upcast(tcx), *span));
+        if result.predicates.is_empty() {
+            result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter);
+        } else {
+            result.predicates = tcx.arena.alloc_from_iter(
+                result.predicates.into_iter().copied().chain(inferred_outlives_iter),
+            );
+        }
+    }
 
     if tcx.is_trait(def_id) {
         // For traits, add `Self: Trait` predicate. This is
@@ -51,7 +67,8 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
                 .chain(std::iter::once((ty::TraitRef::identity(tcx, def_id).upcast(tcx), span))),
         );
     }
-    debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
+
+    debug!("predicates_of({:?}) = {:?}", def_id, result);
     result
 }
 
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 ae0c70d2326..e38492d9e64 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -13,7 +13,6 @@ use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node};
 use rustc_macros::extension;
@@ -22,7 +21,7 @@ use rustc_middle::middle::resolve_bound_vars::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_middle::{bug, span_bug};
-use rustc_span::def_id::DefId;
+use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
@@ -32,7 +31,7 @@ use crate::errors;
 impl ResolvedArg {
     fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
         debug!("ResolvedArg::early: def_id={:?}", param.def_id);
-        (param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))
+        (param.def_id, ResolvedArg::EarlyBound(param.def_id))
     }
 
     fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
@@ -41,10 +40,10 @@ impl ResolvedArg {
             "ResolvedArg::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
             idx, param, depth, param.def_id,
         );
-        (param.def_id, ResolvedArg::LateBound(depth, idx, param.def_id.to_def_id()))
+        (param.def_id, ResolvedArg::LateBound(depth, idx, param.def_id))
     }
 
-    fn id(&self) -> Option<DefId> {
+    fn id(&self) -> Option<LocalDefId> {
         match *self {
             ResolvedArg::StaticLifetime | ResolvedArg::Error(_) => None,
 
@@ -288,13 +287,14 @@ fn late_arg_as_bound_arg<'tcx>(
 ) -> ty::BoundVariableKind {
     match arg {
         ResolvedArg::LateBound(_, _, def_id) => {
-            let name = tcx.hir().name(tcx.local_def_id_to_hir_id(def_id.expect_local()));
+            let def_id = def_id.to_def_id();
+            let name = tcx.item_name(def_id);
             match param.kind {
                 GenericParamKind::Lifetime { .. } => {
-                    ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
+                    ty::BoundVariableKind::Region(ty::BrNamed(def_id, name))
                 }
                 GenericParamKind::Type { .. } => {
-                    ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(*def_id, name))
+                    ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, name))
                 }
                 GenericParamKind::Const { .. } => ty::BoundVariableKind::Const,
             }
@@ -717,7 +717,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     // In the future, this should be fixed and this error should be removed.
                     let def = self.map.defs.get(&lifetime.hir_id).copied();
                     let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
-                    let Some(lifetime_def_id) = lifetime_def_id.as_local() else { continue };
                     let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
 
                     let bad_place = match self.tcx.hir_node(self.tcx.parent_hir_id(lifetime_hir_id))
@@ -1150,7 +1149,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             .param_def_id_to_index(self.tcx, region_def_id.to_def_id())
                             .is_some()
                     {
-                        break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id()));
+                        break Some(ResolvedArg::EarlyBound(region_def_id));
                     }
                     break None;
                 }
@@ -1259,7 +1258,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     kind => span_bug!(
                         use_span,
                         "did not expect to resolve lifetime to {}",
-                        kind.descr(param_def_id)
+                        kind.descr(param_def_id.to_def_id())
                     ),
                 };
                 def = ResolvedArg::Error(guar);
@@ -1277,10 +1276,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         kind: hir::ImplItemKind::Fn(..),
                         ..
                     }) => {
-                        def = ResolvedArg::Free(owner_id.to_def_id(), def.id().unwrap());
+                        def = ResolvedArg::Free(owner_id.def_id, def.id().unwrap());
                     }
                     Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) => {
-                        def = ResolvedArg::Free(closure.def_id.to_def_id(), def.id().unwrap());
+                        def = ResolvedArg::Free(closure.def_id, def.id().unwrap());
                     }
                     _ => {}
                 }
@@ -1351,7 +1350,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                             .param_def_id_to_index(self.tcx, param_def_id.to_def_id())
                             .is_some()
                     {
-                        break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id()));
+                        break Some(ResolvedArg::EarlyBound(param_def_id));
                     }
                     break None;
                 }
@@ -2072,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/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index d1048b742a0..c8b0f03a929 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -331,7 +331,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     owner_def_id: LocalDefId,
-) -> Ty<'_> {
+) -> Ty<'tcx> {
     let tables = tcx.typeck(owner_def_id);
 
     // Check that all of the opaques we inferred during HIR are compatible.
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_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index d77cbe30536..af319fd53bd 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -608,7 +608,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
             let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
-            match &self_ty.kind() {
+            match self_ty.kind() {
                 // Point at the type that couldn't satisfy the bound.
                 ty::Adt(def, _) => {
                     bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 6aff518390f..7be45463f15 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -15,11 +15,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
     /// In edition 2021 and onward we emit a hard error for them.
-    pub(super) fn prohibit_or_lint_bare_trait_object_ty(
-        &self,
-        self_ty: &hir::Ty<'_>,
-        in_path: bool,
-    ) {
+    pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) {
         let tcx = self.tcx();
 
         let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
@@ -28,6 +24,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             return;
         };
 
+        let in_path = match tcx.parent_hir_node(self_ty.hir_id) {
+            hir::Node::Ty(hir::Ty {
+                kind: hir::TyKind::Path(hir::QPath::TypeRelative(qself, _)),
+                ..
+            })
+            | hir::Node::Expr(hir::Expr {
+                kind: hir::ExprKind::Path(hir::QPath::TypeRelative(qself, _)),
+                ..
+            })
+            | hir::Node::Pat(hir::Pat {
+                kind: hir::PatKind::Path(hir::QPath::TypeRelative(qself, _)),
+                ..
+            }) if qself.hir_id == self_ty.hir_id => true,
+            _ => false,
+        };
         let needs_bracket = in_path
             && !tcx
                 .sess
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 2fb1bcf2dbf..0cdd3e4a1c6 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -85,10 +85,9 @@ pub enum PredicateFilter {
 
 #[derive(Debug)]
 pub enum RegionInferReason<'a> {
-    /// Lifetime on a trait object behind a reference.
-    /// This allows inferring information from the reference.
-    BorrowedObjectLifetimeDefault,
-    /// A trait object's lifetime.
+    /// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
+    ExplicitObjectLifetime,
+    /// A trait object's lifetime when it is elided, e.g. `dyn Any`.
     ObjectLifetimeDefault,
     /// Generic lifetime parameter
     Param(&'a ty::GenericParamDef),
@@ -296,25 +295,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static,
 
             Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
-                let name = lifetime_name(def_id.expect_local());
+                let name = lifetime_name(def_id);
                 let br = ty::BoundRegion {
                     var: ty::BoundVar::from_u32(index),
-                    kind: ty::BrNamed(def_id, name),
+                    kind: ty::BrNamed(def_id.to_def_id(), name),
                 };
                 ty::Region::new_bound(tcx, debruijn, br)
             }
 
             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
-                let name = tcx.hir().ty_param_name(def_id.expect_local());
-                let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
+                let name = tcx.hir().ty_param_name(def_id);
+                let item_def_id = tcx.hir().ty_param_owner(def_id);
                 let generics = tcx.generics_of(item_def_id);
-                let index = generics.param_def_id_to_index[&def_id];
+                let index = generics.param_def_id_to_index[&def_id.to_def_id()];
                 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
             }
 
             Some(rbv::ResolvedArg::Free(scope, id)) => {
-                let name = lifetime_name(id.expect_local());
-                ty::Region::new_late_param(tcx, scope, ty::BrNamed(id, name))
+                let name = lifetime_name(id);
+                ty::Region::new_late_param(
+                    tcx,
+                    scope.to_def_id(),
+                    ty::BrNamed(id.to_def_id(), name),
+                )
 
                 // (*) -- not late-bound, won't change
             }
@@ -1053,7 +1056,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         // Find the type of the associated item, and the trait where the associated
         // item is declared.
-        let bound = match (&qself_ty.kind(), qself_res) {
+        let bound = match (qself_ty.kind(), qself_res) {
             (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
                 // `Self` in an impl of a trait -- we have a concrete self type and a
                 // trait reference.
@@ -1953,15 +1956,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let tcx = self.tcx();
         match tcx.named_bound_var(hir_id) {
             Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
-                let name = tcx.item_name(def_id);
+                let name = tcx.item_name(def_id.to_def_id());
                 let br = ty::BoundTy {
                     var: ty::BoundVar::from_u32(index),
-                    kind: ty::BoundTyKind::Param(def_id, name),
+                    kind: ty::BoundTyKind::Param(def_id.to_def_id(), name),
                 };
                 Ty::new_bound(tcx, debruijn, br)
             }
             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
-                let def_id = def_id.expect_local();
                 let item_def_id = tcx.hir().ty_param_owner(def_id);
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
@@ -1982,10 +1984,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
                 // Find the name and index of the const parameter by indexing the generics of
                 // the parent item and construct a `ParamConst`.
-                let item_def_id = tcx.parent(def_id);
+                let item_def_id = tcx.local_parent(def_id);
                 let generics = tcx.generics_of(item_def_id);
-                let index = generics.param_def_id_to_index[&def_id];
-                let name = tcx.item_name(def_id);
+                let index = generics.param_def_id_to_index[&def_id.to_def_id()];
+                let name = tcx.item_name(def_id.to_def_id());
                 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
             }
             Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
@@ -1996,16 +1998,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
     }
 
-    /// Lower a type from the HIR to our internal notion of a type.
-    pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
-        self.lower_ty_common(hir_ty, false, false)
-    }
-
-    /// Lower a type inside of a path from the HIR to our internal notion of a type.
-    pub fn lower_ty_in_path(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
-        self.lower_ty_common(hir_ty, false, true)
-    }
-
     fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
         let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
         match idx {
@@ -2023,7 +2015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// 2. `in_path`: Whether the type appears inside of a path.
     ///    Used to provide correct diagnostics for bare trait object types.
     #[instrument(level = "debug", skip(self), ret)]
-    fn lower_ty_common(&self, hir_ty: &hir::Ty<'tcx>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
+    pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
         let tcx = self.tcx();
 
         let result_ty = match &hir_ty.kind {
@@ -2033,7 +2025,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             hir::TyKind::Ref(region, mt) => {
                 let r = self.lower_lifetime(region, RegionInferReason::Reference);
                 debug!(?r);
-                let t = self.lower_ty_common(mt.ty, true, false);
+                let t = self.lower_ty(mt.ty);
                 Ty::new_ref(tcx, r, t, mt.mutbl)
             }
             hir::TyKind::Never => tcx.types.never,
@@ -2062,20 +2054,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 )
             }
             hir::TyKind::TraitObject(bounds, lifetime, repr) => {
-                self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path);
+                self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
 
                 let repr = match repr {
                     TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
                     TraitObjectSyntax::DynStar => ty::DynStar,
                 };
-                self.lower_trait_object_ty(
-                    hir_ty.span,
-                    hir_ty.hir_id,
-                    bounds,
-                    lifetime,
-                    borrowed,
-                    repr,
-                )
+                self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
             }
             hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
                 debug!(?maybe_qself, ?path);
@@ -2103,7 +2088,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
             hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
                 debug!(?qself, ?segment);
-                let ty = self.lower_ty_common(qself, false, true);
+                let ty = self.lower_ty(qself);
                 self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
                     .map(|(ty, _, _)| ty)
                     .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index 31d1750f33d..52e167379b5 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -30,7 +30,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         hir_id: hir::HirId,
         hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
         lifetime: &hir::Lifetime,
-        borrowed: bool,
         representation: DynKind,
     ) -> Ty<'tcx> {
         let tcx = self.tcx();
@@ -325,22 +324,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         v.dedup();
         let existential_predicates = tcx.mk_poly_existential_predicates(&v);
 
-        // Use explicitly-specified region bound.
+        // Use explicitly-specified region bound, unless the bound is missing.
         let region_bound = if !lifetime.is_elided() {
-            self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
+            self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
         } else {
             self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
+                // Curiously, we prefer object lifetime default for `+ '_`...
                 if tcx.named_bound_var(lifetime.hir_id).is_some() {
-                    self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
+                    self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
                 } else {
-                    self.re_infer(
-                        span,
-                        if borrowed {
-                            RegionInferReason::ObjectLifetimeDefault
+                    let reason =
+                        if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
+                            if let hir::Node::Ty(hir::Ty {
+                                kind: hir::TyKind::Ref(parent_lifetime, _),
+                                ..
+                            }) = tcx.parent_hir_node(hir_id)
+                                && tcx.named_bound_var(parent_lifetime.hir_id).is_none()
+                            {
+                                // Parent lifetime must have failed to resolve. Don't emit a redundant error.
+                                RegionInferReason::ExplicitObjectLifetime
+                            } else {
+                                RegionInferReason::ObjectLifetimeDefault
+                            }
                         } else {
-                            RegionInferReason::BorrowedObjectLifetimeDefault
-                        },
-                    )
+                            RegionInferReason::ExplicitObjectLifetime
+                        };
+                    self.re_infer(span, reason)
                 }
             })
         };
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/dump.rs b/compiler/rustc_hir_analysis/src/variance/dump.rs
index 1a17dabb677..ace183986bd 100644
--- a/compiler/rustc_hir_analysis/src/variance/dump.rs
+++ b/compiler/rustc_hir_analysis/src/variance/dump.rs
@@ -1,18 +1,36 @@
+use std::fmt::Write;
+
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::CRATE_DEF_ID;
-use rustc_middle::ty::TyCtxt;
+use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
+use rustc_middle::ty::{GenericArgs, TyCtxt};
 use rustc_span::symbol::sym;
 
+fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
+    let variances = tcx.variances_of(def_id);
+    let generics = GenericArgs::identity_for_item(tcx, def_id);
+    // 7 = 2-letter parameter + ": " + 1-letter variance + ", "
+    let mut ret = String::with_capacity(2 + 7 * variances.len());
+    ret.push('[');
+    for (arg, variance) in generics.iter().zip(variances.iter()) {
+        write!(ret, "{arg}: {variance:?}, ").unwrap();
+    }
+    // Remove trailing `, `.
+    if !variances.is_empty() {
+        ret.pop();
+        ret.pop();
+    }
+    ret.push(']');
+    ret
+}
+
 pub(crate) fn variances(tcx: TyCtxt<'_>) {
     if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
         for id in tcx.hir().items() {
             let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
 
-            let variances = tcx.variances_of(id.owner_id);
-
             tcx.dcx().emit_err(crate::errors::VariancesOf {
                 span: tcx.def_span(id.owner_id),
-                variances: format!("{variances:?}"),
+                variances: format_variances(tcx, id.owner_id.def_id),
             });
         }
     }
@@ -22,11 +40,9 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
             continue;
         }
 
-        let variances = tcx.variances_of(id.owner_id);
-
         tcx.dcx().emit_err(crate::errors::VariancesOf {
             span: tcx.def_span(id.owner_id),
-            variances: format!("{variances:?}"),
+            variances: format_variances(tcx, id.owner_id.def_id),
         });
     }
 }
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 9b34c59f1f1..54ddff98869 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -106,7 +106,7 @@ fn identity(_: Ty<'_>) -> Vec<Adjustment<'_>> {
     vec![]
 }
 
-fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'_>> {
+fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> {
     move |target| vec![Adjustment { kind, target }]
 }
 
@@ -850,6 +850,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     }
 
                     // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
+                    // FIXME(struct_target_features): should this be true also for functions that inherit
+                    // target features from structs?
 
                     if b_hdr.safety == hir::Safety::Safe
                         && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
@@ -976,7 +978,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 +1013,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 +1034,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 +1049,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 +1343,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 +1352,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 +1363,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 +1372,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 +1388,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 +1396,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 +1405,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 +1427,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 +1922,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 +1936,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 fec6efdc0f7..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>,
@@ -841,6 +841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ret_ty = ret_coercion.borrow().expected_ty();
         let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
         let mut span = return_expr.span;
+        let mut hir_id = return_expr.hir_id;
         // Use the span of the trailing expression for our cause,
         // not the span of the entire function
         if !explicit_return
@@ -848,6 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             && let Some(last_expr) = body.expr
         {
             span = last_expr.span;
+            hir_id = last_expr.hir_id;
         }
         ret_coercion.borrow_mut().coerce(
             self,
@@ -864,6 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.select_obligations_where_possible(|errors| {
                 self.point_at_return_for_opaque_ty_error(
                     errors,
+                    hir_id,
                     span,
                     return_expr_ty,
                     return_expr.span,
@@ -921,6 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn point_at_return_for_opaque_ty_error(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
+        hir_id: HirId,
         span: Span,
         return_expr_ty: Ty<'tcx>,
         return_span: Span,
@@ -935,7 +939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let new_cause = ObligationCause::new(
                     cause.span,
                     cause.body_id,
-                    ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, span))),
+                    ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, hir_id))),
                 );
                 *cause = new_cause;
             }
@@ -973,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 b169f75796b..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,
@@ -798,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // to be object-safe.
                 // We manually call `register_wf_obligation` in the success path
                 // below.
-                let ty = self.lowerer().lower_ty_in_path(qself);
+                let ty = self.lowerer().lower_ty(qself);
                 (LoweredTy::from_raw(self, span, ty), qself, segment)
             }
             QPath::LangItem(..) => {
@@ -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 703273968c5..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>,
@@ -2975,7 +2975,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut suffix_suggestion = sugg.clone();
         suffix_suggestion.push((
             if matches!(
-                (&expected_ty.kind(), &checked_ty.kind()),
+                (expected_ty.kind(), checked_ty.kind()),
                 (ty::Int(_) | ty::Uint(_), ty::Float(_))
             ) {
                 // Remove fractional part from literal, for example `42.0f32` into `42`
@@ -3077,7 +3077,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 err.multipart_suggestion_verbose(msg, suggestion, Applicability::MachineApplicable);
             };
 
-        match (&expected_ty.kind(), &checked_ty.kind()) {
+        match (expected_ty.kind(), checked_ty.kind()) {
             (ty::Int(exp), ty::Int(found)) => {
                 let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width())
                 {
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 9ec101196a4..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]
@@ -87,14 +88,17 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef
     &tcx.typeck(def_id).used_trait_imports
 }
 
-fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
+fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
     let fallback = move || tcx.type_of(def_id.to_def_id()).instantiate_identity();
     typeck_with_fallback(tcx, def_id, fallback, None)
 }
 
 /// Used only to get `TypeckResults` for type inference during error recovery.
 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
-fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
+fn diagnostic_only_typeck<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> &'tcx ty::TypeckResults<'tcx> {
     let fallback = move || {
         let span = tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
         Ty::new_error_with_message(tcx, span, "diagnostic only typeck table used")
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 3df32dd8505..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,
@@ -1012,7 +1012,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
             let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
                 let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
-                match &self_ty.kind() {
+                match self_ty.kind() {
                     // Point at the type that couldn't satisfy the bound.
                     ty::Adt(def, _) => {
                         bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
@@ -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 c4f74adb420..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>,
@@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // More generally, the expected type wants a tuple variant with one field of an
         // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
         // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
-        let missing_parentheses = match (&expected.kind(), fields, had_err) {
+        let missing_parentheses = match (expected.kind(), fields, had_err) {
             // #67037: only do this if we could successfully type-check the expected type against
             // the tuple struct pattern. Otherwise the args could get out of range on e.g.,
             // `let P() = U;` where `P != U` with `struct P<T>(T);`.
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/messages.ftl b/compiler/rustc_incremental/messages.ftl
index de2177ebb6e..2a65101d360 100644
--- a/compiler/rustc_incremental/messages.ftl
+++ b/compiler/rustc_incremental/messages.ftl
@@ -99,6 +99,4 @@ incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
 
 incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized
 
-incremental_write_dep_graph = failed to write dependency graph to `{$path}`: {$err}
-
 incremental_write_new = failed to write {$name} to `{$path}`: {$err}
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 b68c149d398..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,91 +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_write_dep_graph)]
-pub struct WriteDepGraph<'a> {
-    pub path: &'a Path,
-    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,
@@ -289,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,
@@ -304,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 b5e4f02a8d1..eb47ac3c68e 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -2,6 +2,8 @@
 #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))]
 #![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/context.rs b/compiler/rustc_infer/src/infer/context.rs
index f35a8162d96..95888beb6b1 100644
--- a/compiler/rustc_infer/src/infer/context.rs
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -167,7 +167,7 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
     }
 
     fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
-        self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
+        self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None), sub, sup)
     }
 
     fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
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/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index f2fc25a2d2e..5aa7f259685 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -390,7 +390,7 @@ pub enum SubregionOrigin<'tcx> {
 
     /// The given region parameter was instantiated with a region
     /// that must outlive some other region.
-    RelateRegionParamBound(Span),
+    RelateRegionParamBound(Span, Option<Ty<'tcx>>),
 
     /// Creating a pointer `b` to contents of another reference.
     Reborrow(Span),
@@ -859,7 +859,7 @@ impl<'tcx> InferCtxt<'tcx> {
     ) {
         self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
             let origin = SubregionOrigin::from_obligation_cause(cause, || {
-                RelateRegionParamBound(cause.span)
+                RelateRegionParamBound(cause.span, None)
             });
             self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
         })
@@ -1685,7 +1685,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             Subtype(ref a) => a.span(),
             RelateObjectBound(a) => a,
             RelateParamBound(a, ..) => a,
-            RelateRegionParamBound(a) => a,
+            RelateRegionParamBound(a, _) => a,
             Reborrow(a) => a,
             ReferenceOutlivesReferent(_, a) => a,
             CompareImplItemObligation { span, .. } => span,
@@ -1726,6 +1726,10 @@ impl<'tcx> SubregionOrigin<'tcx> {
                 SubregionOrigin::AscribeUserTypeProvePredicate(span)
             }
 
+            traits::ObligationCauseCode::ObjectTypeBound(ty, _reg) => {
+                SubregionOrigin::RelateRegionParamBound(cause.span, Some(ty))
+            }
+
             _ => default(),
         }
     }
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/queries.rs b/compiler/rustc_interface/src/queries.rs
index c5d56c15c6e..44e07b36b61 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -98,7 +98,7 @@ impl<'tcx> Queries<'tcx> {
         self.parse.compute(|| passes::parse(&self.compiler.sess))
     }
 
-    pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
+    pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'tcx, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
             let krate = self.parse()?.steal();
 
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/messages.ftl b/compiler/rustc_lint/messages.ftl
index 28aef9055ef..08a50050a36 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -361,6 +361,11 @@ lint_improper_ctypes_box = box cannot be represented as a single pointer
 lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
 
 lint_improper_ctypes_char_reason = the `char` type has no C equivalent
+
+lint_improper_ctypes_cstr_help =
+    consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+lint_improper_ctypes_cstr_reason = `CStr`/`CString` do not have a guaranteed layout
+
 lint_improper_ctypes_dyn = trait objects have no C equivalent
 
 lint_improper_ctypes_enum_repr_help =
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 85132dd4f98..d8482567bbe 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1925,8 +1925,8 @@ impl ExplicitOutlivesRequirements {
     fn lifetimes_outliving_lifetime<'tcx>(
         tcx: TyCtxt<'tcx>,
         inferred_outlives: impl Iterator<Item = &'tcx (ty::Clause<'tcx>, Span)>,
-        item: DefId,
-        lifetime: DefId,
+        item: LocalDefId,
+        lifetime: LocalDefId,
     ) -> Vec<ty::Region<'tcx>> {
         let item_generics = tcx.generics_of(item);
 
@@ -1934,7 +1934,7 @@ impl ExplicitOutlivesRequirements {
             .filter_map(|(clause, _)| match clause.kind().skip_binder() {
                 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
                     ty::ReEarlyParam(ebr)
-                        if item_generics.region_param(ebr, tcx).def_id == lifetime =>
+                        if item_generics.region_param(ebr, tcx).def_id == lifetime.to_def_id() =>
                     {
                         Some(b)
                     }
@@ -1982,7 +1982,7 @@ impl ExplicitOutlivesRequirements {
                 let is_inferred = match tcx.named_bound_var(lifetime.hir_id) {
                     Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives
                         .iter()
-                        .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id })),
+                        .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id.to_def_id() })),
                     _ => false,
                 };
 
@@ -2097,7 +2097,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                         inferred_outlives
                                             .iter()
                                             .filter(|(_, span)| !predicate.span.contains(*span)),
-                                        item.owner_id.to_def_id(),
+                                        item.owner_id.def_id,
                                         region_def_id,
                                     ),
                                     &predicate.bounds,
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
index 2060858cc8a..a9de258e005 100644
--- a/compiler/rustc_lint/src/drop_forget_useless.rs
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -151,10 +151,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
                     && let Node::Stmt(stmt) = node
                     && let StmtKind::Semi(e) = stmt.kind
                     && e.hir_id == expr.hir_id
+                    && let Some(arg_span) = arg.span.find_ancestor_inside(expr.span)
                 {
                     UseLetUnderscoreIgnoreSuggestion::Suggestion {
-                        start_span: expr.span.shrink_to_lo().until(arg.span),
-                        end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
+                        start_span: expr.span.shrink_to_lo().until(arg_span),
+                        end_span: arg_span.shrink_to_hi().until(expr.span.shrink_to_hi()),
                     }
                 } else {
                     UseLetUnderscoreIgnoreSuggestion::Note
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 990fb2d16f9..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! {
@@ -300,16 +302,17 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
                         Some(
                             ResolvedArg::EarlyBound(def_id) | ResolvedArg::LateBound(_, _, def_id),
                         ) => {
-                            if self.tcx.def_kind(self.tcx.parent(def_id)) == DefKind::OpaqueTy {
+                            if self.tcx.def_kind(self.tcx.local_parent(def_id)) == DefKind::OpaqueTy
+                            {
                                 let def_id = self
                                     .tcx
-                                    .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local())
+                                    .map_opaque_lifetime_to_parent_lifetime(def_id)
                                     .opt_param_def_id(self.tcx, self.parent_def_id.to_def_id())
                                     .expect("variable should have been duplicated from parent");
 
                                 explicitly_captured.insert(def_id);
                             } else {
-                                explicitly_captured.insert(def_id);
+                                explicitly_captured.insert(def_id.to_def_id());
                             }
                         }
                         _ => {
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 044c9413f0b..65571815019 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -8,7 +8,7 @@ use rustc_hir::{
     BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat, PatKind,
     Path, PathSegment, QPath, Ty, TyKind,
 };
-use rustc_middle::ty::{self, Ty as MiddleTy};
+use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -415,14 +415,17 @@ declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE
 
 impl LateLintPass<'_> for Diagnostics {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        let collect_args_tys_and_spans = |args: &[Expr<'_>], reserve_one_extra: bool| {
+            let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra));
+            result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span)));
+            result
+        };
         // Only check function calls and method calls.
-        let (span, def_id, fn_gen_args, call_tys) = match expr.kind {
+        let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind {
             ExprKind::Call(callee, args) => {
                 match cx.typeck_results().node_type(callee.hir_id).kind() {
                     &ty::FnDef(def_id, fn_gen_args) => {
-                        let call_tys: Vec<_> =
-                            args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
-                        (callee.span, def_id, fn_gen_args, call_tys)
+                        (callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false))
                     }
                     _ => return, // occurs for fns passed as args
                 }
@@ -432,38 +435,40 @@ impl LateLintPass<'_> for Diagnostics {
                 else {
                     return;
                 };
-                let mut call_tys: Vec<_> =
-                    args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
-                call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self`
-                (span, def_id, fn_gen_args, call_tys)
+                let mut args = collect_args_tys_and_spans(args, true);
+                args.insert(0, (cx.tcx.types.self_param, _recv.span)); // dummy inserted for `self`
+                (span, def_id, fn_gen_args, args)
             }
             _ => return,
         };
 
-        // Is the callee marked with `#[rustc_lint_diagnostics]`?
-        let has_attr = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args)
-            .ok()
-            .flatten()
-            .is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
-
-        // Closure: is the type `{D,Subd}iagMessage`?
-        let is_diag_message = |ty: MiddleTy<'_>| {
-            if let Some(adt_def) = ty.ty_adt_def()
-                && let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
-                && matches!(name, sym::DiagMessage | sym::SubdiagMessage)
-            {
-                true
-            } else {
-                false
-            }
-        };
+        Self::diagnostic_outside_of_impl(cx, span, expr.hir_id, def_id, fn_gen_args);
+        Self::untranslatable_diagnostic(cx, def_id, &arg_tys_and_spans);
+    }
+}
 
-        // Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
-        let mut impl_into_diagnostic_message_params = vec![];
+impl Diagnostics {
+    // Is the type `{D,Subd}iagMessage`?
+    fn is_diag_message<'cx>(cx: &LateContext<'cx>, ty: MiddleTy<'cx>) -> bool {
+        if let Some(adt_def) = ty.ty_adt_def()
+            && let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
+            && matches!(name, sym::DiagMessage | sym::SubdiagMessage)
+        {
+            true
+        } else {
+            false
+        }
+    }
+
+    fn untranslatable_diagnostic<'cx>(
+        cx: &LateContext<'cx>,
+        def_id: DefId,
+        arg_tys_and_spans: &[(MiddleTy<'cx>, Span)],
+    ) {
         let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
         let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
         for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
-            if let ty::Param(p) = param_ty.kind() {
+            if let ty::Param(sig_param) = param_ty.kind() {
                 // It is a type parameter. Check if it is `impl Into<{D,Subd}iagMessage>`.
                 for pred in predicates.iter() {
                     if let Some(trait_pred) = pred.as_trait_clause()
@@ -471,27 +476,53 @@ impl LateLintPass<'_> for Diagnostics {
                         && trait_ref.self_ty() == param_ty // correct predicate for the param?
                         && cx.tcx.is_diagnostic_item(sym::Into, trait_ref.def_id)
                         && let ty1 = trait_ref.args.type_at(1)
-                        && is_diag_message(ty1)
+                        && Self::is_diag_message(cx, ty1)
                     {
-                        impl_into_diagnostic_message_params.push((i, p.name));
+                        // Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
+                        // with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
+                        // `UNTRANSLATABLE_DIAGNOSTIC` lint.
+                        let (arg_ty, arg_span) = arg_tys_and_spans[i];
+
+                        // Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
+                        let is_translatable = Self::is_diag_message(cx, arg_ty)
+                            || matches!(arg_ty.kind(), ty::Param(arg_param) if arg_param.name == sig_param.name);
+                        if !is_translatable {
+                            cx.emit_span_lint(
+                                UNTRANSLATABLE_DIAGNOSTIC,
+                                arg_span,
+                                UntranslatableDiag,
+                            );
+                        }
                     }
                 }
             }
         }
+    }
 
-        // Is the callee interesting?
-        if !has_attr && impl_into_diagnostic_message_params.is_empty() {
+    fn diagnostic_outside_of_impl<'cx>(
+        cx: &LateContext<'cx>,
+        span: Span,
+        current_id: HirId,
+        def_id: DefId,
+        fn_gen_args: GenericArgsRef<'cx>,
+    ) {
+        // Is the callee marked with `#[rustc_lint_diagnostics]`?
+        let Some(inst) =
+            ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args).ok().flatten()
+        else {
             return;
-        }
+        };
+        let has_attr = cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics);
+        if !has_attr {
+            return;
+        };
 
-        // Is the parent method marked with `#[rustc_lint_diagnostics]`?
-        let mut parent_has_attr = false;
-        for (hir_id, _parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
+        for (hir_id, _parent) in cx.tcx.hir().parent_iter(current_id) {
             if let Some(owner_did) = hir_id.as_owner()
                 && cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics)
             {
-                parent_has_attr = true;
-                break;
+                // The parent method is marked with `#[rustc_lint_diagnostics]`
+                return;
             }
         }
 
@@ -500,37 +531,22 @@ impl LateLintPass<'_> for Diagnostics {
         // - inside a parent function that is itself marked with `#[rustc_lint_diagnostics]`.
         //
         // Otherwise, emit a `DIAGNOSTIC_OUTSIDE_OF_IMPL` lint.
-        if has_attr && !parent_has_attr {
-            let mut is_inside_appropriate_impl = false;
-            for (_hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
-                debug!(?parent);
-                if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
-                    && let Impl { of_trait: Some(of_trait), .. } = impl_
-                    && let Some(def_id) = of_trait.trait_def_id()
-                    && let Some(name) = cx.tcx.get_diagnostic_name(def_id)
-                    && matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
-                {
-                    is_inside_appropriate_impl = true;
-                    break;
-                }
-            }
-            debug!(?is_inside_appropriate_impl);
-            if !is_inside_appropriate_impl {
-                cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
+        let mut is_inside_appropriate_impl = false;
+        for (_hir_id, parent) in cx.tcx.hir().parent_iter(current_id) {
+            debug!(?parent);
+            if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
+                && let Impl { of_trait: Some(of_trait), .. } = impl_
+                && let Some(def_id) = of_trait.trait_def_id()
+                && let Some(name) = cx.tcx.get_diagnostic_name(def_id)
+                && matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic)
+            {
+                is_inside_appropriate_impl = true;
+                break;
             }
         }
-
-        // Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
-        // with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
-        // `UNTRANSLATABLE_DIAGNOSTIC` lint.
-        for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
-            // Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
-            let arg_ty = call_tys[param_i];
-            let is_translatable = is_diag_message(arg_ty)
-                || matches!(arg_ty.kind(), ty::Param(p) if p.name == param_i_p_name);
-            if !is_translatable {
-                cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
-            }
+        debug!(?is_inside_appropriate_impl);
+        if !is_inside_appropriate_impl {
+            cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
         }
     }
 }
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 1828b6ea93c..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;
@@ -572,7 +573,8 @@ fn register_builtins(store: &mut LintStore) {
         "byte_slice_in_packed_struct_with_derive",
         "converted into hard error, see issue #107457 \
          <https://github.com/rust-lang/rust/issues/107457> for more information",
-    )
+    );
+    store.register_removed("writes_through_immutable_pointer", "converted into hard error");
 }
 
 fn register_internals(store: &mut LintStore) {
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 cb7a07116ce..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 }
     }
 }
@@ -985,6 +985,14 @@ struct ImproperCTypesVisitor<'a, 'tcx> {
     mode: CItemKind,
 }
 
+/// Accumulator for recursive ffi type checking
+struct CTypesVisitorState<'tcx> {
+    cache: FxHashSet<Ty<'tcx>>,
+    /// The original type being checked, before we recursed
+    /// to any other types it contains.
+    base_ty: Ty<'tcx>,
+}
+
 enum FfiResult<'tcx> {
     FfiSafe,
     FfiPhantom(Ty<'tcx>),
@@ -1000,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> {
@@ -1213,7 +1221,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     /// Checks if the given field's type is "ffi-safe".
     fn check_field_type_for_ffi(
         &self,
-        cache: &mut FxHashSet<Ty<'tcx>>,
+        acc: &mut CTypesVisitorState<'tcx>,
         field: &ty::FieldDef,
         args: GenericArgsRef<'tcx>,
     ) -> FfiResult<'tcx> {
@@ -1223,13 +1231,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             .tcx
             .try_normalize_erasing_regions(self.cx.param_env, field_ty)
             .unwrap_or(field_ty);
-        self.check_type_for_ffi(cache, field_ty)
+        self.check_type_for_ffi(acc, field_ty)
     }
 
     /// Checks if the given `VariantDef`'s field types are "ffi-safe".
     fn check_variant_for_ffi(
         &self,
-        cache: &mut FxHashSet<Ty<'tcx>>,
+        acc: &mut CTypesVisitorState<'tcx>,
         ty: Ty<'tcx>,
         def: ty::AdtDef<'tcx>,
         variant: &ty::VariantDef,
@@ -1239,7 +1247,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         let transparent_with_all_zst_fields = if def.repr().transparent() {
             if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
                 // Transparent newtypes have at most one non-ZST field which needs to be checked..
-                match self.check_field_type_for_ffi(cache, field, args) {
+                match self.check_field_type_for_ffi(acc, field, args) {
                     FfiUnsafe { ty, .. } if ty.is_unit() => (),
                     r => return r,
                 }
@@ -1257,7 +1265,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         // We can't completely trust `repr(C)` markings, so make sure the fields are actually safe.
         let mut all_phantom = !variant.fields.is_empty();
         for field in &variant.fields {
-            all_phantom &= match self.check_field_type_for_ffi(cache, field, args) {
+            all_phantom &= match self.check_field_type_for_ffi(acc, field, args) {
                 FfiSafe => false,
                 // `()` fields are FFI-safe!
                 FfiUnsafe { ty, .. } if ty.is_unit() => false,
@@ -1277,7 +1285,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
     /// Checks if the given type is "ffi-safe" (has a stable, well-defined
     /// representation which can be exported to C code).
-    fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> FfiResult<'tcx> {
+    fn check_type_for_ffi(
+        &self,
+        acc: &mut CTypesVisitorState<'tcx>,
+        ty: Ty<'tcx>,
+    ) -> FfiResult<'tcx> {
         use FfiResult::*;
 
         let tcx = self.cx.tcx;
@@ -1286,7 +1298,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         // `struct S(*mut S);`.
         // FIXME: A recursion limit is necessary as well, for irregular
         // recursive types.
-        if !cache.insert(ty) {
+        if !acc.cache.insert(ty) {
             return FfiSafe;
         }
 
@@ -1308,6 +1320,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 }
                 match def.adt_kind() {
                     AdtKind::Struct | AdtKind::Union => {
+                        if let Some(sym::cstring_type | sym::cstr_type) =
+                            tcx.get_diagnostic_name(def.did())
+                            && !acc.base_ty.is_mutable_ptr()
+                        {
+                            return FfiUnsafe {
+                                ty,
+                                reason: fluent::lint_improper_ctypes_cstr_reason,
+                                help: Some(fluent::lint_improper_ctypes_cstr_help),
+                            };
+                        }
+
                         if !def.repr().c() && !def.repr().transparent() {
                             return FfiUnsafe {
                                 ty,
@@ -1354,7 +1377,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             };
                         }
 
-                        self.check_variant_for_ffi(cache, ty, def, def.non_enum_variant(), args)
+                        self.check_variant_for_ffi(acc, ty, def, def.non_enum_variant(), args)
                     }
                     AdtKind::Enum => {
                         if def.variants().is_empty() {
@@ -1378,7 +1401,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             if let Some(ty) =
                                 repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
                             {
-                                return self.check_type_for_ffi(cache, ty);
+                                return self.check_type_for_ffi(acc, ty);
                             }
 
                             return FfiUnsafe {
@@ -1399,7 +1422,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                                 };
                             }
 
-                            match self.check_variant_for_ffi(cache, ty, def, variant, args) {
+                            match self.check_variant_for_ffi(acc, ty, def, variant, args) {
                                 FfiSafe => (),
                                 r => return r,
                             }
@@ -1469,9 +1492,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 FfiSafe
             }
 
-            ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty),
+            ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(acc, ty),
 
-            ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
+            ty::Array(inner_ty, _) => self.check_type_for_ffi(acc, inner_ty),
 
             ty::FnPtr(sig_tys, hdr) => {
                 let sig = sig_tys.with(hdr);
@@ -1485,7 +1508,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                 let sig = tcx.instantiate_bound_regions_with_erased(sig);
                 for arg in sig.inputs() {
-                    match self.check_type_for_ffi(cache, *arg) {
+                    match self.check_type_for_ffi(acc, *arg) {
                         FfiSafe => {}
                         r => return r,
                     }
@@ -1496,7 +1519,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                     return FfiSafe;
                 }
 
-                self.check_type_for_ffi(cache, ret_ty)
+                self.check_type_for_ffi(acc, ret_ty)
             }
 
             ty::Foreign(..) => FfiSafe,
@@ -1619,7 +1642,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             return;
         }
 
-        match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
+        let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty };
+        match self.check_type_for_ffi(&mut acc, ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
                 self.emit_ffi_unsafe_type_lint(
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/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 56d77c9d1d0..44c72e0c4fe 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -142,7 +142,6 @@ declare_lint_pass! {
         USELESS_DEPRECATED,
         WARNINGS,
         WASM_C_ABI,
-        WRITES_THROUGH_IMMUTABLE_POINTER,
         // tidy-alphabetical-end
     ]
 }
@@ -251,7 +250,7 @@ declare_lint! {
     Deny,
     "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
         reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>",
     };
 }
@@ -4697,40 +4696,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `writes_through_immutable_pointer` lint detects writes through pointers derived from
-    /// shared references.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![feature(const_mut_refs)]
-    /// const WRITE_AFTER_CAST: () = unsafe {
-    ///     let mut x = 0;
-    ///     let ptr = &x as *const i32 as *mut i32;
-    ///     *ptr = 0;
-    /// };
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Shared references are immutable (when there is no `UnsafeCell` involved),
-    /// and writing through them or through pointers derived from them is Undefined Behavior.
-    /// The compiler recently learned to detect such Undefined Behavior during compile-time
-    /// evaluation, and in the future this will raise a hard error.
-    ///
-    /// [future-incompatible]: ../index.md#future-incompatible-lints
-    pub WRITES_THROUGH_IMMUTABLE_POINTER,
-    Warn,
-    "shared references are immutable, and pointers derived from them must not be written to",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #X <https://github.com/rust-lang/rust/issues/X>",
-    };
-}
-
-declare_lint! {
     /// The `private_macro_use` lint detects private macros that are imported
     /// with `#[macro_use]`.
     ///
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/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 83fda7ef07c..1f74aaf9965 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -10,5 +10,5 @@ libc = "0.2.73"
 
 [build-dependencies]
 # tidy-alphabetical-start
-cc = "1.0.97"
+cc = "=1.0.105" # FIXME(cc): pinned to keep support for VS2013
 # tidy-alphabetical-end
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 283c4fbbb7c..9884ed15b8a 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1607,8 +1607,13 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
   const auto &ExportList = Data->ExportLists.lookup(ModId);
   const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
+#if LLVM_VERSION_GE(20, 0)
+  DenseSet<GlobalValue::GUID> CfiFunctionDefs;
+  DenseSet<GlobalValue::GUID> CfiFunctionDecls;
+#else
   std::set<GlobalValue::GUID> CfiFunctionDefs;
   std::set<GlobalValue::GUID> CfiFunctionDecls;
+#endif
 
   // Based on the 'InProcessThinBackend' constructor in LLVM
   for (auto &Name : Data->Index.cfiFunctionDefs())
@@ -1618,9 +1623,15 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
     CfiFunctionDecls.insert(
         GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
 
+#if LLVM_VERSION_GE(20, 0)
+  Key = llvm::computeLTOCacheKey(conf, Data->Index, ModId, ImportList,
+                                 ExportList, ResolvedODR, DefinedGlobals,
+                                 CfiFunctionDefs, CfiFunctionDecls);
+#else
   llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId, ImportList,
                            ExportList, ResolvedODR, DefinedGlobals,
                            CfiFunctionDefs, CfiFunctionDecls);
+#endif
 
   LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());
 }
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/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 8c0ea3eaea9..a13eac08c9f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1487,7 +1487,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, sess))
     }
 
-    fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
+    fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + 'a {
         self.root.foreign_modules.decode((self, sess))
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 46039f6e5f6..27625f79108 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -224,6 +224,7 @@ provide! { tcx, def_id, other, cdata,
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
+    struct_target_features => { table }
     impl_trait_header => { table }
     const_param_default => { table }
     object_lifetime_default => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 0d83f8c6c5c..fbcfbd3befa 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,
     }
 }
 
@@ -1380,6 +1392,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if def_kind.has_codegen_attrs() {
                 record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
             }
+            if def_kind.has_struct_target_features() {
+                record_array!(self.tables.struct_target_features[def_id] <- self.tcx.struct_target_features(def_id));
+            }
             if should_encode_visibility(def_kind) {
                 let vis =
                     self.tcx.local_visibility(local_id).map_id(|def_id| def_id.local_def_index);
@@ -1458,7 +1473,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/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index c1b77172983..aec728d4262 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -19,7 +19,7 @@ use rustc_macros::{
     Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable,
 };
 use rustc_middle::metadata::ModChild;
-use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
+use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::middle::lib_features::FeatureStability;
@@ -427,6 +427,7 @@ define_tables! {
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
+    struct_target_features: Table<DefIndex, LazyArray<TargetFeature>>,
     impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
     const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>>>,
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
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/arena.rs b/compiler/rustc_middle/src/arena.rs
index 37c10b14054..7050a06b8dc 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -35,7 +35,6 @@ macro_rules! arena_types {
             )>,
             [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
             [] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
-            [decode] code_region: rustc_middle::mir::coverage::CodeRegion,
             [] const_allocs: rustc_middle::mir::interpret::Allocation,
             [] region_scope_tree: rustc_middle::middle::region::ScopeTree,
             // Required for the incremental on-disk cache
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 5bd7736a3f3..ce330b4744b 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -28,12 +28,13 @@
 #![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)]
 #![feature(array_windows)]
 #![feature(assert_matches)]
+#![feature(box_as_ptr)]
 #![feature(box_patterns)]
 #![feature(closure_track_caller)]
 #![feature(const_option)]
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index b7d290e58d2..c098a739592 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -26,8 +26,8 @@ pub struct CodegenFnAttrs {
     /// be set when `link_name` is set. This is for foreign items with the
     /// "raw-dylib" kind.
     pub link_ordinal: Option<u16>,
-    /// The `#[target_feature(enable = "...")]` attribute and the enabled
-    /// features (only enabled features are supported right now).
+    /// All the target features that are enabled for this function. Some features might be enabled
+    /// implicitly.
     pub target_features: Vec<TargetFeature>,
     /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
     pub linkage: Option<Linkage>,
@@ -55,8 +55,8 @@ pub struct CodegenFnAttrs {
 pub struct TargetFeature {
     /// The name of the target feature (e.g. "avx")
     pub name: Symbol,
-    /// The feature is implied by another feature, rather than explicitly added by the
-    /// `#[target_feature]` attribute
+    /// The feature is implied by another feature or by an argument, rather than explicitly
+    /// added by the `#[target_feature]` attribute
     pub implied: bool,
 }
 
diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
index a4f6d7afe4d..32e2f3b4b16 100644
--- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
+++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
@@ -2,7 +2,7 @@
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{ItemLocalId, OwnerId};
 use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
 
@@ -11,9 +11,9 @@ use crate::ty;
 #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum ResolvedArg {
     StaticLifetime,
-    EarlyBound(/* decl */ DefId),
-    LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ DefId),
-    Free(DefId, /* lifetime decl */ DefId),
+    EarlyBound(/* decl */ LocalDefId),
+    LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* decl */ LocalDefId),
+    Free(LocalDefId, /* lifetime decl */ LocalDefId),
     Error(ErrorGuaranteed),
 }
 
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index b11c523cfe9..bfe2a2c2cb3 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -163,7 +163,7 @@ impl Debug for CoverageKind {
 
 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct CodeRegion {
+pub struct SourceRegion {
     pub file_name: Symbol,
     pub start_line: u32,
     pub start_col: u32,
@@ -171,7 +171,7 @@ pub struct CodeRegion {
     pub end_col: u32,
 }
 
-impl Debug for CodeRegion {
+impl Debug for SourceRegion {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         write!(
             fmt,
@@ -242,7 +242,7 @@ impl MappingKind {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct Mapping {
     pub kind: MappingKind,
-    pub code_region: CodeRegion,
+    pub source_region: SourceRegion,
 }
 
 /// Stores per-function coverage information attached to a `mir::Body`,
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 665ab2797f2..3e101c0c635 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -62,13 +62,11 @@ impl AllocBytes for Box<[u8]> {
     }
 
     fn as_mut_ptr(&mut self) -> *mut u8 {
-        // Carefully avoiding any intermediate references.
-        ptr::addr_of_mut!(**self).cast()
+        Box::as_mut_ptr(self).cast()
     }
 
     fn as_ptr(&self) -> *const u8 {
-        // Carefully avoiding any intermediate references.
-        ptr::addr_of!(**self).cast()
+        Box::as_ptr(self).cast()
     }
 }
 
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/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index efdc0c710ba..6785805c27d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -547,8 +547,8 @@ fn write_function_coverage_info(
     for (id, expression) in expressions.iter_enumerated() {
         writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?;
     }
-    for coverage::Mapping { kind, code_region } in mappings {
-        writeln!(w, "{INDENT}coverage {kind:?} => {code_region:?};")?;
+    for coverage::Mapping { kind, source_region } in mappings {
+        writeln!(w, "{INDENT}coverage {kind:?} => {source_region:?};")?;
     }
     writeln!(w)?;
 
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..6434bd0d7bf 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -47,7 +47,7 @@ use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintExpectation;
 use crate::metadata::ModChild;
-use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
+use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
 use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use crate::middle::lib_features::LibFeatures;
@@ -312,20 +312,10 @@ rustc_queries! {
     /// predicates (where-clauses) that must be proven true in order
     /// to reference it. This is almost always the "predicates query"
     /// that you want.
-    ///
-    /// `predicates_of` builds on `predicates_defined_on` -- in fact,
-    /// it is almost always the same as that query, except for the
-    /// case of traits. For traits, `predicates_of` contains
-    /// an additional `Self: Trait<...>` predicate that users don't
-    /// actually write. This reflects the fact that to invoke the
-    /// trait (e.g., via `Default::default`) you must supply types
-    /// that actually implement the trait. (However, this extra
-    /// predicate gets in the way of some checks, which are intended
-    /// to operate over only the actual where-clauses written by the
-    /// user.)
     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 +488,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.
@@ -617,14 +608,6 @@ rustc_queries! {
         desc { "getting wasm import module map" }
     }
 
-    /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
-    /// predicates (where-clauses) directly defined on it. This is
-    /// equal to the `explicit_predicates_of` predicates plus the
-    /// `inferred_outlives_of` predicates.
-    query predicates_defined_on(key: DefId) -> ty::GenericPredicates<'tcx> {
-        desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
-    }
-
     /// Returns everything that looks like a predicate written explicitly
     /// by the user on a trait item.
     ///
@@ -742,6 +725,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 +744,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 {
@@ -1249,6 +1245,11 @@ rustc_queries! {
         feedable
     }
 
+    query struct_target_features(def_id: DefId) -> &'tcx [TargetFeature] {
+        separate_provide_extern
+        desc { |tcx| "computing target features for struct `{}`", tcx.def_path_str(def_id) }
+    }
+
     query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
         desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
     }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index d54e2ca0a74..a3277fb96d2 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -353,7 +353,7 @@ pub enum ObligationCauseCode<'tcx> {
     ReturnValue(HirId),
 
     /// Opaque return type of this function
-    OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
+    OpaqueReturnType(Option<(Ty<'tcx>, HirId)>),
 
     /// Block implicit return
     BlockTailExpression(HirId, hir::MatchSource),
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 401f6da6526..46203ee150f 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -462,7 +462,6 @@ impl_decodable_via_ref! {
     &'tcx traits::ImplSource<'tcx, ()>,
     &'tcx mir::Body<'tcx>,
     &'tcx mir::BorrowCheckResult<'tcx>,
-    &'tcx mir::coverage::CodeRegion,
     &'tcx ty::List<ty::BoundVariableKind>,
     &'tcx ty::ListWithCachedTypeInfo<ty::Clause<'tcx>>,
     &'tcx ty::List<FieldIdx>,
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index e373292741b..362ff8e988d 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -240,7 +240,7 @@ impl<'tcx> Const<'tcx> {
 
         let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
 
-        match Self::try_from_lit(tcx, ty, expr) {
+        match Self::try_from_lit_or_param(tcx, ty, expr) {
             Some(v) => v,
             None => ty::Const::new_unevaluated(
                 tcx,
@@ -281,7 +281,11 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[instrument(skip(tcx), level = "debug")]
-    fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> {
+    fn try_from_lit_or_param(
+        tcx: TyCtxt<'tcx>,
+        ty: Ty<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
+    ) -> Option<Self> {
         // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
         // currently have to be wrapped in curly brackets, so it's necessary to special-case.
         let expr = match &expr.kind {
@@ -291,6 +295,22 @@ impl<'tcx> Const<'tcx> {
             _ => expr,
         };
 
+        if let hir::ExprKind::Path(
+            qpath @ hir::QPath::Resolved(
+                _,
+                &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
+            ),
+        ) = expr.kind
+        {
+            if tcx.features().const_arg_path {
+                span_bug!(
+                    expr.span,
+                    "try_from_lit: received const param which shouldn't be possible"
+                );
+            }
+            return Some(Const::from_param(tcx, qpath, expr.hir_id));
+        };
+
         let lit_input = match expr.kind {
             hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
             hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
@@ -318,14 +338,6 @@ impl<'tcx> Const<'tcx> {
             }
         }
 
-        if let hir::ExprKind::Path(hir::QPath::Resolved(
-            _,
-            &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
-        )) = expr.kind
-        {
-            span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible")
-        }
-
         None
     }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 9b39b849704..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 {
@@ -3035,13 +3041,13 @@ impl<'tcx> TyCtxt<'tcx> {
 
             match self.named_bound_var(lifetime.hir_id) {
                 Some(resolve_bound_vars::ResolvedArg::EarlyBound(ebv)) => {
-                    let new_parent = self.parent(ebv);
+                    let new_parent = self.local_parent(ebv);
 
                     // If we map to another opaque, then it should be a parent
                     // of the opaque we mapped from. Continue mapping.
                     if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
-                        debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
-                        opaque_lifetime_param_def_id = ebv.expect_local();
+                        debug_assert_eq!(self.local_parent(parent), new_parent);
+                        opaque_lifetime_param_def_id = ebv;
                         continue;
                     }
 
@@ -3050,20 +3056,20 @@ impl<'tcx> TyCtxt<'tcx> {
                         self,
                         ty::EarlyParamRegion {
                             index: generics
-                                .param_def_id_to_index(self, ebv)
+                                .param_def_id_to_index(self, ebv.to_def_id())
                                 .expect("early-bound var should be present in fn generics"),
-                            name: self.hir().name(self.local_def_id_to_hir_id(ebv.expect_local())),
+                            name: self.item_name(ebv.to_def_id()),
                         },
                     );
                 }
                 Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => {
-                    let new_parent = self.parent(lbv);
+                    let new_parent = self.local_parent(lbv);
                     return ty::Region::new_late_param(
                         self,
-                        new_parent,
+                        new_parent.to_def_id(),
                         ty::BoundRegionKind::BrNamed(
-                            lbv,
-                            self.hir().name(self.local_def_id_to_hir_id(lbv.expect_local())),
+                            lbv.to_def_id(),
+                            self.item_name(lbv.to_def_id()),
                         ),
                     );
                 }
@@ -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/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 8cb8e9af11c..bbc696e0f08 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -269,7 +269,7 @@ impl<'tcx> Generics {
     }
 
     /// Returns the `GenericParamDef` associated with this `ParamConst`.
-    pub fn const_param(&'tcx self, param: ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
+    pub fn const_param(&'tcx self, param: ParamConst, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Const { .. } => param,
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/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 619981bf021..d0a9039441d 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1104,7 +1104,7 @@ where
     }
 
     fn is_never(this: TyAndLayout<'tcx>) -> bool {
-        this.ty.kind() == &ty::Never
+        matches!(this.ty.kind(), ty::Never)
     }
 
     fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
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_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 7e1255f606c..be611e19b49 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -59,6 +59,7 @@ trivially_parameterized_over_tcx! {
     std::string::String,
     crate::metadata::ModChild,
     crate::middle::codegen_fn_attrs::CodegenFnAttrs,
+    crate::middle::codegen_fn_attrs::TargetFeature,
     crate::middle::debugger_visualizer::DebuggerVisualizerFile,
     crate::middle::exported_symbols::SymbolExportInfo,
     crate::middle::lib_features::FeatureStability,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 319fb7ef03b..f1ff90831b0 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3119,7 +3119,10 @@ define_print! {
 
     ty::ExistentialProjection<'tcx> {
         let name = cx.tcx().associated_item(self.def_id).name;
-        p!(write("{} = ", name), print(self.term))
+        // The args don't contain the self ty (as it has been erased) but the corresp.
+        // generics do as the trait always has a self ty param. We need to offset.
+        let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..];
+        p!(path_generic_args(|cx| write!(cx, "{name}"), args), " = ", print(self.term))
     }
 
     ty::ProjectionPredicate<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 045c8ad39be..efbccca77c1 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -296,7 +296,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> (Ty<'tcx>, Ty<'tcx>) {
         let (mut a, mut b) = (source, target);
         loop {
-            match (&a.kind(), &b.kind()) {
+            match (a.kind(), b.kind()) {
                 (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
                     if a_def == b_def && a_def.is_struct() =>
                 {
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 7a10e627ccd..a42e8ff0168 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -125,6 +125,17 @@ mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
+mir_build_initializing_type_with_target_feature_requires_unsafe =
+    initializing type with `target_feature` attr is unsafe and requires unsafe block
+    .note = this struct can only be constructed if the corresponding `target_feature`s are available
+    .label = initializing type with `target_feature` attr
+
+mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
+    initializing type with `target_feature` attr is unsafe and requires unsafe function or block
+    .note = this struct can only be constructed if the corresponding `target_feature`s are available
+    .label = initializing type with `target_feature` attr
+
+
 mir_build_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
@@ -387,6 +398,11 @@ mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe =
     .note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
     .label = initializing type with `rustc_layout_scalar_valid_range` attr
 
+mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe =
+    initializing type with `target_feature` attr is unsafe and requires unsafe block
+    .note = this struct can only be constructed if the corresponding `target_feature`s are available
+    .label = initializing type with `target_feature` attr
+
 mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe =
     use of inline assembly is unsafe and requires unsafe block
     .note = inline assembly is entirely unchecked and can cause undefined behavior
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 4430aab73a8..4f1166f9111 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -127,7 +127,7 @@ fn lit_to_mir_constant<'tcx>(
         Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
     };
 
-    let value = match (lit, &ty.kind()) {
+    let value = match (lit, ty.kind()) {
         (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
             let s = s.as_str();
             let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b6cf7a40ecd..60cd49b88b4 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -461,14 +461,18 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     };
                     self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
                 } else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
-                    // If the called function has target features the calling function hasn't,
+                    // If the called function has explicit target features the calling function hasn't,
                     // the call requires `unsafe`. Don't check this on wasm
                     // targets, though. For more information on wasm see the
                     // is_like_wasm check in hir_analysis/src/collect.rs
+                    // Implicit target features are OK because they are either a consequence of some
+                    // explicit target feature (which is checked to be present in the caller) or
+                    // come from a witness argument.
                     let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
                     if !self.tcx.sess.target.options.is_like_wasm
                         && !callee_features.iter().all(|feature| {
-                            self.body_target_features.iter().any(|f| f.name == feature.name)
+                            feature.implied
+                                || self.body_target_features.iter().any(|f| f.name == feature.name)
                         })
                     {
                         let missing: Vec<_> = callee_features
@@ -542,10 +546,16 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 user_ty: _,
                 fields: _,
                 base: _,
-            }) => match self.tcx.layout_scalar_valid_range(adt_def.did()) {
-                (Bound::Unbounded, Bound::Unbounded) => {}
-                _ => self.requires_unsafe(expr.span, InitializingTypeWith),
-            },
+            }) => {
+                match self.tcx.layout_scalar_valid_range(adt_def.did()) {
+                    (Bound::Unbounded, Bound::Unbounded) => {}
+                    _ => self.requires_unsafe(expr.span, InitializingTypeWith),
+                }
+                if !self.tcx.struct_target_features(adt_def.did()).is_empty() {
+                    self.requires_unsafe(expr.span, ConstructingTargetFeaturesType)
+                }
+            }
+
             ExprKind::Closure(box ClosureExpr {
                 closure_id,
                 args: _,
@@ -647,6 +657,7 @@ enum UnsafeOpKind {
     CallToUnsafeFunction(Option<DefId>),
     UseOfInlineAssembly,
     InitializingTypeWith,
+    ConstructingTargetFeaturesType,
     UseOfMutableStatic,
     UseOfExternStatic,
     DerefOfRawPointer,
@@ -728,6 +739,15 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
+            ConstructingTargetFeaturesType => tcx.emit_node_span_lint(
+                UNSAFE_OP_IN_UNSAFE_FN,
+                hir_id,
+                span,
+                UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                },
+            ),
             UseOfMutableStatic => tcx.emit_node_span_lint(
                 UNSAFE_OP_IN_UNSAFE_FN,
                 hir_id,
@@ -885,6 +905,20 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 });
             }
+            ConstructingTargetFeaturesType if unsafe_op_in_unsafe_fn_allowed => {
+                dcx.emit_err(
+                    InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+                        span,
+                        unsafe_not_inherited_note,
+                    },
+                );
+            }
+            ConstructingTargetFeaturesType => {
+                dcx.emit_err(InitializingTypeWithTargetFeatureRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                });
+            }
             UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
                 dcx.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 843ac2eb240..e7d6239aa9b 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -87,6 +87,16 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithTargetFeatureRequiresUnsafe {
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
@@ -251,6 +261,17 @@ pub(crate) struct InitializingTypeWithRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
+#[diag(mir_build_initializing_type_with_target_feature_requires_unsafe, code = E0133)]
+#[note]
+pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafe {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
     code = E0133
@@ -265,6 +286,20 @@ pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
+#[diag(
+    mir_build_initializing_type_with_target_feature_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
+    code = E0133
+)]
+#[note]
+pub(crate) struct InitializingTypeWithTargetFeatureRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
 #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub(crate) struct UseOfMutableStaticRequiresUnsafe {
@@ -493,7 +528,7 @@ pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
 }
 
 impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
-    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'_, G> {
+    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
         let mut diag =
             Diag::new(dcx, level, fluent::mir_build_non_exhaustive_patterns_type_not_empty);
         diag.span(self.scrut_span);
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 7b94867114d..b8877a64e47 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -29,7 +29,7 @@ pub(crate) fn lit_to_const<'tcx>(
             .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)))
     };
 
-    let valtree = match (lit, &ty.kind()) {
+    let valtree = match (lit, ty.kind()) {
         (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
             let str_bytes = s.as_str().as_bytes();
             ty::ValTree::from_raw_bytes(tcx, str_bytes)
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/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 96ca3b43d5c..af0f1e38a75 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::coverage::{
-    CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind,
+    CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, SourceRegion,
 };
 use rustc_middle::mir::{
     self, BasicBlock, BasicBlockData, SourceInfo, Statement, StatementKind, Terminator,
@@ -159,7 +159,7 @@ fn create_mappings<'tcx>(
             .expect("all BCBs with spans were given counters")
             .as_term()
     };
-    let region_for_span = |span: Span| make_code_region(source_map, file_name, span, body_span);
+    let region_for_span = |span: Span| make_source_region(source_map, file_name, span, body_span);
 
     // Fully destructure the mappings struct to make sure we don't miss any kinds.
     let ExtractedMappings {
@@ -175,9 +175,9 @@ fn create_mappings<'tcx>(
     mappings.extend(code_mappings.iter().filter_map(
         // Ordinary code mappings are the simplest kind.
         |&mappings::CodeMapping { span, bcb }| {
-            let code_region = region_for_span(span)?;
+            let source_region = region_for_span(span)?;
             let kind = MappingKind::Code(term_for_bcb(bcb));
-            Some(Mapping { kind, code_region })
+            Some(Mapping { kind, source_region })
         },
     ));
 
@@ -186,29 +186,29 @@ fn create_mappings<'tcx>(
             let true_term = term_for_bcb(true_bcb);
             let false_term = term_for_bcb(false_bcb);
             let kind = MappingKind::Branch { true_term, false_term };
-            let code_region = region_for_span(span)?;
-            Some(Mapping { kind, code_region })
+            let source_region = region_for_span(span)?;
+            Some(Mapping { kind, source_region })
         },
     ));
 
     mappings.extend(mcdc_branches.iter().filter_map(
         |&mappings::MCDCBranch { span, true_bcb, false_bcb, condition_info, decision_depth: _ }| {
-            let code_region = region_for_span(span)?;
+            let source_region = region_for_span(span)?;
             let true_term = term_for_bcb(true_bcb);
             let false_term = term_for_bcb(false_bcb);
             let kind = match condition_info {
                 Some(mcdc_params) => MappingKind::MCDCBranch { true_term, false_term, mcdc_params },
                 None => MappingKind::Branch { true_term, false_term },
             };
-            Some(Mapping { kind, code_region })
+            Some(Mapping { kind, source_region })
         },
     ));
 
     mappings.extend(mcdc_decisions.iter().filter_map(
         |&mappings::MCDCDecision { span, bitmap_idx, num_conditions, .. }| {
-            let code_region = region_for_span(span)?;
+            let source_region = region_for_span(span)?;
             let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, num_conditions });
-            Some(Mapping { kind, code_region })
+            Some(Mapping { kind, source_region })
         },
     ));
 
@@ -362,19 +362,13 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
 /// but it's hard to rule out entirely (especially in the presence of complex macros
 /// or other expansions), and if it does happen then skipping a span or function is
 /// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
-fn make_code_region(
+#[instrument(level = "debug", skip(source_map))]
+fn make_source_region(
     source_map: &SourceMap,
     file_name: Symbol,
     span: Span,
     body_span: Span,
-) -> Option<CodeRegion> {
-    debug!(
-        "Called make_code_region(file_name={}, span={}, body_span={})",
-        file_name,
-        source_map.span_to_diagnostic_string(span),
-        source_map.span_to_diagnostic_string(body_span)
-    );
-
+) -> Option<SourceRegion> {
     let lo = span.lo();
     let hi = span.hi();
 
@@ -424,7 +418,7 @@ fn make_code_region(
     start_line = source_map.doctest_offset_line(&file.name, start_line);
     end_line = source_map.doctest_offset_line(&file.name, end_line);
 
-    check_code_region(CodeRegion {
+    check_source_region(SourceRegion {
         file_name,
         start_line: start_line as u32,
         start_col: start_col as u32,
@@ -433,12 +427,12 @@ fn make_code_region(
     })
 }
 
-/// If `llvm-cov` sees a code region that is improperly ordered (end < start),
+/// If `llvm-cov` sees a source region that is improperly ordered (end < start),
 /// it will immediately exit with a fatal error. To prevent that from happening,
 /// discard regions that are improperly ordered, or might be interpreted in a
 /// way that makes them improperly ordered.
-fn check_code_region(code_region: CodeRegion) -> Option<CodeRegion> {
-    let CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region;
+fn check_source_region(source_region: SourceRegion) -> Option<SourceRegion> {
+    let SourceRegion { file_name: _, start_line, start_col, end_line, end_col } = source_region;
 
     // Line/column coordinates are supposed to be 1-based. If we ever emit
     // coordinates of 0, `llvm-cov` might misinterpret them.
@@ -451,17 +445,17 @@ fn check_code_region(code_region: CodeRegion) -> Option<CodeRegion> {
     let is_ordered = (start_line, start_col) <= (end_line, end_col);
 
     if all_nonzero && end_col_has_high_bit_unset && is_ordered {
-        Some(code_region)
+        Some(source_region)
     } else {
         debug!(
-            ?code_region,
+            ?source_region,
             ?all_nonzero,
             ?end_col_has_high_bit_unset,
             ?is_ordered,
-            "Skipping code region that would be misinterpreted or rejected by LLVM"
+            "Skipping source region that would be misinterpreted or rejected by LLVM"
         );
         // If this happens in a debug build, ICE to make it easier to notice.
-        debug_assert!(false, "Improper code region: {code_region:?}");
+        debug_assert!(false, "Improper source region: {source_region:?}");
         None
     }
 }
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 77f6a1e17ce..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(..)
@@ -1035,9 +1034,9 @@ fn find_vtable_types_for_unsizing<'tcx>(
         }
     };
 
-    match (&source_ty.kind(), &target_ty.kind()) {
+    match (source_ty.kind(), target_ty.kind()) {
         (&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
-        | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(*a, *b),
+        | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
         (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
             ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty())
         }
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_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 5738173c7a8..c7a9846cd97 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -862,7 +862,7 @@ where
         _ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution> {
-        panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
+        panic!("`TransmuteFrom` does not have an associated type: {:?}", goal)
     }
 
     fn consider_builtin_effects_intersection_candidate(
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 6391ff901cb..c65cf3f40f6 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -76,6 +76,7 @@ impl<'a> Parser<'a> {
                             token::CommentKind::Line => OuterAttributeType::DocComment,
                             token::CommentKind::Block => OuterAttributeType::DocBlockComment,
                         },
+                        true,
                     ) {
                         err.note(fluent::parse_note);
                         err.span_suggestion_verbose(
@@ -139,7 +140,11 @@ impl<'a> Parser<'a> {
 
             // Emit error if inner attribute is encountered and forbidden.
             if style == ast::AttrStyle::Inner {
-                this.error_on_forbidden_inner_attr(attr_sp, inner_parse_policy);
+                this.error_on_forbidden_inner_attr(
+                    attr_sp,
+                    inner_parse_policy,
+                    item.is_valid_for_outer_style(),
+                );
             }
 
             Ok(attr::mk_attr_from_item(&self.psess.attr_id_generator, item, None, style, attr_sp))
@@ -151,6 +156,7 @@ impl<'a> Parser<'a> {
         err: &mut Diag<'_>,
         span: Span,
         attr_type: OuterAttributeType,
+        suggest_to_outer: bool,
     ) -> Option<Span> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
         let lo = span.lo()
@@ -185,16 +191,18 @@ impl<'a> Parser<'a> {
                 // FIXME(#100717)
                 err.arg("item", item.kind.descr());
                 err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
-                err.span_suggestion_verbose(
-                    replacement_span,
-                    fluent::parse_sugg_change_inner_to_outer,
-                    match attr_type {
-                        OuterAttributeType::Attribute => "",
-                        OuterAttributeType::DocBlockComment => "*",
-                        OuterAttributeType::DocComment => "/",
-                    },
-                    rustc_errors::Applicability::MachineApplicable,
-                );
+                if suggest_to_outer {
+                    err.span_suggestion_verbose(
+                        replacement_span,
+                        fluent::parse_sugg_change_inner_to_outer,
+                        match attr_type {
+                            OuterAttributeType::Attribute => "",
+                            OuterAttributeType::DocBlockComment => "*",
+                            OuterAttributeType::DocComment => "/",
+                        },
+                        rustc_errors::Applicability::MachineApplicable,
+                    );
+                }
                 return None;
             }
             Err(item_err) => {
@@ -205,7 +213,12 @@ impl<'a> Parser<'a> {
         Some(replacement_span)
     }
 
-    pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy) {
+    pub(super) fn error_on_forbidden_inner_attr(
+        &self,
+        attr_sp: Span,
+        policy: InnerAttrPolicy,
+        suggest_to_outer: bool,
+    ) {
         if let InnerAttrPolicy::Forbidden(reason) = policy {
             let mut diag = match reason.as_ref().copied() {
                 Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => {
@@ -239,6 +252,7 @@ impl<'a> Parser<'a> {
                     &mut diag,
                     attr_sp,
                     OuterAttributeType::Attribute,
+                    suggest_to_outer,
                 )
                 .is_some()
             {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 14da6c331f1..c6a5e1908f7 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -51,7 +51,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the contents of a module (inner attributes followed by module items).
-    /// We exit once we hit `term`
+    /// We exit once we hit `term` which can be either
+    /// - EOF (for files)
+    /// - `}` for mod items
     pub fn parse_mod(
         &mut self,
         term: &TokenKind,
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 69044192780..26ad39e06cd 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -459,11 +459,16 @@ impl<'a> Parser<'a> {
     pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         let (attrs, block) = self.parse_inner_attrs_and_block()?;
         if let [.., last] = &*attrs {
+            let suggest_to_outer = match &last.kind {
+                ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(),
+                _ => false,
+            };
             self.error_on_forbidden_inner_attr(
                 last.span,
                 super::attr::InnerAttrPolicy::Forbidden(Some(
                     InnerAttrForbiddenReason::InCodeBlock,
                 )),
+                suggest_to_outer,
             );
         }
         Ok(block)
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index dfc726efeb9..38450fc288a 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -481,10 +481,6 @@ passes_must_not_suspend =
     `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
     .label = is not a struct, enum, union, or trait
 
-passes_must_use_async =
-    `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
-    .label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-
 passes_must_use_no_effect =
     `#[must_use]` has no effect when applied to {$article} {$target}
 
@@ -657,6 +653,10 @@ passes_rustc_lint_opt_ty =
     `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
+passes_rustc_pub_transparent =
+    attribute should be applied to `#[repr(transparent)]` types
+    .label = not a `#[repr(transparent)]` type
+
 passes_rustc_safe_intrinsic =
     attribute should be applied to intrinsic functions
     .label = not an intrinsic function
@@ -672,6 +672,10 @@ passes_should_be_applied_to_fn =
         *[false] not a function definition
     }
 
+passes_should_be_applied_to_fn_or_unit_struct =
+    attribute should be applied to a function definition or unit struct
+    .label = not a function definition or a unit struct
+
 passes_should_be_applied_to_static =
     attribute should be applied to a static
     .label = not a static
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index c93fb5c23b1..5dbb3854c8f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -245,6 +245,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     self.check_coroutine(attr, target);
                 }
                 [sym::linkage, ..] => self.check_linkage(attr, span, target),
+                [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent( attr.span, span, attrs),
                 [
                     // ok
                     sym::allow
@@ -516,6 +517,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             sym::no_mangle,
             sym::naked,
             sym::instruction_set,
+            sym::repr,
             // code generation
             sym::cold,
             sym::target_feature,
@@ -745,12 +747,35 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             Target::Field | Target::Arm | Target::MacroDef => {
                 self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature");
             }
+            Target::Struct if self.tcx.features().struct_target_features => {
+                let ty = self.tcx.hir_node(hir_id).expect_item();
+                match ty.kind {
+                    ItemKind::Struct(data, _) => {
+                        if data.fields().len() != 0 {
+                            self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
+                                attr_span: attr.span,
+                                defn_span: span,
+                            });
+                        }
+                    }
+                    _ => {
+                        panic!("Target::Struct for a non-struct");
+                    }
+                }
+            }
             _ => {
-                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                    attr_span: attr.span,
-                    defn_span: span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
+                if self.tcx.features().struct_target_features {
+                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFnOrUnitStruct {
+                        attr_span: attr.span,
+                        defn_span: span,
+                    });
+                } else {
+                    self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
+                        attr_span: attr.span,
+                        defn_span: span,
+                        on_crate: hir_id == CRATE_HIR_ID,
+                    });
+                }
             }
         }
     }
@@ -951,6 +976,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         bare_fn_ty.decl.inputs.len() == 1
                     } else {
                         false
+                    }
+                    || if let Some(&[hir::GenericArg::Type(ty)]) = i
+                        .of_trait
+                        .as_ref()
+                        .and_then(|trait_ref| trait_ref.path.segments.last())
+                        .map(|last_segment| last_segment.args().args)
+                    {
+                        matches!(&ty.kind, hir::TyKind::Tup([_]))
+                    } else {
+                        false
                     };
                 if !is_valid {
                     self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() });
@@ -2381,6 +2416,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
         }
     }
+
+    fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) {
+        if !attrs
+            .iter()
+            .filter(|attr| attr.has_name(sym::repr))
+            .filter_map(|attr| attr.meta_item_list())
+            .flatten()
+            .any(|nmi| nmi.has_name(sym::transparent))
+        {
+            self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span });
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 1190e60f41f..32db0823cf7 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -83,6 +83,15 @@ pub struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_should_be_applied_to_fn_or_unit_struct)]
+pub struct AttrShouldBeAppliedToFnOrUnitStruct {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn, code = E0739)]
 pub struct TrackedCallerWrongLocation {
     #[primary_span]
@@ -372,13 +381,6 @@ pub struct FfiConstInvalidTarget {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_must_use_async)]
-pub struct MustUseAsync {
-    #[label]
-    pub span: Span,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(passes_must_use_no_effect)]
 pub struct MustUseNoEffect {
     pub article: &'static str,
@@ -623,6 +625,15 @@ pub struct RustcStdInternalSymbol {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_rustc_pub_transparent)]
+pub struct RustcPubTransparent {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_link_ordinal)]
 pub struct LinkOrdinal {
     #[primary_span]
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_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index ed23870dfdf..3595db78e93 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -314,13 +314,15 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
     }
 
     fn visit_anon_const(&mut self, constant: &'a AnonConst) {
-        // HACK(min_generic_const_args): don't create defs for anon consts if we think they will
-        // later be turned into ConstArgKind::Path's. because this is before resolve is done, we
-        // may accidentally identify a construction of a unit struct as a param and not create a
-        // def. we'll then create a def later in ast lowering in this case. the parent of nested
-        // items will be messed up, but that's ok because there can't be any if we're just looking
-        // for bare idents.
-        if constant.value.is_potential_trivial_const_arg() {
+        if self.resolver.tcx.features().const_arg_path
+            && constant.value.is_potential_trivial_const_arg()
+        {
+            // HACK(min_generic_const_args): don't create defs for anon consts if we think they will
+            // later be turned into ConstArgKind::Path's. because this is before resolve is done, we
+            // may accidentally identify a construction of a unit struct as a param and not create a
+            // def. we'll then create a def later in ast lowering in this case. the parent of nested
+            // items will be messed up, but that's ok because there can't be any if we're just looking
+            // for bare idents.
             visit::walk_anon_const(self, constant)
         } else {
             let def =
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/config.rs b/compiler/rustc_session/src/config.rs
index 95d171409d8..4fb3702b05d 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2893,6 +2893,7 @@ pub enum PpHirMode {
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
+/// Pretty print mode
 pub enum PpMode {
     /// Options that print the source code, i.e.
     /// `-Zunpretty=normal` and `-Zunpretty=expanded`
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_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 434df35a515..5e1b1b44bc2 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1415,6 +1415,14 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
 
     // Overwrite the dummy data with our decoded SyntaxContextData
     HygieneData::with(|hygiene_data| {
+        if let Some(old) = hygiene_data.syntax_context_data.get(raw_id as usize)
+            && old.outer_expn == ctxt_data.outer_expn
+            && old.outer_transparency == ctxt_data.outer_transparency
+            && old.parent == ctxt_data.parent
+        {
+            ctxt_data = old.clone();
+        }
+
         let dummy = std::mem::replace(
             &mut hygiene_data.syntax_context_data[ctxt.as_u32() as usize],
             ctxt_data,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a2e94492f8c..aba56732725 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -356,6 +356,7 @@ symbols! {
         _task_context,
         a32,
         aarch64_target_feature,
+        aarch64_unstable_target_feature,
         aarch64_ver_target_feature,
         abi,
         abi_amdgpu_kernel,
@@ -595,6 +596,7 @@ symbols! {
         conservative_impl_trait,
         console,
         const_allocate,
+        const_arg_path,
         const_async_blocks,
         const_closures,
         const_compare_raw_pointers,
@@ -673,6 +675,7 @@ symbols! {
         crate_visibility_modifier,
         crt_dash_static: "crt-static",
         csky_target_feature,
+        cstr_type,
         cstring_type,
         ctlz,
         ctlz_nonzero,
@@ -1672,6 +1675,7 @@ symbols! {
         rustc_private,
         rustc_proc_macro_decls,
         rustc_promotable,
+        rustc_pub_transparent,
         rustc_reallocator,
         rustc_regions,
         rustc_reservation_impl,
@@ -1849,6 +1853,7 @@ symbols! {
         stringify,
         struct_field_attributes,
         struct_inherit,
+        struct_target_features,
         struct_variant,
         structural_match,
         structural_peq,
@@ -1893,6 +1898,7 @@ symbols! {
         three_way_compare,
         thumb2,
         thumb_mode: "thumb-mode",
+        time,
         tmm_reg,
         to_owned_method,
         to_string,
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_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index da66ba270b3..8319cb880cc 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -99,6 +99,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("bti", Stable, &[]),
     // FEAT_CRC
     ("crc", Stable, &[]),
+    // FEAT_CSSC
+    ("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_DIT
     ("dit", Stable, &[]),
     // FEAT_DotProd
@@ -107,21 +109,37 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("dpb", Stable, &[]),
     // FEAT_DPB2
     ("dpb2", Stable, &["dpb"]),
+    // FEAT_ECV
+    ("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_F32MM
     ("f32mm", Stable, &["sve"]),
     // FEAT_F64MM
     ("f64mm", Stable, &["sve"]),
+    // FEAT_FAMINMAX
+    ("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_FCMA
     ("fcma", Stable, &["neon"]),
     // FEAT_FHM
     ("fhm", Stable, &["fp16"]),
     // FEAT_FLAGM
     ("flagm", Stable, &[]),
+    // FEAT_FLAGM2
+    ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_FP16
     // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
     ("fp16", Stable, &["neon"]),
+    // FEAT_FP8
+    ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
+    // FEAT_FP8DOT2
+    ("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
+    // FEAT_FP8DOT4
+    ("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
+    // FEAT_FP8FMA
+    ("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
     // FEAT_FRINTTS
     ("frintts", Stable, &[]),
+    // FEAT_HBC
+    ("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_I8MM
     ("i8mm", Stable, &[]),
     // FEAT_JSCVT
@@ -131,6 +149,14 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("lor", Stable, &[]),
     // FEAT_LSE
     ("lse", Stable, &[]),
+    // FEAT_LSE128
+    ("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
+    // FEAT_LSE2
+    ("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    // FEAT_LUT
+    ("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    // FEAT_MOPS
+    ("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // FEAT_MTE & FEAT_MTE2
     ("mte", Stable, &[]),
     // FEAT_AdvSimd & FEAT_FP
@@ -143,14 +169,16 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("pan", Stable, &[]),
     // FEAT_PMUv3
     ("pmuv3", Stable, &[]),
-    // FEAT_RAND
+    // FEAT_RNG
     ("rand", Stable, &[]),
     // FEAT_RAS & FEAT_RASv1p1
     ("ras", Stable, &[]),
-    // FEAT_RCPC
+    // FEAT_LRCPC
     ("rcpc", Stable, &[]),
-    // FEAT_RCPC2
+    // FEAT_LRCPC2
     ("rcpc2", Stable, &["rcpc"]),
+    // FEAT_LRCPC3
+    ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
     // FEAT_RDM
     ("rdm", Stable, &["neon"]),
     // FEAT_SB
@@ -161,10 +189,36 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("sha3", Stable, &["sha2"]),
     // FEAT_SM3 & FEAT_SM4
     ("sm4", Stable, &["neon"]),
+    // FEAT_SME
+    ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
+    // FEAT_SME_F16F16
+    ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
+    // FEAT_SME_F64F64
+    ("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    // FEAT_SME_F8F16
+    ("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
+    // FEAT_SME_F8F32
+    ("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
+    // FEAT_SME_FA64
+    ("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
+    // FEAT_SME_I16I64
+    ("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    // FEAT_SME_LUTv2
+    ("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
+    // FEAT_SME2
+    ("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
+    // FEAT_SME2p1
+    ("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
     // FEAT_SPE
     ("spe", Stable, &[]),
     // FEAT_SSBS & FEAT_SSBS2
     ("ssbs", Stable, &[]),
+    // FEAT_SSVE_FP8FDOT2
+    ("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
+    // FEAT_SSVE_FP8FDOT4
+    ("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
+    // FEAT_SSVE_FP8FMA
+    ("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
     // FEAT_SVE
     // It was decided that SVE requires Neon: https://github.com/rust-lang/rust/pull/91608
     //
@@ -173,9 +227,11 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     //
     // "For backwards compatibility, Neon and VFP are required in the latest architectures."
     ("sve", Stable, &["neon"]),
+    // FEAT_SVE_B16B16 (SVE or SME Instructions)
+    ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
     // FEAT_SVE2
     ("sve2", Stable, &["sve"]),
-    // FEAT_SVE2_AES
+    // FEAT_SVE_AES & FEAT_SVE_PMULL128
     ("sve2-aes", Stable, &["sve2", "aes"]),
     // FEAT_SVE2_BitPerm
     ("sve2-bitperm", Stable, &["sve2"]),
@@ -183,6 +239,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("sve2-sha3", Stable, &["sve2", "sha3"]),
     // FEAT_SVE2_SM4
     ("sve2-sm4", Stable, &["sve2", "sm4"]),
+    // FEAT_SVE2p1
+    ("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
     // FEAT_TME
     ("tme", Stable, &[]),
     (
@@ -199,9 +257,19 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
     ("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
     ("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
-    ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &[]),
+    ("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
+    ("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
+    ("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
+    ("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
+    ("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
+    ("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
+    ("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
+    ("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
+    ("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
     // FEAT_VHE
     ("vh", Stable, &[]),
+    // FEAT_WFxT
+    ("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
     // tidy-alphabetical-end
 ];
 
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 137850f31d3..3ddd23924b5 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -446,6 +446,8 @@ trait_selection_type_annotations_needed = {$source_kind ->
 }
     .label = type must be known at this point
 
+trait_selection_type_annotations_needed_error_time = this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
+
 trait_selection_types_declared_different = these two types are declared with different lifetimes...
 
 trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 173671059ca..53f013ac153 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -6,7 +6,7 @@ use rustc_errors::codes::*;
 use rustc_errors::{Diag, IntoDiagArg};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
 use rustc_middle::bug;
@@ -18,7 +18,7 @@ use rustc_middle::ty::{
     TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
 };
 use rustc_span::symbol::{sym, Ident};
-use rustc_span::{BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
 
 use crate::error_reporting::TypeErrCtxt;
 use crate::errors::{
@@ -384,6 +384,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 bad_label,
                 was_written: false,
                 path: Default::default(),
+                time_version: false,
             }),
             TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
                 span,
@@ -577,6 +578,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
             }
         }
+
+        let time_version =
+            self.detect_old_time_crate_version(failure_span, &kind, &mut infer_subdiags);
+
         match error_code {
             TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
                 span,
@@ -588,6 +593,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 bad_label: None,
                 was_written: path.is_some(),
                 path: path.unwrap_or_default(),
+                time_version,
             }),
             TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
                 span,
@@ -613,6 +619,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }),
         }
     }
+
+    /// Detect the inference regression on crate `time` <= 0.3.35 and emit a more targeted error.
+    /// <https://github.com/rust-lang/rust/issues/127343>
+    // FIXME: we should figure out a more generic version of doing this, ideally in cargo itself.
+    fn detect_old_time_crate_version(
+        &self,
+        span: Option<Span>,
+        kind: &InferSourceKind<'_>,
+        // We will clear the non-actionable suggestion from the error to reduce noise.
+        infer_subdiags: &mut Vec<SourceKindSubdiag<'_>>,
+    ) -> bool {
+        // FIXME(#129461): We are time-boxing this code in the compiler. It'll start failing
+        // compilation once we promote 1.89 to beta, which will happen in 9 months from now.
+        #[cfg(not(version("1.89")))]
+        const fn version_check() {}
+        #[cfg(version("1.89"))]
+        const fn version_check() {
+            panic!("remove this check as presumably the ecosystem has moved from needing it");
+        }
+        const { version_check() };
+        // Only relevant when building the `time` crate.
+        if self.infcx.tcx.crate_name(LOCAL_CRATE) == sym::time
+            && let Some(span) = span
+            && let InferSourceKind::LetBinding { pattern_name, .. } = kind
+            && let Some(name) = pattern_name
+            && name.as_str() == "items"
+            && let FileName::Real(file) = self.infcx.tcx.sess.source_map().span_to_filename(span)
+        {
+            let path = file.local_path_if_available().to_string_lossy();
+            if path.contains("format_description") && path.contains("parse") {
+                infer_subdiags.clear();
+                return true;
+            }
+        }
+        false
+    }
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index 3f35391be13..cd61747917a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs
@@ -101,7 +101,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
                     // region at the right depth with the same index
                     (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
                         debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
-                        if id == def_id {
+                        if id.to_def_id() == def_id {
                             return ControlFlow::Break(arg);
                         }
                     }
@@ -118,7 +118,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
                             debruijn_index
                         );
                         debug!("LateBound id={:?} def_id={:?}", id, def_id);
-                        if debruijn_index == self.current_index && id == def_id {
+                        if debruijn_index == self.current_index && id.to_def_id() == def_id {
                             return ControlFlow::Break(arg);
                         }
                     }
@@ -192,7 +192,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
             // the lifetime of the TyPath!
             (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
                 debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
-                if id == def_id {
+                if id.to_def_id() == def_id {
                     return ControlFlow::Break(());
                 }
             }
@@ -201,7 +201,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
                 debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,);
                 debug!("id={:?}", id);
                 debug!("def_id={:?}", def_id);
-                if debruijn_index == self.current_index && id == def_id {
+                if debruijn_index == self.current_index && id.to_def_id() == def_id {
                     return ControlFlow::Break(());
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
index 9c772f42cca..f2a7da707b8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
@@ -11,7 +11,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
     pub(super) fn try_report_placeholder_relation(&self) -> Option<Diag<'tcx>> {
         match &self.error {
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::RelateRegionParamBound(span),
+                SubregionOrigin::RelateRegionParamBound(span, _),
                 Region(Interned(
                     RePlaceholder(ty::Placeholder {
                         bound: ty::BoundRegion { kind: sub_name, .. },
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
index 04e1be22a4d..600da730845 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
@@ -52,7 +52,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         .add_to_diag(err);
                 }
             }
-            infer::RelateRegionParamBound(span) => {
+            infer::RelateRegionParamBound(span, _) => {
                 RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
                     .add_to_diag(err);
             }
@@ -199,7 +199,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     note,
                 })
             }
-            infer::RelateRegionParamBound(span) => {
+            infer::RelateRegionParamBound(span, _) => {
                 let param_instantiated = note_and_explain::RegionExplanation::new(
                     self.tcx,
                     generic_param_scope,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 877a8a23d7f..ada44b632d4 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -257,7 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .add_to_diag(err);
                 }
             }
-            infer::RelateRegionParamBound(span) => {
+            infer::RelateRegionParamBound(span, _) => {
                 RegionOriginNote::Plain {
                     span,
                     msg: fluent::trait_selection_relate_region_param_bound,
@@ -410,7 +410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     note,
                 })
             }
-            infer::RelateRegionParamBound(span) => {
+            infer::RelateRegionParamBound(span, ty) => {
                 let param_instantiated = note_and_explain::RegionExplanation::new(
                     self.tcx,
                     generic_param_scope,
@@ -419,11 +419,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     note_and_explain::PrefixKind::LfParamInstantiatedWith,
                     note_and_explain::SuffixKind::Empty,
                 );
+                let mut alt_span = None;
+                if let Some(ty) = ty
+                    && sub.is_static()
+                    && let ty::Dynamic(preds, _, ty::DynKind::Dyn) = ty.kind()
+                    && let Some(def_id) = preds.principal_def_id()
+                {
+                    for (clause, span) in
+                        self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
+                    {
+                        if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) =
+                            clause.kind().skip_binder()
+                            && let ty::Param(param) = a.kind()
+                            && param.name == kw::SelfUpper
+                            && b.is_static()
+                        {
+                            // Point at explicit `'static` bound on the trait (`trait T: 'static`).
+                            alt_span = Some(span);
+                        }
+                    }
+                }
                 let param_must_outlive = note_and_explain::RegionExplanation::new(
                     self.tcx,
                     generic_param_scope,
                     sub,
-                    None,
+                    alt_span,
                     note_and_explain::PrefixKind::LfParamMustOutlive,
                     note_and_explain::SuffixKind::Empty,
                 );
@@ -1079,16 +1099,8 @@ fn msg_span_from_named_region<'tcx>(
 ) -> (String, Option<Span>) {
     match *region {
         ty::ReEarlyParam(br) => {
-            let scope = tcx
-                .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id)
-                .expect_local();
-            let span = if let Some(param) =
-                tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
-            {
-                param.span
-            } else {
-                tcx.def_span(scope)
-            };
+            let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id;
+            let span = tcx.def_span(param_def_id);
             let text = if br.has_name() {
                 format!("the lifetime `{}` as defined here", br.name)
             } else {
@@ -1104,16 +1116,8 @@ fn msg_span_from_named_region<'tcx>(
                 ("the anonymous lifetime defined here".to_string(), Some(ty.span))
             } else {
                 match fr.bound_region {
-                    ty::BoundRegionKind::BrNamed(_, name) => {
-                        let span = if let Some(param) = tcx
-                            .hir()
-                            .get_generics(generic_param_scope)
-                            .and_then(|generics| generics.get_named(name))
-                        {
-                            param.span
-                        } else {
-                            tcx.def_span(generic_param_scope)
-                        };
+                    ty::BoundRegionKind::BrNamed(param_def_id, name) => {
+                        let span = tcx.def_span(param_def_id);
                         let text = if name == kw::UnderscoreLifetime {
                             "the anonymous lifetime as defined here".to_string()
                         } else {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 35f68a56d2d..ba656493d46 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -382,7 +382,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         if !expected_inner.is_fn() || !found_inner.is_fn() {
             return;
         }
-        match (&expected_inner.kind(), &found_inner.kind()) {
+        match (expected_inner.kind(), found_inner.kind()) {
             (ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => {
                 let sig = sig_tys.with(*hdr);
                 let expected_sig = &(self.normalize_fn_sig)(sig);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index d1cc630bc9a..def9d6e9a31 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -438,6 +438,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let is_target_feature_fn = if let ty::FnDef(def_id, _) =
                             *leaf_trait_ref.skip_binder().self_ty().kind()
                         {
+                            // FIXME(struct_target_features): should a function that inherits
+                            // target_features through arguments implement Fn traits?
                             !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                         } else {
                             false
@@ -1693,7 +1695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     StringPart::highlighted("multiple different versions".to_string()),
                     StringPart::normal(" of crate `".to_string()),
                     StringPart::highlighted(format!("{name}")),
-                    StringPart::normal("` the your dependency graph".to_string()),
+                    StringPart::normal("` in the dependency graph".to_string()),
                 ],
             );
             let candidates = if impl_candidates.is_empty() {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index a962be54c3d..3cb95294fb6 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -2727,6 +2727,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         let tcx = self.tcx;
         let predicate = predicate.upcast(tcx);
+        let suggest_remove_deref = |err: &mut Diag<'_, G>, expr: &hir::Expr<'_>| {
+            if let Some(pred) = predicate.as_trait_clause()
+                && tcx.is_lang_item(pred.def_id(), LangItem::Sized)
+                && let hir::ExprKind::Unary(hir::UnOp::Deref, inner) = expr.kind
+            {
+                err.span_suggestion_verbose(
+                    expr.span.until(inner.span),
+                    "references are always `Sized`, even if they point to unsized data; consider \
+                     not dereferencing the expression",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        };
         match *cause_code {
             ObligationCauseCode::ExprAssignable
             | ObligationCauseCode::MatchExpressionArm { .. }
@@ -2773,6 +2787,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
                 if !span.is_dummy() =>
             {
+                if let ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, pos) = &cause_code {
+                    if let Node::Expr(expr) = tcx.parent_hir_node(*hir_id)
+                        && let hir::ExprKind::Call(_, args) = expr.kind
+                        && let Some(expr) = args.get(*pos)
+                    {
+                        suggest_remove_deref(err, &expr);
+                    } else if let Node::Expr(expr) = self.tcx.hir_node(*hir_id)
+                        && let hir::ExprKind::MethodCall(_, _, args, _) = expr.kind
+                        && let Some(expr) = args.get(*pos)
+                    {
+                        suggest_remove_deref(err, &expr);
+                    }
+                }
                 let item_name = tcx.def_path_str(item_def_id);
                 let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
                 let mut multispan = MultiSpan::from(span);
@@ -2970,6 +2997,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     ));
                     err.downgrade_to_delayed_bug();
                 }
+                let mut local = true;
                 match tcx.parent_hir_node(hir_id) {
                     Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
                         err.span_suggestion_verbose(
@@ -2978,7 +3006,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             "&",
                             Applicability::MachineApplicable,
                         );
-                        err.note("all local variables must have a statically known size");
                     }
                     Node::LetStmt(hir::LetStmt {
                         init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
@@ -2993,7 +3020,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             "&",
                             Applicability::MachineApplicable,
                         );
-                        err.note("all local variables must have a statically known size");
+                    }
+                    Node::LetStmt(hir::LetStmt { init: Some(expr), .. }) => {
+                        // When encountering an assignment of an unsized trait, like `let x = *"";`,
+                        // we check if the RHS is a deref operation, to suggest removing it.
+                        suggest_remove_deref(err, &expr);
                     }
                     Node::Param(param) => {
                         err.span_suggestion_verbose(
@@ -3003,10 +3034,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             "&",
                             Applicability::MachineApplicable,
                         );
+                        local = false;
                     }
-                    _ => {
-                        err.note("all local variables must have a statically known size");
-                    }
+                    _ => {}
+                }
+                if local {
+                    err.note("all local variables must have a statically known size");
                 }
                 if !tcx.features().unsized_locals {
                     err.help("unsized locals are gated as an unstable feature");
@@ -3529,14 +3562,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 );
             }
             ObligationCauseCode::OpaqueReturnType(expr_info) => {
-                if let Some((expr_ty, expr_span)) = expr_info {
+                if let Some((expr_ty, hir_id)) = expr_info {
                     let expr_ty = self.tcx.short_ty_string(expr_ty, &mut long_ty_file);
+                    let expr = self.infcx.tcx.hir().expect_expr(hir_id);
                     err.span_label(
-                        expr_span,
+                        expr.span,
                         with_forced_trimmed_paths!(format!(
                             "return type was inferred to be `{expr_ty}` here",
                         )),
                     );
+                    suggest_remove_deref(err, &expr);
                 }
             }
         }
@@ -4667,10 +4702,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             if let hir::ExprKind::Block(b, _) = body.value.kind
                 && b.expr.is_none()
             {
+                // The span of '}' in the end of block.
+                let span = self.tcx.sess.source_map().end_point(b.span);
                 sugg_spans.push((
-                    // The span will point to the closing curly brace `}` of the block.
-                    b.span.shrink_to_hi().with_lo(b.span.hi() - BytePos(1)),
-                    "\n    Ok(())\n}".to_string(),
+                    span.shrink_to_lo(),
+                    format!(
+                        "{}{}",
+                        "    Ok(())\n",
+                        self.tcx.sess.source_map().indentation_before(span).unwrap_or_default(),
+                    ),
                 ));
             }
             err.multipart_suggestion_verbose(
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 5384084f6d7..ebaec0b9059 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -205,6 +205,8 @@ pub struct AnnotationRequired<'a> {
     #[note(trait_selection_full_type_written)]
     pub was_written: bool,
     pub path: PathBuf,
+    #[note(trait_selection_type_annotations_needed_error_time)]
+    pub time_version: bool,
 }
 
 // Copy of `AnnotationRequired` for E0283
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 1bd66266936..c98d6c5f1df 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -19,6 +19,7 @@
 #![feature(assert_matches)]
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
+#![feature(cfg_version)]
 #![feature(control_flow_enum)]
 #![feature(extract_if)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index cb8deeaedb6..a21feec4b1a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -545,6 +545,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
             ty::FnDef(def_id, args) => {
                 let tcx = self.tcx();
+                // FIXME(struct_target_features): should a function that inherits target_features
+                // through an argument implement Fn traits?
                 if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
                     && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
                 {
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 7c73f74e629..2c67e7d4847 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -179,7 +179,7 @@ pub(crate) mod rustc {
     };
 
     use super::Tree;
-    use crate::layout::rustc::{Def, Ref};
+    use crate::layout::rustc::{layout_of, Def, Ref};
 
     #[derive(Debug, Copy, Clone)]
     pub(crate) enum Err {
@@ -206,7 +206,7 @@ pub(crate) mod rustc {
     impl<'tcx> Tree<Def<'tcx>, Ref<'tcx>> {
         pub fn from_ty(ty: Ty<'tcx>, cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, Err> {
             use rustc_target::abi::HasDataLayout;
-            let layout = ty_layout(cx, ty);
+            let layout = layout_of(cx, ty)?;
 
             if let Err(e) = ty.error_reported() {
                 return Err(Err::TypeError(e));
@@ -239,7 +239,7 @@ pub(crate) mod rustc {
                     let FieldsShape::Array { stride, count } = &layout.fields else {
                         return Err(Err::NotYetSupported);
                     };
-                    let inner_layout = ty_layout(cx, *inner_ty);
+                    let inner_layout = layout_of(cx, *inner_ty)?;
                     assert_eq!(*stride, inner_layout.size);
                     let elt = Tree::from_ty(*inner_ty, cx)?;
                     Ok(std::iter::repeat(elt)
@@ -254,7 +254,7 @@ pub(crate) mod rustc {
                 },
 
                 ty::Ref(lifetime, ty, mutability) => {
-                    let layout = ty_layout(cx, *ty);
+                    let layout = layout_of(cx, *ty)?;
                     let align = layout.align.abi.bytes_usize();
                     let size = layout.size.bytes_usize();
                     Ok(Tree::Ref(Ref {
@@ -280,7 +280,7 @@ pub(crate) mod rustc {
                 FieldsShape::Primitive => {
                     assert_eq!(members.len(), 1);
                     let inner_ty = members[0];
-                    let inner_layout = ty_layout(cx, inner_ty);
+                    let inner_layout = layout_of(cx, inner_ty)?;
                     Self::from_ty(inner_ty, cx)
                 }
                 FieldsShape::Arbitrary { offsets, .. } => {
@@ -413,7 +413,7 @@ pub(crate) mod rustc {
                 let padding = Self::padding(padding_needed.bytes_usize());
 
                 let field_ty = ty_field(cx, (ty, layout), field_idx);
-                let field_layout = ty_layout(cx, field_ty);
+                let field_layout = layout_of(cx, field_ty)?;
                 let field_tree = Self::from_ty(field_ty, cx)?;
 
                 struct_tree = struct_tree.then(padding).then(field_tree);
@@ -471,7 +471,7 @@ pub(crate) mod rustc {
                 |fields, (idx, field_def)| {
                     let field_def = Def::Field(field_def);
                     let field_ty = ty_field(cx, (ty, layout), idx);
-                    let field_layout = ty_layout(cx, field_ty);
+                    let field_layout = layout_of(cx, field_ty)?;
                     let field = Self::from_ty(field_ty, cx)?;
                     let trailing_padding_needed = layout.size - field_layout.size;
                     let trailing_padding = Self::padding(trailing_padding_needed.bytes_usize());
@@ -484,10 +484,6 @@ pub(crate) mod rustc {
         }
     }
 
-    pub(crate) fn ty_layout<'tcx>(cx: LayoutCx<'tcx, TyCtxt<'tcx>>, ty: Ty<'tcx>) -> Layout<'tcx> {
-        crate::layout::rustc::layout_of(cx, ty).unwrap()
-    }
-
     fn ty_field<'tcx>(
         cx: LayoutCx<'tcx, TyCtxt<'tcx>>,
         (ty, layout): (Ty<'tcx>, Layout<'tcx>),
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
index 1f3c4e3c817..2762b4e6384 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
@@ -44,18 +44,11 @@ mod rustc {
             let Self { src, dst, assume, context } = self;
 
             let layout_cx = LayoutCx { tcx: context, param_env: ParamEnv::reveal_all() };
-            let layout_of = |ty| {
-                crate::layout::rustc::layout_of(layout_cx, ty)
-                    .map_err(|_| Err::NotYetSupported)
-                    .and_then(|_| Tree::from_ty(ty, layout_cx))
-            };
 
             // Convert `src` and `dst` from their rustc representations, to `Tree`-based
-            // representations. If these conversions fail, conclude that the transmutation is
-            // unacceptable; the layouts of both the source and destination types must be
-            // well-defined.
-            let src = layout_of(src);
-            let dst = layout_of(dst);
+            // representations.
+            let src = Tree::from_ty(src, layout_cx);
+            let dst = Tree::from_ty(dst, layout_cx);
 
             match (src, dst) {
                 (Err(Err::TypeError(_)), _) | (_, Err(Err::TypeError(_))) => {
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
index 95373916a71..f8b59bdf326 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
@@ -4,7 +4,6 @@ use crate::layout;
 pub(crate) trait QueryContext {
     type Def: layout::Def;
     type Ref: layout::Ref;
-    type Scope: Copy;
 }
 
 #[cfg(test)]
@@ -28,20 +27,17 @@ pub(crate) mod test {
     impl QueryContext for UltraMinimal {
         type Def = Def;
         type Ref = !;
-        type Scope = ();
     }
 }
 
 #[cfg(feature = "rustc")]
 mod rustc {
-    use rustc_middle::ty::{Ty, TyCtxt};
+    use rustc_middle::ty::TyCtxt;
 
     use super::*;
 
     impl<'tcx> super::QueryContext for TyCtxt<'tcx> {
         type Def = layout::rustc::Def<'tcx>;
         type Ref = layout::rustc::Ref<'tcx>;
-
-        type Scope = Ty<'tcx>;
     }
 }
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/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index d274a934d52..9a3956596d2 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -366,7 +366,7 @@ fn adt_consider_insignificant_dtor<'tcx>(
 fn adt_drop_tys<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-) -> Result<&ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
+) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
     // This is for the "adt_drop_tys" query, that considers all `Drop` impls, therefore all dtors are
     // significant.
     let adt_has_dtor =
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/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml
index 2750838bbe9..98cc116bd00 100644
--- a/compiler/rustc_type_ir/Cargo.toml
+++ b/compiler/rustc_type_ir/Cargo.toml
@@ -8,6 +8,7 @@ edition = "2021"
 bitflags = "2.4.1"
 derive-where = "1.2.7"
 indexmap = "2.0.0"
+rustc-hash = "1.1.0"
 rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
 rustc_index = { path = "../rustc_index", default-features = false }
@@ -31,3 +32,6 @@ nightly = [
     "rustc_index/nightly",
     "rustc_ast_ir/nightly"
 ]
+
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] }
diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs
index 4ca97c0c86c..96036e53b0a 100644
--- a/compiler/rustc_type_ir/src/data_structures.rs
+++ b/compiler/rustc_type_ir/src/data_structures.rs
@@ -1,8 +1,13 @@
+use std::hash::BuildHasherDefault;
+
+use rustc_hash::FxHasher;
+pub use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
+
+pub type IndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
+pub type IndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
+
 #[cfg(feature = "nightly")]
 mod impl_ {
-    pub use rustc_data_structures::fx::{
-        FxHashMap as HashMap, FxHashSet as HashSet, FxIndexMap as IndexMap, FxIndexSet as IndexSet,
-    };
     pub use rustc_data_structures::sso::{SsoHashMap, SsoHashSet};
     pub use rustc_data_structures::stack::ensure_sufficient_stack;
     pub use rustc_data_structures::sync::Lrc;
@@ -10,11 +15,9 @@ mod impl_ {
 
 #[cfg(not(feature = "nightly"))]
 mod impl_ {
-    pub use std::collections::{HashMap, HashMap as SsoHashMap, HashSet, HashSet as SsoHashSet};
+    pub use std::collections::{HashMap as SsoHashMap, HashSet as SsoHashSet};
     pub use std::sync::Arc as Lrc;
 
-    pub use indexmap::{IndexMap, IndexSet};
-
     #[inline]
     pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
         f()
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index f30419c801f..433c444e701 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -237,7 +237,7 @@ pub fn supertrait_def_ids<I: Interner>(
     cx: I,
     trait_def_id: I::DefId,
 ) -> impl Iterator<Item = I::DefId> {
-    let mut set = HashSet::default();
+    let mut set: HashSet<I::DefId> = HashSet::default();
     let mut stack = vec![trait_def_id];
 
     set.insert(trait_def_id);
diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs
index bfcea6a81d3..e8afaf1a480 100644
--- a/compiler/rustc_type_ir/src/outlives.rs
+++ b/compiler/rustc_type_ir/src/outlives.rs
@@ -68,6 +68,9 @@ struct OutlivesCollector<'a, I: Interner> {
 }
 
 impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
+    #[cfg(not(feature = "nightly"))]
+    type Result = ();
+
     fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
         if !self.visited.insert(ty) {
             return;
diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs
index d47c9e725f3..418139c3aad 100644
--- a/compiler/rustc_type_ir/src/search_graph/mod.rs
+++ b/compiler/rustc_type_ir/src/search_graph/mod.rs
@@ -287,7 +287,7 @@ impl<X: Cx> NestedGoals<X> {
         }
     }
 
-    #[rustc_lint_query_instability]
+    #[cfg_attr(feature = "nightly", rustc_lint_query_instability)]
     #[allow(rustc::potential_query_instability)]
     fn iter(&self) -> impl Iterator<Item = (X::Input, UsageKind)> + '_ {
         self.nested_goals.iter().map(|(i, p)| (*i, *p))
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index 50d7bae21db..aeae866e9d3 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -465,6 +465,22 @@ impl Location {
     }
 }
 
+/// Location of the statement at the given index for a given basic block. Assumes that `stmt_idx`
+/// and `bb_idx` are valid for a given body.
+pub fn statement_location(body: &Body, bb_idx: &BasicBlockIdx, stmt_idx: usize) -> Location {
+    let bb = &body.blocks[*bb_idx];
+    let stmt = &bb.statements[stmt_idx];
+    Location(stmt.span)
+}
+
+/// Location of the terminator for a given basic block. Assumes that `bb_idx` is valid for a given
+/// body.
+pub fn terminator_location(body: &Body, bb_idx: &BasicBlockIdx) -> Location {
+    let bb = &body.blocks[*bb_idx];
+    let terminator = &bb.terminator;
+    Location(terminator.span)
+}
+
 /// Reference to a place used to represent a partial projection.
 pub struct PlaceRef<'a> {
     pub local: Local,
diff --git a/config.example.toml b/config.example.toml
index 1b7de662e84..f1dc32234cc 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -337,6 +337,7 @@
 #    "analysis",
 #    "src",
 #    "wasm-component-ld",
+#    "miri", "cargo-miri" # for dev/nightly channels
 #]
 
 # Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose, 3 == print environment variables on each rustc invocation
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 30f5076e1e2..aa22181a463 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -58,9 +58,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.118"
+version = "0.1.121"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92afe7344b64cccf3662ca26d5d1c0828ab826f04206b97d856e3625e390e4b5"
+checksum = "ce956e6dc07082ec481f0935a51e83b343f8ca51be560452c0ebf830d0bdf5a5"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index bdf16257c7c..a39a0a6ce0e 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = { version = "0.1.118", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "0.1.121", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 7de41259599..caaf37f0465 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -293,6 +293,7 @@ impl<T> Box<T> {
     ///
     /// ```
     /// #![feature(new_uninit)]
+    /// #![feature(new_zeroed_alloc)]
     ///
     /// let zero = Box::<u32>::new_zeroed();
     /// let zero = unsafe { zero.assume_init() };
@@ -303,7 +304,7 @@ impl<T> Box<T> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
         Self::new_zeroed_in(Global)
@@ -684,6 +685,7 @@ impl<T> Box<[T]> {
     /// # Examples
     ///
     /// ```
+    /// #![feature(new_zeroed_alloc)]
     /// #![feature(new_uninit)]
     ///
     /// let values = Box::<[u32]>::new_zeroed_slice(3);
@@ -694,7 +696,7 @@ impl<T> Box<[T]> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         unsafe { RawVec::with_capacity_zeroed(len).into_box(len) }
@@ -955,6 +957,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     /// # Examples
     ///
     /// ```
+    /// #![feature(box_uninit_write)]
     /// #![feature(new_uninit)]
     ///
     /// let big_box = Box::<[usize; 1024]>::new_uninit();
@@ -972,7 +975,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     ///     assert_eq!(*x, i);
     /// }
     /// ```
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "box_uninit_write", issue = "129397")]
     #[inline]
     pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
         unsafe {
@@ -1254,6 +1257,95 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
         unsafe { (Unique::from(&mut *ptr), alloc) }
     }
 
+    /// Returns a raw mutable pointer to the `Box`'s contents.
+    ///
+    /// The caller must ensure that the `Box` outlives the pointer this
+    /// function returns, or else it will end up dangling.
+    ///
+    /// This method guarantees that for the purpose of the aliasing model, this method
+    /// does not materialize a reference to the underlying memory, and thus the returned pointer
+    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+    /// Note that calling other methods that materialize references to the memory
+    /// may still invalidate this pointer.
+    /// See the example below for how this guarantee can be used.
+    ///
+    /// # Examples
+    ///
+    /// Due to the aliasing guarantee, the following code is legal:
+    ///
+    /// ```rust
+    /// #![feature(box_as_ptr)]
+    ///
+    /// unsafe {
+    ///     let mut b = Box::new(0);
+    ///     let ptr1 = Box::as_mut_ptr(&mut b);
+    ///     ptr1.write(1);
+    ///     let ptr2 = Box::as_mut_ptr(&mut b);
+    ///     ptr2.write(2);
+    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ///     ptr1.write(3);
+    /// }
+    /// ```
+    ///
+    /// [`as_mut_ptr`]: Self::as_mut_ptr
+    /// [`as_ptr`]: Self::as_ptr
+    #[unstable(feature = "box_as_ptr", issue = "129090")]
+    #[rustc_never_returns_null_ptr]
+    #[inline]
+    pub fn as_mut_ptr(b: &mut Self) -> *mut T {
+        // This is a primitive deref, not going through `DerefMut`, and therefore not materializing
+        // any references.
+        ptr::addr_of_mut!(**b)
+    }
+
+    /// Returns a raw pointer to the `Box`'s contents.
+    ///
+    /// The caller must ensure that the `Box` outlives the pointer this
+    /// function returns, or else it will end up dangling.
+    ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the `Box`, use [`as_mut_ptr`].
+    ///
+    /// This method guarantees that for the purpose of the aliasing model, this method
+    /// does not materialize a reference to the underlying memory, and thus the returned pointer
+    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+    /// Note that calling other methods that materialize mutable references to the memory,
+    /// as well as writing to this memory, may still invalidate this pointer.
+    /// See the example below for how this guarantee can be used.
+    ///
+    /// # Examples
+    ///
+    /// Due to the aliasing guarantee, the following code is legal:
+    ///
+    /// ```rust
+    /// #![feature(box_as_ptr)]
+    ///
+    /// unsafe {
+    ///     let mut v = Box::new(0);
+    ///     let ptr1 = Box::as_ptr(&v);
+    ///     let ptr2 = Box::as_mut_ptr(&mut v);
+    ///     let _val = ptr2.read();
+    ///     // No write to this memory has happened yet, so `ptr1` is still valid.
+    ///     let _val = ptr1.read();
+    ///     // However, once we do a write...
+    ///     ptr2.write(1);
+    ///     // ... `ptr1` is no longer valid.
+    ///     // This would be UB: let _val = ptr1.read();
+    /// }
+    /// ```
+    ///
+    /// [`as_mut_ptr`]: Self::as_mut_ptr
+    /// [`as_ptr`]: Self::as_ptr
+    #[unstable(feature = "box_as_ptr", issue = "129090")]
+    #[rustc_never_returns_null_ptr]
+    #[inline]
+    pub fn as_ptr(b: &Self) -> *const T {
+        // This is a primitive deref, not going through `DerefMut`, and therefore not materializing
+        // any references.
+        ptr::addr_of!(**b)
+    }
+
     /// Returns a reference to the underlying allocator.
     ///
     /// Note: this is an associated function, which means that you have
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index bdee06154fa..f153aa6d3be 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -539,6 +539,7 @@ impl<T> Rc<T> {
     /// # Examples
     ///
     /// ```
+    /// #![feature(new_zeroed_alloc)]
     /// #![feature(new_uninit)]
     ///
     /// use std::rc::Rc;
@@ -551,7 +552,7 @@ impl<T> Rc<T> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
         unsafe {
@@ -1000,6 +1001,7 @@ impl<T> Rc<[T]> {
     ///
     /// ```
     /// #![feature(new_uninit)]
+    /// #![feature(new_zeroed_alloc)]
     ///
     /// use std::rc::Rc;
     ///
@@ -1011,7 +1013,7 @@ impl<T> Rc<[T]> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
         unsafe {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 2c0d19b0ada..4a3522f1a64 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -542,6 +542,7 @@ impl<T> Arc<T> {
     /// # Examples
     ///
     /// ```
+    /// #![feature(new_zeroed_alloc)]
     /// #![feature(new_uninit)]
     ///
     /// use std::sync::Arc;
@@ -555,7 +556,7 @@ impl<T> Arc<T> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
         unsafe {
@@ -1134,6 +1135,7 @@ impl<T> Arc<[T]> {
     /// # Examples
     ///
     /// ```
+    /// #![feature(new_zeroed_alloc)]
     /// #![feature(new_uninit)]
     ///
     /// use std::sync::Arc;
@@ -1147,7 +1149,7 @@ impl<T> Arc<[T]> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "new_zeroed_alloc", issue = "129396")]
     #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
         unsafe {
@@ -1191,7 +1193,7 @@ impl<T, A: Allocator> Arc<[T], A> {
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
     pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit<T>], A> {
         unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) }
@@ -1220,7 +1222,7 @@ impl<T, A: Allocator> Arc<[T], A> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
     pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit<T>], A> {
         unsafe {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index b4e0bc5fcbe..cfd2e4a1512 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1334,7 +1334,7 @@ impl<T, A: Allocator> Vec<T, A> {
         self.buf.ptr()
     }
 
-    /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
+    /// Returns a raw mutable pointer to the vector's buffer, or a dangling
     /// raw pointer valid for zero sized reads if the vector didn't allocate.
     ///
     /// The caller must ensure that the vector outlives the pointer this
@@ -1350,7 +1350,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// may still invalidate this pointer.
     /// See the second example below for how this guarantee can be used.
     ///
-    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs
index faee64b2f67..bfc31a626fa 100644
--- a/library/alloc/tests/boxed.rs
+++ b/library/alloc/tests/boxed.rs
@@ -59,6 +59,7 @@ fn box_deref_lval() {
     assert_eq!(x.get(), 1000);
 }
 
+#[allow(unused)]
 pub struct ConstAllocator;
 
 unsafe impl Allocator for ConstAllocator {
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index 375358dddf5..ce09a0b444d 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -3,8 +3,8 @@
 //! suggestions from rustc if you get anything slightly wrong in here, and overall
 //! helps with clarity as we're also referring to `char` intentionally in here.
 
-use crate::fmt;
 use crate::mem::transmute;
+use crate::{assert_unsafe_precondition, fmt};
 
 /// One of the 128 Unicode characters from U+0000 through U+007F,
 /// often known as the [ASCII] subset.
@@ -497,14 +497,18 @@ impl AsciiChar {
     /// Notably, it should not be expected to return hex digits, or any other
     /// reasonable extension of the decimal digits.
     ///
-    /// (This lose safety condition is intended to simplify soundness proofs
+    /// (This loose safety condition is intended to simplify soundness proofs
     /// when writing code using this method, since the implementation doesn't
     /// need something really specific, not to make those other arguments do
     /// something useful. It might be tightened before stabilization.)
     #[unstable(feature = "ascii_char", issue = "110998")]
     #[inline]
     pub const unsafe fn digit_unchecked(d: u8) -> Self {
-        debug_assert!(d < 10);
+        assert_unsafe_precondition!(
+            check_language_ub,
+            "`AsciiChar::digit_unchecked` input cannot exceed 9.",
+            (d: u8 = d) => d < 10
+        );
 
         // SAFETY: `'0'` through `'9'` are U+00030 through U+0039,
         // so because `d` must be 64 or less the addition can return at most
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index d860f3415d9..5dd9721d3fe 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -306,6 +306,7 @@ pub use once::OnceCell;
 /// See the [module-level documentation](self) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 pub struct Cell<T: ?Sized> {
     value: UnsafeCell<T>,
 }
@@ -2055,6 +2056,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 #[lang = "unsafe_cell"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 pub struct UnsafeCell<T: ?Sized> {
     value: T,
 }
@@ -2297,6 +2299,7 @@ impl<T> UnsafeCell<*mut T> {
 /// See [`UnsafeCell`] for details.
 #[unstable(feature = "sync_unsafe_cell", issue = "95439")]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 pub struct SyncUnsafeCell<T: ?Sized> {
     value: UnsafeCell<T>,
 }
diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs
index 097fa86c938..87df8a4e272 100644
--- a/library/core/src/cell/once.rs
+++ b/library/core/src/cell/once.rs
@@ -309,7 +309,8 @@ impl<T> OnceCell<T> {
     /// ```
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
-    pub fn into_inner(self) -> Option<T> {
+    #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
+    pub const fn into_inner(self) -> Option<T> {
         // Because `into_inner` takes `self` by value, the compiler statically verifies
         // that it is not currently borrowed. So it is safe to move out `Option<T>`.
         self.inner.into_inner()
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/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 22084dcff8f..7808d42ab5d 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -91,6 +91,7 @@ use crate::{fmt, intrinsics, ops, slice, str};
 /// [str]: prim@str "str"
 #[derive(PartialEq, Eq, Hash)]
 #[stable(feature = "core_c_str", since = "1.64.0")]
+#[rustc_diagnostic_item = "cstr_type"]
 #[rustc_has_incoherent_inherent_impls]
 #[lang = "CStr"]
 // `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs
index 467fa17a6f3..c7c462a4df1 100644
--- a/library/core/src/fmt/builders.rs
+++ b/library/core/src/fmt/builders.rs
@@ -78,7 +78,7 @@ impl fmt::Write for PadAdapter<'_, '_> {
 ///
 /// assert_eq!(
 ///     format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
-///     "Foo { bar: 10, baz: \"Hello World\" }",
+///     r#"Foo { bar: 10, baz: "Hello World" }"#,
 /// );
 /// ```
 #[must_use = "must eventually call `finish()` on Debug builders"]
@@ -125,7 +125,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
-    ///     "Bar { bar: 10, another: \"Hello World\", nonexistent_field: 1 }",
+    ///     r#"Bar { bar: 10, another: "Hello World", nonexistent_field: 1 }"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -237,7 +237,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
-    ///     "Bar { bar: 10, baz: \"Hello World\" }",
+    ///     r#"Bar { bar: 10, baz: "Hello World" }"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -280,7 +280,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
 ///
 /// assert_eq!(
 ///     format!("{:?}", Foo(10, "Hello World".to_string())),
-///     "Foo(10, \"Hello World\")",
+///     r#"Foo(10, "Hello World")"#,
 /// );
 /// ```
 #[must_use = "must eventually call `finish()` on Debug builders"]
@@ -322,7 +322,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(10, "Hello World".to_string())),
-    ///     "Foo(10, \"Hello World\")",
+    ///     r#"Foo(10, "Hello World")"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -360,6 +360,51 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
         self
     }
 
+    /// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some
+    /// other fields that are not shown in the debug representation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(debug_more_non_exhaustive)]
+    ///
+    /// use std::fmt;
+    ///
+    /// struct Foo(i32, String);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         fmt.debug_tuple("Foo")
+    ///            .field(&self.0)
+    ///            .finish_non_exhaustive() // Show that some other field(s) exist.
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(10, "secret!".to_owned())),
+    ///     "Foo(10, ..)",
+    /// );
+    /// ```
+    #[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
+    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
+        self.result = self.result.and_then(|_| {
+            if self.fields > 0 {
+                if self.is_pretty() {
+                    let mut slot = None;
+                    let mut state = Default::default();
+                    let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
+                    writer.write_str("..\n")?;
+                    self.fmt.write_str(")")
+                } else {
+                    self.fmt.write_str(", ..)")
+                }
+            } else {
+                self.fmt.write_str("(..)")
+            }
+        });
+        self.result
+    }
+
     /// Finishes output and returns any error encountered.
     ///
     /// # Examples
@@ -381,7 +426,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(10, "Hello World".to_string())),
-    ///     "Foo(10, \"Hello World\")",
+    ///     r#"Foo(10, "Hello World")"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -555,6 +600,56 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
         self
     }
 
+    /// Marks the set as non-exhaustive, indicating to the reader that there are some other
+    /// elements that are not shown in the debug representation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(debug_more_non_exhaustive)]
+    ///
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<i32>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         // Print at most two elements, abbreviate the rest
+    ///         let mut f = fmt.debug_set();
+    ///         let mut f = f.entries(self.0.iter().take(2));
+    ///         if self.0.len() > 2 {
+    ///             f.finish_non_exhaustive()
+    ///         } else {
+    ///             f.finish()
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(vec![1, 2, 3, 4])),
+    ///     "{1, 2, ..}",
+    /// );
+    /// ```
+    #[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
+    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
+        self.inner.result = self.inner.result.and_then(|_| {
+            if self.inner.has_fields {
+                if self.inner.is_pretty() {
+                    let mut slot = None;
+                    let mut state = Default::default();
+                    let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
+                    writer.write_str("..\n")?;
+                    self.inner.fmt.write_str("}")
+                } else {
+                    self.inner.fmt.write_str(", ..}")
+                }
+            } else {
+                self.inner.fmt.write_str("..}")
+            }
+        });
+        self.inner.result
+    }
+
     /// Finishes output and returns any error encountered.
     ///
     /// # Examples
@@ -699,6 +794,55 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
         self
     }
 
+    /// Marks the list as non-exhaustive, indicating to the reader that there are some other
+    /// elements that are not shown in the debug representation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(debug_more_non_exhaustive)]
+    ///
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<i32>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         // Print at most two elements, abbreviate the rest
+    ///         let mut f = fmt.debug_list();
+    ///         let mut f = f.entries(self.0.iter().take(2));
+    ///         if self.0.len() > 2 {
+    ///             f.finish_non_exhaustive()
+    ///         } else {
+    ///             f.finish()
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(vec![1, 2, 3, 4])),
+    ///     "[1, 2, ..]",
+    /// );
+    /// ```
+    #[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
+    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
+        self.inner.result.and_then(|_| {
+            if self.inner.has_fields {
+                if self.inner.is_pretty() {
+                    let mut slot = None;
+                    let mut state = Default::default();
+                    let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
+                    writer.write_str("..\n")?;
+                    self.inner.fmt.write_str("]")
+                } else {
+                    self.inner.fmt.write_str(", ..]")
+                }
+            } else {
+                self.inner.fmt.write_str("..]")
+            }
+        })
+    }
+
     /// Finishes output and returns any error encountered.
     ///
     /// # Examples
@@ -750,7 +894,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
 ///
 /// assert_eq!(
 ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-///     "{\"A\": 10, \"B\": 11}",
+///     r#"{"A": 10, "B": 11}"#,
 /// );
 /// ```
 #[must_use = "must eventually call `finish()` on Debug builders"]
@@ -790,7 +934,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-    ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
+    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -826,7 +970,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-    ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
+    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
     /// );
     /// ```
     #[stable(feature = "debug_map_key_value", since = "1.42.0")]
@@ -902,7 +1046,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-    ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
+    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
     /// );
     /// ```
     #[stable(feature = "debug_map_key_value", since = "1.42.0")]
@@ -960,7 +1104,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-    ///     "{\"A\": 10, \"B\": 11}",
+    ///     r#"{"A": 10, "B": 11}"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
@@ -976,6 +1120,62 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
         self
     }
 
+    /// Marks the map as non-exhaustive, indicating to the reader that there are some other
+    /// entries that are not shown in the debug representation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(debug_more_non_exhaustive)]
+    ///
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<(String, i32)>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         // Print at most two elements, abbreviate the rest
+    ///         let mut f = fmt.debug_map();
+    ///         let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v)));
+    ///         if self.0.len() > 2 {
+    ///             f.finish_non_exhaustive()
+    ///         } else {
+    ///             f.finish()
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(vec![
+    ///         ("A".to_string(), 10),
+    ///         ("B".to_string(), 11),
+    ///         ("C".to_string(), 12),
+    ///     ])),
+    ///     r#"{"A": 10, "B": 11, ..}"#,
+    /// );
+    /// ```
+    #[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
+    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
+        self.result = self.result.and_then(|_| {
+            assert!(!self.has_key, "attempted to finish a map with a partial entry");
+
+            if self.has_fields {
+                if self.is_pretty() {
+                    let mut slot = None;
+                    let mut state = Default::default();
+                    let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
+                    writer.write_str("..\n")?;
+                    self.fmt.write_str("}")
+                } else {
+                    self.fmt.write_str(", ..}")
+                }
+            } else {
+                self.fmt.write_str("..}")
+            }
+        });
+        self.result
+    }
+
     /// Finishes output and returns any error encountered.
     ///
     /// # Panics
@@ -1000,7 +1200,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     ///
     /// assert_eq!(
     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
-    ///     "{\"A\": 10, \"B\": 11}",
+    ///     r#"{"A": 10, "B": 11}"#,
     /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index bd99e90376a..8cb9accd59d 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2949,7 +2949,7 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
 /// sysroot which is built without ub_checks but with `#[rustc_preserve_ub_checks]`.
 /// For code that gets monomorphized in the user crate (i.e., generic functions and functions with
 /// `#[inline]`), gating assertions on `ub_checks()` rather than `cfg!(ub_checks)` means that
-/// assertions are enabled whenever the *user crate* has UB checks enabled. However if the
+/// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the
 /// user has UB checks disabled, the checks will still get optimized out. This intrinsic is
 /// primarily used by [`ub_checks::assert_unsafe_precondition`].
 #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
@@ -2957,7 +2957,7 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
 #[inline(always)]
 #[rustc_intrinsic]
 pub const fn ub_checks() -> bool {
-    cfg!(debug_assertions)
+    cfg!(ub_checks)
 }
 
 /// Allocates a block of memory at compile time.
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/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs
index c97cd042ab4..5b7d95c2f65 100644
--- a/library/core/src/iter/traits/accum.rs
+++ b/library/core/src/iter/traits/accum.rs
@@ -104,7 +104,7 @@ macro_rules! float_sum_product {
         impl Sum for $a {
             fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
                 iter.fold(
-                    0.0,
+                    -0.0,
                     #[rustc_inherit_overflow_checks]
                     |a, b| a + b,
                 )
@@ -126,7 +126,7 @@ macro_rules! float_sum_product {
         impl<'a> Sum<&'a $a> for $a {
             fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
                 iter.fold(
-                    0.0,
+                    -0.0,
                     #[rustc_inherit_overflow_checks]
                     |a, b| a + b,
                 )
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index e3640627c56..06a745b690a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -110,7 +110,6 @@
 #![cfg_attr(bootstrap, feature(offset_of_nested))]
 #![feature(array_ptr_get)]
 #![feature(asm_experimental_arch)]
-#![feature(char_indices_offset)]
 #![feature(const_align_of_val)]
 #![feature(const_align_of_val_raw)]
 #![feature(const_align_offset)]
@@ -194,6 +193,7 @@
 // Language features:
 // tidy-alphabetical-start
 #![cfg_attr(bootstrap, feature(asm_const))]
+#![cfg_attr(bootstrap, feature(const_fn_floating_point_arithmetic))]
 #![cfg_attr(bootstrap, feature(min_exhaustive_patterns))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
@@ -203,7 +203,7 @@
 #![feature(cfg_sanitize)]
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_has_atomic_equal_alignment)]
-#![feature(const_fn_floating_point_arithmetic)]
+#![feature(cfg_ub_checks)]
 #![feature(const_for)]
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 374fa086aec..5654f5aa4b8 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1097,7 +1097,6 @@ pub mod effects {
     pub trait TyCompat<T: ?Sized> {}
 
     impl<T: ?Sized> TyCompat<T> for T {}
-    impl<T: ?Sized> TyCompat<T> for Maybe {}
     impl<T: ?Sized> TyCompat<Maybe> for T {}
 
     #[lang = "EffectsIntersection"]
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 00c837041b6..be5cee2e852 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -47,6 +47,7 @@ use crate::ptr;
 #[lang = "manually_drop"]
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 pub struct ManuallyDrop<T: ?Sized> {
     value: T,
 }
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index f920ab1792d..c308def2f57 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -237,6 +237,7 @@ use crate::{fmt, intrinsics, ptr, slice};
 #[lang = "maybe_uninit"]
 #[derive(Copy)]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 pub union MaybeUninit<T> {
     uninit: (),
     value: ManuallyDrop<T>,
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 7a9ca4011be..e602b497d17 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -19,7 +19,7 @@ pub use maybe_uninit::MaybeUninit;
 
 mod transmutability;
 #[unstable(feature = "transmutability", issue = "99571")]
-pub use transmutability::{Assume, BikeshedIntrinsicFrom};
+pub use transmutability::{Assume, TransmuteFrom};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(inline)]
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index ea73c5b80ba..049b32ede9c 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -1,40 +1,295 @@
 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: TransmuteFrom<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, TransmuteFrom};
+///
+/// let src = 42u8; // size = 1
+///
+/// #[repr(C, align(2))]
+/// struct Dst(u8); // size = 2
+//
+/// let _ = unsafe {
+///     <Dst as TransmuteFrom<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)]
 #[rustc_coinductive]
-pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOTHING }>
+pub unsafe trait TransmuteFrom<Src, const ASSUME: Assume = { Assume::NOTHING }>
 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 [`TransmuteFrom`].
+///
+/// When `false`, the respective proof obligation belongs to the compiler. When
+/// `true`, the onus of the safety proof belongs to the programmer.
 #[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`, [`TransmuteFrom`] 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, TransmuteFrom};
+    ///
+    /// 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 TransmuteFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`TransmuteFrom`] 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, TransmuteFrom};
+    ///
+    /// 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 TransmuteFrom<_, { 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`, [`TransmuteFrom`] is not implemented for transmutations
+    /// that extend the lifetimes of references.
+    ///
+    /// When `true`, [`TransmuteFrom`] 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`, [`TransmuteFrom`] 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::TransmuteFrom;
+    ///
+    /// let src: u8 = 3;
+    ///
+    /// struct EvenU8 {
+    ///     // SAFETY: `val` must be an even number.
+    ///     val: u8,
+    /// }
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let dst: EvenU8 = unsafe {
+    ///     <_ as TransmuteFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`TransmuteFrom`] 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, TransmuteFrom};
+    ///
+    /// 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 TransmuteFrom<_, { 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`, [`TransmuteFrom`] 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::TransmuteFrom;
+    ///
+    /// let src: u8 = 3;
+    ///
+    /// // SAFETY: No safety obligations.
+    /// let dst: bool = unsafe {
+    ///     <_ as TransmuteFrom<_>>::transmute(src)
+    /// };
+    /// ```
+    ///
+    /// When `true`, [`TransmuteFrom`] 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, TransmuteFrom};
+    ///
+    /// 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 TransmuteFrom<_, { Assume::VALIDITY }>>::transmute(src)
+    ///     })
+    /// } else {
+    ///     None
+    /// };
+    ///
+    /// assert_eq!(maybe_dst, Some(true));
+    /// ```
     pub validity: bool,
 }
 
@@ -44,29 +299,86 @@ impl ConstParamTy_ for Assume {}
 impl UnsizedConstParamTy for Assume {}
 
 impl Assume {
-    /// Do not assume that *you* have ensured any safety properties are met.
+    /// With this, [`TransmuteFrom`] 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, [`TransmuteFrom`] 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, [`TransmuteFrom`] 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, [`TransmuteFrom`] 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, [`TransmuteFrom`] 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, TransmuteFrom};
+    ///
+    /// /// 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: TransmuteFrom<&'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 TransmuteFrom<_, { 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 +388,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 41bd34a2702..1e2f841aca7 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -261,7 +261,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let nan = f16::NAN;
     /// let f = 7.0_f16;
@@ -293,7 +293,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let f = 7.0f16;
     /// let inf = f16::INFINITY;
@@ -319,7 +319,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let f = 7.0f16;
     /// let inf: f16 = f16::INFINITY;
@@ -347,7 +347,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let min = f16::MIN_POSITIVE; // 6.1035e-5
     /// let max = f16::MAX;
@@ -377,7 +377,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let min = f16::MIN_POSITIVE; // 6.1035e-5
     /// let max = f16::MAX;
@@ -409,7 +409,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// use std::num::FpCategory;
     ///
@@ -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")]
@@ -867,7 +873,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let value = 4.6_f16;
     /// let rounded = unsafe { value.to_int_unchecked::<u16>() };
@@ -910,7 +916,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// # // FIXME(f16_f128): enable this once const casting works
     /// # // assert_ne!((1f16).to_bits(), 1f16 as u128); // to_bits() is not casting!
@@ -958,7 +964,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let v = f16::from_bits(0x4a40);
     /// assert_eq!(v, 12.5);
@@ -1071,7 +1077,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let value = f16::from_be_bytes([0x4a, 0x40]);
     /// assert_eq!(value, 12.5);
@@ -1094,7 +1100,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let value = f16::from_le_bytes([0x40, 0x4a]);
     /// assert_eq!(value, 12.5);
@@ -1124,7 +1130,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// let value = f16::from_ne_bytes(if cfg!(target_endian = "big") {
     ///     [0x4a, 0x40]
@@ -1257,7 +1263,7 @@ impl f16 {
     ///
     /// ```
     /// #![feature(f16)]
-    /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
     ///
     /// assert!((-3.0f16).clamp(-2.0, 1.0) == -2.0);
     /// assert!((0.0f16).clamp(-2.0, 1.0) == 0.0);
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..42461a3345b 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`.
         ///
@@ -2826,8 +2888,8 @@ macro_rules! int_impl {
         ///
         /// # Panics
         ///
-        /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
-        /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
+        /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN`
+        /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag.
         ///
         /// # Examples
         ///
@@ -2865,8 +2927,8 @@ macro_rules! int_impl {
         ///
         /// # Panics
         ///
-        /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
-        /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
+        /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` and
+        /// `rhs` is -1. This behavior is not affected by the `overflow-checks` flag.
         ///
         /// # Examples
         ///
@@ -2881,6 +2943,11 @@ macro_rules! int_impl {
         /// assert_eq!(a.rem_euclid(-b), 3);
         /// assert_eq!((-a).rem_euclid(-b), 1);
         /// ```
+        ///
+        /// This will panic:
+        /// ```should_panic
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.rem_euclid(-1);")]
+        /// ```
         #[doc(alias = "modulo", alias = "mod")]
         #[stable(feature = "euclidean_division", since = "1.38.0")]
         #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")]
@@ -2909,8 +2976,8 @@ macro_rules! int_impl {
         ///
         /// # Panics
         ///
-        /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
-        /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
+        /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN`
+        /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag.
         ///
         /// # Examples
         ///
@@ -2945,8 +3012,8 @@ macro_rules! int_impl {
         ///
         /// # Panics
         ///
-        /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
-        /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
+        /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN`
+        /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag.
         ///
         /// # Examples
         ///
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/panic/location.rs b/library/core/src/panic/location.rs
index 930edffd505..e2a842046a9 100644
--- a/library/core/src/panic/location.rs
+++ b/library/core/src/panic/location.rs
@@ -195,6 +195,7 @@ impl<'a> Location<'a> {
 
 #[stable(feature = "panic_hook_display", since = "1.26.0")]
 impl fmt::Display for Location<'_> {
+    #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(formatter, "{}:{}:{}", self.file, self.line, self.col)
     }
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 0569b8b7624..65f6bfb7ee1 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1084,6 +1084,7 @@ use crate::{cmp, fmt};
 #[lang = "pin"]
 #[fundamental]
 #[repr(transparent)]
+#[cfg_attr(not(bootstrap), rustc_pub_transparent)]
 #[derive(Copy, Clone)]
 pub struct Pin<Ptr> {
     // FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to:
@@ -1291,8 +1292,8 @@ impl<Ptr: Deref> Pin<Ptr> {
     ///     // Now, if `x` was the only reference, we have a mutable reference to
     ///     // data that we pinned above, which we could use to move it as we have
     ///     // seen in the previous example. We have violated the pinning API contract.
-    ///  }
-    ///  ```
+    /// }
+    /// ```
     ///
     /// ## Pinning of closure captures
     ///
@@ -1369,33 +1370,14 @@ impl<Ptr: Deref> Pin<Ptr> {
         // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&*self.__pointer) }
     }
-
-    /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
-    ///
-    /// # Safety
-    ///
-    /// This function is unsafe. You must guarantee that you will continue to
-    /// treat the pointer `Ptr` as pinned after you call this function, so that
-    /// the invariants on the `Pin` type can be upheld. If the code using the
-    /// resulting `Ptr` does not continue to maintain the pinning invariants that
-    /// is a violation of the API contract and may lead to undefined behavior in
-    /// later (safe) operations.
-    ///
-    /// Note that you must be able to guarantee that the data pointed to by `Ptr`
-    /// will be treated as pinned all the way until its `drop` handler is complete!
-    ///
-    /// *For more information, see the [`pin` module docs][self]*
-    ///
-    /// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
-    /// instead.
-    #[inline(always)]
-    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
-    #[stable(feature = "pin_into_inner", since = "1.39.0")]
-    pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
-        pin.__pointer
-    }
 }
 
+// These methods being in a `Ptr: DerefMut` impl block concerns semver stability.
+// Currently, calling e.g. `.set()` on a `Pin<&T>` sees that `Ptr: DerefMut`
+// doesn't hold, and goes to check for a `.set()` method on `T`. But, if the
+// `where Ptr: DerefMut` bound is moved to the method, rustc sees the impl block
+// as a valid candidate, and doesn't go on to check other candidates when it
+// sees that the bound on the method.
 impl<Ptr: DerefMut> Pin<Ptr> {
     /// Gets a mutable reference to the pinned value this `Pin<Ptr>` points to.
     ///
@@ -1433,6 +1415,44 @@ impl<Ptr: DerefMut> Pin<Ptr> {
         unsafe { Pin::new_unchecked(&mut *self.__pointer) }
     }
 
+    /// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
+    ///
+    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
+    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
+    /// move in the future, and this method does not enable the pointee to move. "Malicious"
+    /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
+    /// `Pin::new_unchecked`.
+    #[unstable(feature = "pin_deref_mut", issue = "86918")]
+    #[must_use = "`self` will be dropped if the result is not used"]
+    #[inline(always)]
+    pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target> {
+        // SAFETY: What we're asserting here is that going from
+        //
+        //     Pin<&mut Pin<Ptr>>
+        //
+        // to
+        //
+        //     Pin<&mut Ptr::Target>
+        //
+        // is safe.
+        //
+        // We need to ensure that two things hold for that to be the case:
+        //
+        // 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
+        // 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
+        // `Pin<&mut Pin<Ptr>>`
+        //
+        // The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
+        // `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
+        // `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
+        // on the fact that `Ptr` is _also_ pinned.
+        //
+        // For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
+        // `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
+        // any access to the `Ptr` itself, much less the `Pin<Ptr>`.
+        unsafe { self.get_unchecked_mut() }.as_mut()
+    }
+
     /// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`.
     ///
     /// This overwrites pinned data, but that is okay: the original pinned value's destructor gets
@@ -1463,6 +1483,33 @@ impl<Ptr: DerefMut> Pin<Ptr> {
     }
 }
 
+impl<Ptr: Deref> Pin<Ptr> {
+    /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe. You must guarantee that you will continue to
+    /// treat the pointer `Ptr` as pinned after you call this function, so that
+    /// the invariants on the `Pin` type can be upheld. If the code using the
+    /// resulting `Ptr` does not continue to maintain the pinning invariants that
+    /// is a violation of the API contract and may lead to undefined behavior in
+    /// later (safe) operations.
+    ///
+    /// Note that you must be able to guarantee that the data pointed to by `Ptr`
+    /// will be treated as pinned all the way until its `drop` handler is complete!
+    ///
+    /// *For more information, see the [`pin` module docs][self]*
+    ///
+    /// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
+    /// instead.
+    #[inline(always)]
+    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+    #[stable(feature = "pin_into_inner", since = "1.39.0")]
+    pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
+        pin.__pointer
+    }
+}
+
 impl<'a, T: ?Sized> Pin<&'a T> {
     /// Constructs a new pin by mapping the interior value.
     ///
@@ -1613,46 +1660,6 @@ impl<T: ?Sized> Pin<&'static T> {
     }
 }
 
-impl<'a, Ptr: DerefMut> Pin<&'a mut Pin<Ptr>> {
-    /// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
-    ///
-    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
-    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
-    /// move in the future, and this method does not enable the pointee to move. "Malicious"
-    /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
-    /// `Pin::new_unchecked`.
-    #[unstable(feature = "pin_deref_mut", issue = "86918")]
-    #[must_use = "`self` will be dropped if the result is not used"]
-    #[inline(always)]
-    pub fn as_deref_mut(self) -> Pin<&'a mut Ptr::Target> {
-        // SAFETY: What we're asserting here is that going from
-        //
-        //     Pin<&mut Pin<Ptr>>
-        //
-        // to
-        //
-        //     Pin<&mut Ptr::Target>
-        //
-        // is safe.
-        //
-        // We need to ensure that two things hold for that to be the case:
-        //
-        // 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
-        // 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
-        // `Pin<&mut Pin<Ptr>>`
-        //
-        // The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
-        // `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
-        // `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
-        // on the fact that `Ptr` is _also_ pinned.
-        //
-        // For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
-        // `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
-        // any access to the `Ptr` itself, much less the `Pin<Ptr>`.
-        unsafe { self.get_unchecked_mut() }.as_mut()
-    }
-}
-
 impl<T: ?Sized> Pin<&'static mut T> {
     /// Gets a pinning mutable reference from a static mutable reference.
     ///
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/alignment.rs b/library/core/src/ptr/alignment.rs
index 68fce3960c7..19fe03d57cc 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -1,5 +1,4 @@
 use crate::num::NonZero;
-#[cfg(debug_assertions)]
 use crate::ub_checks::assert_unsafe_precondition;
 use crate::{cmp, fmt, hash, mem, num};
 
@@ -77,7 +76,6 @@ impl Alignment {
     #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
     #[inline]
     pub const unsafe fn new_unchecked(align: usize) -> Self {
-        #[cfg(debug_assertions)]
         assert_unsafe_precondition!(
             check_language_ub,
             "Alignment::new_unchecked requires a power of two",
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 3fe5212cea7..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
@@ -2130,6 +2168,33 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
     (p as *const ()) == (q as *const ())
 }
 
+/// Compares the *addresses* of the two function pointers for equality.
+///
+/// Function pointers comparisons can have surprising results since
+/// they are never guaranteed to be unique and could vary between different
+/// code generation units. Furthermore, different functions could have the
+/// same address after being merged together.
+///
+/// This is the same as `f == g` but using this function makes clear
+/// that you are aware of these potentially surprising semantics.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(ptr_fn_addr_eq)]
+/// use std::ptr;
+///
+/// fn a() { println!("a"); }
+/// fn b() { println!("b"); }
+/// assert!(!ptr::fn_addr_eq(a as fn(), b as fn()));
+/// ```
+#[unstable(feature = "ptr_fn_addr_eq", issue = "129322")]
+#[inline(always)]
+#[must_use = "function pointer comparison produces a value"]
+pub fn fn_addr_eq<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool {
+    f.addr() == g.addr()
+}
+
 /// Hash a raw pointer.
 ///
 /// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly)
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/slice/mod.rs b/library/core/src/slice/mod.rs
index c76157720b7..c7918499d4a 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3667,8 +3667,8 @@ impl<T> [T] {
     {
         // The panic code path was put into a cold function to not bloat the
         // call site.
-        #[inline(never)]
-        #[cold]
+        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+        #[cfg_attr(feature = "panic_immediate_abort", inline)]
         #[track_caller]
         fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
             panic!(
diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs
index db0c5c72822..fae628a7c14 100644
--- a/library/core/src/slice/sort/shared/smallsort.rs
+++ b/library/core/src/slice/sort/shared/smallsort.rs
@@ -840,7 +840,8 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
     }
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 fn panic_on_ord_violation() -> ! {
     // This is indicative of a logic bug in the user-provided comparison function or Ord
     // implementation. They are expected to implement a total order as explained in the Ord
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 06f796f9f3a..681ec79c0b7 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -241,24 +241,35 @@ impl<'a> CharIndices<'a> {
     /// Returns the byte position of the next character, or the length
     /// of the underlying string if there are no more characters.
     ///
+    /// This means that, when the iterator has not been fully consumed,
+    /// the returned value will match the index that will be returned
+    /// by the next call to [`next()`](Self::next).
+    ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(char_indices_offset)]
     /// let mut chars = "a楽".char_indices();
     ///
+    /// // `next()` has not been called yet, so `offset()` returns the byte
+    /// // index of the first character of the string, which is always 0.
     /// assert_eq!(chars.offset(), 0);
+    /// // As expected, the first call to `next()` also returns 0 as index.
     /// assert_eq!(chars.next(), Some((0, 'a')));
     ///
+    /// // `next()` has been called once, so `offset()` returns the byte index
+    /// // of the second character ...
     /// assert_eq!(chars.offset(), 1);
+    /// // ... which matches the index returned by the next call to `next()`.
     /// assert_eq!(chars.next(), Some((1, '楽')));
     ///
+    /// // Once the iterator has been consumed, `offset()` returns the length
+    /// // in bytes of the string.
     /// assert_eq!(chars.offset(), 4);
     /// assert_eq!(chars.next(), None);
     /// ```
     #[inline]
     #[must_use]
-    #[unstable(feature = "char_indices_offset", issue = "83871")]
+    #[stable(feature = "char_indices_offset", since = "CURRENT_RUSTC_VERSION")]
     pub fn offset(&self) -> usize {
         self.front_offset
     }
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/src/tuple.rs b/library/core/src/tuple.rs
index 65d4d5cf2ce..9ec92e28450 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -122,23 +122,29 @@ macro_rules! tuple_impls {
             }
         }
 
-        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
-        impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
-            #[inline]
-            #[allow(non_snake_case)]
-            fn from(array: [T; ${count($T)}]) -> Self {
-                let [$($T,)+] = array;
-                ($($T,)+)
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+            impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
+                #[inline]
+                #[allow(non_snake_case)]
+                fn from(array: [T; ${count($T)}]) -> Self {
+                    let [$($T,)+] = array;
+                    ($($T,)+)
+                }
             }
         }
 
-        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
-        impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
-            #[inline]
-            #[allow(non_snake_case)]
-            fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
-                let ($($T,)+) = tuple;
-                [$($T,)+]
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+            impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
+                #[inline]
+                #[allow(non_snake_case)]
+                fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
+                    let ($($T,)+) = tuple;
+                    [$($T,)+]
+                }
             }
         }
     }
@@ -148,7 +154,7 @@ macro_rules! tuple_impls {
 // Otherwise, it hides the docs entirely.
 macro_rules! maybe_tuple_doc {
     ($a:ident @ #[$meta:meta] $item:item) => {
-        #[doc(fake_variadic)]
+        #[cfg_attr(not(bootstrap), doc(fake_variadic))]
         #[doc = "This trait is implemented for tuples up to twelve items long."]
         #[$meta]
         $item
diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs
index b65b48c162d..c1a8c34539e 100644
--- a/library/core/src/ub_checks.rs
+++ b/library/core/src/ub_checks.rs
@@ -10,7 +10,7 @@ use crate::intrinsics::{self, const_eval_select};
 /// macro for language UB are always ignored.
 ///
 /// This macro should be called as
-/// `assert_unsafe_precondition!(check_{library,lang}_ub, "message", (ident: type = expr, ident: type = expr) => check_expr)`
+/// `assert_unsafe_precondition!(check_{library,language}_ub, "message", (ident: type = expr, ident: type = expr) => check_expr)`
 /// where each `expr` will be evaluated and passed in as function argument `ident: type`. Then all
 /// those arguments are passed to a function with the body `check_expr`.
 /// Pick `check_language_ub` when this is guarding a violation of language UB, i.e., immediate UB
diff --git a/library/core/tests/fmt/builders.rs b/library/core/tests/fmt/builders.rs
index 2bdc334b7c0..ba4801f5912 100644
--- a/library/core/tests/fmt/builders.rs
+++ b/library/core/tests/fmt/builders.rs
@@ -79,23 +79,23 @@ mod debug_struct {
         }
 
         assert_eq!(
-            "Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }",
+            r#"Bar { foo: Foo { bar: true, baz: 10/20 }, hello: "world" }"#,
             format!("{Bar:?}")
         );
         assert_eq!(
-            "Bar {
+            r#"Bar {
     foo: Foo {
         bar: true,
         baz: 10/20,
     },
-    hello: \"world\",
-}",
+    hello: "world",
+}"#,
             format!("{Bar:#?}")
         );
     }
 
     #[test]
-    fn test_only_non_exhaustive() {
+    fn test_empty_non_exhaustive() {
         struct Foo;
 
         impl fmt::Debug for Foo {
@@ -157,19 +157,19 @@ mod debug_struct {
         }
 
         assert_eq!(
-            "Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }",
+            r#"Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: "world", .. }"#,
             format!("{Bar:?}")
         );
         assert_eq!(
-            "Bar {
+            r#"Bar {
     foo: Foo {
         bar: true,
         baz: 10/20,
         ..
     },
-    hello: \"world\",
+    hello: "world",
     ..
-}",
+}"#,
             format!("{Bar:#?}")
         );
     }
@@ -249,15 +249,89 @@ mod debug_tuple {
             }
         }
 
-        assert_eq!("Bar(Foo(true, 10/20), \"world\")", format!("{Bar:?}"));
+        assert_eq!(r#"Bar(Foo(true, 10/20), "world")"#, format!("{Bar:?}"));
         assert_eq!(
-            "Bar(
+            r#"Bar(
     Foo(
         true,
         10/20,
     ),
-    \"world\",
+    "world",
+)"#,
+            format!("{Bar:#?}")
+        );
+    }
+
+    #[test]
+    fn test_empty_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_tuple("Foo").finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("Foo(..)", format!("{Foo:?}"));
+        assert_eq!("Foo(..)", format!("{Foo:#?}"));
+    }
+
+    #[test]
+    fn test_multiple_and_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("Foo(true, 10/20, ..)", format!("{Foo:?}"));
+        assert_eq!(
+            "Foo(
+    true,
+    10/20,
+    ..
 )",
+            format!("{Foo:#?}")
+        );
+    }
+
+    #[test]
+    fn test_nested_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!(r#"Bar(Foo(true, 10/20, ..), "world", ..)"#, format!("{Bar:?}"));
+        assert_eq!(
+            r#"Bar(
+    Foo(
+        true,
+        10/20,
+        ..
+    ),
+    "world",
+    ..
+)"#,
             format!("{Bar:#?}")
         );
     }
@@ -301,11 +375,11 @@ mod debug_map {
         assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
         assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
 
-        assert_eq!("{\"bar\": true}", format!("{Entry:?}"));
+        assert_eq!(r#"{"bar": true}"#, format!("{Entry:?}"));
         assert_eq!(
-            "{
-    \"bar\": true,
-}",
+            r#"{
+    "bar": true,
+}"#,
             format!("{Entry:#?}")
         );
     }
@@ -339,12 +413,12 @@ mod debug_map {
         assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
         assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
 
-        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{Entry:?}"));
+        assert_eq!(r#"{"bar": true, 10: 10/20}"#, format!("{Entry:?}"));
         assert_eq!(
-            "{
-    \"bar\": true,
+            r#"{
+    "bar": true,
     10: 10/20,
-}",
+}"#,
             format!("{Entry:#?}")
         );
     }
@@ -371,21 +445,20 @@ mod debug_map {
         }
 
         assert_eq!(
-            "{\"foo\": {\"bar\": true, 10: 10/20}, \
-                    {\"bar\": true, 10: 10/20}: \"world\"}",
+            r#"{"foo": {"bar": true, 10: 10/20}, {"bar": true, 10: 10/20}: "world"}"#,
             format!("{Bar:?}")
         );
         assert_eq!(
-            "{
-    \"foo\": {
-        \"bar\": true,
+            r#"{
+    "foo": {
+        "bar": true,
         10: 10/20,
     },
     {
-        \"bar\": true,
+        "bar": true,
         10: 10/20,
-    }: \"world\",
-}",
+    }: "world",
+}"#,
             format!("{Bar:#?}")
         );
     }
@@ -471,6 +544,103 @@ mod debug_map {
 
         let _ = format!("{Foo:?}");
     }
+
+    #[test]
+    fn test_empty_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map().finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("{..}", format!("{Foo:?}"));
+        assert_eq!("{..}", format!("{Foo:#?}"));
+    }
+
+    #[test]
+    fn test_multiple_and_non_exhaustive() {
+        struct Entry;
+
+        impl fmt::Debug for Entry {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10, &format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        struct KeyValue;
+
+        impl fmt::Debug for KeyValue {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .key(&"bar")
+                    .value(&true)
+                    .key(&10)
+                    .value(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
+        assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
+
+        assert_eq!(r#"{"bar": true, 10: 10/20, ..}"#, format!("{Entry:?}"));
+        assert_eq!(
+            r#"{
+    "bar": true,
+    10: 10/20,
+    ..
+}"#,
+            format!("{Entry:#?}")
+        );
+    }
+
+    #[test]
+    fn test_nested_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10, &format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!(
+            r#"{"foo": {"bar": true, 10: 10/20, ..}, {"bar": true, 10: 10/20, ..}: "world", ..}"#,
+            format!("{Bar:?}")
+        );
+        assert_eq!(
+            r#"{
+    "foo": {
+        "bar": true,
+        10: 10/20,
+        ..
+    },
+    {
+        "bar": true,
+        10: 10/20,
+        ..
+    }: "world",
+    ..
+}"#,
+            format!("{Bar:#?}")
+        );
+    }
 }
 
 mod debug_set {
@@ -547,15 +717,89 @@ mod debug_set {
             }
         }
 
-        assert_eq!("{{true, 10/20}, \"world\"}", format!("{Bar:?}"));
+        assert_eq!(r#"{{true, 10/20}, "world"}"#, format!("{Bar:?}"));
         assert_eq!(
-            "{
+            r#"{
     {
         true,
         10/20,
     },
-    \"world\",
+    "world",
+}"#,
+            format!("{Bar:#?}")
+        );
+    }
+
+    #[test]
+    fn test_empty_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_set().finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("{..}", format!("{Foo:?}"));
+        assert_eq!("{..}", format!("{Foo:#?}"));
+    }
+
+    #[test]
+    fn test_multiple_and_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("{true, 10/20, ..}", format!("{Foo:?}"));
+        assert_eq!(
+            "{
+    true,
+    10/20,
+    ..
 }",
+            format!("{Foo:#?}")
+        );
+    }
+
+    #[test]
+    fn test_nested_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_set().entry(&Foo).entry(&"world").finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!(r#"{{true, 10/20, ..}, "world", ..}"#, format!("{Bar:?}"));
+        assert_eq!(
+            r#"{
+    {
+        true,
+        10/20,
+        ..
+    },
+    "world",
+    ..
+}"#,
             format!("{Bar:#?}")
         );
     }
@@ -635,15 +879,89 @@ mod debug_list {
             }
         }
 
-        assert_eq!("[[true, 10/20], \"world\"]", format!("{Bar:?}"));
+        assert_eq!(r#"[[true, 10/20], "world"]"#, format!("{Bar:?}"));
         assert_eq!(
-            "[
+            r#"[
     [
         true,
         10/20,
     ],
-    \"world\",
+    "world",
+]"#,
+            format!("{Bar:#?}")
+        );
+    }
+
+    #[test]
+    fn test_empty_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_list().finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("[..]", format!("{Foo:?}"));
+        assert_eq!("[..]", format!("{Foo:#?}"));
+    }
+
+    #[test]
+    fn test_multiple_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!("[true, 10/20, ..]", format!("{Foo:?}"));
+        assert_eq!(
+            "[
+    true,
+    10/20,
+    ..
 ]",
+            format!("{Foo:#?}")
+        );
+    }
+
+    #[test]
+    fn test_nested_non_exhaustive() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish_non_exhaustive()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_list().entry(&Foo).entry(&"world").finish_non_exhaustive()
+            }
+        }
+
+        assert_eq!(r#"[[true, 10/20, ..], "world", ..]"#, format!("{Bar:?}"));
+        assert_eq!(
+            r#"[
+    [
+        true,
+        10/20,
+        ..
+    ],
+    "world",
+    ..
+]"#,
             format!("{Bar:#?}")
         );
     }
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 2f0d03abed3..c205f028dd3 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -43,6 +43,7 @@
 #![feature(core_io_borrowed_buf)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
+#![feature(debug_more_non_exhaustive)]
 #![feature(dec2flt)]
 #![feature(duration_constants)]
 #![feature(duration_constructors)]
@@ -140,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/float_iter_sum_identity.rs b/library/core/tests/num/float_iter_sum_identity.rs
new file mode 100644
index 00000000000..6d3224522a8
--- /dev/null
+++ b/library/core/tests/num/float_iter_sum_identity.rs
@@ -0,0 +1,27 @@
+#[test]
+fn f32_ref() {
+    let x: f32 = -0.0;
+    let still_x: f32 = [x].iter().sum();
+    assert_eq!(1. / x, 1. / still_x)
+}
+
+#[test]
+fn f32_own() {
+    let x: f32 = -0.0;
+    let still_x: f32 = [x].into_iter().sum();
+    assert_eq!(1. / x, 1. / still_x)
+}
+
+#[test]
+fn f64_ref() {
+    let x: f64 = -0.0;
+    let still_x: f64 = [x].iter().sum();
+    assert_eq!(1. / x, 1. / still_x)
+}
+
+#[test]
+fn f64_own() {
+    let x: f64 = -0.0;
+    let still_x: f64 = [x].into_iter().sum();
+    assert_eq!(1. / x, 1. / still_x)
+}
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 9d2912c4b22..dad46ad88fe 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -30,6 +30,7 @@ mod int_log;
 mod ops;
 mod wrapping;
 
+mod float_iter_sum_identity;
 mod ieee754;
 mod nan;
 
@@ -177,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/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index 9d1c1ba305b..c1e0e5c1c89 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -3,7 +3,7 @@
 //! See the build.rs for libcompiler_builtins crate for details.
 
 use std::env;
-use std::path::Path;
+use std::path::PathBuf;
 
 fn main() {
     println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB");
@@ -79,17 +79,25 @@ fn main() {
         cfg.define("COMPILER_RT_HAS_ATOMICS", Some("1"));
     }
 
-    // Note that this should exist if we're going to run (otherwise we just
-    // don't build profiler builtins at all).
-    let root = Path::new("../../src/llvm-project/compiler-rt");
+    // Get the LLVM `compiler-rt` directory from bootstrap.
+    println!("cargo:rerun-if-env-changed=RUST_COMPILER_RT_FOR_PROFILER");
+    let root = PathBuf::from(env::var("RUST_COMPILER_RT_FOR_PROFILER").unwrap_or_else(|_| {
+        let path = "../../src/llvm-project/compiler-rt";
+        println!("RUST_COMPILER_RT_FOR_PROFILER was not set; falling back to {path:?}");
+        path.to_owned()
+    }));
 
     let src_root = root.join("lib").join("profile");
+    assert!(src_root.exists(), "profiler runtime source directory not found: {src_root:?}");
+    let mut n_sources_found = 0u32;
     for src in profile_sources {
         let path = src_root.join(src);
         if path.exists() {
             cfg.file(path);
+            n_sources_found += 1;
         }
     }
+    assert!(n_sources_found > 0, "couldn't find any profiler runtime source files in {src_root:?}");
 
     cfg.include(root.join("include"));
     cfg.warnings(false);
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 7f23681ee45..334c75df231 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "0.1.118" }
+compiler_builtins = { version = "0.1.121" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.14", default-features = false, features = [
diff --git a/library/std/build.rs b/library/std/build.rs
index 35a5977b6eb..fecdf2c3e1f 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -103,9 +103,9 @@ fn main() {
         ("arm64ec", _) => false,
         // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
         ("x86_64", "windows") => false,
-        // x86 has ABI bugs that show up with optimizations. This should be partially fixed with
-        // the compiler-builtins update. <https://github.com/rust-lang/rust/issues/123885>
-        ("x86" | "x86_64", _) => false,
+        // Apple has a special ABI for `f16` that we do not yet support
+        // FIXME(builtins): fixed by <https://github.com/rust-lang/compiler-builtins/pull/675>
+        ("x86" | "x86_64", _) if target_vendor == "apple" => false,
         // Missing `__gnu_h2f_ieee` and `__gnu_f2h_ieee`
         ("powerpc" | "powerpc64", _) => false,
         // Missing `__gnu_h2f_ieee` and `__gnu_f2h_ieee`
@@ -140,17 +140,17 @@ fn main() {
         _ => false,
     };
 
-    // These are currently empty, but will fill up as some platforms move from completely
-    // unreliable to reliable basics but unreliable math.
+    // Configure platforms that have reliable basics but may have unreliable math.
 
     // LLVM is currenlty adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
     let has_reliable_f16_math = has_reliable_f16
         && match (target_arch.as_str(), target_os.as_str()) {
             // FIXME: Disabled on Miri as the intrinsics are not implemented yet.
             _ if is_miri => false,
-            // Currently nothing special. Hooray!
-            // This will change as platforms gain better better support for standard ops but math
-            // lags behind.
+            // x86 has a crash for `powi`: <https://github.com/llvm/llvm-project/issues/105747>
+            ("x86" | "x86_64", _) => false,
+            // Assume that working `f16` means working `f16` math for most platforms, since
+            // operations just go through `f32`.
             _ => true,
         };
 
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index f6df6259137..506d708d0d2 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -248,11 +248,11 @@ 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. Note, however, that conserving the sign bit on NaN across arithmetical operations
+    /// is not generally guaranteed. See [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..033a3d45009 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -247,11 +247,11 @@ 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. Note, however, that conserving the sign bit on NaN across arithmetical operations
+    /// is not generally guaranteed. See [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..35c2a77b533 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -226,11 +226,11 @@ 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. Note, however, that conserving the sign bit on NaN across arithmetical operations
+    /// is not generally guaranteed. See [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..c177f74a97e 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -226,11 +226,11 @@ 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. Note, however, that conserving the sign bit on NaN across arithmetical operations
+    /// is not generally guaranteed. See [specification of NaN bit
+    /// patterns](primitive@f32#nan-bit-patterns) for more info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index c5edb03bb08..6a0d9f47960 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2491,6 +2491,8 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// Consider ignoring the error if validating the removal is not required for your use case.
 ///
+/// [`io::ErrorKind::NotFound`] is only returned if no removal occurs.
+///
 /// [`fs::remove_file`]: remove_file
 /// [`fs::remove_dir`]: remove_dir
 ///
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 2530a376387..f65e9bc8d8b 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -363,6 +363,7 @@
 #![feature(get_mut_unchecked)]
 #![feature(map_try_insert)]
 #![feature(new_uninit)]
+#![feature(new_zeroed_alloc)]
 #![feature(slice_concat_trait)]
 #![feature(thin_box)]
 #![feature(try_reserve_kind)]
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index a58ca543d67..9ec3e387e2b 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -2,7 +2,6 @@
 //!
 //! [`std::fs`]: crate::fs
 
-#![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "71213")]
 
 // Used for `File::read` on intra-doc links
diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs
index e36b93e60ea..33b50c9e53b 100644
--- a/library/std/src/os/wasi/mod.rs
+++ b/library/std/src/os/wasi/mod.rs
@@ -30,7 +30,7 @@
 
 #![cfg_attr(not(target_env = "p2"), stable(feature = "rust1", since = "1.0.0"))]
 #![cfg_attr(target_env = "p2", unstable(feature = "wasip2", issue = "none"))]
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 #![doc(cfg(target_os = "wasi"))]
 
 pub mod ffi;
diff --git a/library/std/src/os/wasip2/mod.rs b/library/std/src/os/wasip2/mod.rs
index 1d44dd72814..809a288f20d 100644
--- a/library/std/src/os/wasip2/mod.rs
+++ b/library/std/src/os/wasip2/mod.rs
@@ -2,4 +2,5 @@
 //!
 //! This module is currently empty, but will be filled over time as wasi-libc support for WASI Preview 2 is stabilized.
 
+#![forbid(unsafe_op_in_unsafe_fn)]
 #![stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index e818b448270..190eed94555 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -275,7 +275,7 @@ fn default_hook(info: &PanicHookInfo<'_>) {
                     if cfg!(miri) {
                         let _ = writeln!(
                             err,
-                            "note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` \
+                            "note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` \
                                 for the environment variable to have an effect"
                         );
                     }
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/fs.rs b/library/std/src/sys/pal/solid/fs.rs
index 8179ec8821a..591be66fcb4 100644
--- a/library/std/src/sys/pal/solid/fs.rs
+++ b/library/std/src/sys/pal/solid/fs.rs
@@ -10,6 +10,7 @@ use crate::sync::Arc;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
 pub use crate::sys_common::fs::exists;
+use crate::sys_common::ignore_notfound;
 
 /// A file descriptor.
 #[derive(Clone, Copy)]
@@ -527,15 +528,23 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
 
 pub fn remove_dir_all(path: &Path) -> io::Result<()> {
     for child in readdir(path)? {
-        let child = child?;
-        let child_type = child.file_type()?;
-        if child_type.is_dir() {
-            remove_dir_all(&child.path())?;
-        } else {
-            unlink(&child.path())?;
+        let result: io::Result<()> = try {
+            let child = child?;
+            let child_type = child.file_type()?;
+            if child_type.is_dir() {
+                remove_dir_all(&child.path())?;
+            } else {
+                unlink(&child.path())?;
+            }
+        };
+        // ignore internal NotFound errors
+        if let Err(err) = result
+            && err.kind() != io::ErrorKind::NotFound
+        {
+            return result;
         }
     }
-    rmdir(path)
+    ignore_notfound(rmdir(path))
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
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/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index be13e1ae9b3..fc9d7e98883 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -2002,6 +2002,7 @@ mod remove_dir_impl {
     use crate::path::{Path, PathBuf};
     use crate::sys::common::small_c_string::run_path_with_cstr;
     use crate::sys::{cvt, cvt_r};
+    use crate::sys_common::ignore_notfound;
 
     pub fn openat_nofollow_dironly(parent_fd: Option<RawFd>, p: &CStr) -> io::Result<OwnedFd> {
         let fd = cvt_r(|| unsafe {
@@ -2055,6 +2056,16 @@ mod remove_dir_impl {
         }
     }
 
+    fn is_enoent(result: &io::Result<()>) -> bool {
+        if let Err(err) = result
+            && matches!(err.raw_os_error(), Some(libc::ENOENT))
+        {
+            true
+        } else {
+            false
+        }
+    }
+
     fn remove_dir_all_recursive(parent_fd: Option<RawFd>, path: &CStr) -> io::Result<()> {
         // try opening as directory
         let fd = match openat_nofollow_dironly(parent_fd, &path) {
@@ -2078,27 +2089,35 @@ mod remove_dir_impl {
         for child in dir {
             let child = child?;
             let child_name = child.name_cstr();
-            match is_dir(&child) {
-                Some(true) => {
-                    remove_dir_all_recursive(Some(fd), child_name)?;
-                }
-                Some(false) => {
-                    cvt(unsafe { unlinkat(fd, child_name.as_ptr(), 0) })?;
-                }
-                None => {
-                    // POSIX specifies that calling unlink()/unlinkat(..., 0) on a directory can succeed
-                    // if the process has the appropriate privileges. This however can causing orphaned
-                    // directories requiring an fsck e.g. on Solaris and Illumos. So we try recursing
-                    // into it first instead of trying to unlink() it.
-                    remove_dir_all_recursive(Some(fd), child_name)?;
+            // we need an inner try block, because if one of these
+            // directories has already been deleted, then we need to
+            // continue the loop, not return ok.
+            let result: io::Result<()> = try {
+                match is_dir(&child) {
+                    Some(true) => {
+                        remove_dir_all_recursive(Some(fd), child_name)?;
+                    }
+                    Some(false) => {
+                        cvt(unsafe { unlinkat(fd, child_name.as_ptr(), 0) })?;
+                    }
+                    None => {
+                        // POSIX specifies that calling unlink()/unlinkat(..., 0) on a directory can succeed
+                        // if the process has the appropriate privileges. This however can causing orphaned
+                        // directories requiring an fsck e.g. on Solaris and Illumos. So we try recursing
+                        // into it first instead of trying to unlink() it.
+                        remove_dir_all_recursive(Some(fd), child_name)?;
+                    }
                 }
+            };
+            if result.is_err() && !is_enoent(&result) {
+                return result;
             }
         }
 
         // unlink the directory after removing its contents
-        cvt(unsafe {
+        ignore_notfound(cvt(unsafe {
             unlinkat(parent_fd.unwrap_or(libc::AT_FDCWD), path.as_ptr(), libc::AT_REMOVEDIR)
-        })?;
+        }))?;
         Ok(())
     }
 
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/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 0fa610eebb4..c9dcc5ad97a 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -267,14 +267,32 @@ impl Thread {
 
     #[cfg(target_os = "espidf")]
     pub fn sleep(dur: Duration) {
-        let mut micros = dur.as_micros();
-        unsafe {
-            while micros > 0 {
-                let st = if micros > u32::MAX as u128 { u32::MAX } else { micros as u32 };
+        // ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
+        // As per the documentation of `usleep`, it is expected to support
+        // sleep times as big as at least up to 1 second.
+        //
+        // ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its
+        // `usleep` implementation
+        // (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210),
+        // we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow
+        // (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default).
+        const MAX_MICROS: u32 = u32::MAX - 1_000_000 - 1;
+
+        // Add any nanoseconds smaller than a microsecond as an extra microsecond
+        // so as to comply with the `std::thread::sleep` contract which mandates
+        // implementations to sleep for _at least_ the provided `dur`.
+        // We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of
+        // (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second
+        // (i.e. < 1_000_000_000)
+        let mut micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
+
+        while micros > 0 {
+            let st = if micros > MAX_MICROS as u128 { MAX_MICROS } else { micros as u32 };
+            unsafe {
                 libc::usleep(st);
-
-                micros -= st as u128;
             }
+
+            micros -= st as u128;
         }
     }
 
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/args.rs b/library/std/src/sys/pal/wasi/args.rs
index 6b6d1b8ff4e..52cfa202af8 100644
--- a/library/std/src/sys/pal/wasi/args.rs
+++ b/library/std/src/sys/pal/wasi/args.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::os::wasi::ffi::OsStrExt;
diff --git a/library/std/src/sys/pal/wasi/env.rs b/library/std/src/sys/pal/wasi/env.rs
index 730e356d7fe..8d444982673 100644
--- a/library/std/src/sys/pal/wasi/env.rs
+++ b/library/std/src/sys/pal/wasi/env.rs
@@ -1,3 +1,5 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
 pub mod os {
     pub const FAMILY: &str = "";
     pub const OS: &str = "";
diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/pal/wasi/fd.rs
index 8966e4b80ad..19b60157e2e 100644
--- a/library/std/src/sys/pal/wasi/fd.rs
+++ b/library/std/src/sys/pal/wasi/fd.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 #![allow(dead_code)]
 
 use super::err2io;
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 11900886f0b..88b1e543ec7 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use super::fd::WasiFd;
 use crate::ffi::{CStr, OsStr, OsString};
@@ -13,7 +13,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
 pub use crate::sys_common::fs::exists;
-use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys_common::{ignore_notfound, AsInner, FromInner, IntoInner};
 use crate::{fmt, iter, ptr};
 
 pub struct File {
@@ -794,14 +794,22 @@ fn remove_dir_all_recursive(parent: &WasiFd, path: &Path) -> io::Result<()> {
             io::const_io_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found")
         })?;
 
-        if entry.file_type()?.is_dir() {
-            remove_dir_all_recursive(&entry.inner.dir.fd, path.as_ref())?;
-        } else {
-            entry.inner.dir.fd.unlink_file(path)?;
+        let result: io::Result<()> = try {
+            if entry.file_type()?.is_dir() {
+                remove_dir_all_recursive(&entry.inner.dir.fd, path.as_ref())?;
+            } else {
+                entry.inner.dir.fd.unlink_file(path)?;
+            }
+        };
+        // ignore internal NotFound errors
+        if let Err(err) = &result
+            && err.kind() != io::ErrorKind::NotFound
+        {
+            return result;
         }
     }
 
     // Once all this directory's contents are deleted it should be safe to
     // delete the directory tiself.
-    parent.remove_directory(osstr2str(path.as_ref())?)
+    ignore_notfound(parent.remove_directory(osstr2str(path.as_ref())?))
 }
diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs
index 4b770ee23bc..d047bf2fce8 100644
--- a/library/std/src/sys/pal/wasi/helpers.rs
+++ b/library/std/src/sys/pal/wasi/helpers.rs
@@ -1,3 +1,5 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
 use crate::{io as std_io, mem};
 
 #[inline]
diff --git a/library/std/src/sys/pal/wasi/io.rs b/library/std/src/sys/pal/wasi/io.rs
index 2cd45df88fa..b7c2f03daa0 100644
--- a/library/std/src/sys/pal/wasi/io.rs
+++ b/library/std/src/sys/pal/wasi/io.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use crate::marker::PhantomData;
 use crate::os::fd::{AsFd, AsRawFd};
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/wasi/net.rs b/library/std/src/sys/pal/wasi/net.rs
index b4cf94c8781..a6486799828 100644
--- a/library/std/src/sys/pal/wasi/net.rs
+++ b/library/std/src/sys/pal/wasi/net.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use super::err2io;
 use super::fd::WasiFd;
diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs
index f5b17d9df94..f7701360f5a 100644
--- a/library/std/src/sys/pal/wasi/os.rs
+++ b/library/std/src/sys/pal/wasi/os.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use core::slice::memchr;
 
diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/pal/wasi/stdio.rs
index 4cc0e4ed5a4..ca49f871e19 100644
--- a/library/std/src/sys/pal/wasi/stdio.rs
+++ b/library/std/src/sys/pal/wasi/stdio.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use super::fd::WasiFd;
 use crate::io::{self, IoSlice, IoSliceMut};
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index c37acd8dfee..31c9cbd4699 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -1,3 +1,5 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
 use crate::ffi::CStr;
 use crate::num::NonZero;
 use crate::sys::unsupported;
@@ -73,13 +75,13 @@ impl Thread {
         if #[cfg(target_feature = "atomics")] {
             pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
                 let p = Box::into_raw(Box::new(p));
-                let mut native: libc::pthread_t = mem::zeroed();
-                let mut attr: libc::pthread_attr_t = mem::zeroed();
-                assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+                let mut native: libc::pthread_t = unsafe { mem::zeroed() };
+                let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() };
+                assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0);
 
                 let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE);
 
-                match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
+                match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } {
                     0 => {}
                     n => {
                         assert_eq!(n, libc::EINVAL);
@@ -90,20 +92,20 @@ impl Thread {
                         let page_size = os::page_size();
                         let stack_size =
                             (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
-                        assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
+                        assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0);
                     }
                 };
 
-                let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
+                let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, p as *mut _) };
                 // Note: if the thread creation fails and this assert fails, then p will
                 // be leaked. However, an alternative design could cause double-free
                 // which is clearly worse.
-                assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+                assert_eq!(unsafe {libc::pthread_attr_destroy(&mut attr) }, 0);
 
                 return if ret != 0 {
                     // The thread failed to start and as a result p was not consumed. Therefore, it is
                     // safe to reconstruct the box so that it gets deallocated.
-                    drop(Box::from_raw(p));
+                    unsafe { drop(Box::from_raw(p)); }
                     Err(io::Error::from_raw_os_error(ret))
                 } else {
                     Ok(Thread { id: native })
diff --git a/library/std/src/sys/pal/wasi/time.rs b/library/std/src/sys/pal/wasi/time.rs
index 016b06efbdc..0d8d0b59ac1 100644
--- a/library/std/src/sys/pal/wasi/time.rs
+++ b/library/std/src/sys/pal/wasi/time.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 use crate::time::Duration;
 
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/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index d99d4931de4..2134152ea93 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -14,7 +14,7 @@ use crate::sys::handle::Handle;
 use crate::sys::path::maybe_verbatim;
 use crate::sys::time::SystemTime;
 use crate::sys::{c, cvt, Align8};
-use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys_common::{ignore_notfound, AsInner, FromInner, IntoInner};
 use crate::{fmt, ptr, slice, thread};
 
 pub struct File {
@@ -1160,7 +1160,7 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
         return Err(io::Error::from_raw_os_error(c::ERROR_DIRECTORY as _));
     }
 
-    match remove_dir_all_iterative(&file, File::posix_delete) {
+    match ignore_notfound(remove_dir_all_iterative(&file, File::posix_delete)) {
         Err(e) => {
             if let Some(code) = e.raw_os_error() {
                 match code as u32 {
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/library/std/src/sys_common/fs.rs b/library/std/src/sys_common/fs.rs
index acb6713cf1b..a25a7244660 100644
--- a/library/std/src/sys_common/fs.rs
+++ b/library/std/src/sys_common/fs.rs
@@ -3,6 +3,7 @@
 use crate::fs;
 use crate::io::{self, Error, ErrorKind};
 use crate::path::Path;
+use crate::sys_common::ignore_notfound;
 
 pub(crate) const NOT_FILE_ERROR: Error = io::const_io_error!(
     ErrorKind::InvalidInput,
@@ -32,14 +33,22 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
 
 fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
     for child in fs::read_dir(path)? {
-        let child = child?;
-        if child.file_type()?.is_dir() {
-            remove_dir_all_recursive(&child.path())?;
-        } else {
-            fs::remove_file(&child.path())?;
+        let result: io::Result<()> = try {
+            let child = child?;
+            if child.file_type()?.is_dir() {
+                remove_dir_all_recursive(&child.path())?;
+            } else {
+                fs::remove_file(&child.path())?;
+            }
+        };
+        // ignore internal NotFound errors to prevent race conditions
+        if let Err(err) = &result
+            && err.kind() != io::ErrorKind::NotFound
+        {
+            return result;
         }
     }
-    fs::remove_dir(path)
+    ignore_notfound(fs::remove_dir(path))
 }
 
 pub fn exists(path: &Path) -> io::Result<bool> {
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 60ee405ecaa..1c884f107be 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -80,3 +80,11 @@ pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 {
     // r < denom, so (denom*numer) is the upper bound of (r*numer)
     q * numer + r * numer / denom
 }
+
+pub fn ignore_notfound<T>(result: crate::io::Result<T>) -> crate::io::Result<()> {
+    match result {
+        Err(err) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()),
+        Ok(_) => Ok(()),
+        Err(err) => Err(err),
+    }
+}
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index 69486705656..dcd5cd7f6b9 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -5,6 +5,10 @@
     feature(stdarch_arm_feature_detection)
 )]
 #![cfg_attr(
+    all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")),
+    feature(stdarch_aarch64_feature_detection)
+)]
+#![cfg_attr(
     all(target_arch = "powerpc", target_os = "linux"),
     feature(stdarch_powerpc_feature_detection)
 )]
@@ -36,21 +40,34 @@ fn aarch64_linux() {
     println!("bf16: {}", is_aarch64_feature_detected!("bf16"));
     println!("bti: {}", is_aarch64_feature_detected!("bti"));
     println!("crc: {}", is_aarch64_feature_detected!("crc"));
+    println!("cssc: {}", is_aarch64_feature_detected!("cssc"));
     println!("dit: {}", is_aarch64_feature_detected!("dit"));
     println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
     println!("dpb2: {}", is_aarch64_feature_detected!("dpb2"));
     println!("dpb: {}", is_aarch64_feature_detected!("dpb"));
+    println!("ecv: {}", is_aarch64_feature_detected!("ecv"));
     println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
     println!("f64mm: {}", is_aarch64_feature_detected!("f64mm"));
+    println!("faminmax: {}", is_aarch64_feature_detected!("faminmax"));
     println!("fcma: {}", is_aarch64_feature_detected!("fcma"));
     println!("fhm: {}", is_aarch64_feature_detected!("fhm"));
+    println!("flagm2: {}", is_aarch64_feature_detected!("flagm2"));
     println!("flagm: {}", is_aarch64_feature_detected!("flagm"));
     println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
+    println!("fp8: {}", is_aarch64_feature_detected!("fp8"));
+    println!("fp8dot2: {}", is_aarch64_feature_detected!("fp8dot2"));
+    println!("fp8dot4: {}", is_aarch64_feature_detected!("fp8dot4"));
+    println!("fp8fma: {}", is_aarch64_feature_detected!("fp8fma"));
+    println!("fpmr: {}", is_aarch64_feature_detected!("fpmr"));
     println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
+    println!("hbc: {}", is_aarch64_feature_detected!("hbc"));
     println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
     println!("jsconv: {}", is_aarch64_feature_detected!("jsconv"));
+    println!("lse128: {}", is_aarch64_feature_detected!("lse128"));
     println!("lse2: {}", is_aarch64_feature_detected!("lse2"));
     println!("lse: {}", is_aarch64_feature_detected!("lse"));
+    println!("lut: {}", is_aarch64_feature_detected!("lut"));
+    println!("mops: {}", is_aarch64_feature_detected!("mops"));
     println!("mte: {}", is_aarch64_feature_detected!("mte"));
     println!("neon: {}", is_aarch64_feature_detected!("neon"));
     println!("paca: {}", is_aarch64_feature_detected!("paca"));
@@ -58,20 +75,37 @@ fn aarch64_linux() {
     println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
     println!("rand: {}", is_aarch64_feature_detected!("rand"));
     println!("rcpc2: {}", is_aarch64_feature_detected!("rcpc2"));
+    println!("rcpc3: {}", is_aarch64_feature_detected!("rcpc3"));
     println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
     println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
     println!("sb: {}", is_aarch64_feature_detected!("sb"));
     println!("sha2: {}", is_aarch64_feature_detected!("sha2"));
     println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
     println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
+    println!("sme-f16f16: {}", is_aarch64_feature_detected!("sme-f16f16"));
+    println!("sme-f64f64: {}", is_aarch64_feature_detected!("sme-f64f64"));
+    println!("sme-f8f16: {}", is_aarch64_feature_detected!("sme-f8f16"));
+    println!("sme-f8f32: {}", is_aarch64_feature_detected!("sme-f8f32"));
+    println!("sme-fa64: {}", is_aarch64_feature_detected!("sme-fa64"));
+    println!("sme-i16i64: {}", is_aarch64_feature_detected!("sme-i16i64"));
+    println!("sme-lutv2: {}", is_aarch64_feature_detected!("sme-lutv2"));
+    println!("sme2: {}", is_aarch64_feature_detected!("sme2"));
+    println!("sme2p1: {}", is_aarch64_feature_detected!("sme2p1"));
+    println!("sme: {}", is_aarch64_feature_detected!("sme"));
     println!("ssbs: {}", is_aarch64_feature_detected!("ssbs"));
+    println!("ssve-fp8dot2: {}", is_aarch64_feature_detected!("ssve-fp8dot2"));
+    println!("ssve-fp8dot4: {}", is_aarch64_feature_detected!("ssve-fp8dot4"));
+    println!("ssve-fp8fma: {}", is_aarch64_feature_detected!("ssve-fp8fma"));
+    println!("sve-b16b16: {}", is_aarch64_feature_detected!("sve-b16b16"));
     println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
     println!("sve2-bitperm: {}", is_aarch64_feature_detected!("sve2-bitperm"));
     println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
     println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
     println!("sve2: {}", is_aarch64_feature_detected!("sve2"));
+    println!("sve2p1: {}", is_aarch64_feature_detected!("sve2p1"));
     println!("sve: {}", is_aarch64_feature_detected!("sve"));
     println!("tme: {}", is_aarch64_feature_detected!("tme"));
+    println!("wfxt: {}", is_aarch64_feature_detected!("wfxt"));
     // tidy-alphabetical-end
 }
 
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 4e8e0fd2532..71f69e03a9f 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -79,6 +79,11 @@ def get(base, url, path, checksums, verbose=False):
                 eprint("removing", temp_path)
             os.unlink(temp_path)
 
+def curl_version():
+    m = re.match(bytes("^curl ([0-9]+)\\.([0-9]+)", "utf8"), require(["curl", "-V"]))
+    if m is None:
+        return (0, 0)
+    return (int(m[1]), int(m[2]))
 
 def download(path, url, probably_big, verbose):
     for _ in range(4):
@@ -107,11 +112,15 @@ def _download(path, url, probably_big, verbose, exception):
         # If curl is not present on Win32, we should not sys.exit
         #   but raise `CalledProcessError` or `OSError` instead
         require(["curl", "--version"], exception=platform_is_win32())
-        run(["curl", option,
+        extra_flags = []
+        if curl_version() > (7, 70):
+            extra_flags = [ "--retry-all-errors" ]
+        run(["curl", option] + extra_flags + [
             "-L", # Follow redirect.
             "-y", "30", "-Y", "10",    # timeout if speed is < 10 bytes/sec for > 30 seconds
             "--connect-timeout", "30",  # timeout if cannot connect within 30 seconds
             "-o", path,
+            "--continue-at", "-",
             "--retry", "3", "-SRf", url],
             verbose=verbose,
             exception=True, # Will raise RuntimeError on failure
@@ -533,9 +542,13 @@ class RustBuild(object):
         bin_root = self.bin_root()
 
         key = self.stage0_compiler.date
-        if self.rustc().startswith(bin_root) and \
-                (not os.path.exists(self.rustc()) or
-                 self.program_out_of_date(self.rustc_stamp(), key)):
+        is_outdated = self.program_out_of_date(self.rustc_stamp(), key)
+        need_rustc = self.rustc().startswith(bin_root) and (not os.path.exists(self.rustc()) \
+            or is_outdated)
+        need_cargo = self.cargo().startswith(bin_root) and (not os.path.exists(self.cargo()) \
+            or is_outdated)
+
+        if need_rustc or need_cargo:
             if os.path.exists(bin_root):
                 # HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's
                 # running. Kill it.
@@ -556,7 +569,6 @@ class RustBuild(object):
                     run_powershell([script])
                 shutil.rmtree(bin_root)
 
-            key = self.stage0_compiler.date
             cache_dst = (self.get_toml('bootstrap-cache-path', 'build') or
                 os.path.join(self.build_dir, "cache"))
 
@@ -568,11 +580,16 @@ class RustBuild(object):
 
             toolchain_suffix = "{}-{}{}".format(rustc_channel, self.build, tarball_suffix)
 
-            tarballs_to_download = [
-                ("rust-std-{}".format(toolchain_suffix), "rust-std-{}".format(self.build)),
-                ("rustc-{}".format(toolchain_suffix), "rustc"),
-                ("cargo-{}".format(toolchain_suffix), "cargo"),
-            ]
+            tarballs_to_download = []
+
+            if need_rustc:
+                tarballs_to_download.append(
+                    ("rust-std-{}".format(toolchain_suffix), "rust-std-{}".format(self.build))
+                )
+                tarballs_to_download.append(("rustc-{}".format(toolchain_suffix), "rustc"))
+
+            if need_cargo:
+                tarballs_to_download.append(("cargo-{}".format(toolchain_suffix), "cargo"))
 
             tarballs_download_info = [
                 DownloadInfo(
diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs
index ba6b0c2dbda..a338b9c8080 100644
--- a/src/bootstrap/src/bin/rustdoc.rs
+++ b/src/bootstrap/src/bin/rustdoc.rs
@@ -59,8 +59,6 @@ fn main() {
     if stage == "0" {
         cmd.arg("--cfg=bootstrap");
     }
-    cmd.arg("-Zunstable-options");
-    cmd.arg("--check-cfg=cfg(bootstrap)");
 
     maybe_dump(format!("stage{stage}-rustdoc"), &cmd);
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 4353cfadd8d..edf18e2ebf3 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -199,16 +199,6 @@ impl Step for Std {
 
         builder.require_submodule("library/stdarch", None);
 
-        // Profiler information requires LLVM's compiler-rt
-        if builder.config.profiler {
-            builder.require_submodule(
-                "src/llvm-project",
-                Some(
-                    "The `build.profiler` config option requires `compiler-rt` sources from LLVM.",
-                ),
-            );
-        }
-
         let mut target_deps = builder.ensure(StartupObjects { compiler, target });
 
         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
@@ -466,6 +456,29 @@ pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
     }
 }
 
+/// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.
+///
+/// Normally it lives in the `src/llvm-project` submodule, but if we will be using a
+/// downloaded copy of CI LLVM, then we try to use the `compiler-rt` sources from
+/// there instead, which lets us avoid checking out the LLVM submodule.
+fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf {
+    // Try to use `compiler-rt` sources from downloaded CI LLVM, if possible.
+    if builder.config.llvm_from_ci {
+        // CI LLVM might not have been downloaded yet, so try to download it now.
+        builder.config.maybe_download_ci_llvm();
+        let ci_llvm_compiler_rt = builder.config.ci_llvm_root().join("compiler-rt");
+        if ci_llvm_compiler_rt.exists() {
+            return ci_llvm_compiler_rt;
+        }
+    }
+
+    // Otherwise, fall back to requiring the LLVM submodule.
+    builder.require_submodule("src/llvm-project", {
+        Some("The `build.profiler` config option requires `compiler-rt` sources from LLVM.")
+    });
+    builder.src.join("src/llvm-project/compiler-rt")
+}
+
 /// Configure cargo to compile the standard library, adding appropriate env vars
 /// and such.
 pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
@@ -473,8 +486,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
         cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
     }
 
+    // Paths needed by `library/profiler_builtins/build.rs`.
     if let Some(path) = builder.config.profiler_path(target) {
         cargo.env("LLVM_PROFILER_RT_LIB", path);
+    } else if builder.config.profiler_enabled(target) {
+        let compiler_rt = compiler_rt_for_profiler(builder);
+        // Currently this is separate from the env var used by `compiler_builtins`
+        // (below) so that adding support for CI LLVM here doesn't risk breaking
+        // the compiler builtins. But they could be unified if desired.
+        cargo.env("RUST_COMPILER_RT_FOR_PROFILER", compiler_rt);
     }
 
     // Determine if we're going to compile in optimized C intrinsics to
@@ -507,8 +527,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
         );
         let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
         assert!(compiler_builtins_root.exists());
-        // Note that `libprofiler_builtins/build.rs` also computes this so if
-        // you're changing something here please also change that.
+        // The path to `compiler-rt` is also used by `profiler_builtins` (above),
+        // so if you're changing something here please also change that as appropriate.
         cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
         " compiler-builtins-c"
     } else {
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 8d20b956213..4957de2e1b7 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -269,34 +269,45 @@ fn make_win_dist(
     let target_libs = find_files(&target_libs, &lib_path);
 
     // Copy runtime dlls next to rustc.exe
-    let dist_bin_dir = rust_root.join("bin/");
-    fs::create_dir_all(&dist_bin_dir).expect("creating dist_bin_dir failed");
-    for src in rustc_dlls {
-        builder.copy_link_to_folder(&src, &dist_bin_dir);
+    let rust_bin_dir = rust_root.join("bin/");
+    fs::create_dir_all(&rust_bin_dir).expect("creating rust_bin_dir failed");
+    for src in &rustc_dlls {
+        builder.copy_link_to_folder(src, &rust_bin_dir);
+    }
+
+    if builder.config.lld_enabled {
+        // rust-lld.exe also needs runtime dlls
+        let rust_target_bin_dir = rust_root.join("lib/rustlib").join(target).join("bin");
+        fs::create_dir_all(&rust_target_bin_dir).expect("creating rust_target_bin_dir failed");
+        for src in &rustc_dlls {
+            builder.copy_link_to_folder(src, &rust_target_bin_dir);
+        }
     }
 
     //Copy platform tools to platform-specific bin directory
-    let target_bin_dir =
-        plat_root.join("lib").join("rustlib").join(target).join("bin").join("self-contained");
-    fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
+    let plat_target_bin_self_contained_dir =
+        plat_root.join("lib/rustlib").join(target).join("bin/self-contained");
+    fs::create_dir_all(&plat_target_bin_self_contained_dir)
+        .expect("creating plat_target_bin_self_contained_dir failed");
     for src in target_tools {
-        builder.copy_link_to_folder(&src, &target_bin_dir);
+        builder.copy_link_to_folder(&src, &plat_target_bin_self_contained_dir);
     }
 
     // Warn windows-gnu users that the bundled GCC cannot compile C files
     builder.create(
-        &target_bin_dir.join("GCC-WARNING.txt"),
+        &plat_target_bin_self_contained_dir.join("GCC-WARNING.txt"),
         "gcc.exe contained in this folder cannot be used for compiling C files - it is only \
          used as a linker. In order to be able to compile projects containing C code use \
          the GCC provided by MinGW or Cygwin.",
     );
 
     //Copy platform libs to platform-specific lib directory
-    let target_lib_dir =
-        plat_root.join("lib").join("rustlib").join(target).join("lib").join("self-contained");
-    fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
+    let plat_target_lib_self_contained_dir =
+        plat_root.join("lib/rustlib").join(target).join("lib/self-contained");
+    fs::create_dir_all(&plat_target_lib_self_contained_dir)
+        .expect("creating plat_target_lib_self_contained_dir failed");
     for src in target_libs {
-        builder.copy_link_to_folder(&src, &target_lib_dir);
+        builder.copy_link_to_folder(&src, &plat_target_lib_self_contained_dir);
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 301633559fe..ffb617c642b 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -303,10 +303,11 @@ fn invoke_rustdoc(
         .arg(&out)
         .arg(&path)
         .arg("--markdown-css")
-        .arg("../rust.css");
+        .arg("../rust.css")
+        .arg("-Zunstable-options");
 
     if !builder.config.docs_minification {
-        cmd.arg("-Z").arg("unstable-options").arg("--disable-minification");
+        cmd.arg("--disable-minification");
     }
 
     cmd.run(builder);
@@ -376,8 +377,6 @@ impl Step for Standalone {
             }
 
             let mut cmd = builder.rustdoc_cmd(compiler);
-            // Needed for --index-page flag
-            cmd.arg("-Z").arg("unstable-options");
 
             cmd.arg("--html-after-content")
                 .arg(&footer)
@@ -386,6 +385,7 @@ impl Step for Standalone {
                 .arg("--html-in-header")
                 .arg(&favicon)
                 .arg("--markdown-no-toc")
+                .arg("-Zunstable-options")
                 .arg("--index-page")
                 .arg(builder.src.join("src/doc/index.md"))
                 .arg("--markdown-playground-url")
@@ -478,9 +478,6 @@ impl Step for Releases {
             mem::drop(tmpfile);
             let mut cmd = builder.rustdoc_cmd(compiler);
 
-            // Needed for --index-page flag
-            cmd.arg("-Z").arg("unstable-options");
-
             cmd.arg("--html-after-content")
                 .arg(&footer)
                 .arg("--html-before-content")
@@ -490,6 +487,7 @@ impl Step for Releases {
                 .arg("--markdown-no-toc")
                 .arg("--markdown-css")
                 .arg("rust.css")
+                .arg("-Zunstable-options")
                 .arg("--index-page")
                 .arg(builder.src.join("src/doc/index.md"))
                 .arg("--markdown-playground-url")
@@ -636,6 +634,8 @@ impl Step for Std {
         if !builder.config.docs_minification {
             extra_args.push("--disable-minification");
         }
+        // For `--index-page` and `--output-format=json`.
+        extra_args.push("-Zunstable-options");
 
         doc_std(builder, self.format, stage, target, &out, &extra_args, &crates);
 
@@ -715,8 +715,6 @@ fn doc_std(
         .arg("--target-dir")
         .arg(&*target_dir.to_string_lossy())
         .arg("-Zskip-rustdoc-fingerprint")
-        .rustdocflag("-Z")
-        .rustdocflag("unstable-options")
         .rustdocflag("--resource-suffix")
         .rustdocflag(&builder.version);
     for arg in extra_args {
@@ -822,7 +820,6 @@ impl Step for Rustc {
         // Since we always pass --document-private-items, there's no need to warn about linking to private items.
         cargo.rustdocflag("-Arustdoc::private-intra-doc-links");
         cargo.rustdocflag("--enable-index-page");
-        cargo.rustdocflag("-Zunstable-options");
         cargo.rustdocflag("-Znormalize-docs");
         cargo.rustdocflag("--show-type-layout");
         // FIXME: `--generate-link-to-definition` tries to resolve cfged out code
@@ -830,7 +827,6 @@ impl Step for Rustc {
         // cargo.rustdocflag("--generate-link-to-definition");
 
         compile::rustc_cargo(builder, &mut cargo, target, &compiler);
-        cargo.arg("-Zunstable-options");
         cargo.arg("-Zskip-rustdoc-fingerprint");
 
         // Only include compiler crates, no dependencies of those, such as `libc`.
@@ -986,7 +982,6 @@ macro_rules! tool_doc {
                 cargo.rustdocflag("-Arustdoc::private-intra-doc-links");
                 cargo.rustdocflag("--enable-index-page");
                 cargo.rustdocflag("--show-type-layout");
-                cargo.rustdocflag("-Zunstable-options");
                 // FIXME: `--generate-link-to-definition` tries to resolve cfged out code
                 // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
                 // cargo.rustdocflag("--generate-link-to-definition");
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index c5a1ab78801..e1eea31b3bb 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -110,7 +110,7 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L
 
     // Initialize the llvm submodule if not initialized already.
     // If submodules are disabled, this does nothing.
-    builder.update_submodule("src/llvm-project");
+    builder.config.update_submodule("src/llvm-project");
 
     let root = "src/llvm-project/llvm";
     let out_dir = builder.llvm_out(target);
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index ff8ca2ad74a..3a1eb43b801 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -1096,7 +1096,7 @@ tool_extended!((self, builder),
     CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
     Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"];
     Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"];
-    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"];
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, add_bins_to_sysroot = ["cargo-miri"];
     Rls, "src/tools/rls", "rls", stable=true;
     Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
 );
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index a848163b272..ff0d1f3a725 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1612,7 +1612,6 @@ impl<'a> Builder<'a> {
             rustflags.arg("-Csymbol-mangling-version=v0");
         } else {
             rustflags.arg("-Csymbol-mangling-version=legacy");
-            rustflags.arg("-Zunstable-options");
         }
 
         // Enable compile-time checking of `cfg` names, values and Cargo `features`.
@@ -1860,16 +1859,7 @@ impl<'a> Builder<'a> {
             },
         );
 
-        let split_debuginfo = self.config.split_debuginfo(target);
-        let split_debuginfo_is_stable = target.contains("linux")
-            || target.contains("apple")
-            || (target.is_msvc() && split_debuginfo == SplitDebuginfo::Packed)
-            || (target.is_windows() && split_debuginfo == SplitDebuginfo::Off);
-
-        if !split_debuginfo_is_stable {
-            rustflags.arg("-Zunstable-options");
-        }
-        match split_debuginfo {
+        match self.config.split_debuginfo(target) {
             SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"),
             SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"),
             SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"),
@@ -2046,7 +2036,6 @@ impl<'a> Builder<'a> {
         }
 
         if mode == Mode::Rustc {
-            rustflags.arg("-Zunstable-options");
             rustflags.arg("-Wrustc::internal");
             // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
             // of the individual lints are satisfied.
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index bdd9fd755aa..bdfee55d8d1 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -14,7 +14,7 @@ use std::sync::OnceLock;
 use std::{cmp, env, fs};
 
 use build_helper::exit;
-use build_helper::git::GitConfig;
+use build_helper::git::{output_result, GitConfig};
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
 
@@ -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);
@@ -2509,6 +2524,123 @@ impl Config {
         }
     }
 
+    /// Given a path to the directory of a submodule, update it.
+    ///
+    /// `relative_path` should be relative to the root of the git repository, not an absolute path.
+    ///
+    /// This *does not* update the submodule if `config.toml` explicitly says
+    /// not to, or if we're not in a git repository (like a plain source
+    /// tarball). Typically [`crate::Build::require_submodule`] should be
+    /// used instead to provide a nice error to the user if the submodule is
+    /// missing.
+    pub(crate) fn update_submodule(&self, relative_path: &str) {
+        if !self.submodules() {
+            return;
+        }
+
+        let absolute_path = self.src.join(relative_path);
+
+        // NOTE: The check for the empty directory is here because when running x.py the first time,
+        // the submodule won't be checked out. Check it out now so we can build it.
+        if !GitInfo::new(false, &absolute_path).is_managed_git_subrepository()
+            && !helpers::dir_is_empty(&absolute_path)
+        {
+            return;
+        }
+
+        // Submodule updating actually happens during in the dry run mode. We need to make sure that
+        // all the git commands below are actually executed, because some follow-up code
+        // in bootstrap might depend on the submodules being checked out. Furthermore, not all
+        // the command executions below work with an empty output (produced during dry run).
+        // Therefore, all commands below are marked with `run_always()`, so that they also run in
+        // dry run mode.
+        let submodule_git = || {
+            let mut cmd = helpers::git(Some(&absolute_path));
+            cmd.run_always();
+            cmd
+        };
+
+        // Determine commit checked out in submodule.
+        let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]).as_command_mut());
+        let checked_out_hash = checked_out_hash.trim_end();
+        // Determine commit that the submodule *should* have.
+        let recorded = output(
+            helpers::git(Some(&self.src))
+                .run_always()
+                .args(["ls-tree", "HEAD"])
+                .arg(relative_path)
+                .as_command_mut(),
+        );
+
+        let actual_hash = recorded
+            .split_whitespace()
+            .nth(2)
+            .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
+
+        if actual_hash == checked_out_hash {
+            // already checked out
+            return;
+        }
+
+        println!("Updating submodule {relative_path}");
+        self.check_run(
+            helpers::git(Some(&self.src))
+                .run_always()
+                .args(["submodule", "-q", "sync"])
+                .arg(relative_path),
+        );
+
+        // Try passing `--progress` to start, then run git again without if that fails.
+        let update = |progress: bool| {
+            // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository,
+            // even though that has no relation to the upstream for the submodule.
+            let current_branch = output_result(
+                helpers::git(Some(&self.src))
+                    .allow_failure()
+                    .run_always()
+                    .args(["symbolic-ref", "--short", "HEAD"])
+                    .as_command_mut(),
+            )
+            .map(|b| b.trim().to_owned());
+
+            let mut git = helpers::git(Some(&self.src)).allow_failure();
+            git.run_always();
+            if let Ok(branch) = current_branch {
+                // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name.
+                // This syntax isn't accepted by `branch.{branch}`. Strip it.
+                let branch = branch.strip_prefix("heads/").unwrap_or(&branch);
+                git.arg("-c").arg(format!("branch.{branch}.remote=origin"));
+            }
+            git.args(["submodule", "update", "--init", "--recursive", "--depth=1"]);
+            if progress {
+                git.arg("--progress");
+            }
+            git.arg(relative_path);
+            git
+        };
+        if !self.check_run(&mut update(true)) {
+            self.check_run(&mut update(false));
+        }
+
+        // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
+        // diff-index reports the modifications through the exit status
+        let has_local_modifications = !self.check_run(submodule_git().allow_failure().args([
+            "diff-index",
+            "--quiet",
+            "HEAD",
+        ]));
+        if has_local_modifications {
+            self.check_run(submodule_git().args(["stash", "push"]));
+        }
+
+        self.check_run(submodule_git().args(["reset", "-q", "--hard"]));
+        self.check_run(submodule_git().args(["clean", "-qdfx"]));
+
+        if has_local_modifications {
+            self.check_run(submodule_git().args(["stash", "pop"]));
+        }
+    }
+
     #[cfg(feature = "bootstrap-self-test")]
     pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {}
 
@@ -2613,19 +2745,23 @@ impl Config {
         asserts: bool,
     ) -> bool {
         let if_unchanged = || {
-            // Git is needed to track modifications here, but tarball source is not available.
-            // If not modified here or built through tarball source, we maintain consistency
-            // with '"if available"'.
-            if !self.rust_info.is_from_tarball()
-                && self
-                    .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
-                    .is_none()
-            {
-                // there are some untracked changes in the given paths.
-                false
-            } else {
-                llvm::is_ci_llvm_available(self, asserts)
+            if self.rust_info.is_from_tarball() {
+                // Git is needed for running "if-unchanged" logic.
+                println!(
+                    "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
+                );
+                return false;
             }
+
+            self.update_submodule("src/llvm-project");
+
+            // Check for untracked changes in `src/llvm-project`.
+            let has_changes = self
+                .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
+                .is_none();
+
+            // Return false if there are untracked changes, otherwise check if CI LLVM is available.
+            if has_changes { false } else { llvm::is_ci_llvm_available(self, asserts) }
         };
 
         match download_ci_llvm {
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index dd0309733ae..1e3f8da5258 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -22,6 +22,24 @@ fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> {
     config.try_run(cmd)
 }
 
+fn extract_curl_version(out: &[u8]) -> semver::Version {
+    let out = String::from_utf8_lossy(out);
+    // The output should look like this: "curl <major>.<minor>.<patch> ..."
+    out.lines()
+        .next()
+        .and_then(|line| line.split(" ").nth(1))
+        .and_then(|version| semver::Version::parse(version).ok())
+        .unwrap_or(semver::Version::new(1, 0, 0))
+}
+
+fn curl_version() -> semver::Version {
+    let mut curl = Command::new("curl");
+    curl.arg("-V");
+    let Ok(out) = curl.output() else { return semver::Version::new(1, 0, 0) };
+    let out = out.stdout;
+    extract_curl_version(&out)
+}
+
 /// Generic helpers that are useful anywhere in bootstrap.
 impl Config {
     pub fn is_verbose(&self) -> bool {
@@ -56,7 +74,7 @@ impl Config {
     /// Returns false if do not execute at all, otherwise returns its
     /// `status.success()`.
     pub(crate) fn check_run(&self, cmd: &mut BootstrapCommand) -> bool {
-        if self.dry_run() {
+        if self.dry_run() && !cmd.run_always {
             return true;
         }
         self.verbose(|| println!("running: {cmd:?}"));
@@ -220,6 +238,8 @@ impl Config {
             "30", // timeout if cannot connect within 30 seconds
             "-o",
             tempfile.to_str().unwrap(),
+            "--continue-at",
+            "-",
             "--retry",
             "3",
             "-SRf",
@@ -230,6 +250,10 @@ impl Config {
         } else {
             curl.arg("--progress-bar");
         }
+        // --retry-all-errors was added in 7.71.0, don't use it if curl is old.
+        if curl_version() >= semver::Version::new(7, 71, 0) {
+            curl.arg("--retry-all-errors");
+        }
         curl.arg(url);
         if !self.check_run(&mut curl) {
             if self.build.contains("windows-msvc") {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 784519a20a2..268392c5fb1 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -473,117 +473,6 @@ impl Build {
         build
     }
 
-    /// Given a path to the directory of a submodule, update it.
-    ///
-    /// `relative_path` should be relative to the root of the git repository, not an absolute path.
-    ///
-    /// This *does not* update the submodule if `config.toml` explicitly says
-    /// not to, or if we're not in a git repository (like a plain source
-    /// tarball). Typically [`Build::require_submodule`] should be
-    /// used instead to provide a nice error to the user if the submodule is
-    /// missing.
-    fn update_submodule(&self, relative_path: &str) {
-        if !self.config.submodules() {
-            return;
-        }
-
-        let absolute_path = self.config.src.join(relative_path);
-
-        // NOTE: The check for the empty directory is here because when running x.py the first time,
-        // the submodule won't be checked out. Check it out now so we can build it.
-        if !GitInfo::new(false, &absolute_path).is_managed_git_subrepository()
-            && !dir_is_empty(&absolute_path)
-        {
-            return;
-        }
-
-        // Submodule updating actually happens during in the dry run mode. We need to make sure that
-        // all the git commands below are actually executed, because some follow-up code
-        // in bootstrap might depend on the submodules being checked out. Furthermore, not all
-        // the command executions below work with an empty output (produced during dry run).
-        // Therefore, all commands below are marked with `run_always()`, so that they also run in
-        // dry run mode.
-        let submodule_git = || {
-            let mut cmd = helpers::git(Some(&absolute_path));
-            cmd.run_always();
-            cmd
-        };
-
-        // Determine commit checked out in submodule.
-        let checked_out_hash =
-            submodule_git().args(["rev-parse", "HEAD"]).run_capture_stdout(self).stdout();
-        let checked_out_hash = checked_out_hash.trim_end();
-        // Determine commit that the submodule *should* have.
-        let recorded = helpers::git(Some(&self.src))
-            .run_always()
-            .args(["ls-tree", "HEAD"])
-            .arg(relative_path)
-            .run_capture_stdout(self)
-            .stdout();
-        let actual_hash = recorded
-            .split_whitespace()
-            .nth(2)
-            .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
-
-        if actual_hash == checked_out_hash {
-            // already checked out
-            return;
-        }
-
-        println!("Updating submodule {relative_path}");
-        helpers::git(Some(&self.src))
-            .run_always()
-            .args(["submodule", "-q", "sync"])
-            .arg(relative_path)
-            .run(self);
-
-        // Try passing `--progress` to start, then run git again without if that fails.
-        let update = |progress: bool| {
-            // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository,
-            // even though that has no relation to the upstream for the submodule.
-            let current_branch = helpers::git(Some(&self.src))
-                .allow_failure()
-                .run_always()
-                .args(["symbolic-ref", "--short", "HEAD"])
-                .run_capture_stdout(self)
-                .stdout_if_ok()
-                .map(|s| s.trim().to_owned());
-
-            let mut git = helpers::git(Some(&self.src)).allow_failure();
-            git.run_always();
-            if let Some(branch) = current_branch {
-                // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name.
-                // This syntax isn't accepted by `branch.{branch}`. Strip it.
-                let branch = branch.strip_prefix("heads/").unwrap_or(&branch);
-                git.arg("-c").arg(format!("branch.{branch}.remote=origin"));
-            }
-            git.args(["submodule", "update", "--init", "--recursive", "--depth=1"]);
-            if progress {
-                git.arg("--progress");
-            }
-            git.arg(relative_path);
-            git
-        };
-        if !update(true).run(self) {
-            update(false).run(self);
-        }
-
-        // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
-        // diff-index reports the modifications through the exit status
-        let has_local_modifications =
-            !submodule_git().allow_failure().args(["diff-index", "--quiet", "HEAD"]).run(self);
-        if has_local_modifications {
-            submodule_git().args(["stash", "push"]).run(self);
-        }
-
-        submodule_git().args(["reset", "-q", "--hard"]).run(self);
-        submodule_git().args(["clean", "-qdfx"]).run(self);
-
-        if has_local_modifications {
-            submodule_git().args(["stash", "pop"]).run(self);
-        }
-    }
-
     /// Updates a submodule, and exits with a failure if submodule management
     /// is disabled and the submodule does not exist.
     ///
@@ -598,7 +487,7 @@ impl Build {
         if cfg!(test) && !self.config.submodules() {
             return;
         }
-        self.update_submodule(submodule);
+        self.config.update_submodule(submodule);
         let absolute_path = self.config.src.join(submodule);
         if dir_is_empty(&absolute_path) {
             let maybe_enable = if !self.config.submodules()
@@ -646,7 +535,7 @@ impl Build {
             let path = Path::new(submodule);
             // Don't update the submodule unless it's already been cloned.
             if GitInfo::new(false, path).is_managed_git_subrepository() {
-                self.update_submodule(submodule);
+                self.config.update_submodule(submodule);
             }
         }
     }
@@ -659,7 +548,7 @@ impl Build {
         }
 
         if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
-            self.update_submodule(submodule);
+            self.config.update_submodule(submodule);
         }
     }
 
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index c629f04c00e..51a25104e4c 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -230,4 +230,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "./x test --rustc-args was renamed to --compiletest-rustc-args as it only applies there. ./x miri --rustc-args was also removed.",
     },
+    ChangeInfo {
+        change_id: 129295,
+        severity: ChangeSeverity::Info,
+        summary: "The `build.profiler` option now tries to use source code from `download-ci-llvm` if possible, instead of checking out the `src/llvm-project` submodule.",
+    },
 ];
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/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index d690aac27fa..389abb2fdd3 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -2,7 +2,7 @@
 
 set -euo pipefail
 
-LINUX_VERSION=v6.11-rc1
+LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee
 
 # Build rustc, rustdoc and cargo
 ../x.py build --stage 1 library rustdoc
@@ -28,7 +28,7 @@ rm -rf linux || true
 # Download Linux at a specific commit
 mkdir -p linux
 git -C linux init
-git -C linux remote add origin https://github.com/torvalds/linux.git
+git -C linux remote add origin https://github.com/Rust-for-Linux/linux.git
 git -C linux fetch --depth 1 origin ${LINUX_VERSION}
 git -C linux checkout FETCH_HEAD
 
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index cb0b2e63452..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)
@@ -81,6 +82,7 @@
     - [wasm32-wasip1](platform-support/wasm32-wasip1.md)
     - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md)
     - [wasm32-wasip2](platform-support/wasm32-wasip2.md)
+    - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
     - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
     - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 667758a1203..0d79e5f4114 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -192,7 +192,7 @@ target | std | notes
 [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline
 [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat
 `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
-`wasm32-unknown-unknown` | ✓ | WebAssembly
+[`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly
 `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
 [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
@@ -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/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
new file mode 100644
index 00000000000..12b7817c382
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
@@ -0,0 +1,197 @@
+# `wasm32-unknown-unknown`
+
+**Tier: 2**
+
+The `wasm32-unknown-unknown` target is a WebAssembly compilation target which
+does not import any functions from the host for the standard library. This is
+the "minimal" WebAssembly in the sense of making the fewest assumptions about
+the host environment. This target is often used when compiling to the web or
+JavaScript environments as there is no standard for what functions can be
+imported on the web. This target can also be useful for creating minimal or
+bare-bones WebAssembly binaries.
+
+The `wasm32-unknown-unknown` target has support for the Rust standard library
+but many parts of the standard library do not work and return errors. For
+example `println!` does nothing, `std::fs` always return errors, and
+`std::thread::spawn` will panic. There is no means by which this can be
+overridden. For a WebAssembly target that more fully supports the standard
+library see the [`wasm32-wasip1`](./wasm32-wasip1.md) or
+[`wasm32-wasip2`](./wasm32-wasip2.md) targets.
+
+The `wasm32-unknown-unknown` target has full support for the `core` and `alloc`
+crates. It additionally supports the `HashMap` type in the `std` crate, although
+hash maps are not randomized like they are on other platforms.
+
+One existing user of this target (please feel free to edit and expand this list
+too) is the [`wasm-bindgen` project](https://github.com/rustwasm/wasm-bindgen)
+which facilitates Rust code interoperating with JavaScript code. Note, though,
+that not all uses of `wasm32-unknown-unknown` are using JavaScript and the web.
+
+## Target maintainers
+
+When this target was added to the compiler, platform-specific documentation here
+was not maintained at that time. This means that the list below is not
+exhaustive, and there are more interested parties in this target. That being
+said, those interested in maintaining this target are:
+
+- Alex Crichton, https://github.com/alexcrichton
+
+## Requirements
+
+This target is cross-compiled. The target includes support for `std` itself,
+but as mentioned above many pieces of functionality that require an operating
+system do not work and will return errors.
+
+This target currently has no equivalent in C/C++. There is no C/C++ toolchain
+for this target. While interop is theoretically possible it's recommended to
+instead use one of:
+
+* `wasm32-unknown-emscripten` - for web-based use cases the Emscripten
+  toolchain is typically chosen for running C/C++.
+* [`wasm32-wasip1`](./wasm32-wasip1.md) - the wasi-sdk toolchain is used to
+  compile C/C++ on this target and can interop with Rust code. WASI works on
+  the web so far as there's no blocker, but an implementation of WASI APIs
+  must be either chosen or reimplemented.
+
+This target has no build requirements beyond what's in-tree in the Rust
+repository. Linking binaries requires LLD to be enabled for the `wasm-ld`
+driver. This target uses the `dlmalloc` crate as the default global allocator.
+
+## Building the target
+
+Building this target can be done by:
+
+* Configure the `wasm32-unknown-unknown` target to get built.
+* Configure LLD to be built.
+* Ensure the `WebAssembly` target backend is not disabled in LLVM.
+
+These are all controlled through `config.toml` options. It should be possible
+to build this target on any platform.
+
+## Building Rust programs
+
+Rust programs can be compiled by adding this target via rustup:
+
+```sh
+$ rustup target add wasm32-unknown-unknown
+```
+
+and then compiling with the target:
+
+```sh
+$ rustc foo.rs --target wasm32-unknown-unknown
+$ file foo.wasm
+```
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+This target is not tested in CI for the rust-lang/rust repository. Many tests
+must be disabled to run on this target and failures are non-obvious because
+`println!` doesn't work in the standard library. It's recommended to test the
+`wasm32-wasip1` target instead for WebAssembly compatibility.
+
+## Conditionally compiling code
+
+It's recommended to conditionally compile code for this target with:
+
+```text
+#[cfg(all(target_family = "wasm", target_os = "unknown"))]
+```
+
+Note that there is no way to tell via `#[cfg]` whether code will be running on
+the web or not.
+
+## Enabled WebAssembly features
+
+WebAssembly is an evolving standard which adds new features such as new
+instructions over time. This target's default set of supported WebAssembly
+features will additionally change over time. The `wasm32-unknown-unknown` target
+inherits the default settings of LLVM which typically matches the default
+settings of Emscripten as well.
+
+Changes to WebAssembly go through a [proposals process][proposals] but reaching
+the final stage (stage 5) does not automatically mean that the feature will be
+enabled in LLVM and Rust by default. At this time the general guidance is that
+features must be present in most engines for a "good chunk of time" before
+they're enabled in LLVM by default. There is currently no exact number of
+months or engines that are required to enable features by default.
+
+[proposals]: https://github.com/WebAssembly/proposals
+
+As of the time of this writing the proposals that are enabled by default (the
+`generic` CPU in LLVM terminology) are:
+
+* `multivalue`
+* `mutable-globals`
+* `reference-types`
+* `sign-ext`
+
+If you're compiling WebAssembly code for an engine that does not support a
+feature in LLVM's default feature set then the feature must be disabled at
+compile time. Note, though, that enabled features may be used in the standard
+library or precompiled libraries shipped via rustup. This means that not only
+does your own code need to be compiled with the correct set of flags but the
+Rust standard library additionally must be recompiled.
+
+Compiling all code for the initial release of WebAssembly looks like:
+
+```sh
+$ export RUSTFLAGS=-Ctarget-cpu=mvp
+$ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown
+```
+
+Here the `mvp` "cpu" is a placeholder in LLVM for disabling all supported
+features by default. Cargo's `-Zbuild-std` feature, a Nightly Rust feature, is
+then used to recompile the standard library in addition to your own code. This
+will produce a binary that uses only the original WebAssembly features by
+default and no proposals since its inception.
+
+To enable individual features it can be done with `-Ctarget-feature=+foo`.
+Available features for Rust code itself are documented in the [reference] and
+can also be found through:
+
+```sh
+$ rustc -Ctarget-feature=help --target wasm32-unknown-unknown
+```
+
+You'll need to consult your WebAssembly engine's documentation to learn more
+about the supported WebAssembly features the engine has.
+
+[reference]: https://doc.rust-lang.org/reference/attributes/codegen.html#wasm32-or-wasm64
+
+Note that it is still possible for Rust crates and libraries to enable
+WebAssembly features on a per-function level. This means that the build
+command above may not be sufficient to disable all WebAssembly features. If the
+final binary still has SIMD instructions, for example, the function in question
+will need to be found and the crate in question will likely contain something
+like:
+
+```rust,ignore (not-always-compiled-to-wasm)
+#[target_feature(enable = "simd128")]
+fn foo() {
+    // ...
+}
+```
+
+In this situation there is no compiler flag to disable emission of SIMD
+instructions and the crate must instead be modified to not include this function
+at compile time either by default or through a Cargo feature. For crate authors
+it's recommended to avoid `#[target_feature(enable = "...")]` except where
+necessary and instead use:
+
+```rust,ignore (not-always-compiled-to-wasm)
+#[cfg(target_feature = "simd128")]
+fn foo() {
+    // ...
+}
+```
+
+That is to say instead of enabling target features it's recommended to
+conditionally compile code instead. This is notably different to the way native
+platforms such as x86\_64 work, and this is due to the fact that WebAssembly
+binaries must only contain code the engine understands. Native binaries work so
+long as the CPU doesn't execute unknown code dynamically at runtime.
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md
index c3eda26ca8e..994c0f4bbb3 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md
@@ -162,3 +162,17 @@ It's recommended to conditionally compile code for this target with:
 Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the
 `target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]`
 necessary to detect this target may change as the target becomes more stable.
+
+## Enabled WebAssembly features
+
+The default set of WebAssembly features enabled for compilation includes two
+more features in addition to that which
+[`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) enables:
+
+* `bulk-memory`
+* `atomics`
+
+For more information about features see the documentation for
+[`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md), but note that the
+`mvp` CPU in LLVM does not support this target as it's required that
+`bulk-memory`, `atomics`, and `mutable-globals` are all enabled.
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
index fb70bbdc2b4..0e4def6768d 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
@@ -132,3 +132,9 @@ It's recommended to conditionally compile code for this target with:
 
 Note that the `target_env = "p1"` condition first appeared in Rust 1.80. Prior
 to Rust 1.80 the `target_env` condition was not set.
+
+## Enabled WebAssembly features
+
+The default set of WebAssembly features enabled for compilation is currently the
+same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the
+documentation there for more information.
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md
index 1e53fbc178e..bb2348b201e 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md
@@ -61,3 +61,9 @@ It's recommended to conditionally compile code for this target with:
 ```text
 #[cfg(all(target_os = "wasi", target_env = "p2"))]
 ```
+
+## Enabled WebAssembly features
+
+The default set of WebAssembly features enabled for compilation is currently the
+same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the
+documentation there for more information.
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/doc/unstable-book/src/language-features/struct-target-features.md b/src/doc/unstable-book/src/language-features/struct-target-features.md
new file mode 100644
index 00000000000..e814fe90072
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/struct-target-features.md
@@ -0,0 +1,7 @@
+# `struct_target_features`
+
+The tracking issue for this feature is: [#129107]
+
+[#129107]: https://github.com/rust-lang/rust/issues/129107
+
+------------------------
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index b3fccbf6456..34332de80b3 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -12,7 +12,7 @@ rinja = { version = "0.3", default-features = false, features = ["config"] }
 base64 = "0.21.7"
 itertools = "0.12"
 indexmap = "2"
-minifier = "0.3.0"
+minifier = "0.3.1"
 pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
 regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index db81b4c4282..5260e363dd6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -272,7 +272,7 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
         | rbv::ResolvedArg::LateBound(_, _, did)
         | rbv::ResolvedArg::Free(_, did),
     ) = cx.tcx.named_bound_var(lifetime.hir_id)
-        && let Some(lt) = cx.args.get(&did).and_then(|arg| arg.as_lt())
+        && let Some(lt) = cx.args.get(&did.to_def_id()).and_then(|arg| arg.as_lt())
     {
         return lt.clone();
     }
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/format.rs b/src/librustdoc/html/format.rs
index 6357cfee141..5cbf8c5e19f 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1288,56 +1288,90 @@ impl clean::Impl {
                 if self.is_negative_trait_impl() {
                     write!(f, "!")?;
                 }
-                ty.print(cx).fmt(f)?;
+                if self.kind.is_fake_variadic()
+                    && let generics = ty.generics()
+                    && let &[inner_type] = generics.as_ref().map_or(&[][..], |v| &v[..])
+                {
+                    let last = ty.last();
+                    if f.alternate() {
+                        write!(f, "{}<", last)?;
+                        self.print_type(inner_type, f, use_absolute, cx)?;
+                        write!(f, ">")?;
+                    } else {
+                        write!(f, "{}&lt;", anchor(ty.def_id(), last, cx).to_string())?;
+                        self.print_type(inner_type, f, use_absolute, cx)?;
+                        write!(f, "&gt;")?;
+                    }
+                } else {
+                    ty.print(cx).fmt(f)?;
+                }
                 write!(f, " for ")?;
             }
 
-            if let clean::Type::Tuple(types) = &self.for_
-                && let [clean::Type::Generic(name)] = &types[..]
-                && (self.kind.is_fake_variadic() || self.kind.is_auto())
-            {
-                // Hardcoded anchor library/core/src/primitive_docs.rs
-                // Link should match `# Trait implementations`
-                primitive_link_fragment(
-                    f,
-                    PrimitiveType::Tuple,
-                    format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
-                    "#trait-implementations-1",
-                    cx,
-                )?;
-            } else if let clean::BareFunction(bare_fn) = &self.for_
-                && let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
-                    &bare_fn.decl.inputs.values[..]
-                && (self.kind.is_fake_variadic() || self.kind.is_auto())
-            {
-                // Hardcoded anchor library/core/src/primitive_docs.rs
-                // Link should match `# Trait implementations`
-
-                print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
-                bare_fn.safety.print_with_space().fmt(f)?;
-                print_abi_with_space(bare_fn.abi).fmt(f)?;
-                let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
-                primitive_link_fragment(
-                    f,
-                    PrimitiveType::Tuple,
-                    format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
-                    "#trait-implementations-1",
-                    cx,
-                )?;
-                // Write output.
-                if !bare_fn.decl.output.is_unit() {
-                    write!(f, " -> ")?;
-                    fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
-                }
-            } else if let Some(ty) = self.kind.as_blanket_ty() {
+            if let Some(ty) = self.kind.as_blanket_ty() {
                 fmt_type(ty, f, use_absolute, cx)?;
             } else {
-                fmt_type(&self.for_, f, use_absolute, cx)?;
+                self.print_type(&self.for_, f, use_absolute, cx)?;
             }
 
             print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f)
         })
     }
+    fn print_type<'a, 'tcx: 'a>(
+        &self,
+        type_: &clean::Type,
+        f: &mut fmt::Formatter<'_>,
+        use_absolute: bool,
+        cx: &'a Context<'tcx>,
+    ) -> Result<(), fmt::Error> {
+        if let clean::Type::Tuple(types) = type_
+            && let [clean::Type::Generic(name)] = &types[..]
+            && (self.kind.is_fake_variadic() || self.kind.is_auto())
+        {
+            // Hardcoded anchor library/core/src/primitive_docs.rs
+            // Link should match `# Trait implementations`
+            primitive_link_fragment(
+                f,
+                PrimitiveType::Tuple,
+                format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
+                "#trait-implementations-1",
+                cx,
+            )?;
+        } else if let clean::Type::Array(ty, len) = type_
+            && let clean::Type::Generic(name) = &**ty
+            && &len[..] == "1"
+            && (self.kind.is_fake_variadic() || self.kind.is_auto())
+        {
+            primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?;
+        } else if let clean::BareFunction(bare_fn) = &type_
+            && let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
+                &bare_fn.decl.inputs.values[..]
+            && (self.kind.is_fake_variadic() || self.kind.is_auto())
+        {
+            // Hardcoded anchor library/core/src/primitive_docs.rs
+            // Link should match `# Trait implementations`
+
+            print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
+            bare_fn.safety.print_with_space().fmt(f)?;
+            print_abi_with_space(bare_fn.abi).fmt(f)?;
+            let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
+            primitive_link_fragment(
+                f,
+                PrimitiveType::Tuple,
+                format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
+                "#trait-implementations-1",
+                cx,
+            )?;
+            // Write output.
+            if !bare_fn.decl.output.is_unit() {
+                write!(f, " -> ")?;
+                fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
+            }
+        } else {
+            fmt_type(&type_, f, use_absolute, cx)?;
+        }
+        Ok(())
+    }
 }
 
 impl clean::Arguments {
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/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 8a12bdef69b..d7682bd1c19 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -579,12 +579,14 @@ pub(crate) fn build_index<'tcx>(
             let mut names = Vec::with_capacity(self.items.len());
             let mut types = String::with_capacity(self.items.len());
             let mut full_paths = Vec::with_capacity(self.items.len());
-            let mut parents = Vec::with_capacity(self.items.len());
+            let mut parents = String::with_capacity(self.items.len());
+            let mut parents_backref_queue = VecDeque::new();
             let mut functions = String::with_capacity(self.items.len());
             let mut deprecated = Vec::with_capacity(self.items.len());
 
-            let mut backref_queue = VecDeque::new();
+            let mut type_backref_queue = VecDeque::new();
 
+            let mut last_name = None;
             for (index, item) in self.items.iter().enumerate() {
                 let n = item.ty as u8;
                 let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
@@ -597,17 +599,39 @@ pub(crate) fn build_index<'tcx>(
                     "`{}` is missing idx",
                     item.name
                 );
-                // 0 is a sentinel, everything else is one-indexed
-                parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0));
+                assert!(
+                    parents_backref_queue.len() <= 16,
+                    "the string encoding only supports 16 slots of lookback"
+                );
+                let parent: i32 = item.parent_idx.map(|x| x + 1).unwrap_or(0).try_into().unwrap();
+                if let Some(idx) = parents_backref_queue.iter().position(|p: &i32| *p == parent) {
+                    parents.push(
+                        char::try_from('0' as u32 + u32::try_from(idx).unwrap())
+                            .expect("last possible value is '?'"),
+                    );
+                } else if parent == 0 {
+                    write_vlqhex_to_string(parent, &mut parents);
+                } else {
+                    parents_backref_queue.push_front(parent);
+                    write_vlqhex_to_string(parent, &mut parents);
+                    if parents_backref_queue.len() > 16 {
+                        parents_backref_queue.pop_back();
+                    }
+                }
 
-                names.push(item.name.as_str());
+                if Some(item.name.as_str()) == last_name {
+                    names.push("");
+                } else {
+                    names.push(item.name.as_str());
+                    last_name = Some(item.name.as_str());
+                }
 
                 if !item.path.is_empty() {
                     full_paths.push((index, &item.path));
                 }
 
                 match &item.search_type {
-                    Some(ty) => ty.write_to_string(&mut functions, &mut backref_queue),
+                    Some(ty) => ty.write_to_string(&mut functions, &mut type_backref_queue),
                     None => functions.push('`'),
                 }
 
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index a18b7a252a4..60dc142b9ff 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -75,11 +75,11 @@ pub(crate) fn write_shared(
     let crate_name = krate.name(cx.tcx());
     let crate_name = crate_name.as_str(); // rand
     let crate_name_json = OrderedJson::serialize(crate_name).unwrap(); // "rand"
-    let external_crates = hack_get_external_crate_names(&cx.dst)?;
+    let external_crates = hack_get_external_crate_names(&cx.dst, &cx.shared.resource_suffix)?;
     let info = CrateInfo {
         src_files_js: SourcesPart::get(cx, &crate_name_json)?,
         search_index_js: SearchIndexPart::get(index, &cx.shared.resource_suffix)?,
-        all_crates: AllCratesPart::get(crate_name_json.clone())?,
+        all_crates: AllCratesPart::get(crate_name_json.clone(), &cx.shared.resource_suffix)?,
         crates_index: CratesIndexPart::get(&crate_name, &external_crates)?,
         trait_impl: TraitAliasPart::get(cx, &crate_name_json)?,
         type_impl: TypeAliasPart::get(cx, krate, &crate_name_json)?,
@@ -291,10 +291,13 @@ impl AllCratesPart {
         SortedTemplate::from_before_after("window.ALL_CRATES = [", "];")
     }
 
-    fn get(crate_name_json: OrderedJson) -> Result<PartsAndLocations<Self>, Error> {
+    fn get(
+        crate_name_json: OrderedJson,
+        resource_suffix: &str,
+    ) -> Result<PartsAndLocations<Self>, Error> {
         // external hack_get_external_crate_names not needed here, because
         // there's no way that we write the search index but not crates.js
-        let path = PathBuf::from("crates.js");
+        let path = suffix_path("crates.js", resource_suffix);
         Ok(PartsAndLocations::with(path, crate_name_json))
     }
 }
@@ -305,8 +308,11 @@ impl AllCratesPart {
 ///
 /// This is to match the current behavior of rustdoc, which allows you to get all crates
 /// on the index page, even if --enable-index-page is only passed to the last crate.
-fn hack_get_external_crate_names(doc_root: &Path) -> Result<Vec<String>, Error> {
-    let path = doc_root.join("crates.js");
+fn hack_get_external_crate_names(
+    doc_root: &Path,
+    resource_suffix: &str,
+) -> Result<Vec<String>, Error> {
+    let path = doc_root.join(suffix_path("crates.js", resource_suffix));
     let Ok(content) = fs::read_to_string(&path) else {
         // they didn't emit invocation specific, so we just say there were no crates
         return Ok(Vec::default());
diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs
index 4d1874b7df5..e282cd99e43 100644
--- a/src/librustdoc/html/render/write_shared/tests.rs
+++ b/src/librustdoc/html/render/write_shared/tests.rs
@@ -6,10 +6,10 @@ use crate::html::render::write_shared::*;
 fn hack_external_crate_names() {
     let path = tempfile::TempDir::new().unwrap();
     let path = path.path();
-    let crates = hack_get_external_crate_names(&path).unwrap();
+    let crates = hack_get_external_crate_names(&path, "").unwrap();
     assert!(crates.is_empty());
     fs::write(path.join("crates.js"), r#"window.ALL_CRATES = ["a","b","c"];"#).unwrap();
-    let crates = hack_get_external_crate_names(&path).unwrap();
+    let crates = hack_get_external_crate_names(&path, "").unwrap();
     assert_eq!(crates, ["a".to_string(), "b".to_string(), "c".to_string()]);
 }
 
@@ -60,7 +60,7 @@ fn all_crates_template() {
 
 #[test]
 fn all_crates_parts() {
-    let parts = AllCratesPart::get(OrderedJson::serialize("crate").unwrap()).unwrap();
+    let parts = AllCratesPart::get(OrderedJson::serialize("crate").unwrap(), "").unwrap();
     assert_eq!(&parts.parts[0].0, Path::new("crates.js"));
     assert_eq!(&parts.parts[0].1.to_string(), r#""crate""#);
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index eb5a5d935e2..28df8d3f011 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1547,10 +1547,23 @@ instead, we check that it's not a "finger" cursor.
 	margin-left: 24px;
 }
 
+@keyframes targetfadein {
+	from {
+		background-color: var(--main-background-color);
+	}
+	10% {
+		background-color: var(--target-border-color);
+	}
+	to {
+		background-color: var(--target-background-color);
+	}
+}
+
 :target {
 	padding-right: 3px;
 	background-color: var(--target-background-color);
 	border-right: 3px solid var(--target-border-color);
+	animation: 0.65s cubic-bezier(0, 0, 0.1, 1.0) 0.1s targetfadein;
 }
 
 .code-header a.tooltip {
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 3eb27ea087c..be0ec425946 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1393,6 +1393,7 @@ function initSearch(rawSearchIndex) {
          */
         async function sortResults(results, isType, preferredCrate) {
             const userQuery = parsedQuery.userQuery;
+            const casedUserQuery = parsedQuery.original;
             const result_list = [];
             for (const result of results.values()) {
                 result.item = searchIndex[result.id];
@@ -1403,6 +1404,13 @@ function initSearch(rawSearchIndex) {
             result_list.sort((aaa, bbb) => {
                 let a, b;
 
+                // sort by exact case-sensitive match
+                a = (aaa.item.name !== casedUserQuery);
+                b = (bbb.item.name !== casedUserQuery);
+                if (a !== b) {
+                    return a - b;
+                }
+
                 // sort by exact match with regard to the last word (mismatch goes later)
                 a = (aaa.word !== userQuery);
                 b = (bbb.word !== userQuery);
@@ -3546,7 +3554,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // Used to de-duplicate inlined and re-exported stuff
             const itemReexports = new Map(crateCorpus.r);
             // an array of (Number) the parent path index + 1 to `paths`, or 0 if none
-            const itemParentIdxs = crateCorpus.i;
+            const itemParentIdxDecoder = new VlqHexDecoder(crateCorpus.i, noop => noop);
             // a map Number, string for impl disambiguators
             const implDisambiguator = new Map(crateCorpus.b);
             // an array of [(Number) item type,
@@ -3593,6 +3601,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             // faster analysis operations
             lastPath = "";
             len = itemTypes.length;
+            let lastName = "";
+            let lastWord = "";
             for (let i = 0; i < len; ++i) {
                 const bitIndex = i + 1;
                 if (descIndex >= descShard.len &&
@@ -3608,10 +3618,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                     descIndex = 0;
                     descShardList.push(descShard);
                 }
-                let word = "";
-                if (typeof itemNames[i] === "string") {
-                    word = itemNames[i].toLowerCase();
-                }
+                const name = itemNames[i] === "" ? lastName : itemNames[i];
+                const word = itemNames[i] === "" ? lastWord : itemNames[i].toLowerCase();
                 const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
                 const type = itemFunctionDecoder.next();
                 if (type !== null) {
@@ -3633,15 +3641,16 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 }
                 // This object should have exactly the same set of fields as the "crateRow"
                 // object defined above.
+                const itemParentIdx = itemParentIdxDecoder.next();
                 const row = {
                     crate,
                     ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
-                    name: itemNames[i],
+                    name,
                     path,
                     descShard,
                     descIndex,
                     exactPath: itemReexports.has(i) ? itemPaths.get(itemReexports.get(i)) : path,
-                    parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined,
+                    parent: itemParentIdx > 0 ? paths[itemParentIdx - 1] : undefined,
                     type,
                     id,
                     word,
@@ -3655,6 +3664,8 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 if (!searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
                     descIndex += 1;
                 }
+                lastName = name;
+                lastWord = word;
             }
 
             if (aliases) {
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5b96529fed7..eae12b84839 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -53,7 +53,7 @@ fn filter_assoc_items_by_name_and_namespace<'a>(
     assoc_items_of: DefId,
     ident: Ident,
     ns: Namespace,
-) -> impl Iterator<Item = &ty::AssocItem> + 'a {
+) -> impl Iterator<Item = &'a ty::AssocItem> + 'a {
     tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| {
         item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of)
     })
@@ -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/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index faf42b3aab1..23e298571d5 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -2,7 +2,7 @@
 
 use std::mem;
 
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
@@ -145,8 +145,9 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
                 let old = mem::replace(&mut self.update_retained, false);
                 let ret = self.set_is_in_hidden_item_and_fold(true, i);
                 self.update_retained = old;
-                if ret.is_crate() {
-                    // We don't strip the crate, even if it has `#[doc(hidden)]`.
+                if ret.item_id == clean::ItemId::DefId(CRATE_DEF_ID.into()) {
+                    // We don't strip the current crate, even if it has `#[doc(hidden)]`.
+                    debug!("strip_hidden: Not strippping local crate");
                     Some(ret)
                 } else {
                     Some(strip_item(ret))
diff --git a/src/llvm-project b/src/llvm-project
-Subproject ccf4c38bdd73f1a37ec266c73bdaef80e39f8cf
+Subproject 2b259b3c201f939f2ed8d2fb0a0e9b37dd2d132
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject ba8b39413c74d08494f94a7542fe79aa636e166
+Subproject 8f40fc59fb0c8df91c97405785197f3c630304e
diff --git a/src/tools/clippy/.cargo/config.toml b/src/tools/clippy/.cargo/config.toml
index ce07290d1e1..d9c635df5dc 100644
--- a/src/tools/clippy/.cargo/config.toml
+++ b/src/tools/clippy/.cargo/config.toml
@@ -1,10 +1,10 @@
 [alias]
+bless = "test --config env.RUSTC_BLESS='1'"
 uitest = "test --test compile-test"
-uibless = "test --test compile-test -- -- --bless"
-bless = "test -- -- --bless"
+uibless = "bless --test compile-test"
 dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
 lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml  -- "
-collect-metadata = "test --test dogfood --features internal -- collect_metadata"
+collect-metadata = "test --test compile-test --config env.COLLECT_METADATA='1'"
 
 [build]
 # -Zbinary-dep-depinfo allows us to track which rlib files to use for compiling UI tests
diff --git a/src/tools/clippy/.github/deploy.sh b/src/tools/clippy/.github/deploy.sh
index 5a59f94ec91..d937661c0f8 100644
--- a/src/tools/clippy/.github/deploy.sh
+++ b/src/tools/clippy/.github/deploy.sh
@@ -10,6 +10,7 @@ mkdir out/master/
 cp util/gh-pages/index.html out/master
 cp util/gh-pages/script.js out/master
 cp util/gh-pages/lints.json out/master
+cp util/gh-pages/style.css out/master
 
 if [[ -n $TAG_NAME ]]; then
   echo "Save the doc for the current tag ($TAG_NAME) and point stable/ to it"
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 10e18e84c89..2aa13313fa5 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -136,11 +136,6 @@ jobs:
     - name: Test metadata collection
       run: cargo collect-metadata
 
-    - name: Test lint_configuration.md is up-to-date
-      run: |
-        echo "run \`cargo collect-metadata\` if this fails"
-        git update-index --refresh
-
   integration_build:
     needs: changelog
     runs-on: ubuntu-latest
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index fddc2fd994e..9bc4ad9698d 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5914,6 +5914,7 @@ Released 2018-09-13
 [`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args
 [`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_trait_impl
 [`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
+[`too_long_first_doc_paragraph`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph
 [`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
 [`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
 [`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 78409c7a09e..b48b881097f 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -30,8 +30,11 @@ color-print = "0.3.4"
 anstream = "0.6.0"
 
 [dev-dependencies]
+cargo_metadata = "0.18.1"
 ui_test = "0.25"
 regex = "1.5.5"
+serde = { version = "1.0.145", features = ["derive"] }
+serde_json = "1.0.122"
 toml = "0.7.3"
 walkdir = "2.3"
 filetime = "0.2.9"
@@ -41,7 +44,6 @@ itertools = "0.12"
 clippy_utils = { path = "clippy_utils" }
 if_chain = "1.0"
 quote = "1.0.25"
-serde = { version = "1.0.145", features = ["derive"] }
 syn = { version = "2.0", features = ["full"] }
 futures = "0.3"
 parking_lot = "0.12"
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index a71d94daca7..963e02e5c16 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -739,7 +739,7 @@ for some users. Adding a configuration is done in the following steps:
 
 5. Update [Lint Configuration](../lint_configuration.md)
 
-   Run `cargo collect-metadata` to generate documentation changes for the book.
+   Run `cargo bless --test config-metadata` to generate documentation changes for the book.
 
 [`clippy_config::conf`]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_config/src/conf.rs
 [`clippy_lints` lib file]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index e3d550b1466..78348797588 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -1,5 +1,5 @@
 <!--
-This file is generated by `cargo collect-metadata`.
+This file is generated by `cargo bless --test config-metadata`.
 Please use that command to update the file and do not edit it by hand.
 -->
 
@@ -199,7 +199,7 @@ Allowed names below the minimum allowed characters. The value `".."` can be used
 the list to indicate, that the configured values should be appended to the default
 configuration of Clippy. By default, any configuration will replace the default value.
 
-**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
+**Default Value:** `["i", "j", "x", "y", "z", "w", "n"]`
 
 ---
 **Affected lints:**
@@ -455,7 +455,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["TiB", "CoreGraphics", "CoffeeScript", "TeX", "Direct2D", "PiB", "DirectX", "NetBSD", "OAuth", "NaN", "OpenType", "WebGL2", "WebTransport", "JavaScript", "OpenSSL", "OpenSSH", "EiB", "PureScript", "OpenAL", "MiB", "WebAssembly", "MinGW", "CoreFoundation", "WebGPU", "ClojureScript", "CamelCase", "OpenDNS", "NaNs", "OpenMP", "GitLab", "KiB", "sRGB", "CoreText", "macOS", "TypeScript", "GiB", "OpenExr", "YCbCr", "OpenTelemetry", "OpenBSD", "FreeBSD", "GPLv2", "PostScript", "WebP", "LaTeX", "TensorFlow", "AccessKit", "TrueType", "OpenStreetMap", "OpenGL", "DevOps", "OCaml", "WebRTC", "WebGL", "BibLaTeX", "GitHub", "GraphQL", "iOS", "Direct3D", "BibTeX", "DirectWrite", "GPLv3", "IPv6", "WebSocket", "IPv4", "ECMAScript"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -949,5 +949,3 @@ Whether to also emit warnings for unsafe blocks with metavariable expansions in
 ---
 **Affected lints:**
 * [`macro_metavars_in_unsafe`](https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe)
-
-
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index d5b28e25323..5c4e0761dbc 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2021"
 
 [dependencies]
 itertools = "0.12"
-rustc-semver = "1.1"
 serde = { version = "1.0", features = ["derive"] }
 toml = "0.7.3"
 
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 4c2a8255d6b..a6f1b958bfb 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -1,7 +1,6 @@
 use crate::msrvs::Msrv;
 use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
 use crate::ClippyConfiguration;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
@@ -218,7 +217,7 @@ macro_rules! define_Conf {
 define_Conf! {
     /// Which crates to allow absolute paths from
     #[lints(absolute_paths)]
-    absolute_paths_allowed_crates: FxHashSet<String> = FxHashSet::default(),
+    absolute_paths_allowed_crates: Vec<String> = Vec::new(),
     /// The maximum number of segments a path can have before being linted, anything above this will
     /// be linted.
     #[lints(absolute_paths)]
@@ -280,12 +279,12 @@ define_Conf! {
     allowed_dotfiles: Vec<String> = Vec::default(),
     /// A list of crate names to allow duplicates of
     #[lints(multiple_crate_versions)]
-    allowed_duplicate_crates: FxHashSet<String> = FxHashSet::default(),
+    allowed_duplicate_crates: Vec<String> = Vec::new(),
     /// Allowed names below the minimum allowed characters. The value `".."` can be used as part of
     /// the list to indicate, that the configured values should be appended to the default
     /// configuration of Clippy. By default, any configuration will replace the default value.
     #[lints(min_ident_chars)]
-    allowed_idents_below_min_chars: FxHashSet<String> =
+    allowed_idents_below_min_chars: Vec<String> =
         DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect(),
     /// List of prefixes to allow when determining whether an item's name ends with the module's name.
     /// If the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`),
@@ -323,7 +322,7 @@ define_Conf! {
     /// 2. Paths with any segment that containing the word 'prelude'
     /// are already allowed by default.
     #[lints(wildcard_imports)]
-    allowed_wildcard_imports: FxHashSet<String> = FxHashSet::default(),
+    allowed_wildcard_imports: Vec<String> = Vec::new(),
     /// Suppress checking of the passed type names in all types of operations.
     ///
     /// If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
@@ -355,7 +354,7 @@ define_Conf! {
     /// arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
     /// ```
     #[lints(arithmetic_side_effects)]
-    arithmetic_side_effects_allowed_binary: Vec<[String; 2]> = <_>::default(),
+    arithmetic_side_effects_allowed_binary: Vec<(String, String)> = <_>::default(),
     /// Suppress checking of the passed type names in unary operations like "negation" (`-`).
     ///
     /// #### Example
@@ -431,7 +430,7 @@ define_Conf! {
     /// * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
     /// * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
     #[lints(doc_markdown)]
-    doc_valid_idents: FxHashSet<String> = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect(),
+    doc_valid_idents: Vec<String> = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect(),
     /// Whether to apply the raw pointer heuristic to determine if a type is `Send`.
     #[lints(non_send_fields_in_send_ty)]
     enable_raw_pointer_heuristic_for_send: bool = true,
@@ -706,12 +705,12 @@ fn deserialize(file: &SourceFile) -> TryConf {
                 DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS,
             );
             // TODO: THIS SHOULD BE TESTED, this comment will be gone soon
-            if conf.conf.allowed_idents_below_min_chars.contains("..") {
+            if conf.conf.allowed_idents_below_min_chars.iter().any(|e| e == "..") {
                 conf.conf
                     .allowed_idents_below_min_chars
                     .extend(DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string));
             }
-            if conf.conf.doc_valid_idents.contains("..") {
+            if conf.conf.doc_valid_idents.iter().any(|e| e == "..") {
                 conf.conf
                     .doc_valid_idents
                     .extend(DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string));
@@ -890,14 +889,14 @@ fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
 
 #[cfg(test)]
 mod tests {
-    use rustc_data_structures::fx::{FxHashMap, FxHashSet};
     use serde::de::IgnoredAny;
+    use std::collections::{HashMap, HashSet};
     use std::fs;
     use walkdir::WalkDir;
 
     #[test]
     fn configs_are_tested() {
-        let mut names: FxHashSet<String> = crate::get_configuration_metadata()
+        let mut names: HashSet<String> = crate::get_configuration_metadata()
             .into_iter()
             .map(|meta| meta.name.replace('_', "-"))
             .collect();
@@ -910,7 +909,7 @@ mod tests {
         for entry in toml_files {
             let file = fs::read_to_string(entry.path()).unwrap();
             #[allow(clippy::zero_sized_map_values)]
-            if let Ok(map) = toml::from_str::<FxHashMap<String, IgnoredAny>>(&file) {
+            if let Ok(map) = toml::from_str::<HashMap<String, IgnoredAny>>(&file) {
                 for name in map.keys() {
                     names.remove(name.as_str());
                 }
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index d2246f12029..ac838cc81d2 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -14,7 +14,7 @@
 )]
 
 extern crate rustc_ast;
-extern crate rustc_data_structures;
+extern crate rustc_attr;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
 extern crate rustc_errors;
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index fc56ac51796..0e8215aa8e3 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -1,6 +1,6 @@
 use rustc_ast::Attribute;
-use rustc_semver::RustcVersion;
-use rustc_session::Session;
+use rustc_attr::parse_version;
+use rustc_session::{RustcVersion, Session};
 use rustc_span::{sym, Symbol};
 use serde::Deserialize;
 use std::fmt;
@@ -10,7 +10,7 @@ macro_rules! msrv_aliases {
         $($name:ident),* $(,)?
     })*) => {
         $($(
-        pub const $name: RustcVersion = RustcVersion::new($major, $minor, $patch);
+        pub const $name: RustcVersion = RustcVersion { major: $major, minor :$minor, patch: $patch };
         )*)*
     };
 }
@@ -18,6 +18,7 @@ macro_rules! msrv_aliases {
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
     1,81,0  { LINT_REASONS_STABILIZATION }
+    1,80,0 { BOX_INTO_ITER}
     1,77,0 { C_STR_LITERALS }
     1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
@@ -81,9 +82,9 @@ impl<'de> Deserialize<'de> for Msrv {
         D: serde::Deserializer<'de>,
     {
         let v = String::deserialize(deserializer)?;
-        RustcVersion::parse(&v)
+        parse_version(Symbol::intern(&v))
             .map(|v| Msrv { stack: vec![v] })
-            .map_err(|_| serde::de::Error::custom("not a valid Rust version"))
+            .ok_or_else(|| serde::de::Error::custom("not a valid Rust version"))
     }
 }
 
@@ -95,7 +96,7 @@ impl Msrv {
     pub fn read_cargo(&mut self, sess: &Session) {
         let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION")
             .ok()
-            .and_then(|v| RustcVersion::parse(&v).ok());
+            .and_then(|v| parse_version(Symbol::intern(&v)));
 
         match (self.current(), cargo_msrv) {
             (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv],
@@ -115,7 +116,7 @@ impl Msrv {
     }
 
     pub fn meets(&self, required: RustcVersion) -> bool {
-        self.current().map_or(true, |version| version.meets(required))
+        self.current().map_or(true, |msrv| msrv >= required)
     }
 
     fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
@@ -131,7 +132,7 @@ impl Msrv {
             }
 
             if let Some(msrv) = msrv_attr.value_str() {
-                if let Ok(version) = RustcVersion::parse(msrv.as_str()) {
+                if let Some(version) = parse_version(msrv) {
                     return Some(version);
                 }
 
diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs
index 755b04b0b23..fc15913354c 100644
--- a/src/tools/clippy/clippy_dev/src/main.rs
+++ b/src/tools/clippy/clippy_dev/src/main.rs
@@ -1,3 +1,4 @@
+#![feature(rustc_private)]
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 15578d69c3a..8dbda1c634c 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -604,7 +604,7 @@ fn gen_declared_lints<'a>(
     details.sort_unstable();
 
     let mut output = GENERATED_FILE_COMMENT.to_string();
-    output.push_str("pub(crate) static LINTS: &[&crate::LintInfo] = &[\n");
+    output.push_str("pub static LINTS: &[&crate::LintInfo] = &[\n");
 
     for (is_public, module_name, lint_name) in details {
         if !is_public {
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 99ed93468a0..fbd4566da58 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -25,7 +25,6 @@ regex = { version = "1.5", optional = true }
 unicode-normalization = "0.1"
 unicode-script = { version = "0.5", default-features = false }
 semver = "1.0"
-rustc-semver = "1.1"
 url = "2.2"
 
 [dev-dependencies]
diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
index c0a9d888e0b..c72b3f1318c 100644
--- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::is_from_proc_macro;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
@@ -8,6 +8,7 @@ use rustc_hir::{HirId, ItemKind, Node, Path};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
+use rustc_span::Symbol;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -24,6 +25,13 @@ declare_clippy_lint! {
     /// Note: One exception to this is code from macro expansion - this does not lint such cases, as
     /// using absolute paths is the proper way of referencing items in one.
     ///
+    /// ### Known issues
+    ///
+    /// There are currently a few cases which are not caught by this lint:
+    /// * Macro calls. e.g. `path::to::macro!()`
+    /// * Derive macros. e.g. `#[derive(path::to::macro)]`
+    /// * Attribute macros. e.g. `#[path::to::macro]`
+    ///
     /// ### Example
     /// ```no_run
     /// let x = std::f64::consts::PI;
@@ -48,63 +56,66 @@ impl_lint_pass!(AbsolutePaths => [ABSOLUTE_PATHS]);
 
 pub struct AbsolutePaths {
     pub absolute_paths_max_segments: u64,
-    pub absolute_paths_allowed_crates: &'static FxHashSet<String>,
+    pub absolute_paths_allowed_crates: FxHashSet<Symbol>,
 }
 
 impl AbsolutePaths {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
             absolute_paths_max_segments: conf.absolute_paths_max_segments,
-            absolute_paths_allowed_crates: &conf.absolute_paths_allowed_crates,
+            absolute_paths_allowed_crates: conf
+                .absolute_paths_allowed_crates
+                .iter()
+                .map(|x| Symbol::intern(x))
+                .collect(),
         }
     }
 }
 
-impl LateLintPass<'_> for AbsolutePaths {
+impl<'tcx> LateLintPass<'tcx> for AbsolutePaths {
     // We should only lint `QPath::Resolved`s, but since `Path` is only used in `Resolved` and `UsePath`
     // we don't need to use a visitor or anything as we can just check if the `Node` for `hir_id` isn't
     // a `Use`
-    #[expect(clippy::cast_possible_truncation)]
-    fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
-        let Self {
-            absolute_paths_max_segments,
-            absolute_paths_allowed_crates,
-        } = self;
-
-        if !path.span.from_expansion()
-            && let node = cx.tcx.hir_node(hir_id)
-            && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _)))
-            && let [first, rest @ ..] = path.segments
-            // Handle `::std`
-            && let (segment, len) = if first.ident.name == kw::PathRoot {
-                // Indexing is fine as `PathRoot` must be followed by another segment. `len() - 1`
-                // is fine here for the same reason
-                (&rest[0], path.segments.len() - 1)
-            } else {
-                (first, path.segments.len())
-            }
-            && len > *absolute_paths_max_segments as usize
-            && let Some(segment_snippet) = snippet_opt(cx, segment.ident.span)
-            && segment_snippet == segment.ident.as_str()
-        {
-            let is_abs_external =
-                matches!(segment.res, Res::Def(DefKind::Mod, DefId { index, .. }) if index == CRATE_DEF_INDEX);
-            let is_abs_crate = segment.ident.name == kw::Crate;
-
-            if is_abs_external && absolute_paths_allowed_crates.contains(segment.ident.name.as_str())
-                || is_abs_crate && absolute_paths_allowed_crates.contains("crate")
+    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, hir_id: HirId) {
+        let segments = match path.segments {
+            [] | [_] => return,
+            // Don't count enum variants and trait items as part of the length.
+            [rest @ .., _]
+                if let [.., s] = rest
+                    && matches!(s.res, Res::Def(DefKind::Enum | DefKind::Trait | DefKind::TraitAlias, _)) =>
+            {
+                rest
+            },
+            path => path,
+        };
+        if let [s1, s2, ..] = segments
+            && let has_root = s1.ident.name == kw::PathRoot
+            && let first = if has_root { s2 } else { s1 }
+            && let len = segments.len() - usize::from(has_root)
+            && len as u64 > self.absolute_paths_max_segments
+            && let crate_name = if let Res::Def(DefKind::Mod, DefId { index, .. }) = first.res
+                && index == CRATE_DEF_INDEX
             {
+                // `other_crate::foo` or `::other_crate::foo`
+                first.ident.name
+            } else if first.ident.name == kw::Crate || has_root {
+                // `::foo` or `crate::foo`
+                kw::Crate
+            } else {
                 return;
             }
-
-            if is_abs_external || is_abs_crate {
-                span_lint(
-                    cx,
-                    ABSOLUTE_PATHS,
-                    path.span,
-                    "consider bringing this path into scope with the `use` keyword",
-                );
-            }
+            && !path.span.from_expansion()
+            && let node = cx.tcx.hir_node(hir_id)
+            && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(..)))
+            && !self.absolute_paths_allowed_crates.contains(&crate_name)
+            && !is_from_proc_macro(cx, path)
+        {
+            span_lint(
+                cx,
+                ABSOLUTE_PATHS,
+                path.span,
+                "consider bringing this path into scope with the `use` keyword",
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 3b4cc113480..56f5e903dc3 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -4,8 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
-use rustc_session::impl_lint_pass;
+use rustc_session::{impl_lint_pass, RustcVersion};
 use rustc_span::symbol;
 use std::f64::consts as f64;
 
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index 6e336efbb90..55645d04eef 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -3,7 +3,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::mir::{enclosing_mir, PossibleBorrowerMap};
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{is_diag_trait_item, last_path_segment, local_is_initialized, path_to_local};
+use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local};
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -118,6 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
                 }
             )
             && !clone_source_borrows_from_dest(cx, lhs, rhs.span)
+            && !is_in_test(cx.tcx, e.hir_id)
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
index ca43e76ac57..7ff644b4c44 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
@@ -1,6 +1,6 @@
 use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::source::{is_present_in_source, snippet_opt, without_block_comments};
+use clippy_utils::source::{is_present_in_source, without_block_comments, SpanRangeExt};
 use rustc_ast::{AttrKind, AttrStyle};
 use rustc_lint::EarlyContext;
 use rustc_span::Span;
@@ -26,7 +26,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
                 item.span.parent(),
             );
 
-            if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
+            if let Some(snippet) = end_of_attr_to_next_attr_or_item.get_source_text(cx) {
                 let lines = snippet.split('\n').collect::<Vec<_>>();
                 let lines = without_block_comments(lines);
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index 8f430ae601a..3b14e9aee7f 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -1,5 +1,3 @@
-//! checks for attributes
-
 mod allow_attributes;
 mod allow_attributes_without_reason;
 mod blanket_clippy_restriction_lints;
@@ -310,8 +308,8 @@ declare_clippy_lint! {
     /// ```rust,ignore
     /// #[allow(unused_mut)]
     /// fn foo() -> usize {
-    ///    let mut a = Vec::new();
-    ///    a.len()
+    ///     let mut a = Vec::new();
+    ///     a.len()
     /// }
     /// ```
     /// Use instead:
diff --git a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
index 3fde7061585..877025cce4c 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
@@ -1,6 +1,6 @@
 use super::{Attribute, NON_MINIMAL_CFG};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::{MetaItemKind, NestedMetaItem};
 use rustc_errors::Applicability;
 use rustc_lint::EarlyContext;
@@ -29,8 +29,13 @@ fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
                         meta.span,
                         "unneeded sub `cfg` when there is only one condition",
                         |diag| {
-                            if let Some(snippet) = snippet_opt(cx, list[0].span()) {
-                                diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect);
+                            if let Some(snippet) = list[0].span().get_source_text(cx) {
+                                diag.span_suggestion(
+                                    meta.span,
+                                    "try",
+                                    snippet.to_owned(),
+                                    Applicability::MaybeIncorrect,
+                                );
                             }
                         },
                     );
diff --git a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
index 486e7c6ec4f..478ba7a187b 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
@@ -1,6 +1,7 @@
 use super::{Attribute, UNNECESSARY_CLIPPY_CFG};
 use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
+use itertools::Itertools;
 use rustc_ast::AttrStyle;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, Level};
@@ -31,7 +32,7 @@ pub(super) fn check(
             return;
         }
         if nb_items == clippy_lints.len() {
-            if let Some(snippet) = snippet_opt(cx, behind_cfg_attr.span) {
+            if let Some(snippet) = behind_cfg_attr.span.get_source_text(cx) {
                 span_lint_and_sugg(
                     cx,
                     UNNECESSARY_CLIPPY_CFG,
@@ -47,11 +48,7 @@ pub(super) fn check(
                 );
             }
         } else {
-            let snippet = clippy_lints
-                .iter()
-                .filter_map(|sp| snippet_opt(cx, *sp))
-                .collect::<Vec<_>>()
-                .join(",");
+            let snippet = clippy_lints.iter().filter_map(|sp| sp.get_source_text(cx)).join(",");
             span_lint_and_note(
                 cx,
                 UNNECESSARY_CLIPPY_CFG,
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index f0868231d01..67ba605a59f 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -1,7 +1,7 @@
 use super::utils::{extract_clippy_lint, is_lint_level, is_word};
 use super::{Attribute, USELESS_ATTRIBUTE};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{first_line_of_span, snippet_opt};
+use clippy_utils::source::{first_line_of_span, SpanRangeExt};
 use rustc_ast::NestedMetaItem;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
@@ -69,14 +69,14 @@ pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute])
                 }
                 let line_span = first_line_of_span(cx, attr.span);
 
-                if let Some(mut sugg) = snippet_opt(cx, line_span) {
-                    if sugg.contains("#[") {
+                if let Some(src) = line_span.get_source_text(cx) {
+                    if src.contains("#[") {
+                        #[expect(clippy::collapsible_span_lint_calls)]
                         span_lint_and_then(cx, USELESS_ATTRIBUTE, line_span, "useless lint attribute", |diag| {
-                            sugg = sugg.replacen("#[", "#![", 1);
                             diag.span_suggestion(
                                 line_span,
                                 "if you just forgot a `!`, use",
-                                sugg,
+                                src.replacen("#[", "#![", 1),
                                 Applicability::MaybeIncorrect,
                             );
                         });
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index a2f48c18170..e933fdf1d6e 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::eq_expr_value;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -134,28 +134,30 @@ fn check_inverted_bool_in_condition(
 
     let suggestion = match (left.kind, right.kind) {
         (ExprKind::Unary(UnOp::Not, left_sub), ExprKind::Unary(UnOp::Not, right_sub)) => {
-            let Some(left) = snippet_opt(cx, left_sub.span) else {
+            let Some(left) = left_sub.span.get_source_text(cx) else {
                 return;
             };
-            let Some(right) = snippet_opt(cx, right_sub.span) else {
+            let Some(right) = right_sub.span.get_source_text(cx) else {
                 return;
             };
             let Some(op) = bin_op_eq_str(op) else { return };
             format!("{left} {op} {right}")
         },
         (ExprKind::Unary(UnOp::Not, left_sub), _) => {
-            let Some(left) = snippet_opt(cx, left_sub.span) else {
+            let Some(left) = left_sub.span.get_source_text(cx) else {
                 return;
             };
-            let Some(right) = snippet_opt(cx, right.span) else {
+            let Some(right) = right.span.get_source_text(cx) else {
                 return;
             };
             let Some(op) = inverted_bin_op_eq_str(op) else { return };
             format!("{left} {op} {right}")
         },
         (_, ExprKind::Unary(UnOp::Not, right_sub)) => {
-            let Some(left) = snippet_opt(cx, left.span) else { return };
-            let Some(right) = snippet_opt(cx, right_sub.span) else {
+            let Some(left) = left.span.get_source_text(cx) else {
+                return;
+            };
+            let Some(right) = right_sub.span.get_source_text(cx) else {
                 return;
             };
             let Some(op) = inverted_bin_op_eq_str(op) else { return };
@@ -313,8 +315,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
                         self.output.push_str(&str);
                     } else {
                         self.output.push('!');
-                        let snip = snippet_opt(self.cx, terminal.span)?;
-                        self.output.push_str(&snip);
+                        self.output.push_str(&terminal.span.get_source_text(self.cx)?);
                     }
                 },
                 True | False | Not(_) => {
@@ -345,8 +346,12 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
                 }
             },
             &Term(n) => {
-                let snip = snippet_opt(self.cx, self.terminals[n as usize].span.source_callsite())?;
-                self.output.push_str(&snip);
+                self.output.push_str(
+                    &self.terminals[n as usize]
+                        .span
+                        .source_callsite()
+                        .get_source_text(self.cx)?,
+                );
             },
         }
         Some(())
@@ -370,8 +375,8 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
                 _ => None,
             }
             .and_then(|op| {
-                let lhs_snippet = snippet_opt(cx, lhs.span)?;
-                let rhs_snippet = snippet_opt(cx, rhs.span)?;
+                let lhs_snippet = lhs.span.get_source_text(cx)?;
+                let rhs_snippet = rhs.span.get_source_text(cx)?;
 
                 if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')')) {
                     if let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node) {
@@ -399,7 +404,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
                     let path: &str = path.ident.name.as_str();
                     a == path
                 })
-                .and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", snippet_opt(cx, receiver.span)?)))
+                .and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", receiver.span.get_source_text(cx)?)))
         },
         _ => None,
     }
diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
index bd123a725a7..cba8224b84c 100644
--- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
@@ -1,6 +1,6 @@
 use crate::reference::DEREF_ADDROF;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
 use rustc_errors::Applicability;
@@ -73,6 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
                 }
             })
             && !is_from_proc_macro(cx, e)
+            && let Some(deref_text) = deref_target.span.get_source_text(cx)
         {
             span_lint_and_then(
                 cx,
@@ -83,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
                     diag.span_suggestion(
                         e.span,
                         "if you would like to reborrow, try removing `&*`",
-                        snippet_opt(cx, deref_target.span).unwrap(),
+                        deref_text.as_str(),
                         Applicability::MachineApplicable,
                     );
 
@@ -98,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
                     diag.span_suggestion(
                         e.span,
                         "if you would like to deref, try using `&**`",
-                        format!("&**{}", &snippet_opt(cx, deref_target.span).unwrap()),
+                        format!("&**{deref_text}"),
                         Applicability::MaybeIncorrect,
                     );
                 },
diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
index 3af2d8c0256..fed0aa8b275 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
@@ -1,5 +1,3 @@
-//! lint on missing cargo common metadata
-
 use cargo_metadata::Metadata;
 use clippy_utils::diagnostics::span_lint;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index 312ad4c2990..96a2b161464 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -205,7 +205,7 @@ declare_clippy_lint! {
 }
 
 pub struct Cargo {
-    allowed_duplicate_crates: &'static FxHashSet<String>,
+    allowed_duplicate_crates: FxHashSet<String>,
     ignore_publish: bool,
 }
 
@@ -221,7 +221,7 @@ impl_lint_pass!(Cargo => [
 impl Cargo {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
-            allowed_duplicate_crates: &conf.allowed_duplicate_crates,
+            allowed_duplicate_crates: conf.allowed_duplicate_crates.iter().cloned().collect(),
             ignore_publish: conf.cargo_ignore_publish,
         }
     }
@@ -263,7 +263,7 @@ impl LateLintPass<'_> for Cargo {
         {
             match MetadataCommand::new().exec() {
                 Ok(metadata) => {
-                    multiple_crate_versions::check(cx, &metadata, self.allowed_duplicate_crates);
+                    multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);
                 },
                 Err(e) => {
                     for lint in WITH_DEPS_LINTS {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
index 2769463c8a5..44cd1f7192f 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
@@ -1,5 +1,3 @@
-//! lint on multiple versions of a crate being used
-
 use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};
 use clippy_utils::diagnostics::span_lint;
 use itertools::Itertools;
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
index f05fd3fcde5..15ecba20a0b 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
         && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity()
         && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
         && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
-        && let Some(recv) = snippet_opt(cx, receiver.span)
+        && let Some(recv) = receiver.span.get_source_text(cx)
     {
         // `as_mut_ptr` might not exist
         let applicability = Applicability::MaybeIncorrect;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index bd3acc06f4b..346aed7e9f1 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -1,7 +1,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_const_context;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_isize_or_usize;
 use rustc_errors::Applicability;
@@ -34,7 +34,7 @@ pub(super) fn check(
             diag.help("an `as` cast can become silently lossy if the types change in the future");
             let mut applicability = Applicability::MachineApplicable;
             let from_sugg = Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), "<from>", &mut applicability);
-            let Some(ty) = snippet_opt(cx, hygiene::walk_chain(cast_to_hir.span, expr.span.ctxt())) else {
+            let Some(ty) = hygiene::walk_chain(cast_to_hir.span, expr.span.ctxt()).get_source_text(cx) else {
                 return;
             };
             match cast_to_hir.kind {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 102fe25fc67..5708aae3f3e 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -4,7 +4,7 @@ use clippy_utils::expr_or_init;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
-use rustc_errors::{Applicability, Diag, SuggestionStyle};
+use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -190,12 +190,10 @@ fn offer_suggestion(
         format!("{cast_to_snip}::try_from({})", Sugg::hir(cx, cast_expr, ".."))
     };
 
-    diag.span_suggestion_with_style(
+    diag.span_suggestion_verbose(
         expr.span,
         "... or use `try_from` and handle the error accordingly",
         suggestion,
         Applicability::Unspecified,
-        // always show the suggestion in a separate line
-        SuggestionStyle::ShowAlways,
     );
 }
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
index 5dc6df1e907..b22e8f4ee89 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
@@ -24,12 +24,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             expr.span,
             format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
             |diag| {
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     expr.span,
                     "did you mean to invoke the function?",
                     format!("{from_snippet}() as {cast_to}"),
                     applicability,
-                    SuggestionStyle::ShowAlways,
                 );
             },
         );
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index fb0b0cba6a6..566adc83d69 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::numeric_literal::NumericLiteral;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::{snippet_opt, SpanRangeExt};
 use clippy_utils::visitors::{for_each_expr_without_closures, Visitable};
 use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local};
 use rustc_ast::{LitFloatType, LitIntType, LitKind};
@@ -104,7 +104,7 @@ pub(super) fn check<'tcx>(
         let literal_str = &cast_str;
 
         if let LitKind::Int(n, _) = lit.node
-            && let Some(src) = snippet_opt(cx, cast_expr.span)
+            && let Some(src) = cast_expr.span.get_source_text(cx)
             && cast_to.is_floating_point()
             && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)
             && let from_nbits = 128 - n.get().leading_zeros()
@@ -131,7 +131,7 @@ pub(super) fn check<'tcx>(
             | LitKind::Float(_, LitFloatType::Suffixed(_))
                 if cast_from.kind() == cast_to.kind() =>
             {
-                if let Some(src) = snippet_opt(cx, cast_expr.span) {
+                if let Some(src) = cast_expr.span.get_source_text(cx) {
                     if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) {
                         lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);
                         return true;
@@ -253,7 +253,7 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
             let res = cx.qpath_res(&qpath, expr.hir_id);
             // Function call
             if let Res::Def(DefKind::Fn, def_id) = res {
-                let Some(snippet) = snippet_opt(cx, cx.tcx.def_span(def_id)) else {
+                let Some(snippet) = cx.tcx.def_span(def_id).get_source_text(cx) else {
                     return ControlFlow::Continue(());
                 };
                 // This is the worst part of this entire function. This is the only way I know of to
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
index 3c1c7d2dc3a..c5c4a28646d 100644
--- a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_in_const_context, is_integer_literal, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability, Ty, TyKind};
@@ -20,7 +20,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>
 
         let sugg = if let TyKind::Infer = mut_ty.ty.kind {
             format!("{std_or_core}::{sugg_fn}()")
-        } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
+        } else if let Some(mut_ty_snip) = mut_ty.ty.span.get_source_text(cx) {
             format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
         } else {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
index b54f392bf2f..d820c1e0720 100644
--- a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
+++ b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
@@ -5,7 +5,7 @@ use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#{cfg(not(test))]`)
+    /// Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)
     ///
     /// ### Why is this bad?
     /// This may give the false impression that a codebase has 100% coverage, yet actually has untested code.
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 1711565fca8..dd7c34d1e46 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -1,5 +1,3 @@
-//! lint on manually implemented checked conversions that could be transformed into `try_from`
-
 use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 5fa0522e4e5..0099eefbc8d 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -1,5 +1,3 @@
-//! calculate cognitive complexity and warn about overly complex functions
-
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::{IntoSpan, SpanRangeExt};
diff --git a/src/tools/clippy/clippy_lints/src/collapsible_if.rs b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
index f311c052ad6..e73bfc6ebf7 100644
--- a/src/tools/clippy/clippy_lints/src/collapsible_if.rs
+++ b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
@@ -1,17 +1,3 @@
-//! Checks for if expressions that contain only an if expression.
-//!
-//! For example, the lint would catch:
-//!
-//! ```rust,ignore
-//! if x {
-//!     if y {
-//!         println!("Hello world");
-//!     }
-//! }
-//! ```
-//!
-//! This lint is **warn** by default
-
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet, snippet_block, snippet_block_with_applicability};
 use clippy_utils::sugg::Sugg;
diff --git a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
index eebda3ff76f..c6847411c75 100644
--- a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
+++ b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
+use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
 use clippy_utils::visitors::{for_each_expr, Visitable};
 use clippy_utils::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
@@ -7,7 +7,6 @@ use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
-use rustc_span::Symbol;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -44,24 +43,11 @@ declare_clippy_lint! {
 }
 declare_lint_pass!(CollectionIsNeverRead => [COLLECTION_IS_NEVER_READ]);
 
-// Add `String` here when it is added to diagnostic items
-static COLLECTIONS: [Symbol; 9] = [
-    sym::BTreeMap,
-    sym::BTreeSet,
-    sym::BinaryHeap,
-    sym::HashMap,
-    sym::HashSet,
-    sym::LinkedList,
-    sym::Option,
-    sym::Vec,
-    sym::VecDeque,
-];
-
 impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         // Look for local variables whose type is a container. Search surrounding block for read access.
         if let PatKind::Binding(_, local_id, _, _) = local.pat.kind
-            && match_acceptable_type(cx, local, &COLLECTIONS)
+            && match_acceptable_type(cx, local)
             && let Some(enclosing_block) = get_enclosing_block(cx, local.hir_id)
             && has_no_read_access(cx, local_id, enclosing_block)
         {
@@ -70,11 +56,22 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
     }
 }
 
-fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[Symbol]) -> bool {
+fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
     let ty = cx.typeck_results().pat_ty(local.pat);
-    collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym))
-    // String type is a lang item but not a diagnostic item for now so we need a separate check
-        || is_type_lang_item(cx, ty, LangItem::String)
+    matches!(
+        get_type_diagnostic_name(cx, ty),
+        Some(
+            sym::BTreeMap
+                | sym::BTreeSet
+                | sym::BinaryHeap
+                | sym::HashMap
+                | sym::HashSet
+                | sym::LinkedList
+                | sym::Option
+                | sym::Vec
+                | sym::VecDeque
+        )
+    ) || is_type_lang_item(cx, ty, LangItem::String)
 }
 
 fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs
index b49a977dbea..24570d8f440 100644
--- a/src/tools/clippy/clippy_lints/src/create_dir.rs
+++ b/src/tools/clippy/clippy_lints/src/create_dir.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -46,7 +46,7 @@ impl LateLintPass<'_> for CreateDir {
                 "calling `std::fs::create_dir` where there may be a better way",
                 |diag| {
                     let mut app = Applicability::MaybeIncorrect;
-                    diag.span_suggestion_with_style(
+                    diag.span_suggestion_verbose(
                         expr.span,
                         "consider calling `std::fs::create_dir_all` instead",
                         format!(
@@ -54,7 +54,6 @@ impl LateLintPass<'_> for CreateDir {
                             snippet_with_applicability(cx, arg.span, "..", &mut app)
                         ),
                         app,
-                        SuggestionStyle::ShowAlways,
                     );
                 },
             );
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 3fb083dd833..60e51713173 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -2,7 +2,7 @@
 // Use that command to update this file and do not edit by hand.
 // Manual edits will be overwritten.
 
-pub(crate) static LINTS: &[&crate::LintInfo] = &[
+pub static LINTS: &[&crate::LintInfo] = &[
     #[cfg(feature = "internal")]
     crate::utils::internal_lints::almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION_INFO,
     #[cfg(feature = "internal")]
@@ -22,8 +22,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     #[cfg(feature = "internal")]
     crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO,
     #[cfg(feature = "internal")]
-    crate::utils::internal_lints::metadata_collector::METADATA_COLLECTOR_INFO,
-    #[cfg(feature = "internal")]
     crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO,
     #[cfg(feature = "internal")]
     crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO,
@@ -146,6 +144,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
     crate::doc::SUSPICIOUS_DOC_COMMENTS_INFO,
     crate::doc::TEST_ATTR_IN_DOCTEST_INFO,
+    crate::doc::TOO_LONG_FIRST_DOC_PARAGRAPH_INFO,
     crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
     crate::double_parens::DOUBLE_PARENS_INFO,
     crate::drop_forget_ref::DROP_NON_DROP_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs b/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
index bd1cc46e185..771bcac2441 100644
--- a/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use itertools::Itertools;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_span::{BytePos, Span};
 use std::ops::Range;
@@ -59,12 +59,11 @@ pub(super) fn check(
                 && (doc_comment == "///" || doc_comment == "//!")
             {
                 // suggest filling in a blank line
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     line_break_span.shrink_to_lo(),
                     "if this should be its own paragraph, add a blank doc comment line",
                     format!("\n{doc_comment}"),
                     Applicability::MaybeIncorrect,
-                    SuggestionStyle::ShowAlways,
                 );
                 if ccount > 0 || blockquote_level > 0 {
                     diag.help("if this not intended to be a quote at all, escape it with `\\>`");
@@ -79,12 +78,11 @@ pub(super) fn check(
             if ccount == 0 && blockquote_level == 0 {
                 // simpler suggestion style for indentation
                 let indent = list_indentation - lcount;
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     span.shrink_to_hi(),
                     "indent this line",
                     std::iter::repeat(" ").take(indent).join(""),
                     Applicability::MaybeIncorrect,
-                    SuggestionStyle::ShowAlways,
                 );
                 diag.help("if this is supposed to be its own paragraph, add a blank line");
                 return;
@@ -107,12 +105,11 @@ pub(super) fn check(
                     suggested.push_str(text);
                 }
             }
-            diag.span_suggestion_with_style(
+            diag.span_suggestion_verbose(
                 span,
                 "add markers to start of line",
                 suggested,
                 Applicability::MachineApplicable,
-                SuggestionStyle::ShowAlways,
             );
             diag.help("if this not intended to be a quote at all, escape it with `\\>`");
         });
diff --git a/src/tools/clippy/clippy_lints/src/doc/markdown.rs b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
index 41c0bcd55ad..8cdaba88e50 100644
--- a/src/tools/clippy/clippy_lints/src/doc/markdown.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet_with_applicability;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_span::{BytePos, Pos, Span};
 use url::Url;
@@ -92,6 +92,10 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span, code_level: isize, b
             && matches!(prefix.chars().last(), Some('S' | 'X'))
         {
             prefix
+        } else if let Some(prefix) = s.strip_suffix("ified")
+            && prefix.chars().all(|c| c.is_ascii_uppercase())
+        {
+            prefix
         } else {
             s.strip_suffix('s').unwrap_or(s)
         };
@@ -133,24 +137,15 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span, code_level: isize, b
     }
 
     if has_underscore(word) || word.contains("::") || is_camel_case(word) || word.ends_with("()") {
-        let mut applicability = Applicability::MachineApplicable;
-
         span_lint_and_then(
             cx,
             DOC_MARKDOWN,
             span,
             "item in documentation is missing backticks",
             |diag| {
+                let mut applicability = Applicability::MachineApplicable;
                 let snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
-                diag.span_suggestion_with_style(
-                    span,
-                    "try",
-                    format!("`{snippet}`"),
-                    applicability,
-                    // always show the suggestion in a separate line, since the
-                    // inline presentation adds another pair of backticks
-                    SuggestionStyle::ShowAlways,
-                );
+                diag.span_suggestion_verbose(span, "try", format!("`{snippet}`"), applicability);
             },
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index d7b3a7c74f3..790579b21c9 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -1,4 +1,6 @@
 mod lazy_continuation;
+mod too_long_first_doc_paragraph;
+
 use clippy_config::Conf;
 use clippy_utils::attrs::is_doc_hidden;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
@@ -309,7 +311,7 @@ declare_clippy_lint! {
     /// ### Known problems
     /// Inner doc comments can only appear before items, so there are certain cases where the suggestion
     /// made by this lint is not valid code. For example:
-    /// ```rs
+    /// ```rust
     /// fn foo() {}
     /// ///!
     /// fn bar() {}
@@ -422,15 +424,47 @@ declare_clippy_lint! {
     "require every line of a paragraph to be indented and marked"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if the first line in the documentation of items listed in module page is too long.
+    ///
+    /// ### Why is this bad?
+    /// Documentation will show the first paragraph of the doscstring in the summary page of a
+    /// module, so having a nice, short summary in the first paragraph is part of writing good docs.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// /// A very short summary.
+    /// /// A much longer explanation that goes into a lot more detail about
+    /// /// how the thing works, possibly with doclinks and so one,
+    /// /// and probably spanning a many rows.
+    /// struct Foo {}
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// /// A very short summary.
+    /// ///
+    /// /// A much longer explanation that goes into a lot more detail about
+    /// /// how the thing works, possibly with doclinks and so one,
+    /// /// and probably spanning a many rows.
+    /// struct Foo {}
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub TOO_LONG_FIRST_DOC_PARAGRAPH,
+    style,
+    "ensure that the first line of a documentation paragraph isn't too long"
+}
+
+#[derive(Clone)]
 pub struct Documentation {
-    valid_idents: &'static FxHashSet<String>,
+    valid_idents: FxHashSet<String>,
     check_private_items: bool,
 }
 
 impl Documentation {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
-            valid_idents: &conf.doc_valid_idents,
+            valid_idents: conf.doc_valid_idents.iter().cloned().collect(),
             check_private_items: conf.check_private_items,
         }
     }
@@ -448,48 +482,60 @@ impl_lint_pass!(Documentation => [
     SUSPICIOUS_DOC_COMMENTS,
     EMPTY_DOCS,
     DOC_LAZY_CONTINUATION,
+    TOO_LONG_FIRST_DOC_PARAGRAPH,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Documentation {
     fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
-        let Some(headers) = check_attrs(cx, self.valid_idents, attrs) else {
+        let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
             return;
         };
 
         match cx.tcx.hir_node(cx.last_node_with_lint_attrs) {
-            Node::Item(item) => match item.kind {
-                ItemKind::Fn(sig, _, body_id) => {
-                    if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
-                        let body = cx.tcx.hir().body(body_id);
-
-                        let panic_info = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value);
-                        missing_headers::check(
+            Node::Item(item) => {
+                too_long_first_doc_paragraph::check(
+                    cx,
+                    item,
+                    attrs,
+                    headers.first_paragraph_len,
+                    self.check_private_items,
+                );
+                match item.kind {
+                    ItemKind::Fn(sig, _, body_id) => {
+                        if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())
+                            || in_external_macro(cx.tcx.sess, item.span))
+                        {
+                            let body = cx.tcx.hir().body(body_id);
+
+                            let panic_info = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value);
+                            missing_headers::check(
+                                cx,
+                                item.owner_id,
+                                sig,
+                                headers,
+                                Some(body_id),
+                                panic_info,
+                                self.check_private_items,
+                            );
+                        }
+                    },
+                    ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
+                        (false, Safety::Unsafe) => span_lint(
                             cx,
-                            item.owner_id,
-                            sig,
-                            headers,
-                            Some(body_id),
-                            panic_info,
-                            self.check_private_items,
-                        );
-                    }
-                },
-                ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
-                    (false, Safety::Unsafe) => span_lint(
-                        cx,
-                        MISSING_SAFETY_DOC,
-                        cx.tcx.def_span(item.owner_id),
-                        "docs for unsafe trait missing `# Safety` section",
-                    ),
-                    (true, Safety::Safe) => span_lint(
-                        cx,
-                        UNNECESSARY_SAFETY_DOC,
-                        cx.tcx.def_span(item.owner_id),
-                        "docs for safe trait have unnecessary `# Safety` section",
-                    ),
+                            MISSING_SAFETY_DOC,
+                            cx.tcx.def_span(item.owner_id),
+                            "docs for unsafe trait missing `# Safety` section",
+                        ),
+                        (true, Safety::Safe) => span_lint(
+                            cx,
+                            UNNECESSARY_SAFETY_DOC,
+                            cx.tcx.def_span(item.owner_id),
+                            "docs for safe trait have unnecessary `# Safety` section",
+                        ),
+                        _ => (),
+                    },
                     _ => (),
-                },
-                _ => (),
+                }
             },
             Node::TraitItem(trait_item) => {
                 if let TraitItemKind::Fn(sig, ..) = trait_item.kind
@@ -547,6 +593,7 @@ struct DocHeaders {
     safety: bool,
     errors: bool,
     panics: bool,
+    first_paragraph_len: usize,
 }
 
 /// Does some pre-processing on raw, desugared `#[doc]` attributes such as parsing them and
@@ -653,6 +700,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut paragraph_range = 0..0;
     let mut code_level = 0;
     let mut blockquote_level = 0;
+    let mut is_first_paragraph = true;
 
     let mut containers = Vec::new();
 
@@ -720,6 +768,10 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 }
                 ticks_unbalanced = false;
                 paragraph_range = range;
+                if is_first_paragraph {
+                    headers.first_paragraph_len = doc[paragraph_range.clone()].chars().count();
+                    is_first_paragraph = false;
+                }
             },
             End(TagEnd::Heading(_) | TagEnd::Paragraph | TagEnd::Item) => {
                 if let End(TagEnd::Heading(_)) = event {
diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
new file mode 100644
index 00000000000..7bb3bb12f2c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -0,0 +1,91 @@
+use rustc_ast::ast::Attribute;
+use rustc_errors::Applicability;
+use rustc_hir::{Item, ItemKind};
+use rustc_lint::LateContext;
+
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_from_proc_macro;
+use clippy_utils::source::snippet_opt;
+
+use super::TOO_LONG_FIRST_DOC_PARAGRAPH;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    item: &Item<'_>,
+    attrs: &[Attribute],
+    mut first_paragraph_len: usize,
+    check_private_items: bool,
+) {
+    if !check_private_items && !cx.effective_visibilities.is_exported(item.owner_id.def_id) {
+        return;
+    }
+    if first_paragraph_len <= 200
+        || !matches!(
+            item.kind,
+            // This is the list of items which can be documented AND are displayed on the module
+            // page. So associated items or impl blocks are not part of this list.
+            ItemKind::Static(..)
+                | ItemKind::Const(..)
+                | ItemKind::Fn(..)
+                | ItemKind::Macro(..)
+                | ItemKind::Mod(..)
+                | ItemKind::TyAlias(..)
+                | ItemKind::Enum(..)
+                | ItemKind::Struct(..)
+                | ItemKind::Union(..)
+                | ItemKind::Trait(..)
+                | ItemKind::TraitAlias(..)
+        )
+    {
+        return;
+    }
+
+    let mut spans = Vec::new();
+    let mut should_suggest_empty_doc = false;
+
+    for attr in attrs {
+        if let Some(doc) = attr.doc_str() {
+            spans.push(attr.span);
+            let doc = doc.as_str();
+            let doc = doc.trim();
+            if spans.len() == 1 {
+                // We make this suggestion only if the first doc line ends with a punctuation
+                // because it might just need to add an empty line with `///`.
+                should_suggest_empty_doc = doc.ends_with('.') || doc.ends_with('!') || doc.ends_with('?');
+            }
+            let len = doc.chars().count();
+            if len >= first_paragraph_len {
+                break;
+            }
+            first_paragraph_len -= len;
+        }
+    }
+
+    let &[first_span, .., last_span] = spans.as_slice() else {
+        return;
+    };
+    if is_from_proc_macro(cx, item) {
+        return;
+    }
+
+    span_lint_and_then(
+        cx,
+        TOO_LONG_FIRST_DOC_PARAGRAPH,
+        first_span.with_hi(last_span.lo()),
+        "first doc comment paragraph is too long",
+        |diag| {
+            if should_suggest_empty_doc
+                && let Some(second_span) = spans.get(1)
+                && let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi())
+                && let Some(snippet) = snippet_opt(cx, new_span)
+            {
+                diag.span_suggestion(
+                    new_span,
+                    "add an empty line",
+                    format!("{snippet}///\n"),
+                    Applicability::MachineApplicable,
+                );
+            }
+        },
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
index 02f9c2c3648..5315f55ba38 100644
--- a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
+++ b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
@@ -1,5 +1,3 @@
-//! Lint on if expressions with an else if, but without a final else branch.
-
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs
index 1869faab1d3..f4c55738cb8 100644
--- a/src/tools/clippy/clippy_lints/src/empty_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs
@@ -1,5 +1,3 @@
-//! lint when there is an enum with no variants
-
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index e54cd248ead..4755cefe784 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -1,6 +1,3 @@
-//! lint on C-like enums that are `repr(isize/usize)` and have values that
-//! don't fit into an `i32`
-
 use clippy_utils::consts::{mir_to_const, Constant};
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::{Item, ItemKind};
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index a7e831fdc42..cabc6592258 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::higher::VecArgs;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::type_diagnostic_name;
+use clippy_utils::ty::get_type_diagnostic_name;
 use clippy_utils::usage::{local_used_after_expr, local_used_in};
 use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id};
 use rustc_errors::Applicability;
@@ -139,7 +139,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
         {
             let callee_ty_raw = typeck.expr_ty(callee);
             let callee_ty = callee_ty_raw.peel_refs();
-            if matches!(type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc))
+            if matches!(get_type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc))
                 || !check_inputs(typeck, body.params, None, args)
             {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs
index f095c1add91..012ad8e1a22 100644
--- a/src/tools/clippy/clippy_lints/src/float_literal.rs
+++ b/src/tools/clippy/clippy_lints/src/float_literal.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::numeric_literal;
 use rustc_ast::ast::{self, LitFloatType, LitKind};
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, FloatTy};
@@ -117,12 +117,11 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
                             if type_suffix.is_none() {
                                 float_str.push_str(".0");
                             }
-                            diag.span_suggestion_with_style(
+                            diag.span_suggestion_verbose(
                                 expr.span,
                                 "consider changing the type or replacing it with",
                                 numeric_literal::format(&float_str, type_suffix, true),
                                 Applicability::MachineApplicable,
-                                SuggestionStyle::ShowAlways,
                             );
                         },
                     );
@@ -134,12 +133,11 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
                     expr.span,
                     "float has excessive precision",
                     |diag| {
-                        diag.span_suggestion_with_style(
+                        diag.span_suggestion_verbose(
                             expr.span,
                             "consider changing the type or truncating it to",
                             numeric_literal::format(&float_str, type_suffix, true),
                             Applicability::MachineApplicable,
-                            SuggestionStyle::ShowAlways,
                         );
                     },
                 );
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index 0b248f784b7..4dedff69b9a 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::{find_format_arg_expr, root_macro_call_first_node, FormatArgsStorage};
-use clippy_utils::source::{snippet_opt, snippet_with_context};
+use clippy_utils::source::{snippet_with_context, SpanRangeExt};
 use clippy_utils::sugg::Sugg;
 use rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};
 use rustc_errors::Applicability;
@@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
                 ([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
                 ([], [_]) => {
                     // Simulate macro expansion, converting {{ and }} to { and }.
-                    let Some(snippet) = snippet_opt(cx, format_args.span) else {
+                    let Some(snippet) = format_args.span.get_source_text(cx) else {
                         return;
                     };
                     let s_expand = snippet.replace("{{", "{").replace("}}", "}");
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
                     span_useless_format(cx, call_site, sugg, applicability);
                 },
                 ([arg], [piece]) => {
-                    if let Ok(value) = find_format_arg_expr(expr, arg)
+                    if let Some(value) = find_format_arg_expr(expr, arg)
                         && let FormatArgsPiece::Placeholder(placeholder) = piece
                         && placeholder.format_trait == FormatTrait::Display
                         && placeholder.format_options == FormatOptions::default()
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index a31d5cb6ec7..020c0c5440d 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -7,7 +7,7 @@ use clippy_utils::macros::{
     find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro,
     is_panic, matching_root_macro_call, root_macro_call_first_node, FormatArgsStorage, FormatParamUsage, MacroCall,
 };
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
 use itertools::Itertools;
 use rustc_ast::{
@@ -224,13 +224,11 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
             if let FormatArgsPiece::Placeholder(placeholder) = piece
                 && let Ok(index) = placeholder.argument.index
                 && let Some(arg) = self.format_args.arguments.all_args().get(index)
+                && let Some(arg_expr) = find_format_arg_expr(self.expr, arg)
             {
-                let arg_expr = find_format_arg_expr(self.expr, arg);
-
                 self.check_unused_format_specifier(placeholder, arg_expr);
 
-                if let Ok(arg_expr) = arg_expr
-                    && placeholder.format_trait == FormatTrait::Display
+                if placeholder.format_trait == FormatTrait::Display
                     && placeholder.format_options == FormatOptions::default()
                     && !self.is_aliased(index)
                 {
@@ -242,28 +240,13 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
         }
     }
 
-    fn check_unused_format_specifier(
-        &self,
-        placeholder: &FormatPlaceholder,
-        arg_expr: Result<&Expr<'_>, &rustc_ast::Expr>,
-    ) {
-        let ty_or_ast_expr = arg_expr.map(|expr| self.cx.typeck_results().expr_ty(expr).peel_refs());
-
-        let is_format_args = match ty_or_ast_expr {
-            Ok(ty) => is_type_lang_item(self.cx, ty, LangItem::FormatArguments),
-            Err(expr) => matches!(expr.peel_parens_and_refs().kind, rustc_ast::ExprKind::FormatArgs(_)),
-        };
-
+    fn check_unused_format_specifier(&self, placeholder: &FormatPlaceholder, arg: &Expr<'_>) {
         let options = &placeholder.format_options;
 
-        let arg_span = match arg_expr {
-            Ok(expr) => expr.span,
-            Err(expr) => expr.span,
-        };
-
         if let Some(placeholder_span) = placeholder.span
-            && is_format_args
             && *options != FormatOptions::default()
+            && let ty = self.cx.typeck_results().expr_ty(arg).peel_refs()
+            && is_type_lang_item(self.cx, ty, LangItem::FormatArguments)
         {
             span_lint_and_then(
                 self.cx,
@@ -274,7 +257,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
                     let mut suggest_format = |spec| {
                         let message = format!("for the {spec} to apply consider using `format!()`");
 
-                        if let Some(mac_call) = matching_root_macro_call(self.cx, arg_span, sym::format_args_macro) {
+                        if let Some(mac_call) = matching_root_macro_call(self.cx, arg.span, sym::format_args_macro) {
                             diag.span_suggestion(
                                 self.cx.sess().source_map().span_until_char(mac_call.span, '!'),
                                 message,
@@ -424,7 +407,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
                 count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter())
             && implements_trait(cx, target, display_trait_id, &[])
             && let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait()
-            && let Some(receiver_snippet) = snippet_opt(cx, receiver.span.source_callsite())
+            && let Some(receiver_snippet) = receiver.span.source_callsite().get_source_text(cx)
         {
             let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);
             if n_needed_derefs == 0 && !needs_ref {
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index e6f27cb82d1..7cd12ac7db8 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -196,7 +196,7 @@ impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
                     && trait_name == self.format_trait_impl.name
                     && let Ok(index) = placeholder.argument.index
                     && let Some(arg) = format_args.arguments.all_args().get(index)
-                    && let Ok(arg_expr) = find_format_arg_expr(self.expr, arg)
+                    && let Some(arg_expr) = find_format_arg_expr(self.expr, arg)
                 {
                     self.check_format_arg_self(arg_expr);
                 }
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 1c1d8b57bc4..b84bf7c821c 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -3,7 +3,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::span_is_local;
 use clippy_utils::path_def_id;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_path, Visitor};
 use rustc_hir::{
@@ -178,8 +178,8 @@ fn convert_to_from(
         return None;
     };
 
-    let from = snippet_opt(cx, self_ty.span)?;
-    let into = snippet_opt(cx, target_ty.span)?;
+    let from = self_ty.span.get_source_text(cx)?;
+    let into = target_ty.span.get_source_text(cx)?;
 
     let mut suggestions = vec![
         // impl Into<T> for U  ->  impl From<T> for U
@@ -187,10 +187,10 @@ fn convert_to_from(
         (into_trait_seg.ident.span, String::from("From")),
         // impl Into<T> for U  ->  impl Into<U> for U
         //           ~                       ~
-        (target_ty.span, from.clone()),
+        (target_ty.span, from.to_owned()),
         // impl Into<T> for U  ->  impl Into<T> for T
         //                  ~                       ~
-        (self_ty.span, into),
+        (self_ty.span, into.to_owned()),
         // fn into(self) -> T  ->  fn from(self) -> T
         //    ~~~~                    ~~~~
         (impl_item.ident.span, String::from("from")),
@@ -223,7 +223,7 @@ fn convert_to_from(
     }
 
     for span in finder.upper {
-        suggestions.push((span, from.clone()));
+        suggestions.push((span, from.to_owned()));
     }
     for span in finder.lower {
         suggestions.push((span, String::from("val")));
diff --git a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
index 6ab7bbc2dfc..e5fa67d6964 100644
--- a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
+++ b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
@@ -22,8 +22,8 @@ declare_clippy_lint! {
     ///
     /// ### Known problems
     ///
-    /// This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly
-    /// in some cases, which is correct but adds unnecessary complexity to the code.
+    /// This lint may suggest using `(&<expression>).parse()` instead of `<expression>.parse()`
+    /// directly in some cases, which is correct but adds unnecessary complexity to the code.
     ///
     /// ### Example
     /// ```ignore
diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
index cf85c74e688..05e341e06fd 100644
--- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_test;
 
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind};
@@ -18,20 +19,18 @@ fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_
         |diag| {
             if let Some(gen_span) = generics.span_for_param_suggestion() {
                 // If there's already a generic param with the same bound, do not lint **this** suggestion.
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     gen_span,
                     "add a type parameter",
                     format!(", {{ /* Generic name */ }}: {}", &param.name.ident().as_str()[5..]),
-                    rustc_errors::Applicability::HasPlaceholders,
-                    rustc_errors::SuggestionStyle::ShowAlways,
+                    Applicability::HasPlaceholders,
                 );
             } else {
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     generics.span,
                     "add a type parameter",
                     format!("<{{ /* Generic name */ }}: {}>", &param.name.ident().as_str()[5..]),
-                    rustc_errors::Applicability::HasPlaceholders,
-                    rustc_errors::SuggestionStyle::ShowAlways,
+                    Applicability::HasPlaceholders,
                 );
             }
         },
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index b179d7b5249..93828121047 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -8,11 +8,11 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{sym, Span};
 
 use clippy_utils::attrs::is_proc_macro;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_must_use_ty;
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{return_ty, trait_ref_of_method};
@@ -129,9 +129,9 @@ fn check_needless_must_use(
             cx,
             DOUBLE_MUST_USE,
             fn_header_span,
-            "this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`",
+            "this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`",
             None,
-            "either add some descriptive text or remove the attribute",
+            "either add some descriptive message or remove the attribute",
         );
     }
 }
@@ -155,7 +155,7 @@ fn check_must_use_candidate<'tcx>(
         return;
     }
     span_lint_and_then(cx, MUST_USE_CANDIDATE, fn_span, msg, |diag| {
-        if let Some(snippet) = snippet_opt(cx, fn_span) {
+        if let Some(snippet) = fn_span.get_source_text(cx) {
             diag.span_suggestion(
                 fn_span,
                 "add the attribute",
@@ -193,17 +193,13 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
     }
 }
 
-static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc];
-
 fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {
     match *ty.kind() {
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
         ty::Adt(adt, args) => {
             tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env)
-                || KNOWN_WRAPPER_TYS
-                    .iter()
-                    .any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
+                || matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::Rc | sym::Arc))
                     && args.types().any(|ty| is_mutable_ty(cx, ty, tys))
         },
         ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
index 586ca58d60d..0f5ce340c44 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
@@ -1,12 +1,11 @@
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::source::SpanRangeExt;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_span::Span;
 
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::source::snippet_opt;
-
 use super::TOO_MANY_LINES;
 
 pub(super) fn check_fn(
@@ -22,57 +21,57 @@ pub(super) fn check_fn(
         return;
     }
 
-    let Some(code_snippet) = snippet_opt(cx, body.value.span) else {
-        return;
-    };
     let mut line_count: u64 = 0;
-    let mut in_comment = false;
-    let mut code_in_line;
+    let too_many = body.value.span.check_source_text(cx, |src| {
+        let mut in_comment = false;
+        let mut code_in_line;
 
-    let function_lines = if matches!(body.value.kind, hir::ExprKind::Block(..))
-        && code_snippet.as_bytes().first().copied() == Some(b'{')
-        && code_snippet.as_bytes().last().copied() == Some(b'}')
-    {
-        // Removing the braces from the enclosing block
-        &code_snippet[1..code_snippet.len() - 1]
-    } else {
-        &code_snippet
-    }
-    .trim() // Remove leading and trailing blank lines
-    .lines();
+        let function_lines = if matches!(body.value.kind, hir::ExprKind::Block(..))
+            && src.as_bytes().first().copied() == Some(b'{')
+            && src.as_bytes().last().copied() == Some(b'}')
+        {
+            // Removing the braces from the enclosing block
+            &src[1..src.len() - 1]
+        } else {
+            src
+        }
+        .trim() // Remove leading and trailing blank lines
+        .lines();
 
-    for mut line in function_lines {
-        code_in_line = false;
-        loop {
-            line = line.trim_start();
-            if line.is_empty() {
-                break;
-            }
-            if in_comment {
-                if let Some(i) = line.find("*/") {
-                    line = &line[i + 2..];
-                    in_comment = false;
-                    continue;
+        for mut line in function_lines {
+            code_in_line = false;
+            loop {
+                line = line.trim_start();
+                if line.is_empty() {
+                    break;
                 }
-            } else {
-                let multi_idx = line.find("/*").unwrap_or(line.len());
-                let single_idx = line.find("//").unwrap_or(line.len());
-                code_in_line |= multi_idx > 0 && single_idx > 0;
-                // Implies multi_idx is below line.len()
-                if multi_idx < single_idx {
-                    line = &line[multi_idx + 2..];
-                    in_comment = true;
-                    continue;
+                if in_comment {
+                    if let Some(i) = line.find("*/") {
+                        line = &line[i + 2..];
+                        in_comment = false;
+                        continue;
+                    }
+                } else {
+                    let multi_idx = line.find("/*").unwrap_or(line.len());
+                    let single_idx = line.find("//").unwrap_or(line.len());
+                    code_in_line |= multi_idx > 0 && single_idx > 0;
+                    // Implies multi_idx is below line.len()
+                    if multi_idx < single_idx {
+                        line = &line[multi_idx + 2..];
+                        in_comment = true;
+                        continue;
+                    }
                 }
+                break;
+            }
+            if code_in_line {
+                line_count += 1;
             }
-            break;
-        }
-        if code_in_line {
-            line_count += 1;
         }
-    }
+        line_count > too_many_lines_threshold
+    });
 
-    if line_count > too_many_lines_threshold {
+    if too_many {
         span_lint(
             cx,
             TOO_MANY_LINES,
diff --git a/src/tools/clippy/clippy_lints/src/if_not_else.rs b/src/tools/clippy/clippy_lints/src/if_not_else.rs
index 0ebd8d0c237..120c5396a1c 100644
--- a/src/tools/clippy/clippy_lints/src/if_not_else.rs
+++ b/src/tools/clippy/clippy_lints/src/if_not_else.rs
@@ -1,6 +1,3 @@
-//! lint on if branches that could be swapped so no `!` operation is necessary
-//! on the condition
-
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_else_clause;
diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs
index b926e1e62ba..ba06567b957 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_return.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::{snippet_with_applicability, snippet_with_context, wal
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{get_async_fn_body, is_async_fn, is_from_proc_macro};
 use core::ops::ControlFlow;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -54,13 +54,7 @@ fn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {
         |diag| {
             let mut app = Applicability::MachineApplicable;
             let snip = snippet_with_applicability(cx, span, "..", &mut app);
-            diag.span_suggestion_with_style(
-                span,
-                "add `return` as shown",
-                format!("return {snip}"),
-                app,
-                SuggestionStyle::ShowAlways,
-            );
+            diag.span_suggestion_verbose(span, "add `return` as shown", format!("return {snip}"), app);
         },
     );
 }
@@ -75,12 +69,11 @@ fn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, exp
         |diag| {
             let mut app = Applicability::MachineApplicable;
             let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0;
-            diag.span_suggestion_with_style(
+            diag.span_suggestion_verbose(
                 break_span,
                 "change `break` to `return` as shown",
                 format!("return {snip}"),
                 app,
-                SuggestionStyle::ShowAlways,
             );
         },
     );
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 0ef5b803a89..2ad045e1268 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -7,8 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{Expr, ExprKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
-use rustc_semver::RustcVersion;
-use rustc_session::impl_lint_pass;
+use rustc_session::{impl_lint_pass, RustcVersion};
 use rustc_span::def_id::DefId;
 use rustc_span::{ExpnKind, Span};
 
@@ -65,18 +64,18 @@ impl IncompatibleMsrv {
                 StabilityLevel::Stable {
                     since: StableSince::Version(version),
                     ..
-                } => Some(RustcVersion::new(
-                    version.major.into(),
-                    version.minor.into(),
-                    version.patch.into(),
-                )),
+                } => Some(version),
                 _ => None,
             }) {
             version
         } else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
             self.get_def_id_version(tcx, parent_def_id)
         } else {
-            RustcVersion::new(1, 0, 0)
+            RustcVersion {
+                major: 1,
+                minor: 0,
+                patch: 0,
+            }
         };
         self.is_above_msrv.insert(def_id, version);
         version
diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
index 5b0aadf35c6..d386bfca6ba 100644
--- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
+++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::fulfill_or_allowed;
 use clippy_utils::source::snippet;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
@@ -71,6 +72,8 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
             && let ty = cx.typeck_results().expr_ty(expr)
             && let Some(adt_def) = ty.ty_adt_def()
             && adt_def.is_struct()
+            && let Some(local_def_id) = adt_def.did().as_local()
+            && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id)
             && let Some(variant) = adt_def.variants().iter().next()
         {
             let mut def_order_map = FxHashMap::default();
@@ -103,15 +106,17 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
                 snippet(cx, qpath.span(), ".."),
             );
 
-            span_lint_and_sugg(
-                cx,
-                INCONSISTENT_STRUCT_CONSTRUCTOR,
-                expr.span,
-                "struct constructor field order is inconsistent with struct definition field order",
-                "try",
-                sugg,
-                Applicability::MachineApplicable,
-            );
+            if !fulfill_or_allowed(cx, INCONSISTENT_STRUCT_CONSTRUCTOR, Some(ty_hir_id)) {
+                span_lint_and_sugg(
+                    cx,
+                    INCONSISTENT_STRUCT_CONSTRUCTOR,
+                    expr.span,
+                    "struct constructor field order is inconsistent with struct definition field order",
+                    "try",
+                    sugg,
+                    Applicability::MachineApplicable,
+                );
+            }
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
index 3ac50b8f1fb..22e9674714f 100644
--- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
@@ -1,5 +1,3 @@
-//! lint on indexing and slicing operations
-
 use clippy_config::Conf;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
index 676d50c4951..71c317552ee 100644
--- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::higher;
-use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
 use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -210,18 +210,6 @@ const COMPLETING_METHODS: [(&str, usize); 12] = [
     ("product", 0),
 ];
 
-/// the paths of types that are known to be infinitely allocating
-const INFINITE_COLLECTORS: &[Symbol] = &[
-    sym::BinaryHeap,
-    sym::BTreeMap,
-    sym::BTreeSet,
-    sym::HashMap,
-    sym::HashSet,
-    sym::LinkedList,
-    sym::Vec,
-    sym::VecDeque,
-];
-
 fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
     match expr.kind {
         ExprKind::MethodCall(method, receiver, args, _) => {
@@ -248,10 +236,19 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                 }
             } else if method.ident.name == sym!(collect) {
                 let ty = cx.typeck_results().expr_ty(expr);
-                if INFINITE_COLLECTORS
-                    .iter()
-                    .any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item))
-                {
+                if matches!(
+                    get_type_diagnostic_name(cx, ty),
+                    Some(
+                        sym::BinaryHeap
+                            | sym::BTreeMap
+                            | sym::BTreeSet
+                            | sym::HashMap
+                            | sym::HashSet
+                            | sym::LinkedList
+                            | sym::Vec
+                            | sym::VecDeque,
+                    )
+                ) {
                     return is_infinite(cx, receiver);
                 }
             }
diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
index 9eed7aa9243..d39f910f993 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
@@ -1,5 +1,3 @@
-//! lint on inherent implementations
-
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_lint_allowed;
 use rustc_data_structures::fx::FxHashMap;
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index 5657c58bb0a..1b900f6be8e 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -1,5 +1,3 @@
-//! checks for `#[inline]` on trait methods without bodies
-
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sugg::DiagExt;
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/int_plus_one.rs b/src/tools/clippy/clippy_lints/src/int_plus_one.rs
index b8e0eef7c7e..fc575bff7e6 100644
--- a/src/tools/clippy/clippy_lints/src/int_plus_one.rs
+++ b/src/tools/clippy/clippy_lints/src/int_plus_one.rs
@@ -1,7 +1,5 @@
-//! lint on blocks unnecessarily using >= with a + 1 or - 1
-
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};
 use rustc_ast::token;
 use rustc_errors::Applicability;
@@ -132,8 +130,8 @@ impl IntPlusOne {
             BinOpKind::Le => "<",
             _ => return None,
         };
-        if let Some(snippet) = snippet_opt(cx, node.span) {
-            if let Some(other_side_snippet) = snippet_opt(cx, other_side.span) {
+        if let Some(snippet) = node.span.get_source_text(cx) {
+            if let Some(other_side_snippet) = other_side.span.get_source_text(cx) {
                 let rec = match side {
                     Side::Lhs => Some(format!("{snippet} {binop_string} {other_side_snippet}")),
                     Side::Rhs => Some(format!("{other_side_snippet} {binop_string} {snippet}")),
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index 4d44bae02b8..74bf82f58bd 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -1,5 +1,3 @@
-//! lint on enum variants that are prefixed or suffixed by the same characters
-
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
 use clippy_utils::is_bool;
diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
index a88d8e24fda..4f066113aea 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
@@ -1,5 +1,3 @@
-//! lint when items are used after statements
-
 use clippy_utils::diagnostics::span_lint_hir;
 use rustc_hir::{Block, ItemKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
index 3614fb8cc96..8caa484bb99 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{fulfill_or_allowed, is_cfg_test, is_from_proc_macro};
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::{HirId, Item, ItemKind, Mod};
@@ -93,11 +93,14 @@ impl LateLintPass<'_> for ItemsAfterTestModule {
                     if let Some(prev) = mod_pos.checked_sub(1)
                         && let prev = cx.tcx.hir().item(module.item_ids[prev])
                         && let items_span = last.span.with_lo(test_mod.span.hi())
-                        && let Some(items) = snippet_opt(cx, items_span)
+                        && let Some(items) = items_span.get_source_text(cx)
                     {
                         diag.multipart_suggestion_with_style(
                             "move the items to before the test module was defined",
-                            vec![(prev.span.shrink_to_hi(), items), (items_span, String::new())],
+                            vec![
+                                (prev.span.shrink_to_hi(), items.to_owned()),
+                                (items_span, String::new()),
+                            ],
                             Applicability::MachineApplicable,
                             SuggestionStyle::HideCodeAlways,
                         );
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 225d79aa71d..2f027c11707 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -1,5 +1,3 @@
-//! lint when there is a large size difference between variants on an enum
-
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
index 4abf7edc9b4..d2bdf194ada 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
@@ -3,7 +3,7 @@ use std::{fmt, ops};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::fn_has_unsatisfiable_preds;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl};
@@ -186,7 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames {
                         // TODO: Is there a cleaner, robust way to ask this question?
                         // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data",
                         // and that doesn't get us the true name in scope rather than the span text either.
-                        if let Some(name) = snippet_opt(cx, local_span)
+                        if let Some(name) = local_span.get_source_text(cx)
                             && is_ident(&name)
                         {
                             // If the local is an ordinary named variable,
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
index 752e1326e3e..ccab1e27d3b 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -3,7 +3,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::{get_parent_expr, is_from_proc_macro};
 use hir::def_id::DefId;
-use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -143,12 +143,11 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
             && !is_from_proc_macro(cx, expr)
         {
             span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
-                diag.span_suggestion_with_style(
+                diag.span_suggestion_verbose(
                     span,
                     "use the associated constant instead",
                     sugg,
                     Applicability::MaybeIncorrect,
-                    SuggestionStyle::ShowAlways,
                 );
             });
         }
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 4c737371bd2..0bc7fc2dd9d 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet_opt, snippet_with_context};
+use clippy_utils::source::{snippet_with_context, SpanRangeExt};
 use clippy_utils::sugg::{has_enclosing_paren, Sugg};
 use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
 use rustc_ast::ast::LitKind;
@@ -216,7 +216,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
 }
 
 fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
-    let Some(snippet) = snippet_opt(cx, span) else {
+    let Some(snippet) = span.get_source_text(cx) else {
         return span;
     };
     if has_enclosing_paren(snippet) {
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index ce13a9afef5..2ac06b360be 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -66,8 +66,8 @@ extern crate declare_clippy_lint;
 #[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
 mod utils;
 
-mod declared_lints;
-mod deprecated_lints;
+pub mod declared_lints;
+pub mod deprecated_lints;
 
 // begin lints modules, do not remove this comment, it’s used in `update_lints`
 mod absolute_paths;
@@ -440,7 +440,7 @@ impl RegistrationGroups {
     }
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub(crate) enum LintCategory {
     Cargo,
     Complexity,
@@ -479,11 +479,39 @@ impl LintCategory {
     }
 }
 
-pub(crate) struct LintInfo {
+pub struct LintInfo {
     /// Double reference to maintain pointer equality
-    lint: &'static &'static Lint,
+    pub lint: &'static &'static Lint,
     category: LintCategory,
-    explanation: &'static str,
+    pub explanation: &'static str,
+    /// e.g. `clippy_lints/src/absolute_paths.rs#43`
+    pub location: &'static str,
+    pub version: Option<&'static str>,
+}
+
+impl LintInfo {
+    /// Returns the lint name in lowercase without the `clippy::` prefix
+    #[allow(clippy::missing_panics_doc)]
+    pub fn name_lower(&self) -> String {
+        self.lint.name.strip_prefix("clippy::").unwrap().to_ascii_lowercase()
+    }
+
+    /// Returns the name of the lint's category in lowercase (`style`, `pedantic`)
+    pub fn category_str(&self) -> &'static str {
+        match self.category {
+            Cargo => "cargo",
+            Complexity => "complexity",
+            Correctness => "correctness",
+            Nursery => "nursery",
+            Pedantic => "pedantic",
+            Perf => "perf",
+            Restriction => "restriction",
+            Style => "style",
+            Suspicious => "suspicious",
+            #[cfg(feature = "internal")]
+            Internal => "internal",
+        }
+    }
 }
 
 pub fn explain(name: &str) -> i32 {
@@ -538,14 +566,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         store.register_removed(name, reason);
     }
 
-    #[cfg(feature = "internal")]
-    {
-        if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
-            store.register_late_pass(|_| Box::new(utils::internal_lints::metadata_collector::MetadataCollector::new()));
-            return;
-        }
-    }
-
     let format_args_storage = FormatArgsStorage::default();
     let format_args = format_args_storage.clone();
     store.register_early_pass(move || {
diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs
index 259e4d6c08f..81f2a03fb55 100644
--- a/src/tools/clippy/clippy_lints/src/literal_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs
@@ -1,10 +1,7 @@
-//! Lints concerned with the grouping of digits with underscores in integral or
-//! floating-point literal expressions.
-
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::numeric_literal::{NumericLiteral, Radix};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{Expr, ExprKind, LitKind};
 use rustc_ast::token;
 use rustc_errors::Applicability;
@@ -228,7 +225,7 @@ impl LiteralDigitGrouping {
     }
 
     fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
-        if let Some(src) = snippet_opt(cx, span)
+        if let Some(src) = span.get_source_text(cx)
             && let Ok(lit_kind) = LitKind::from_token_lit(lit)
             && let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
         {
@@ -442,7 +439,7 @@ impl DecimalLiteralRepresentation {
         // Lint integral literals.
         if let Ok(lit_kind) = LitKind::from_token_lit(lit)
             && let LitKind::Int(val, _) = lit_kind
-            && let Some(src) = snippet_opt(cx, span)
+            && let Some(src) = span.get_source_text(cx)
             && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
             && num_lit.radix == Radix::Decimal
             && val >= u128::from(self.threshold)
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index eea5f2a94ea..b134af500f5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -3,7 +3,7 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{
-    implements_trait, implements_trait_with_env, is_copy, make_normalized_projection,
+    implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection,
     make_normalized_projection_with_regions, normalize_with_regions,
 };
 use rustc_errors::Applicability;
@@ -20,9 +20,10 @@ pub(super) fn check(
     msrv: &Msrv,
     enforce_iter_loop_reborrow: bool,
 ) {
-    let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr, enforce_iter_loop_reborrow) else {
+    let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr, enforce_iter_loop_reborrow, msrv) else {
         return;
     };
+
     if let ty::Array(_, count) = *ty.peel_refs().kind() {
         if !ty.is_ref() {
             if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) {
@@ -109,6 +110,7 @@ fn is_ref_iterable<'tcx>(
     self_arg: &Expr<'_>,
     call_expr: &Expr<'_>,
     enforce_iter_loop_reborrow: bool,
+    msrv: &Msrv,
 ) -> Option<(AdjustKind, Ty<'tcx>)> {
     let typeck = cx.typeck_results();
     if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
@@ -128,6 +130,12 @@ fn is_ref_iterable<'tcx>(
         let self_ty = typeck.expr_ty(self_arg);
         let self_is_copy = is_copy(cx, self_ty);
 
+        if !msrv.meets(msrvs::BOX_INTO_ITER)
+            && is_type_lang_item(cx, self_ty.peel_refs(), rustc_hir::LangItem::OwnedBox)
+        {
+            return None;
+        }
+
         if adjustments.is_empty() && self_is_copy {
             // Exact type match, already checked earlier
             return Some((AdjustKind::None, self_ty));
diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
index fed58f7ff14..e215097142b 100644
--- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -122,8 +122,23 @@ struct BodyVisitor<'a, 'tcx> {
     /// within a relevant macro.
     macro_unsafe_blocks: Vec<HirId>,
     /// When this is >0, it means that the node currently being visited is "within" a
-    /// macro definition. This is not necessary for correctness, it merely helps reduce the number
-    /// of spans we need to insert into the map, since only spans from macros are relevant.
+    /// macro definition.
+    /// This is used to detect if an expression represents a metavariable.
+    ///
+    /// For example, the following pre-expansion code that we want to lint
+    /// ```ignore
+    /// macro_rules! m { ($e:expr) => { unsafe { $e; } } }
+    /// m!(1);
+    /// ```
+    /// would look like this post-expansion code:
+    /// ```ignore
+    /// unsafe { /* macro */
+    ///     1 /* root */; /* macro */
+    /// }
+    /// ```
+    /// Visiting the block and the statement will increment the `expn_depth` so that it is >0,
+    /// and visiting the expression with a root context while `expn_depth > 0` tells us
+    /// that it must be a metavariable.
     expn_depth: u32,
     cx: &'a LateContext<'tcx>,
     lint: &'a mut ExprMetavarsInUnsafe,
@@ -157,7 +172,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BodyVisitor<'a, 'tcx> {
             && (self.lint.warn_unsafe_macro_metavars_in_private_macros || is_public_macro(self.cx, macro_def_id))
         {
             self.macro_unsafe_blocks.push(block.hir_id);
+            self.expn_depth += 1;
             walk_block(self, block);
+            self.expn_depth -= 1;
             self.macro_unsafe_blocks.pop();
         } else if ctxt.is_root() && self.expn_depth > 0 {
             let unsafe_block = self.macro_unsafe_blocks.last().copied();
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 25c7e5d38b3..61723aec590 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{position_before_rarrow, snippet_block, snippet_opt};
+use clippy_utils::source::{position_before_rarrow, snippet_block, SpanRangeExt};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
@@ -68,8 +68,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                 header_span,
                 "this function can be simplified using the `async fn` syntax",
                 |diag| {
-                    if let Some(vis_snip) = snippet_opt(cx, *vis_span)
-                        && let Some(header_snip) = snippet_opt(cx, header_span)
+                    if let Some(vis_snip) = vis_span.get_source_text(cx)
+                        && let Some(header_snip) = header_span.get_source_text(cx)
                         && let Some(ret_pos) = position_before_rarrow(&header_snip)
                         && let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output)
                     {
@@ -190,6 +190,6 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
         Some((sugg, String::new()))
     } else {
         let sugg = "return the output of the future directly";
-        snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {snip}")))
+        output.span.get_source_text(cx).map(|src| (sugg, format!(" -> {src}")))
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index 6bdc79129a9..9d3ddab60bb 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -1,6 +1,6 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, path_to_local};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
             // case somebody does that for some reason
             && (is_infinity(&const_1) && is_neg_infinity(&const_2)
                 || is_neg_infinity(&const_1) && is_infinity(&const_2))
-            && let Some(local_snippet) = snippet_opt(cx, first.span)
+            && let Some(local_snippet) = first.span.get_source_text(cx)
         {
             let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
                 (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite,
diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
index 1c568b1b74f..11716a539ab 100644
--- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -1,7 +1,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::visitors::{is_local_used, local_used_once};
 use clippy_utils::{is_trait_method, path_to_local_id};
 use rustc_errors::Applicability;
@@ -107,8 +107,8 @@ impl LateLintPass<'_> for ManualHashOne {
                 finish_expr.span,
                 "manual implementation of `BuildHasher::hash_one`",
                 |diag| {
-                    if let Some(build_hasher) = snippet_opt(cx, build_hasher.span)
-                        && let Some(hashed_value) = snippet_opt(cx, hashed_value.span)
+                    if let Some(build_hasher) = build_hasher.span.get_source_text(cx)
+                        && let Some(hashed_value) = hashed_value.span.get_source_text(cx)
                     {
                         diag.multipart_suggestion(
                             "try",
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 28cfe22835a..6b1d90483cc 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -2,7 +2,7 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::is_doc_hidden;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{self, VisibilityKind};
 use rustc_ast::attr;
 use rustc_data_structures::fx::FxHashSet;
@@ -124,7 +124,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
                     |diag| {
                         if !item.attrs.iter().any(|attr| attr.has_name(sym::non_exhaustive))
                             && let header_span = cx.sess().source_map().span_until_char(item.span, delimiter)
-                            && let Some(snippet) = snippet_opt(cx, header_span)
+                            && let Some(snippet) = header_span.get_source_text(cx)
                         {
                             diag.span_suggestion(
                                 header_span,
@@ -194,7 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
                 "this seems like a manual implementation of the non-exhaustive pattern",
                 |diag| {
                     let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
-                    if let Some(snippet) = snippet_opt(cx, header_span) {
+                    if let Some(snippet) = header_span.get_source_text(cx) {
                         diag.span_suggestion(
                             header_span,
                             "add the attribute",
diff --git a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
index 07d4abbf5cd..9afb2b5bc84 100644
--- a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -143,8 +143,8 @@ impl LateLintPass<'_> for ManualRangePatterns {
                 pat.span,
                 "this OR pattern can be rewritten using a range",
                 |diag| {
-                    if let Some(min) = snippet_opt(cx, min.span)
-                        && let Some(max) = snippet_opt(cx, max.span)
+                    if let Some(min) = min.span.get_source_text(cx)
+                        && let Some(max) = max.span.get_source_text(cx)
                     {
                         diag.span_suggestion(
                             pat.span,
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 09f6362b4dd..d4e53f8f74b 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -2,14 +2,13 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
+use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
 use clippy_utils::{match_def_path, paths, SpanlessEq};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::ExprKind::Assign;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
@@ -21,16 +20,6 @@ const ACCEPTABLE_METHODS: [&[&str]; 5] = [
     &paths::SLICE_INTO,
     &paths::VEC_DEQUE_ITER,
 ];
-const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
-    (sym::BinaryHeap, Some(msrvs::BINARY_HEAP_RETAIN)),
-    (sym::BTreeSet, Some(msrvs::BTREE_SET_RETAIN)),
-    (sym::BTreeMap, Some(msrvs::BTREE_MAP_RETAIN)),
-    (sym::HashSet, Some(msrvs::HASH_SET_RETAIN)),
-    (sym::HashMap, Some(msrvs::HASH_MAP_RETAIN)),
-    (sym::Vec, None),
-    (sym::VecDeque, None),
-];
-const MAP_TYPES: [rustc_span::Symbol; 2] = [sym::BTreeMap, sym::HashMap];
 
 declare_clippy_lint! {
     /// ### What it does
@@ -265,16 +254,22 @@ fn match_acceptable_def_path(cx: &LateContext<'_>, collect_def_id: DefId) -> boo
 }
 
 fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool {
-    let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
-    ACCEPTABLE_TYPES.iter().any(|(ty, acceptable_msrv)| {
-        is_type_diagnostic_item(cx, expr_ty, *ty)
-            && acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
-    })
+    let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+    let required = match get_type_diagnostic_name(cx, ty) {
+        Some(sym::BinaryHeap) => msrvs::BINARY_HEAP_RETAIN,
+        Some(sym::BTreeSet) => msrvs::BTREE_SET_RETAIN,
+        Some(sym::BTreeMap) => msrvs::BTREE_MAP_RETAIN,
+        Some(sym::HashSet) => msrvs::HASH_SET_RETAIN,
+        Some(sym::HashMap) => msrvs::HASH_MAP_RETAIN,
+        Some(sym::Vec | sym::VecDeque) => return true,
+        _ => return false,
+    };
+    msrv.meets(required)
 }
 
 fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
-    let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
-    MAP_TYPES.iter().any(|ty| is_type_diagnostic_item(cx, expr_ty, *ty))
+    let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+    matches!(get_type_diagnostic_name(cx, ty), Some(sym::BTreeMap | sym::HashMap))
 }
 
 fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {
diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
index 90cfdecc199..b666e77c09e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -96,7 +96,7 @@ fn check_arm<'tcx>(
         // collapsing patterns need an explicit field name in struct pattern matching
         // ex: Struct {x: Some(1)}
         let replace_msg = if is_innermost_parent_pat_struct {
-            format!(", prefixed by {}:", snippet(cx, binding_span, "their field name"))
+            format!(", prefixed by `{}`:", snippet(cx, binding_span, "their field name"))
         } else {
             String::new()
         };
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
index 2d4c8daf5cb..d5d83df9347 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
@@ -1,6 +1,6 @@
 use clippy_utils::consts::ConstEvalCtxt;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
+use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::contains_return_break_continue_macro;
 use clippy_utils::{is_res_lang_ctor, path_to_local_id, peel_blocks, sugg};
@@ -67,11 +67,11 @@ fn check_and_lint<'tcx>(
         && path_to_local_id(peel_blocks(then_expr), binding_hir_id)
         && cx.typeck_results().expr_adjustments(then_expr).is_empty()
         && let Some(ty_name) = find_type_name(cx, ty)
-        && let Some(or_body_snippet) = snippet_opt(cx, else_expr.span)
+        && let Some(or_body_snippet) = else_expr.span.get_source_text(cx)
         && let Some(indent) = indent_of(cx, expr.span)
         && ConstEvalCtxt::new(cx).eval_simple(else_expr).is_some()
     {
-        lint(cx, expr, let_expr, ty_name, or_body_snippet, indent);
+        lint(cx, expr, let_expr, ty_name, &or_body_snippet, indent);
     }
 }
 
@@ -110,7 +110,7 @@ fn lint<'tcx>(
     expr: &Expr<'tcx>,
     scrutinee: &'tcx Expr<'_>,
     ty_name: &str,
-    or_body_snippet: String,
+    or_body_snippet: &str,
     indent: usize,
 ) {
     let reindented_or_body = reindent_multiline(or_body_snippet.into(), true, Some(indent));
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 24dea03601c..b6930f7b9d1 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -22,7 +22,7 @@ use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
 /// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
 /// match arms.
 fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
-    if let Some(ff) = span.get_source_text(cx)
+    if let Some(ff) = span.get_source_range(cx)
         && let Some(text) = ff.as_str()
     {
         text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*")
diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
index a5df863d800..740cce0a6c2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
+use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
 use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -49,10 +49,12 @@ pub(super) fn check<'tcx>(
             "case-sensitive file extension comparison",
             |diag| {
                 diag.help("consider using a case-insensitive comparison instead");
-                if let Some(mut recv_source) = snippet_opt(cx, recv.span) {
-                    if !cx.typeck_results().expr_ty(recv).is_ref() {
-                        recv_source = format!("&{recv_source}");
-                    }
+                if let Some(recv_source) = recv.span.get_source_text(cx) {
+                    let recv_source = if cx.typeck_results().expr_ty(recv).is_ref() {
+                        recv_source.to_owned()
+                    } else {
+                        format!("&{recv_source}")
+                    };
 
                     let suggestion_source = reindent_multiline(
                         format!(
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index 2e43d19a699..4fbf661727d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -1,7 +1,7 @@
 use super::FILTER_MAP_BOOL_THEN;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::paths::BOOL_THEN;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_copy;
 use clippy_utils::{is_from_proc_macro, is_trait_method, match_def_path, peel_blocks};
 use rustc_errors::Applicability;
@@ -42,9 +42,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
             .iter()
             .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
             .count()
-        && let Some(param_snippet) = snippet_opt(cx, param.span)
-        && let Some(filter) = snippet_opt(cx, recv.span)
-        && let Some(map) = snippet_opt(cx, then_body.span)
+        && let Some(param_snippet) = param.span.get_source_text(cx)
+        && let Some(filter) = recv.span.get_source_text(cx)
+        && let Some(map) = then_body.span.get_source_text(cx)
     {
         span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
index 917a8e33eb9..f4840785584 100644
--- a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{is_path_diagnostic_item, sugg};
 use rustc_errors::Applicability;
@@ -39,7 +39,7 @@ fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'_>) ->
     }
 
     let call_site = expr.span.source_callsite();
-    if let Some(snippet) = snippet_opt(cx, call_site)
+    if let Some(snippet) = call_site.get_source_text(cx)
         && let snippet_split = snippet.split("::").collect::<Vec<_>>()
         && let Some((_, elements)) = snippet_split.split_last()
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
index c6285c87a26..9daad1a8a94 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
@@ -74,7 +74,7 @@ pub(super) fn check<'tcx>(
                 "&"
             };
 
-            diag.span_suggestion_with_style(
+            diag.span_suggestion_verbose(
                 span,
                 "using `[]` is clearer and more concise",
                 format!(
@@ -82,7 +82,6 @@ pub(super) fn check<'tcx>(
                     snippet_with_applicability(cx, recv.span, "..", &mut applicability)
                 ),
                 applicability,
-                rustc_errors::SuggestionStyle::ShowAlways,
             );
         },
     );
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
index 22d896433f0..40b48ccca5d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
@@ -1,5 +1,3 @@
-//! Lint for `c.is_digit(10)`
-
 use super::IS_DIGIT_ASCII_RADIX;
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, FullInt};
diff --git a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
index aa1ec60d434..2dad7fcf3c1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::expr_or_init;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_a
             join_arg.span,
             "argument to `Path::join` starts with a path separator",
             |diag| {
-                let arg_str = snippet_opt(cx, spanned.span).unwrap_or_else(|| "..".to_string());
+                let arg_str = snippet(cx, spanned.span, "..");
 
                 let no_separator = if sym_str.starts_with('/') {
                     arg_str.replacen('/', "", 1)
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
index b1af0083e65..b1a8e1e5e47 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
+use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{is_res_lang_ctor, path_res, path_to_local_id};
 use rustc_errors::Applicability;
@@ -23,11 +23,11 @@ pub(super) fn check<'tcx>(
         && let ExprKind::Call(err_path, [err_arg]) = or_expr.kind
         && is_res_lang_ctor(cx, path_res(cx, err_path), ResultErr)
         && is_ok_wrapping(cx, map_expr)
-        && let Some(recv_snippet) = snippet_opt(cx, recv.span)
-        && let Some(err_arg_snippet) = snippet_opt(cx, err_arg.span)
+        && let Some(recv_snippet) = recv.span.get_source_text(cx)
+        && let Some(err_arg_snippet) = err_arg.span.get_source_text(cx)
         && let Some(indent) = indent_of(cx, expr.span)
     {
-        let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.into(), true, Some(indent + 4));
+        let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.as_str().into(), true, Some(indent + 4));
         span_lint_and_sugg(
             cx,
             MANUAL_OK_OR,
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
index f93edded729..11fba35c16e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
@@ -1,6 +1,6 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{is_from_proc_macro, is_trait_method};
 use rustc_errors::Applicability;
@@ -31,13 +31,15 @@ pub(super) fn check<'tcx>(
         && let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id)
         && let ExprKind::Closure(closure) = acc.kind
         && !is_from_proc_macro(cx, expr)
-        && let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| snippet_opt(cx, fn_arg_span))
+        && let Some(args_snip) = closure
+            .fn_arg_span
+            .and_then(|fn_arg_span| fn_arg_span.get_source_text(cx))
     {
         let init_snip = rest
             .is_empty()
             .then_some(first.span)
-            .and_then(|span| snippet_opt(cx, span))
-            .unwrap_or("...".to_owned());
+            .and_then(|span| span.get_source_text(cx))
+            .map_or_else(|| "...".to_owned(), |src| src.to_owned());
 
         span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 1d7b10fe8f0..d7126990edb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -2702,10 +2702,10 @@ declare_clippy_lint! {
     ///             }
     ///         })
     /// }
-    ///  ```
+    /// ```
     ///
-    ///  After:
-    ///  ```rust
+    /// After:
+    /// ```rust
     /// use std::{fmt, num::ParseIntError};
     ///
     /// #[derive(Debug)]
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
index e3d78207715..332da722a37 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
@@ -7,7 +7,7 @@ use rustc_span::Span;
 use super::utils::get_last_chain_binding_hir_id;
 use super::NEEDLESS_CHARACTER_ITERATION;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{match_def_path, path_to_local_id, peel_blocks};
 
 fn peels_expr_ref<'a, 'tcx>(mut expr: &'a Expr<'tcx>) -> &'a Expr<'tcx> {
@@ -35,7 +35,7 @@ fn handle_expr(
                 && path_to_local_id(receiver, first_param)
                 && let char_arg_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs()
                 && *char_arg_ty.kind() == ty::Char
-                && let Some(snippet) = snippet_opt(cx, before_chars)
+                && let Some(snippet) = before_chars.get_source_text(cx)
             {
                 span_lint_and_sugg(
                     cx,
@@ -79,7 +79,7 @@ fn handle_expr(
                 && let Some(fn_def_id) = cx.qpath_res(&path, fn_path.hir_id).opt_def_id()
                 && match_def_path(cx, fn_def_id, &["core", "char", "methods", "<impl char>", "is_ascii"])
                 && path_to_local_id(peels_expr_ref(arg), first_param)
-                && let Some(snippet) = snippet_opt(cx, before_chars)
+                && let Some(snippet) = before_chars.get_source_text(cx)
             {
                 span_lint_and_sugg(
                     cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 46b457daf70..f61923e5bf5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -2,7 +2,7 @@ use super::NEEDLESS_COLLECT;
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::{is_type_diagnostic_item, make_normalized_projection, make_projection};
+use clippy_utils::ty::{get_type_diagnostic_name, make_normalized_projection, make_projection};
 use clippy_utils::{
     can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local, path_to_local_id,
     CaptureKind,
@@ -88,9 +88,10 @@ pub(super) fn check<'tcx>(
         Node::LetStmt(l) => {
             if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind
                 && let ty = cx.typeck_results().expr_ty(collect_expr)
-                && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList]
-                    .into_iter()
-                    .any(|item| is_type_diagnostic_item(cx, ty, item))
+                && matches!(
+                    get_type_diagnostic_name(cx, ty),
+                    Some(sym::Vec | sym::VecDeque | sym::BinaryHeap | sym::LinkedList)
+                )
                 && let iter_ty = cx.typeck_results().expr_ty(iter_expr)
                 && let Some(block) = get_enclosing_block(cx, l.hir_id)
                 && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty))
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
index eaae8613d44..9f714fdd47b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::path_res;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::local_used_after_expr;
 use rustc_errors::Applicability;
@@ -32,7 +32,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name
             expr.span,
             "derefed type is same as origin",
             "try",
-            snippet_opt(cx, recv.span).unwrap(),
+            recv.span.get_source_text(cx).unwrap().to_owned(),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
index 5f6f027a3b5..cc0d432b799 100644
--- a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
@@ -1,6 +1,6 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local};
 use itertools::Itertools;
 use rustc_ast::LitKind;
@@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(
             _ => return,
         }
         && !is_from_proc_macro(cx, expr)
-        && let Some(scrutinee_snip) = snippet_opt(cx, scrutinee.span)
+        && let Some(scrutinee_snip) = scrutinee.span.get_source_text(cx)
     {
         // Normalize the char using `map` so `join` doesn't use `Display`, if we don't then
         // something like `r"\"` will become `'\'`, which is of course invalid
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
index f6184222d8e..64eb8411795 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_type_diagnostic_item;
 
 use rustc_errors::Applicability;
@@ -38,11 +38,11 @@ pub(super) fn check(
         return;
     };
     let both_calls_span = get_call_span.with_hi(call_span.hi());
-    if let Some(snippet) = snippet_opt(cx, both_calls_span)
-        && let Some(arg_snippet) = snippet_opt(cx, arg.span)
+    if let Some(snippet) = both_calls_span.get_source_text(cx)
+        && let Some(arg_snippet) = arg.span.get_source_text(cx)
     {
         let generics_snippet = if let Some(generics) = path.args
-            && let Some(generics_snippet) = snippet_opt(cx, generics.span_ext)
+            && let Some(generics_snippet) = generics.span_ext.get_source_text(cx)
         {
             format!("::{generics_snippet}")
         } else {
@@ -63,7 +63,7 @@ pub(super) fn check(
                 suggestion,
                 Applicability::MaybeIncorrect,
             );
-        } else if let Some(caller_snippet) = snippet_opt(cx, get_caller.span) {
+        } else if let Some(caller_snippet) = get_caller.span.get_source_text(cx) {
             let full_span = get_caller.span.with_hi(call_span.hi());
 
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 70885e46e95..4d18bc7ac77 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -1,7 +1,7 @@
 use super::utils::clone_or_copy_needed;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::ForLoop;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local};
@@ -40,7 +40,7 @@ pub fn check_for_loop_iter(
         && let Some(ForLoop { pat, body, .. }) = ForLoop::hir(grandparent)
         && let (clone_or_copy_needed, references_to_binding) = clone_or_copy_needed(cx, pat, body)
         && !clone_or_copy_needed
-        && let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
+        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
     {
         // Issue 12098
         // https://github.com/rust-lang/rust-clippy/issues/12098
@@ -100,7 +100,7 @@ pub fn check_for_loop_iter(
             && implements_trait(cx, collection_ty, into_iterator_trait_id, &[])
             && let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item")
             && iter_item_ty == into_iter_item_ty
-            && let Some(collection_snippet) = snippet_opt(cx, collection.span)
+            && let Some(collection_snippet) = collection.span.get_source_text(cx)
         {
             collection_snippet
         } else {
@@ -122,7 +122,7 @@ pub fn check_for_loop_iter(
                 } else {
                     Applicability::MachineApplicable
                 };
-                diag.span_suggestion(expr.span, "use", snippet, applicability);
+                diag.span_suggestion(expr.span, "use", snippet.to_owned(), applicability);
                 if !references_to_binding.is_empty() {
                     diag.multipart_suggestion(
                         "remove any references to the binding",
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
index 4429f032605..b84594c0da1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
@@ -64,9 +64,9 @@ pub(super) fn check<'tcx>(
                 // but prefer to avoid changing the signature of the function itself.
                 if let hir::ExprKind::MethodCall(.., span) = expr.kind {
                     span_lint_and_then(cx, UNNECESSARY_LAZY_EVALUATIONS, expr.span, msg, |diag| {
-                        diag.span_suggestion(
+                        diag.span_suggestion_verbose(
                             span,
-                            format!("use `{simplify_using}(..)` instead"),
+                            format!("use `{simplify_using}` instead"),
                             format!("{simplify_using}({})", snippet(cx, body_expr.span, "..")),
                             applicability,
                         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index fed2b128dcf..69c5bc57e29 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -2,7 +2,7 @@ use super::implicit_clone::is_clone_like;
 use super::unnecessary_iter_cloned::{self, is_into_iter};
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, SpanRangeExt};
 use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{
@@ -133,7 +133,7 @@ fn check_addr_of_expr(
         && (*referent_ty != receiver_ty
             || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty))
             || is_cow_into_owned(cx, method_name, method_def_id))
-        && let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
+        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
     {
         if receiver_ty == target_ty && n_target_refs >= n_receiver_refs {
             span_lint_and_sugg(
@@ -167,7 +167,7 @@ fn check_addr_of_expr(
                     parent.span,
                     format!("unnecessary use of `{method_name}`"),
                     "use",
-                    receiver_snippet,
+                    receiver_snippet.to_owned(),
                     Applicability::MachineApplicable,
                 );
             } else {
@@ -217,7 +217,7 @@ fn check_into_iter_call_arg(
         && let parent_ty = cx.typeck_results().expr_ty(parent)
         && implements_trait(cx, parent_ty, iterator_trait_id, &[])
         && let Some(item_ty) = get_iterator_item_ty(cx, parent_ty)
-        && let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
+        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
     {
         if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
             return true;
@@ -309,8 +309,8 @@ fn check_split_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symb
     if let Some(parent) = get_parent_expr(cx, expr)
         && let Some((fn_name, argument_expr)) = get_fn_name_and_arg(cx, parent)
         && fn_name.as_str() == "split"
-        && let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
-        && let Some(arg_snippet) = snippet_opt(cx, argument_expr.span)
+        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
+        && let Some(arg_snippet) = argument_expr.span.get_source_text(cx)
     {
         // We may end-up here because of an expression like `x.to_string().split(…)` where the type of `x`
         // implements `AsRef<str>` but does not implement `Deref<Target = str>`. In this case, we have to
@@ -405,7 +405,7 @@ fn check_other_call_arg<'tcx>(
             None
         }
         && can_change_type(cx, maybe_arg, receiver_ty)
-        && let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
+        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
     {
         span_lint_and_sugg(
             cx,
@@ -695,7 +695,7 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx
         && let arg_ty = arg_ty.peel_refs()
         // For now we limit this lint to `String` and `Vec`.
         && (is_str_and_string(cx, arg_ty, original_arg_ty) || is_slice_and_vec(cx, arg_ty, original_arg_ty))
-        && let Some(snippet) = snippet_opt(cx, caller.span)
+        && let Some(snippet) = caller.span.get_source_text(cx)
     {
         span_lint_and_sugg(
             cx,
@@ -706,7 +706,7 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx
             if original_arg_ty.is_array() {
                 format!("{snippet}.as_slice()")
             } else {
-                snippet
+                snippet.to_owned()
             },
             Applicability::MaybeIncorrect,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
index 3004d9c4233..ee5177d1ffa 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, SpanRangeExt};
 use clippy_utils::{expr_or_init, is_trait_method, pat_is_wild};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, FnDecl, PatKind, TyKind};
@@ -81,8 +81,14 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>,
         let new_closure_param = match find_elem_explicit_type_span(closure.fn_decl) {
             // We have an explicit type. Get its snippet, that of the binding name, and do `binding: ty`.
             // Fallback to `..` if we fail getting either snippet.
-            Some(ty_span) => snippet_opt(cx, elem.span)
-                .and_then(|binding_name| snippet_opt(cx, ty_span).map(|ty_name| format!("{binding_name}: {ty_name}")))
+            Some(ty_span) => elem
+                .span
+                .get_source_text(cx)
+                .and_then(|binding_name| {
+                    ty_span
+                        .get_source_text(cx)
+                        .map(|ty_name| format!("{binding_name}: {ty_name}"))
+                })
                 .unwrap_or_else(|| "..".to_string()),
             // Otherwise, we have no explicit type. We can replace with the binding name of the element.
             None => snippet(cx, elem.span, "..").into_owned(),
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index 53fa444e93c..c83e5198c27 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -41,14 +41,14 @@ declare_clippy_lint! {
 impl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS]);
 
 pub struct MinIdentChars {
-    allowed_idents_below_min_chars: &'static FxHashSet<String>,
+    allowed_idents_below_min_chars: FxHashSet<String>,
     min_ident_chars_threshold: u64,
 }
 
 impl MinIdentChars {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
-            allowed_idents_below_min_chars: &conf.allowed_idents_below_min_chars,
+            allowed_idents_below_min_chars: conf.allowed_idents_below_min_chars.iter().cloned().collect(),
             min_ident_chars_threshold: conf.min_ident_chars_threshold,
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
index 6db03adf44a..33ab94e00a5 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
+use itertools::Itertools;
 use rustc_ast::ast::{Pat, PatKind};
 use rustc_lint::EarlyContext;
 
@@ -45,19 +46,6 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
                             "you matched a field with a wildcard pattern, consider using `..` instead",
                         );
                     } else {
-                        let mut normal = vec![];
-
-                        for field in pfields {
-                            match field.pat.kind {
-                                PatKind::Wild => {},
-                                _ => {
-                                    if let Some(n) = snippet_opt(cx, field.span) {
-                                        normal.push(n);
-                                    }
-                                },
-                            }
-                        }
-
                         #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
                         span_lint_and_then(
                             cx,
@@ -65,7 +53,16 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
                             field.span,
                             "you matched a field with a wildcard pattern, consider using `..` instead",
                             |diag| {
-                                diag.help(format!("try with `{type_name} {{ {}, .. }}`", normal[..].join(", ")));
+                                diag.help(format!(
+                                    "try with `{type_name} {{ {}, .. }}`",
+                                    pfields
+                                        .iter()
+                                        .filter_map(|f| match f.pat.kind {
+                                            PatKind::Wild => None,
+                                            _ => f.span.get_source_text(cx),
+                                        })
+                                        .format(", "),
+                                ));
                             },
                         );
                     }
diff --git a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
index cdf6645b3df..59f29d242ab 100644
--- a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
 use clippy_utils::def_path_def_ids;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefIdMap;
@@ -73,7 +73,7 @@ impl LateLintPass<'_> for ImportRename {
                     && let Some(name) = self.renames.get(&id)
                     // Remove semicolon since it is not present for nested imports
                     && let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';')
-                    && let Some(snip) = snippet_opt(cx, span_without_semi)
+                    && let Some(snip) = span_without_semi.get_source_text(cx)
                     && let Some(import) = match snip.split_once(" as ") {
                         None => Some(snip.as_str()),
                         Some((import, rename)) => {
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 83af9979b9e..f52b3a6a5a1 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -125,14 +125,12 @@ impl<'tcx> MutableKeyType<'tcx> {
     // generics (because the compiler cannot ensure immutability for unknown types).
     fn check_ty_(&mut self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
         let ty = ty.peel_refs();
-        if let ty::Adt(def, args) = ty.kind() {
-            let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
-                .iter()
-                .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
-            if !is_keyed_type {
-                return;
-            }
-
+        if let ty::Adt(def, args) = ty.kind()
+            && matches!(
+                cx.tcx.get_diagnostic_name(def.did()),
+                Some(sym::HashMap | sym::BTreeMap | sym::HashSet | sym::BTreeSet)
+            )
+        {
             let subst_ty = args.type_at(0);
             if self.interior_mut.is_interior_mut_ty(cx, subst_ty) {
                 span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
index 853e476a006..38841496458 100644
--- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
+++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
@@ -1,7 +1,3 @@
-//! Checks for usage of mutex where an atomic value could be used
-//!
-//! This lint is **allow** by default
-
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 9cb4fa41c73..df155a7a412 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -1,7 +1,3 @@
-//! Checks for needless boolean results of if-else expressions
-//!
-//! This lint is **warn** by default
-
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs
index b97cb4579ca..ce97370d4d9 100644
--- a/src/tools/clippy/clippy_lints/src/needless_continue.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs
@@ -1,38 +1,3 @@
-//! Checks for continue statements in loops that are redundant.
-//!
-//! For example, the lint would catch
-//!
-//! ```rust
-//! let mut a = 1;
-//! let x = true;
-//!
-//! while a < 5 {
-//!     a = 6;
-//!     if x {
-//!         // ...
-//!     } else {
-//!         continue;
-//!     }
-//!     println!("Hello, world");
-//! }
-//! ```
-//!
-//! And suggest something like this:
-//!
-//! ```rust
-//! let mut a = 1;
-//! let x = true;
-//!
-//! while a < 5 {
-//!     a = 6;
-//!     if x {
-//!         // ...
-//!         println!("Hello, world");
-//!     }
-//! }
-//! ```
-//!
-//! This lint is **warn** by default.
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::{indent_of, snippet, snippet_block};
 use rustc_ast::ast;
diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs
index 1d6233d432a..8e14fbf2f80 100644
--- a/src/tools/clippy/clippy_lints/src/needless_if.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_if.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::higher::If;
 use clippy_utils::is_from_proc_macro;
-use clippy_utils::source::{snippet_opt, SpanRangeExt};
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -57,7 +57,7 @@ impl LateLintPass<'_> for NeedlessIf {
                 src.bytes()
                     .all(|ch| matches!(ch, b'{' | b'}') || ch.is_ascii_whitespace())
             })
-            && let Some(cond_snippet) = snippet_opt(cx, cond.span)
+            && let Some(cond_snippet) = cond.span.get_source_text(cx)
             && !is_from_proc_macro(cx, expr)
         {
             span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
index 4bfc30fa5cf..46cdb82130f 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::path_to_local;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::{SourceText, SpanRangeExt};
 use clippy_utils::ty::needs_ordered_drop;
 use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};
 use core::ops::ControlFlow;
@@ -236,7 +236,7 @@ fn first_usage<'tcx>(
         })
 }
 
-fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<String> {
+fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<SourceText> {
     let span = local.span.with_hi(match local.ty {
         // let <pat>: <ty>;
         // ~~~~~~~~~~~~~~~
@@ -246,7 +246,7 @@ fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) ->
         None => local.pat.span.hi(),
     });
 
-    snippet_opt(cx, span)
+    span.get_source_text(cx)
 }
 
 fn check<'tcx>(
@@ -275,7 +275,10 @@ fn check<'tcx>(
                 |diag| {
                     diag.multipart_suggestion(
                         format!("move the declaration `{binding_name}` here"),
-                        vec![(local_stmt.span, String::new()), (assign.lhs_span, let_snippet)],
+                        vec![
+                            (local_stmt.span, String::new()),
+                            (assign.lhs_span, let_snippet.to_owned()),
+                        ],
                         Applicability::MachineApplicable,
                     );
                 },
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index a0bbf6b14b2..addb4b1aee8 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_self;
 use clippy_utils::ptr::get_spans;
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, SpanRangeExt};
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
 };
@@ -242,8 +242,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                         for (span, suggestion) in clone_spans {
                             diag.span_suggestion(
                                 span,
-                                snippet_opt(cx, span)
-                                    .map_or("change the call to".into(), |x| format!("change `{x}` to")),
+                                span.get_source_text(cx)
+                                    .map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
                                 suggestion,
                                 Applicability::Unspecified,
                             );
@@ -267,8 +267,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                             for (span, suggestion) in clone_spans {
                                 diag.span_suggestion(
                                     span,
-                                    snippet_opt(cx, span)
-                                        .map_or("change the call to".into(), |x| format!("change `{x}` to")),
+                                    span.get_source_text(cx)
+                                        .map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
                                     suggestion,
                                     Applicability::Unspecified,
                                 );
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 8232e69db39..b181791699a 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::has_drop;
 use clippy_utils::{
     in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
@@ -268,34 +268,31 @@ fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
         && reduced.iter().all(|e| e.span.ctxt() == ctxt)
     {
         if let ExprKind::Index(..) = &expr.kind {
-            if is_inside_always_const_context(cx.tcx, expr.hir_id) {
-                return;
+            if !is_inside_always_const_context(cx.tcx, expr.hir_id)
+                && let [arr, func] = &*reduced
+                && let Some(arr) = arr.span.get_source_text(cx)
+                && let Some(func) = func.span.get_source_text(cx)
+            {
+                span_lint_hir_and_then(
+                    cx,
+                    UNNECESSARY_OPERATION,
+                    expr.hir_id,
+                    stmt.span,
+                    "unnecessary operation",
+                    |diag| {
+                        diag.span_suggestion(
+                            stmt.span,
+                            "statement can be written as",
+                            format!("assert!({arr}.len() > {func});"),
+                            Applicability::MaybeIncorrect,
+                        );
+                    },
+                );
             }
-            let snippet =
-                if let (Some(arr), Some(func)) = (snippet_opt(cx, reduced[0].span), snippet_opt(cx, reduced[1].span)) {
-                    format!("assert!({arr}.len() > {func});")
-                } else {
-                    return;
-                };
-            span_lint_hir_and_then(
-                cx,
-                UNNECESSARY_OPERATION,
-                expr.hir_id,
-                stmt.span,
-                "unnecessary operation",
-                |diag| {
-                    diag.span_suggestion(
-                        stmt.span,
-                        "statement can be written as",
-                        snippet,
-                        Applicability::MaybeIncorrect,
-                    );
-                },
-            );
         } else {
             let mut snippet = String::new();
             for e in reduced {
-                if let Some(snip) = snippet_opt(cx, e.span) {
+                if let Some(snip) = e.span.get_source_text(cx) {
                     snippet.push_str(&snip);
                     snippet.push(';');
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 6915cd40615..25f547f1a43 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -1,7 +1,3 @@
-//! Checks for usage of const which the type is not `Freeze` (`Cell`-free).
-//!
-//! This lint is **warn** by default.
-
 use std::ptr;
 
 use clippy_config::Conf;
@@ -188,7 +184,7 @@ impl_lint_pass!(NonCopyConst<'_> => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTE
 impl<'tcx> NonCopyConst<'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {
         Self {
-            interior_mut: InteriorMut::new(tcx, &conf.ignore_interior_mutability),
+            interior_mut: InteriorMut::without_pointers(tcx, &conf.ignore_interior_mutability),
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
index 2aaf1e6ff46..51ba29d7389 100644
--- a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
@@ -1,7 +1,7 @@
 use clippy_config::types::MacroMatcher;
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::{SourceText, SpanRangeExt};
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
@@ -34,7 +34,7 @@ declare_clippy_lint! {
 }
 
 /// The (callsite span, (open brace, close brace), source snippet)
-type MacroInfo = (Span, (char, char), String);
+type MacroInfo = (Span, (char, char), SourceText);
 
 pub struct MacroBraces {
     macro_braces: FxHashMap<String, (char, char)>,
@@ -94,7 +94,7 @@ fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBrace
     if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind
         && let name = mac_name.as_str()
         && let Some(&braces) = mac_braces.macro_braces.get(name)
-        && let Some(snip) = snippet_opt(cx, span_call_site)
+        && let Some(snip) = span_call_site.get_source_text(cx)
         // we must check only invocation sites
         // https://github.com/rust-lang/rust-clippy/issues/7422
         && snip.starts_with(&format!("{name}!"))
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index bc71a4790b9..8b9f899d82d 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -35,7 +35,7 @@ impl ArithmeticSideEffects {
             ("f64", FxHashSet::from_iter(["f64"])),
             ("std::string::String", FxHashSet::from_iter(["str"])),
         ]);
-        for [lhs, rhs] in &conf.arithmetic_side_effects_allowed_binary {
+        for (lhs, rhs) in &conf.arithmetic_side_effects_allowed_binary {
             allowed_binary.entry(lhs).or_default().insert(rhs);
         }
         for s in &conf.arithmetic_side_effects_allowed {
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index 641d881d974..11c97b4ef00 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method};
@@ -46,8 +46,8 @@ pub(super) fn check<'tcx>(
                     expr.span,
                     "manual implementation of an assign operation",
                     |diag| {
-                        if let (Some(snip_a), Some(snip_r)) =
-                            (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
+                        if let Some(snip_a) = assignee.span.get_source_text(cx)
+                            && let Some(snip_r) = rhs.span.get_source_text(cx)
                         {
                             diag.span_suggestion(
                                 expr.span,
diff --git a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
index 311cbd050a1..8daedd1c901 100644
--- a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{eq_expr_value, sugg};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -42,7 +42,9 @@ fn lint_misrefactored_assign_op(
         expr.span,
         "variable appears on both sides of an assignment operation",
         |diag| {
-            if let (Some(snip_a), Some(snip_r)) = (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs_other.span)) {
+            if let Some(snip_a) = assignee.span.get_source_text(cx)
+                && let Some(snip_r) = rhs_other.span.get_source_text(cx)
+            {
                 let a = &sugg::Sugg::hir(cx, assignee, "..");
                 let r = &sugg::Sugg::hir(cx, rhs, "..");
                 let long = format!("{snip_a} = {}", sugg::make_binop(op, a, r));
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index 9baecff801f..9e8a821c3f4 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -80,7 +80,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// // `n` can be any number, including `i32::MAX`.
     /// fn foo(n: i32) -> i32 {
-    ///   n + 1
+    ///     n + 1
     /// }
     /// ```
     ///
diff --git a/src/tools/clippy/clippy_lints/src/operators/needless_bitwise_bool.rs b/src/tools/clippy/clippy_lints/src/operators/needless_bitwise_bool.rs
index ab5fb178700..9d8e833ef6d 100644
--- a/src/tools/clippy/clippy_lints/src/operators/needless_bitwise_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/needless_bitwise_bool.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -24,8 +24,8 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Exp
             e.span,
             "use of bitwise operator instead of lazy operator between booleans",
             |diag| {
-                if let Some(lhs_snip) = snippet_opt(cx, lhs.span)
-                    && let Some(rhs_snip) = snippet_opt(cx, rhs.span)
+                if let Some(lhs_snip) = lhs.span.get_source_text(cx)
+                    && let Some(rhs_snip) = rhs.span.get_source_text(cx)
                 {
                     let sugg = format!("{lhs_snip} {op_str} {rhs_snip}");
                     diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
diff --git a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
index 607930561e0..861564d5456 100644
--- a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
@@ -22,8 +22,8 @@ pub(super) fn check<'tcx>(
 
         if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left)
             && let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right)
-            && let Some(left_snip) = snippet_opt(cx, left_var.span)
-            && let Some(right_snip) = snippet_opt(cx, right_var.span)
+            && let Some(left_snip) = left_var.span.get_source_text(cx)
+            && let Some(right_snip) = right_var.span.get_source_text(cx)
         {
             let Some(top_crate) = std_or_core(cx) else { return };
             span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
index 18bfb588a11..d7fa48c1e38 100644
--- a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::path_to_local_id;
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, SpanRangeExt};
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_ast::{LitKind, StrStyle};
 use rustc_errors::Applicability;
@@ -74,7 +74,7 @@ impl<'tcx> PathbufPushSearcher<'tcx> {
             && let Some(arg) = self.arg
             && let ExprKind::Lit(x) = arg.kind
             && let LitKind::Str(_, StrStyle::Cooked) = x.node
-            && let Some(s) = snippet_opt(cx, arg.span)
+            && let Some(s) = arg.span.get_source_text(cx)
         {
             Some(format!(" = PathBuf::from({s});"))
         } else {
@@ -84,8 +84,8 @@ impl<'tcx> PathbufPushSearcher<'tcx> {
 
     fn gen_pathbuf_join(&self, cx: &LateContext<'_>) -> Option<String> {
         let arg = self.arg?;
-        let arg_str = snippet_opt(cx, arg.span)?;
-        let init_val = snippet_opt(cx, self.init_val.span)?;
+        let arg_str = arg.span.get_source_text(cx)?;
+        let init_val = self.init_val.span.get_source_text(cx)?;
         Some(format!(" = {init_val}.join({arg_str});"))
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 02c05e0aaf9..125f694996c 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -1,7 +1,5 @@
-//! Checks for usage of  `&Vec[_]` and `&String`.
-
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::expr_sig;
 use clippy_utils::visitors::contains_unsafe_block;
 use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local};
@@ -243,7 +241,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
                         .chain(result.replacements.iter().map(|r| {
                             (
                                 r.expr_span,
-                                format!("{}{}", snippet_opt(cx, r.self_span).unwrap(), r.replacement),
+                                format!("{}{}", r.self_span.get_source_text(cx).unwrap(), r.replacement),
                             )
                         }))
                         .collect(),
@@ -372,7 +370,7 @@ impl fmt::Display for DerefTyDisplay<'_, '_> {
             DerefTy::Path => f.write_str("Path"),
             DerefTy::Slice(hir_ty, ty) => {
                 f.write_char('[')?;
-                match hir_ty.and_then(|s| snippet_opt(self.0, s)) {
+                match hir_ty.and_then(|s| s.get_source_text(self.0)) {
                     Some(s) => f.write_str(&s)?,
                     None => ty.fmt(f)?,
                 }
@@ -413,6 +411,7 @@ impl<'tcx> DerefTy<'tcx> {
     }
 }
 
+#[expect(clippy::too_many_lines)]
 fn check_fn_args<'cx, 'tcx: 'cx>(
     cx: &'cx LateContext<'tcx>,
     fn_sig: ty::FnSig<'tcx>,
@@ -488,8 +487,6 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                                 return None;
                             }
 
-                            let ty_name = snippet_opt(cx, ty.span()).unwrap_or_else(|| args.type_at(1).to_string());
-
                             span_lint_hir_and_then(
                                 cx,
                                 PTR_ARG,
@@ -500,7 +497,10 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                                     diag.span_suggestion(
                                         hir_ty.span,
                                         "change this to",
-                                        format!("&{}{ty_name}", mutability.prefix_str()),
+                                        match ty.span().get_source_text(cx) {
+                                            Some(s) => format!("&{}{s}", mutability.prefix_str()),
+                                            None => format!("&{}{}", mutability.prefix_str(), args.type_at(1)),
+                                        },
                                         Applicability::Unspecified,
                                     );
                                 },
diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
index 7c82895d609..87a52cb2186 100644
--- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -120,8 +120,8 @@ fn build_suggestion(
     receiver_expr: &Expr<'_>,
     cast_lhs_expr: &Expr<'_>,
 ) -> Option<String> {
-    let receiver = snippet_opt(cx, receiver_expr.span)?;
-    let cast_lhs = snippet_opt(cx, cast_lhs_expr.span)?;
+    let receiver = receiver_expr.span.get_source_text(cx)?;
+    let cast_lhs = cast_lhs_expr.span.get_source_text(cx)?;
     Some(format!("{receiver}.{}({cast_lhs})", method.suggestion()))
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index a1231c082e6..bfdc1cbeed7 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
 use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
 use rustc_errors::Applicability;
@@ -208,7 +208,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
                 .assert_crate_local()
                 .lint_root;
 
-            if let Some(snip) = snippet_opt(cx, span)
+            if let Some(snip) = span.get_source_text(cx)
                 && let Some(dot) = snip.rfind('.')
             {
                 let sugg_span = span.with_lo(span.lo() + BytePos(u32::try_from(dot).unwrap()));
diff --git a/src/tools/clippy/clippy_lints/src/reference.rs b/src/tools/clippy/clippy_lints/src/reference.rs
index 8f32cf5f2a1..2b4ef21fc48 100644
--- a/src/tools/clippy/clippy_lints/src/reference.rs
+++ b/src/tools/clippy/clippy_lints/src/reference.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{snippet_opt, snippet_with_applicability};
+use clippy_utils::source::{snippet_with_applicability, SpanRangeExt};
 use rustc_ast::ast::{Expr, ExprKind, Mutability, UnOp};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::BytePos;
+use rustc_span::{BytePos, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -56,11 +56,11 @@ impl EarlyLintPass for DerefAddrOf {
         {
             let mut applicability = Applicability::MachineApplicable;
             let sugg = if e.span.from_expansion() {
-                if let Some(macro_source) = snippet_opt(cx, e.span) {
+                if let Some(macro_source) = e.span.get_source_text(cx) {
                     // Remove leading whitespace from the given span
                     // e.g: ` $visitor` turns into `$visitor`
-                    let trim_leading_whitespaces = |span| {
-                        snippet_opt(cx, span)
+                    let trim_leading_whitespaces = |span: Span| {
+                        span.get_source_text(cx)
                             .and_then(|snip| {
                                 #[expect(clippy::cast_possible_truncation)]
                                 snip.find(|c: char| !c.is_whitespace())
diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs
index 95014b23043..f6ef02b7c23 100644
--- a/src/tools/clippy/clippy_lints/src/regex.rs
+++ b/src/tools/clippy/clippy_lints/src/regex.rs
@@ -2,7 +2,7 @@ use std::fmt::Display;
 
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{def_path_def_ids, path_def_id, paths};
 use rustc_ast::ast::{LitKind, StrStyle};
 use rustc_hir::def_id::DefIdMap;
@@ -122,7 +122,7 @@ fn lint_syntax_error(cx: &LateContext<'_>, error: &regex_syntax::Error, unescape
     };
 
     if let Some((primary, auxiliary, kind)) = parts
-        && let Some(literal_snippet) = snippet_opt(cx, base)
+        && let Some(literal_snippet) = base.get_source_text(cx)
         && let Some(inner) = literal_snippet.get(offset as usize..)
         // Only convert to native rustc spans if the parsed regex matches the
         // source snippet exactly, to ensure the span offsets are correct
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 13016cdadb0..5ce091b7a7a 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::source::{snippet_opt, snippet_with_context};
+use clippy_utils::source::{snippet_with_context, SpanRangeExt};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::visitors::{for_each_expr, Descend};
 use clippy_utils::{
@@ -250,20 +250,25 @@ impl<'tcx> LateLintPass<'tcx> for Return {
                 |err| {
                     err.span_label(local.span, "unnecessary `let` binding");
 
-                    if let Some(mut snippet) = snippet_opt(cx, initexpr.span) {
-                        if binary_expr_needs_parentheses(initexpr) {
-                            if !has_enclosing_paren(&snippet) {
-                                snippet = format!("({snippet})");
+                    if let Some(src) = initexpr.span.get_source_text(cx) {
+                        let sugg = if binary_expr_needs_parentheses(initexpr) {
+                            if has_enclosing_paren(&src) {
+                                src.to_owned()
+                            } else {
+                                format!("({src})")
                             }
                         } else if !cx.typeck_results().expr_adjustments(retexpr).is_empty() {
-                            if !has_enclosing_paren(&snippet) {
-                                snippet = format!("({snippet})");
+                            if has_enclosing_paren(&src) {
+                                format!("{src} as _")
+                            } else {
+                                format!("({src}) as _")
                             }
-                            snippet.push_str(" as _");
-                        }
+                        } else {
+                            src.to_owned()
+                        };
                         err.multipart_suggestion(
                             "return the expression directly",
-                            vec![(local.span, String::new()), (retexpr.span, snippet)],
+                            vec![(local.span, String::new()), (retexpr.span, sugg)],
                             Applicability::MachineApplicable,
                         );
                     } else {
@@ -394,7 +399,7 @@ fn check_final_expr<'tcx>(
 
             // Returns may be used to turn an expression into a statement in rustc's AST.
             // This allows the addition of attributes, like `#[allow]` (See: clippy#9361)
-            // `#[expect(clippy::needless_return)]` needs to be handled separatly to
+            // `#[expect(clippy::needless_return)]` needs to be handled separately to
             // actually fulfill the expectation (clippy::#12998)
             match cx.tcx.hir().attrs(expr.hir_id) {
                 [] => {},
diff --git a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
index e0558429638..44e585953bf 100644
--- a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
+++ b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::get_trait_def_id;
 use clippy_utils::higher::VecArgs;
 use clippy_utils::macros::root_macro_call_first_node;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use rustc_ast::{LitIntType, LitKind, UintTy};
 use rustc_errors::Applicability;
@@ -92,12 +92,12 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
 
         if matches!(lang_item, LangItem::Range)
             && let ty = cx.typeck_results().expr_ty(start.expr)
-            && let Some(snippet) = snippet_opt(cx, span)
+            && let Some(snippet) = span.get_source_text(cx)
             // `is_from_proc_macro` will skip any `vec![]`. Let's not!
             && snippet.starts_with(suggested_type.starts_with())
             && snippet.ends_with(suggested_type.ends_with())
-            && let Some(start_snippet) = snippet_opt(cx, start.span)
-            && let Some(end_snippet) = snippet_opt(cx, end.span)
+            && let Some(start_snippet) = start.span.get_source_text(cx)
+            && let Some(end_snippet) = end.span.get_source_text(cx)
         {
             let should_emit_every_value = if let Some(step_def_id) = get_trait_def_id(cx.tcx, &["core", "iter", "Step"])
                 && implements_trait(cx, ty, step_def_id, &[])
diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
index 01f0e3cfadb..7750d8909d3 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
@@ -1,6 +1,3 @@
-//! Lint on use of `size_of` or `size_of_val` of T in an expression
-//! expecting a count of T
-
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 974e21df817..44283a49e84 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -9,7 +9,6 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{HirId, Path, PathSegment};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
 use rustc_span::{sym, Span};
@@ -185,9 +184,7 @@ fn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: &Msrv) -> bool {
             } = stability.level
         {
             let stable = match since {
-                StableSince::Version(v) => {
-                    msrv.meets(RustcVersion::new(v.major.into(), v.minor.into(), v.patch.into()))
-                },
+                StableSince::Version(v) => msrv.meets(v),
                 StableSince::Current => msrv.current().is_none(),
                 StableSince::Err => false,
             };
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index cfc387886dc..6ca4ca000e9 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
                 }
             },
             ExprKind::Index(target, _idx, _) => {
-                let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
+                let e_ty = cx.typeck_results().expr_ty_adjusted(target).peel_refs();
                 if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) {
                     span_lint(
                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 59b74122f30..2e87d36df31 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -1,7 +1,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
-use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
+use clippy_utils::source::{snippet, snippet_with_applicability, SpanRangeExt};
 use clippy_utils::{is_from_proc_macro, SpanlessEq, SpanlessHash};
 use core::hash::{Hash, Hasher};
 use itertools::Itertools;
@@ -206,8 +206,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
 
                 let fixed_trait_snippet = unique_traits
                     .iter()
-                    .filter_map(|b| snippet_opt(cx, b.span))
-                    .collect::<Vec<_>>()
+                    .filter_map(|b| b.span.get_source_text(cx))
                     .join(" + ");
 
                 span_lint_and_sugg(
@@ -462,9 +461,8 @@ fn rollup_traits(
 
         let traits = comparable_bounds
             .iter()
-            .filter_map(|&(_, span)| snippet_opt(cx, span))
-            .collect::<Vec<_>>();
-        let traits = traits.join(" + ");
+            .filter_map(|&(_, span)| span.get_source_text(cx))
+            .join(" + ");
 
         span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index afc53e6f32d..978d49f09c3 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
+use clippy_utils::source::{indent_of, reindent_multiline, SourceText, SpanRangeExt};
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
 use rustc_lint::LateContext;
@@ -79,7 +79,7 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
                         && block.expr.is_none()
                         && let Some(last_stmt) = block.stmts.iter().last()
                         && let StmtKind::Semi(last_expr) = last_stmt.kind
-                        && let Some(snip) = snippet_opt(cx, last_expr.span)
+                        && let Some(snip) = last_expr.span.get_source_text(cx)
                     {
                         Some((last_stmt.span, snip))
                     } else {
@@ -90,24 +90,24 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
                     db.span_suggestion(
                         span,
                         "remove the semicolon from the last statement in the block",
-                        sugg,
+                        sugg.as_str(),
                         Applicability::MaybeIncorrect,
                     );
                     or = "or ";
                     applicability = Applicability::MaybeIncorrect;
                 });
 
-            let arg_snippets: Vec<String> = args_to_recover
+            let arg_snippets: Vec<_> = args_to_recover
                 .iter()
-                .filter_map(|arg| snippet_opt(cx, arg.span))
+                .filter_map(|arg| arg.span.get_source_text(cx))
                 .collect();
-            let arg_snippets_without_empty_blocks: Vec<String> = args_to_recover
+            let arg_snippets_without_empty_blocks: Vec<_> = args_to_recover
                 .iter()
                 .filter(|arg| !is_empty_block(arg))
-                .filter_map(|arg| snippet_opt(cx, arg.span))
+                .filter_map(|arg| arg.span.get_source_text(cx))
                 .collect();
 
-            if let Some(call_snippet) = snippet_opt(cx, expr.span) {
+            if let Some(call_snippet) = expr.span.get_source_text(cx) {
                 let sugg = fmt_stmts_and_call(
                     cx,
                     expr,
@@ -161,8 +161,8 @@ fn fmt_stmts_and_call(
     cx: &LateContext<'_>,
     call_expr: &Expr<'_>,
     call_snippet: &str,
-    args_snippets: &[impl AsRef<str>],
-    non_empty_block_args_snippets: &[impl AsRef<str>],
+    args_snippets: &[SourceText],
+    non_empty_block_args_snippets: &[SourceText],
 ) -> String {
     let call_expr_indent = indent_of(cx, call_expr.span).unwrap_or(0);
     let call_snippet_with_replacements = args_snippets
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index 448946bd66d..af7abd009d2 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -34,11 +34,18 @@ declare_clippy_lint! {
     /// ```rust,ignore
     /// use std::io;
     /// fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {
-    ///     // must be `w.write_all(b"foo")?;`
     ///     w.write(b"foo")?;
     ///     Ok(())
     /// }
     /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// use std::io;
+    /// fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {
+    ///     w.write_all(b"foo")?;
+    ///     Ok(())
+    /// }
+    /// ```
     #[clippy::version = "pre 1.29.0"]
     pub UNUSED_IO_AMOUNT,
     correctness,
@@ -235,7 +242,7 @@ fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 
 /// If `expr` is an (e).await, return the inner expression "e" that's being
 /// waited on.  Otherwise return None.
-fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
+fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
     if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
         if let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
             if matches!(
diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs
index b70aa768b46..65f431d338b 100644
--- a/src/tools/clippy/clippy_lints/src/unused_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{position_before_rarrow, snippet_opt};
+use clippy_utils::source::{position_before_rarrow, SpanRangeExt};
 use rustc_ast::visit::FnKind;
 use rustc_ast::{ast, ClosureBinder};
 use rustc_errors::Applicability;
@@ -128,15 +128,17 @@ fn is_unit_expr(expr: &ast::Expr) -> bool {
 
 fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
     let (ret_span, appl) =
-        snippet_opt(cx, span.with_hi(ty.span.hi())).map_or((ty.span, Applicability::MaybeIncorrect), |fn_source| {
-            position_before_rarrow(&fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
-                (
-                    #[expect(clippy::cast_possible_truncation)]
-                    ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
-                    Applicability::MachineApplicable,
-                )
-            })
-        });
+        span.with_hi(ty.span.hi())
+            .get_source_text(cx)
+            .map_or((ty.span, Applicability::MaybeIncorrect), |src| {
+                position_before_rarrow(&src).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
+                    (
+                        #[expect(clippy::cast_possible_truncation)]
+                        ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
+                        Applicability::MachineApplicable,
+                    )
+                })
+            });
     span_lint_and_sugg(
         cx,
         UNUSED_UNIT,
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index c0d9bcdd259..0b4ea0752b6 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -89,15 +89,15 @@ enum UnwrappableKind {
 impl UnwrappableKind {
     fn success_variant_pattern(self) -> &'static str {
         match self {
-            UnwrappableKind::Option => "Some(..)",
-            UnwrappableKind::Result => "Ok(..)",
+            UnwrappableKind::Option => "Some(<item>)",
+            UnwrappableKind::Result => "Ok(<item>)",
         }
     }
 
     fn error_variant_pattern(self) -> &'static str {
         match self {
             UnwrappableKind::Option => "None",
-            UnwrappableKind::Result => "Err(..)",
+            UnwrappableKind::Result => "Err(<item>)",
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 93785b45c27..5da48f4f7fb 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -229,7 +229,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
             && same_type_and_consts(ty, impl_ty)
             // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that
-            // the lifetime parameters of `ty` are ellided (`impl<'a> Foo<'a> { fn new() -> Self { Foo{..} } }`, in
+            // the lifetime parameters of `ty` are elided (`impl<'a> Foo<'a> { fn new() -> Self { Foo{..} } }`, in
             // which case we must still trigger the lint.
             && (has_no_lifetime(ty) || same_lifetimes(ty, impl_ty))
         {
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 316c1f32d3a..0cce45290cf 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -1,6 +1,3 @@
-//! A group of attributes that can be attached to Rust code in order
-//! to generate a clippy lint detecting said code automatically.
-
 use clippy_utils::{get_attr, higher};
 use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_ast::LitIntType;
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index 5acfd35fd6a..f50ce6c99de 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -1,5 +1,5 @@
 use clippy_utils::macros::FormatArgsStorage;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use itertools::Itertools;
 use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
 use rustc_data_structures::fx::FxHashMap;
@@ -75,38 +75,21 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool {
 
     // `format!("{} {} {c}", "one", "two", c = "three")`
     //                     ^^     ^^     ^^^^^^
-    let between_spans = once(args.span)
+    !once(args.span)
         .chain(argument_span)
         .tuple_windows()
-        .map(|(start, end)| start.between(end));
-
-    for between_span in between_spans {
-        let mut seen_comma = false;
-
-        let Some(snippet) = snippet_opt(cx, between_span) else {
-            return true;
-        };
-        for token in tokenize(&snippet) {
-            match token.kind {
-                TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace => {},
-                TokenKind::Comma if !seen_comma => seen_comma = true,
-                // named arguments, `start_val, name = end_val`
-                //                            ^^^^^^^^^ between_span
-                TokenKind::Ident | TokenKind::Eq if seen_comma => {},
-                // An unexpected token usually indicates that we crossed a macro boundary
-                //
-                // `println!(some_proc_macro!("input {}"), a)`
-                //                                      ^^^ between_span
-                // `println!("{}", val!(x))`
-                //               ^^^^^^^ between_span
-                _ => return true,
-            }
-        }
-
-        if !seen_comma {
-            return true;
-        }
-    }
-
-    false
+        .map(|(start, end)| start.between(end))
+        .all(|sp| {
+            sp.check_source_text(cx, |src| {
+                // text should be either `, name` or `, name =`
+                let mut iter = tokenize(src).filter(|t| {
+                    !matches!(
+                        t.kind,
+                        TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
+                    )
+                });
+                iter.next().is_some_and(|t| matches!(t.kind, TokenKind::Comma))
+                    && iter.all(|t| matches!(t.kind, TokenKind::Ident | TokenKind::Eq))
+            })
+        })
 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index 1d294c2944b..f662c7651f6 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -3,7 +3,6 @@ pub mod collapsible_calls;
 pub mod interning_defined_symbol;
 pub mod invalid_paths;
 pub mod lint_without_lint_pass;
-pub mod metadata_collector;
 pub mod msrv_attr_impl;
 pub mod outer_expn_data_pass;
 pub mod produce_ice;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index df342e48d63..20526113d69 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -9,7 +9,6 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ExprKind, HirId, Item, MutTy, Mutability, Path, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_semver::RustcVersion;
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
@@ -92,7 +91,12 @@ pub struct LintWithoutLintPass {
     registered_lints: FxHashSet<Symbol>,
 }
 
-impl_lint_pass!(LintWithoutLintPass => [DEFAULT_LINT, LINT_WITHOUT_LINT_PASS, INVALID_CLIPPY_VERSION_ATTRIBUTE, MISSING_CLIPPY_VERSION_ATTRIBUTE]);
+impl_lint_pass!(LintWithoutLintPass => [
+    DEFAULT_LINT,
+    LINT_WITHOUT_LINT_PASS,
+    INVALID_CLIPPY_VERSION_ATTRIBUTE,
+    MISSING_CLIPPY_VERSION_ATTRIBUTE,
+]);
 
 impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -220,7 +224,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
             return;
         }
 
-        if RustcVersion::parse(value.as_str()).is_err() {
+        if rustc_attr::parse_version(value).is_none() {
             span_lint_and_help(
                 cx,
                 INVALID_CLIPPY_VERSION_ATTRIBUTE,
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
deleted file mode 100644
index 57f45aa3e48..00000000000
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ /dev/null
@@ -1,1078 +0,0 @@
-//! This lint is used to collect metadata about clippy lints. This metadata is exported as a json
-//! file and then used to generate the [clippy lint list](https://rust-lang.github.io/rust-clippy/master/index.html)
-//!
-//! This module and therefore the entire lint is guarded by a feature flag called `internal`
-//!
-//! The module transforms all lint names to ascii lowercase to ensure that we don't have mismatches
-//! during any comparison or mapping. (Please take care of this, it's not fun to spend time on such
-//! a simple mistake)
-
-use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type};
-use clippy_config::{get_configuration_metadata, ClippyConfiguration};
-
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
-use clippy_utils::{last_path_segment, match_function_call, match_path, paths};
-use itertools::Itertools;
-use rustc_ast as ast;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def::DefKind;
-use rustc_hir::intravisit::Visitor;
-use rustc_hir::{self as hir, intravisit, Closure, ExprKind, Item, ItemKind, Mutability, QPath};
-use rustc_lint::{unerased_lint_store, CheckLintNameResult, LateContext, LateLintPass, LintContext, LintId};
-use rustc_middle::hir::nested_filter;
-use rustc_session::impl_lint_pass;
-use rustc_span::symbol::Ident;
-use rustc_span::{sym, Loc, Span, Symbol};
-use serde::ser::SerializeStruct;
-use serde::{Serialize, Serializer};
-use std::collections::{BTreeSet, BinaryHeap};
-use std::fmt::Write as _;
-use std::fs::{self, File};
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-use std::{env, fmt};
-
-/// This is the json output file of the lint collector.
-const JSON_OUTPUT_FILE: &str = "../util/gh-pages/lints.json";
-/// This is the markdown output file of the lint collector.
-const MARKDOWN_OUTPUT_FILE: &str = "../book/src/lint_configuration.md";
-/// These groups will be ignored by the lint group matcher. This is useful for collections like
-/// `clippy::all`
-const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"];
-/// Lints within this group will be excluded from the collection. These groups
-/// have to be defined without the `clippy::` prefix.
-const EXCLUDED_LINT_GROUPS: [&str; 1] = ["internal"];
-/// Collected deprecated lint will be assigned to this group in the JSON output
-const DEPRECATED_LINT_GROUP_STR: &str = "deprecated";
-/// This is the lint level for deprecated lints that will be displayed in the lint list
-const DEPRECATED_LINT_LEVEL: &str = "none";
-/// This array holds Clippy's lint groups with their corresponding default lint level. The
-/// lint level for deprecated lints is set in `DEPRECATED_LINT_LEVEL`.
-const DEFAULT_LINT_LEVELS: &[(&str, &str)] = &[
-    ("correctness", "deny"),
-    ("suspicious", "warn"),
-    ("restriction", "allow"),
-    ("style", "warn"),
-    ("pedantic", "allow"),
-    ("complexity", "warn"),
-    ("perf", "warn"),
-    ("cargo", "allow"),
-    ("nursery", "allow"),
-];
-/// This prefix is in front of the lint groups in the lint store. The prefix will be trimmed
-/// to only keep the actual lint group in the output.
-const CLIPPY_LINT_GROUP_PREFIX: &str = "clippy::";
-const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
-    &["clippy_utils", "diagnostics", "span_lint"],
-    &["clippy_utils", "diagnostics", "span_lint_and_help"],
-    &["clippy_utils", "diagnostics", "span_lint_and_note"],
-    &["clippy_utils", "diagnostics", "span_lint_hir"],
-    &["clippy_utils", "diagnostics", "span_lint_and_sugg"],
-    &["clippy_utils", "diagnostics", "span_lint_and_then"],
-    &["clippy_utils", "diagnostics", "span_lint_hir_and_then"],
-];
-const SUGGESTION_DIAG_METHODS: [(&str, bool); 9] = [
-    ("span_suggestion", false),
-    ("span_suggestion_short", false),
-    ("span_suggestion_verbose", false),
-    ("span_suggestion_hidden", false),
-    ("tool_only_span_suggestion", false),
-    ("multipart_suggestion", true),
-    ("multipart_suggestions", true),
-    ("tool_only_multipart_suggestion", true),
-    ("span_suggestions", true),
-];
-
-/// The index of the applicability name of `paths::APPLICABILITY_VALUES`
-const APPLICABILITY_NAME_INDEX: usize = 2;
-/// This applicability will be set for unresolved applicability values.
-const APPLICABILITY_UNRESOLVED_STR: &str = "Unresolved";
-/// The version that will be displayed if none has been defined
-const VERSION_DEFAULT_STR: &str = "Unknown";
-
-const CHANGELOG_PATH: &str = "../CHANGELOG.md";
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Collects metadata about clippy lints for the website.
-    ///
-    /// This lint will be used to report problems of syntax parsing. You should hopefully never
-    /// see this but never say never I guess ^^
-    ///
-    /// ### Why is this bad?
-    /// This is not a bad thing but definitely a hacky way to do it. See
-    /// issue [#4310](https://github.com/rust-lang/rust-clippy/issues/4310) for a discussion
-    /// about the implementation.
-    ///
-    /// ### Known problems
-    /// Hopefully none. It would be pretty uncool to have a problem here :)
-    ///
-    /// ### Example output
-    /// ```json,ignore
-    /// {
-    ///     "id": "metadata_collector",
-    ///     "id_span": {
-    ///         "path": "clippy_lints/src/utils/internal_lints/metadata_collector.rs",
-    ///         "line": 1
-    ///     },
-    ///     "group": "clippy::internal",
-    ///     "docs": " ### What it does\nCollects metadata about clippy lints for the website. [...] "
-    /// }
-    /// ```
-    #[clippy::version = "1.56.0"]
-    pub METADATA_COLLECTOR,
-    internal,
-    "A busy bee collection metadata about lints"
-}
-
-impl_lint_pass!(MetadataCollector => [METADATA_COLLECTOR]);
-
-#[allow(clippy::module_name_repetitions)]
-#[derive(Debug, Clone)]
-pub struct MetadataCollector {
-    /// All collected lints
-    ///
-    /// We use a Heap here to have the lints added in alphabetic order in the export
-    lints: BinaryHeap<LintMetadata>,
-    applicability_info: FxHashMap<String, ApplicabilityInfo>,
-    config: Vec<ClippyConfiguration>,
-    clippy_project_root: PathBuf,
-}
-
-impl MetadataCollector {
-    pub fn new() -> Self {
-        Self {
-            lints: BinaryHeap::<LintMetadata>::default(),
-            applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(),
-            config: get_configuration_metadata(),
-            clippy_project_root: env::current_dir()
-                .expect("failed to get current dir")
-                .ancestors()
-                .nth(1)
-                .expect("failed to get project root")
-                .to_path_buf(),
-        }
-    }
-
-    fn get_lint_configs(&self, lint_name: &str) -> Option<String> {
-        self.config
-            .iter()
-            .filter(|config| config.lints.iter().any(|&lint| lint == lint_name))
-            .map(ToString::to_string)
-            .reduce(|acc, x| acc + "\n\n" + &x)
-            .map(|configurations| {
-                format!(
-                    r#"
-### Configuration
-This lint has the following configuration variables:
-
-{configurations}
-"#
-                )
-            })
-    }
-
-    fn configs_to_markdown(&self, map_fn: fn(&ClippyConfiguration) -> String) -> String {
-        self.config
-            .iter()
-            .filter(|config| config.deprecation_reason.is_none())
-            .filter(|config| !config.lints.is_empty())
-            .map(map_fn)
-            .join("\n")
-    }
-
-    fn get_markdown_docs(&self) -> String {
-        format!(
-            r#"# Lint Configuration Options
-
-The following list shows each configuration option, along with a description, its default value, an example
-and lints affected.
-
----
-
-{}"#,
-            self.configs_to_markdown(ClippyConfiguration::to_markdown_paragraph),
-        )
-    }
-}
-
-impl Drop for MetadataCollector {
-    /// You might ask: How hacky is this?
-    /// My answer:     YES
-    fn drop(&mut self) {
-        // The metadata collector gets dropped twice, this makes sure that we only write
-        // when the list is full
-        if self.lints.is_empty() {
-            return;
-        }
-
-        let mut applicability_info = std::mem::take(&mut self.applicability_info);
-
-        // Add deprecated lints
-        self.lints.extend(
-            crate::deprecated_lints::DEPRECATED
-                .iter()
-                .zip(crate::deprecated_lints::DEPRECATED_VERSION)
-                .filter_map(|((lint, reason), version)| LintMetadata::new_deprecated(lint, reason, version)),
-        );
-        // Mapping the final data
-        let mut lints = std::mem::take(&mut self.lints).into_sorted_vec();
-        for x in &mut lints {
-            x.applicability = Some(applicability_info.remove(&x.id).unwrap_or_default());
-            replace_produces(&x.id, &mut x.docs, &self.clippy_project_root);
-        }
-
-        collect_renames(&mut lints);
-
-        // Outputting json
-        fs::write(JSON_OUTPUT_FILE, serde_json::to_string_pretty(&lints).unwrap()).unwrap();
-
-        // Outputting markdown
-        let mut file = File::create(MARKDOWN_OUTPUT_FILE).unwrap();
-        writeln!(
-            file,
-            "<!--
-This file is generated by `cargo collect-metadata`.
-Please use that command to update the file and do not edit it by hand.
--->
-
-{}",
-            self.get_markdown_docs(),
-        )
-        .unwrap();
-
-        // Write configuration links to CHANGELOG.md
-        let changelog = fs::read_to_string(CHANGELOG_PATH).unwrap();
-        let mut changelog_file = File::create(CHANGELOG_PATH).unwrap();
-        let position = changelog
-            .find("<!-- begin autogenerated links to configuration documentation -->")
-            .unwrap();
-        writeln!(
-            changelog_file,
-            "{}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
-            &changelog[..position],
-            self.configs_to_markdown(ClippyConfiguration::to_markdown_link)
-        )
-        .unwrap();
-    }
-}
-
-#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
-struct LintMetadata {
-    id: String,
-    id_span: Option<SerializableSpan>,
-    group: String,
-    level: String,
-    docs: String,
-    version: String,
-    /// This field is only used in the output and will only be
-    /// mapped shortly before the actual output.
-    applicability: Option<ApplicabilityInfo>,
-    /// All the past names of lints which have been renamed.
-    #[serde(skip_serializing_if = "BTreeSet::is_empty")]
-    former_ids: BTreeSet<String>,
-}
-
-impl LintMetadata {
-    fn new(
-        id: String,
-        id_span: SerializableSpan,
-        group: String,
-        level: &'static str,
-        version: String,
-        docs: String,
-    ) -> Self {
-        Self {
-            id,
-            id_span: Some(id_span),
-            group,
-            level: level.to_string(),
-            version,
-            docs,
-            applicability: None,
-            former_ids: BTreeSet::new(),
-        }
-    }
-
-    fn new_deprecated(name: &str, reason: &str, version: &str) -> Option<Self> {
-        // The reason starts with a lowercase letter and end without a period.
-        // This needs to be fixed for the website.
-        let mut reason = reason.to_owned();
-        if let Some(reason) = reason.get_mut(0..1) {
-            reason.make_ascii_uppercase();
-        }
-        name.strip_prefix("clippy::").map(|name| Self {
-            id: name.into(),
-            id_span: None,
-            group: DEPRECATED_LINT_GROUP_STR.into(),
-            level: DEPRECATED_LINT_LEVEL.into(),
-            version: version.into(),
-            docs: format!(
-                "### What it does\n\n\
-                Nothing. This lint has been deprecated\n\n\
-                ### Deprecation reason\n\n{reason}.\n",
-            ),
-            applicability: None,
-            former_ids: BTreeSet::new(),
-        })
-    }
-}
-
-fn replace_produces(lint_name: &str, docs: &mut String, clippy_project_root: &Path) {
-    let mut doc_lines = docs.lines().map(ToString::to_string).collect::<Vec<_>>();
-    let mut lines = doc_lines.iter_mut();
-
-    'outer: loop {
-        // Find the start of the example
-
-        // ```rust
-        loop {
-            match lines.next() {
-                Some(line) if line.trim_start().starts_with("```rust") => {
-                    if line.contains("ignore") || line.contains("no_run") {
-                        // A {{produces}} marker may have been put on a ignored code block by mistake,
-                        // just seek to the end of the code block and continue checking.
-                        if lines.any(|line| line.trim_start().starts_with("```")) {
-                            continue;
-                        }
-
-                        panic!("lint `{lint_name}` has an unterminated code block")
-                    }
-
-                    break;
-                },
-                Some(line) if line.trim_start() == "{{produces}}" => {
-                    panic!("lint `{lint_name}` has marker {{{{produces}}}} with an ignored or missing code block")
-                },
-                Some(line) => {
-                    let line = line.trim();
-                    // These are the two most common markers of the corrections section
-                    if line.eq_ignore_ascii_case("Use instead:") || line.eq_ignore_ascii_case("Could be written as:") {
-                        break 'outer;
-                    }
-                },
-                None => break 'outer,
-            }
-        }
-
-        // Collect the example
-        let mut example = Vec::new();
-        loop {
-            match lines.next() {
-                Some(line) if line.trim_start() == "```" => break,
-                Some(line) => example.push(line),
-                None => panic!("lint `{lint_name}` has an unterminated code block"),
-            }
-        }
-
-        // Find the {{produces}} and attempt to generate the output
-        loop {
-            match lines.next() {
-                Some(line) if line.is_empty() => {},
-                Some(line) if line.trim() == "{{produces}}" => {
-                    let output = get_lint_output(lint_name, &example, clippy_project_root);
-                    line.replace_range(
-                        ..,
-                        &format!(
-                            "<details>\
-                            <summary>Produces</summary>\n\
-                            \n\
-                            ```text\n\
-                            {output}\n\
-                            ```\n\
-                        </details>"
-                        ),
-                    );
-
-                    break;
-                },
-                // No {{produces}}, we can move on to the next example
-                Some(_) => break,
-                None => break 'outer,
-            }
-        }
-    }
-
-    *docs = cleanup_docs(&doc_lines);
-}
-
-fn get_lint_output(lint_name: &str, example: &[&mut String], clippy_project_root: &Path) -> String {
-    let dir = tempfile::tempdir().unwrap_or_else(|e| panic!("failed to create temp dir: {e}"));
-    let file = dir.path().join("lint_example.rs");
-
-    let mut source = String::new();
-    let unhidden = example
-        .iter()
-        .map(|line| line.trim_start().strip_prefix("# ").unwrap_or(line));
-
-    // Get any attributes
-    let mut lines = unhidden.peekable();
-    while let Some(line) = lines.peek() {
-        if line.starts_with("#!") {
-            source.push_str(line);
-            source.push('\n');
-            lines.next();
-        } else {
-            break;
-        }
-    }
-
-    let needs_main = !example.iter().any(|line| line.contains("fn main"));
-    if needs_main {
-        source.push_str("fn main() {\n");
-    }
-
-    for line in lines {
-        source.push_str(line);
-        source.push('\n');
-    }
-
-    if needs_main {
-        source.push_str("}\n");
-    }
-
-    if let Err(e) = fs::write(&file, &source) {
-        panic!("failed to write to `{}`: {e}", file.as_path().to_string_lossy());
-    }
-
-    let prefixed_name = format!("{CLIPPY_LINT_GROUP_PREFIX}{lint_name}");
-
-    let mut cmd = Command::new(env::var("CARGO").unwrap_or("cargo".into()));
-
-    cmd.current_dir(clippy_project_root)
-        .env("CARGO_INCREMENTAL", "0")
-        .env("CLIPPY_ARGS", "")
-        .env("CLIPPY_DISABLE_DOCS_LINKS", "1")
-        // We need to disable this to enable all lints
-        .env("ENABLE_METADATA_COLLECTION", "0")
-        .args(["run", "--bin", "clippy-driver"])
-        .args(["--target-dir", "./clippy_lints/target"])
-        .args(["--", "--error-format=json"])
-        .args(["--edition", "2021"])
-        .arg("-Cdebuginfo=0")
-        .args(["-A", "clippy::all"])
-        .args(["-W", &prefixed_name])
-        .args(["-L", "./target/debug"])
-        .args(["-Z", "no-codegen"]);
-
-    let output = cmd
-        .arg(file.as_path())
-        .output()
-        .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
-
-    let tmp_file_path = file.to_string_lossy();
-    let stderr = std::str::from_utf8(&output.stderr).unwrap();
-    let msgs = stderr
-        .lines()
-        .filter(|line| line.starts_with('{'))
-        .map(|line| serde_json::from_str(line).unwrap())
-        .collect::<Vec<serde_json::Value>>();
-
-    let mut rendered = String::new();
-    let iter = msgs
-        .iter()
-        .filter(|msg| matches!(&msg["code"]["code"], serde_json::Value::String(s) if s == &prefixed_name));
-
-    for message in iter {
-        let rendered_part = message["rendered"].as_str().expect("rendered field should exist");
-        rendered.push_str(rendered_part);
-    }
-
-    if rendered.is_empty() {
-        let rendered: Vec<&str> = msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
-        let non_json: Vec<&str> = stderr.lines().filter(|line| !line.starts_with('{')).collect();
-        panic!(
-            "did not find lint `{lint_name}` in output of example, got:\n{}\n{}",
-            non_json.join("\n"),
-            rendered.join("\n")
-        );
-    }
-
-    // The reader doesn't need to see `/tmp/.tmpfiy2Qd/lint_example.rs` :)
-    rendered.trim_end().replace(&*tmp_file_path, "lint_example.rs")
-}
-
-#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
-struct SerializableSpan {
-    path: String,
-    line: usize,
-}
-
-impl fmt::Display for SerializableSpan {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}:{}", self.path.rsplit('/').next().unwrap_or_default(), self.line)
-    }
-}
-
-impl SerializableSpan {
-    fn from_item(cx: &LateContext<'_>, item: &Item<'_>) -> Self {
-        Self::from_span(cx, item.ident.span)
-    }
-
-    fn from_span(cx: &LateContext<'_>, span: Span) -> Self {
-        let loc: Loc = cx.sess().source_map().lookup_char_pos(span.lo());
-
-        Self {
-            path: format!("{}", loc.file.name.prefer_remapped_unconditionaly()),
-            line: loc.line,
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
-struct ApplicabilityInfo {
-    /// Indicates if any of the lint emissions uses multiple spans. This is related to
-    /// [rustfix#141](https://github.com/rust-lang/rustfix/issues/141) as such suggestions can
-    /// currently not be applied automatically.
-    is_multi_part_suggestion: bool,
-    applicability: Option<usize>,
-}
-
-impl Serialize for ApplicabilityInfo {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        let mut s = serializer.serialize_struct("ApplicabilityInfo", 2)?;
-        s.serialize_field("is_multi_part_suggestion", &self.is_multi_part_suggestion)?;
-        if let Some(index) = self.applicability {
-            s.serialize_field(
-                "applicability",
-                &paths::APPLICABILITY_VALUES[index][APPLICABILITY_NAME_INDEX],
-            )?;
-        } else {
-            s.serialize_field("applicability", APPLICABILITY_UNRESOLVED_STR)?;
-        }
-        s.end()
-    }
-}
-
-// ==================================================================
-// Lint pass
-// ==================================================================
-impl<'hir> LateLintPass<'hir> for MetadataCollector {
-    /// Collecting lint declarations like:
-    /// ```rust, ignore
-    /// declare_clippy_lint! {
-    ///     /// ### What it does
-    ///     /// Something IDK.
-    ///     pub SOME_LINT,
-    ///     internal,
-    ///     "Who am I?"
-    /// }
-    /// ```
-    fn check_item(&mut self, cx: &LateContext<'hir>, item: &'hir Item<'_>) {
-        if let ItemKind::Static(ty, Mutability::Not, _) = item.kind {
-            // Normal lint
-            if is_lint_ref_type(cx, ty)
-                // item validation
-                // disallow check
-                && let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase()
-                // metadata extraction
-                && let Some((group, level)) = get_lint_group_and_level_or_lint(cx, &lint_name, item)
-                && let Some(mut raw_docs) = extract_attr_docs_or_lint(cx, item)
-            {
-                if let Some(configuration_section) = self.get_lint_configs(&lint_name) {
-                    raw_docs.push_str(&configuration_section);
-                }
-                let version = get_lint_version(cx, item);
-
-                self.lints.push(LintMetadata::new(
-                    lint_name,
-                    SerializableSpan::from_item(cx, item),
-                    group,
-                    level,
-                    version,
-                    raw_docs,
-                ));
-            }
-        }
-    }
-
-    /// Collecting constant applicability from the actual lint emissions
-    ///
-    /// Example:
-    /// ```rust, ignore
-    /// span_lint_and_sugg(
-    ///     cx,
-    ///     SOME_LINT,
-    ///     item.span,
-    ///     "Le lint message",
-    ///     "Here comes help:",
-    ///     "#![allow(clippy::all)]",
-    ///     Applicability::MachineApplicable, // <-- Extracts this constant value
-    /// );
-    /// ```
-    fn check_expr(&mut self, cx: &LateContext<'hir>, expr: &'hir hir::Expr<'_>) {
-        if let Some(args) = match_lint_emission(cx, expr) {
-            let emission_info = extract_emission_info(cx, args);
-            if emission_info.is_empty() {
-                // See:
-                // - src/misc.rs:734:9
-                // - src/methods/mod.rs:3545:13
-                // - src/methods/mod.rs:3496:13
-                // We are basically unable to resolve the lint name itself.
-                return;
-            }
-
-            for (lint_name, applicability, is_multi_part) in emission_info {
-                let app_info = self.applicability_info.entry(lint_name).or_default();
-                app_info.applicability = applicability;
-                app_info.is_multi_part_suggestion = is_multi_part;
-            }
-        }
-    }
-}
-
-// ==================================================================
-// Lint definition extraction
-// ==================================================================
-fn sym_to_string(sym: Symbol) -> String {
-    sym.as_str().to_string()
-}
-
-fn extract_attr_docs_or_lint(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
-    extract_attr_docs(cx, item).or_else(|| {
-        lint_collection_error_item(cx, item, "could not collect the lint documentation");
-        None
-    })
-}
-
-/// This function collects all documentation that has been added to an item using
-/// `#[doc = r""]` attributes. Several attributes are aggravated using line breaks
-///
-/// ```ignore
-/// #[doc = r"Hello world!"]
-/// #[doc = r"=^.^="]
-/// struct SomeItem {}
-/// ```
-///
-/// Would result in `Hello world!\n=^.^=\n`
-fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
-    let attrs = cx.tcx.hir().attrs(item.hir_id());
-    let mut lines = attrs.iter().filter_map(ast::Attribute::doc_str);
-
-    if let Some(line) = lines.next() {
-        let raw_docs = lines.fold(String::from(line.as_str()) + "\n", |s, line| s + line.as_str() + "\n");
-        return Some(raw_docs);
-    }
-
-    None
-}
-
-/// This function may modify the doc comment to ensure that the string can be displayed using a
-/// markdown viewer in Clippy's lint list. The following modifications could be applied:
-/// * Removal of leading space after a new line. (Important to display tables)
-/// * Ensures that code blocks only contain language information
-fn cleanup_docs(docs_collection: &Vec<String>) -> String {
-    let mut in_code_block = false;
-    let mut is_code_block_rust = false;
-
-    let mut docs = String::new();
-    for line in docs_collection {
-        // Rustdoc hides code lines starting with `# ` and this removes them from Clippy's lint list :)
-        if is_code_block_rust && line.trim_start().starts_with("# ") {
-            continue;
-        }
-
-        // The line should be represented in the lint list, even if it's just an empty line
-        docs.push('\n');
-        if let Some(info) = line.trim_start().strip_prefix("```") {
-            in_code_block = !in_code_block;
-            is_code_block_rust = false;
-            if in_code_block {
-                let lang = info
-                    .trim()
-                    .split(',')
-                    // remove rustdoc directives
-                    .find(|&s| !matches!(s, "" | "ignore" | "no_run" | "should_panic"))
-                    // if no language is present, fill in "rust"
-                    .unwrap_or("rust");
-                let len_diff = line.len() - line.trim_start().len();
-                if len_diff != 0 {
-                    // We put back the indentation.
-                    docs.push_str(&line[..len_diff]);
-                }
-                docs.push_str("```");
-                docs.push_str(lang);
-
-                is_code_block_rust = lang == "rust";
-                continue;
-            }
-        }
-        // This removes the leading space that the macro translation introduces
-        if let Some(stripped_doc) = line.strip_prefix(' ') {
-            docs.push_str(stripped_doc);
-        } else if !line.is_empty() {
-            docs.push_str(line);
-        }
-    }
-
-    docs
-}
-
-fn get_lint_version(cx: &LateContext<'_>, item: &Item<'_>) -> String {
-    extract_clippy_version_value(cx, item).map_or_else(
-        || VERSION_DEFAULT_STR.to_string(),
-        |version| version.as_str().to_string(),
-    )
-}
-
-fn get_lint_group_and_level_or_lint(
-    cx: &LateContext<'_>,
-    lint_name: &str,
-    item: &Item<'_>,
-) -> Option<(String, &'static str)> {
-    let result = unerased_lint_store(cx.tcx.sess).check_lint_name(
-        lint_name,
-        Some(sym::clippy),
-        &std::iter::once(Ident::with_dummy_span(sym::clippy)).collect(),
-    );
-    if let CheckLintNameResult::Tool(lint_lst, None) = result {
-        if let Some(group) = get_lint_group(cx, lint_lst[0]) {
-            if EXCLUDED_LINT_GROUPS.contains(&group.as_str()) {
-                return None;
-            }
-
-            if let Some(level) = get_lint_level_from_group(&group) {
-                Some((group, level))
-            } else {
-                lint_collection_error_item(
-                    cx,
-                    item,
-                    &format!("Unable to determine lint level for found group `{group}`"),
-                );
-                None
-            }
-        } else {
-            lint_collection_error_item(cx, item, "Unable to determine lint group");
-            None
-        }
-    } else {
-        lint_collection_error_item(cx, item, "Unable to find lint in lint_store");
-        None
-    }
-}
-
-fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
-    for (group_name, lints, _) in unerased_lint_store(cx.tcx.sess).get_lint_groups() {
-        if IGNORED_LINT_GROUPS.contains(&group_name) {
-            continue;
-        }
-
-        if lints.iter().any(|group_lint| *group_lint == lint_id) {
-            let group = group_name.strip_prefix(CLIPPY_LINT_GROUP_PREFIX).unwrap_or(group_name);
-            return Some((*group).to_string());
-        }
-    }
-
-    None
-}
-
-fn get_lint_level_from_group(lint_group: &str) -> Option<&'static str> {
-    DEFAULT_LINT_LEVELS
-        .iter()
-        .find_map(|(group_name, group_level)| (*group_name == lint_group).then_some(*group_level))
-}
-
-fn collect_renames(lints: &mut Vec<LintMetadata>) {
-    for lint in lints {
-        let mut collected = String::new();
-        let mut names = vec![lint.id.clone()];
-
-        loop {
-            if let Some(lint_name) = names.pop() {
-                for (k, v) in crate::deprecated_lints::RENAMED {
-                    if let Some(name) = v.strip_prefix(CLIPPY_LINT_GROUP_PREFIX)
-                        && name == lint_name
-                        && let Some(past_name) = k.strip_prefix(CLIPPY_LINT_GROUP_PREFIX)
-                    {
-                        lint.former_ids.insert(past_name.to_owned());
-                        writeln!(collected, "* `{past_name}`").unwrap();
-                        names.push(past_name.to_string());
-                    }
-                }
-
-                continue;
-            }
-
-            break;
-        }
-
-        if !collected.is_empty() {
-            write!(
-                &mut lint.docs,
-                r#"
-### Past names
-
-{collected}
-"#
-            )
-            .unwrap();
-        }
-    }
-}
-
-// ==================================================================
-// Lint emission
-// ==================================================================
-fn lint_collection_error_item(cx: &LateContext<'_>, item: &Item<'_>, message: &str) {
-    span_lint(
-        cx,
-        METADATA_COLLECTOR,
-        item.ident.span,
-        format!("metadata collection error for `{}`: {message}", item.ident.name),
-    );
-}
-
-// ==================================================================
-// Applicability
-// ==================================================================
-/// This function checks if a given expression is equal to a simple lint emission function call.
-/// It will return the function arguments if the emission matched any function.
-fn match_lint_emission<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'_>) -> Option<&'hir [hir::Expr<'hir>]> {
-    LINT_EMISSION_FUNCTIONS
-        .iter()
-        .find_map(|emission_fn| match_function_call(cx, expr, emission_fn))
-}
-
-fn take_higher_applicability(a: Option<usize>, b: Option<usize>) -> Option<usize> {
-    a.map_or(b, |a| a.max(b.unwrap_or_default()).into())
-}
-
-fn extract_emission_info<'hir>(
-    cx: &LateContext<'hir>,
-    args: &'hir [hir::Expr<'hir>],
-) -> Vec<(String, Option<usize>, bool)> {
-    let mut lints = Vec::new();
-    let mut applicability = None;
-    let mut multi_part = false;
-
-    for arg in args {
-        let (arg_ty, _) = walk_ptrs_ty_depth(cx.typeck_results().expr_ty(arg));
-
-        if match_type(cx, arg_ty, &paths::LINT) {
-            // If we found the lint arg, extract the lint name
-            let mut resolved_lints = resolve_lints(cx, arg);
-            lints.append(&mut resolved_lints);
-        } else if match_type(cx, arg_ty, &paths::APPLICABILITY) {
-            applicability = resolve_applicability(cx, arg);
-        } else if arg_ty.is_closure() {
-            multi_part |= check_is_multi_part(cx, arg);
-            applicability = applicability.or_else(|| resolve_applicability(cx, arg));
-        }
-    }
-
-    lints
-        .into_iter()
-        .map(|lint_name| (lint_name, applicability, multi_part))
-        .collect()
-}
-
-/// Resolves the possible lints that this expression could reference
-fn resolve_lints<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Vec<String> {
-    let mut resolver = LintResolver::new(cx);
-    resolver.visit_expr(expr);
-    resolver.lints
-}
-
-/// This function tries to resolve the linked applicability to the given expression.
-fn resolve_applicability<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<usize> {
-    let mut resolver = ApplicabilityResolver::new(cx);
-    resolver.visit_expr(expr);
-    resolver.complete()
-}
-
-fn check_is_multi_part<'hir>(cx: &LateContext<'hir>, closure_expr: &'hir hir::Expr<'hir>) -> bool {
-    if let ExprKind::Closure(&Closure { body, .. }) = closure_expr.kind {
-        let mut scanner = IsMultiSpanScanner::new(cx);
-        intravisit::walk_body(&mut scanner, cx.tcx.hir().body(body));
-        return scanner.is_multi_part();
-    } else if let Some(local) = get_parent_local(cx, closure_expr) {
-        if let Some(local_init) = local.init {
-            return check_is_multi_part(cx, local_init);
-        }
-    }
-
-    false
-}
-
-struct LintResolver<'a, 'hir> {
-    cx: &'a LateContext<'hir>,
-    lints: Vec<String>,
-}
-
-impl<'a, 'hir> LintResolver<'a, 'hir> {
-    fn new(cx: &'a LateContext<'hir>) -> Self {
-        Self {
-            cx,
-            lints: Vec::<String>::default(),
-        }
-    }
-}
-
-impl<'a, 'hir> Visitor<'hir> for LintResolver<'a, 'hir> {
-    type NestedFilter = nested_filter::All;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.cx.tcx.hir()
-    }
-
-    fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
-        if let ExprKind::Path(qpath) = &expr.kind
-            && let QPath::Resolved(_, path) = qpath
-            && let (expr_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(expr))
-            && match_type(self.cx, expr_ty, &paths::LINT)
-        {
-            if let hir::def::Res::Def(DefKind::Static { .. }, _) = path.res {
-                let lint_name = last_path_segment(qpath).ident.name;
-                self.lints.push(sym_to_string(lint_name).to_ascii_lowercase());
-            } else if let Some(local) = get_parent_local(self.cx, expr) {
-                if let Some(local_init) = local.init {
-                    intravisit::walk_expr(self, local_init);
-                }
-            }
-        }
-
-        intravisit::walk_expr(self, expr);
-    }
-}
-
-/// This visitor finds the highest applicability value in the visited expressions
-struct ApplicabilityResolver<'a, 'hir> {
-    cx: &'a LateContext<'hir>,
-    /// This is the index of highest `Applicability` for `paths::APPLICABILITY_VALUES`
-    applicability_index: Option<usize>,
-}
-
-impl<'a, 'hir> ApplicabilityResolver<'a, 'hir> {
-    fn new(cx: &'a LateContext<'hir>) -> Self {
-        Self {
-            cx,
-            applicability_index: None,
-        }
-    }
-
-    fn add_new_index(&mut self, new_index: usize) {
-        self.applicability_index = take_higher_applicability(self.applicability_index, Some(new_index));
-    }
-
-    fn complete(self) -> Option<usize> {
-        self.applicability_index
-    }
-}
-
-impl<'a, 'hir> Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
-    type NestedFilter = nested_filter::All;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.cx.tcx.hir()
-    }
-
-    fn visit_path(&mut self, path: &hir::Path<'hir>, _id: hir::HirId) {
-        for (index, enum_value) in paths::APPLICABILITY_VALUES.iter().enumerate() {
-            if match_path(path, enum_value) {
-                self.add_new_index(index);
-                return;
-            }
-        }
-    }
-
-    fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
-        let (expr_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(expr));
-
-        if match_type(self.cx, expr_ty, &paths::APPLICABILITY)
-            && let Some(local) = get_parent_local(self.cx, expr)
-            && let Some(local_init) = local.init
-        {
-            intravisit::walk_expr(self, local_init);
-        };
-
-        intravisit::walk_expr(self, expr);
-    }
-}
-
-/// This returns the parent local node if the expression is a reference one
-fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<&'hir hir::LetStmt<'hir>> {
-    if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
-        if let hir::def::Res::Local(local_hir) = path.res {
-            return get_parent_local_hir_id(cx, local_hir);
-        }
-    }
-
-    None
-}
-
-fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::LetStmt<'hir>> {
-    match cx.tcx.parent_hir_node(hir_id) {
-        hir::Node::LetStmt(local) => Some(local),
-        hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id),
-        _ => None,
-    }
-}
-
-/// This visitor finds the highest applicability value in the visited expressions
-struct IsMultiSpanScanner<'a, 'hir> {
-    cx: &'a LateContext<'hir>,
-    suggestion_count: usize,
-}
-
-impl<'a, 'hir> IsMultiSpanScanner<'a, 'hir> {
-    fn new(cx: &'a LateContext<'hir>) -> Self {
-        Self {
-            cx,
-            suggestion_count: 0,
-        }
-    }
-
-    /// Add a new single expression suggestion to the counter
-    fn add_single_span_suggestion(&mut self) {
-        self.suggestion_count += 1;
-    }
-
-    /// Signals that a suggestion with possible multiple spans was found
-    fn add_multi_part_suggestion(&mut self) {
-        self.suggestion_count += 2;
-    }
-
-    /// Checks if the suggestions include multiple spans
-    fn is_multi_part(&self) -> bool {
-        self.suggestion_count > 1
-    }
-}
-
-impl<'a, 'hir> Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> {
-    type NestedFilter = nested_filter::All;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.cx.tcx.hir()
-    }
-
-    fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
-        // Early return if the lint is already multi span
-        if self.is_multi_part() {
-            return;
-        }
-
-        if let ExprKind::MethodCall(path, recv, _, _arg_span) = &expr.kind {
-            let (self_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(recv));
-            if match_type(self.cx, self_ty, &paths::DIAG) {
-                let called_method = path.ident.name.as_str().to_string();
-                for (method_name, is_multi_part) in &SUGGESTION_DIAG_METHODS {
-                    if *method_name == called_method {
-                        if *is_multi_part {
-                            self.add_multi_part_suggestion();
-                        } else {
-                            self.add_single_span_suggestion();
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-
-        intravisit::walk_expr(self, expr);
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 228db14d1b7..d3e49bff422 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -5,7 +5,7 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method};
@@ -214,9 +214,11 @@ impl SuggestedType {
     }
 
     fn snippet(self, cx: &LateContext<'_>, args_span: Option<Span>, len_span: Option<Span>) -> String {
-        let maybe_args = args_span.and_then(|sp| snippet_opt(cx, sp)).unwrap_or_default();
+        let maybe_args = args_span
+            .and_then(|sp| sp.get_source_text(cx))
+            .map_or(String::new(), |x| x.to_owned());
         let maybe_len = len_span
-            .and_then(|sp| snippet_opt(cx, sp).map(|s| format!("; {s}")))
+            .and_then(|sp| sp.get_source_text(cx).map(|s| format!("; {s}")))
             .unwrap_or_default();
 
         match self {
diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs
index 63f3a5d7f83..7a85196ceca 100644
--- a/src/tools/clippy/clippy_lints/src/visibility.rs
+++ b/src/tools/clippy/clippy_lints/src/visibility.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{Item, VisibilityKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
@@ -82,9 +82,7 @@ impl EarlyLintPass for Visibility {
         if !in_external_macro(cx.sess(), item.span)
             && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
         {
-            if **path == kw::SelfLower
-                && let Some(false) = is_from_proc_macro(cx, item.vis.span)
-            {
+            if **path == kw::SelfLower && !is_from_proc_macro(cx, item.vis.span) {
                 span_lint_and_then(
                     cx,
                     NEEDLESS_PUB_SELF,
@@ -104,7 +102,7 @@ impl EarlyLintPass for Visibility {
             if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate)
                 && !*shorthand
                 && let [.., last] = &*path.segments
-                && let Some(false) = is_from_proc_macro(cx, item.vis.span)
+                && !is_from_proc_macro(cx, item.vis.span)
             {
                 #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
                 span_lint_and_then(
@@ -125,7 +123,7 @@ impl EarlyLintPass for Visibility {
 
             if *shorthand
                 && let [.., last] = &*path.segments
-                && let Some(false) = is_from_proc_macro(cx, item.vis.span)
+                && !is_from_proc_macro(cx, item.vis.span)
             {
                 #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
                 span_lint_and_then(
@@ -147,6 +145,6 @@ impl EarlyLintPass for Visibility {
     }
 }
 
-fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> Option<bool> {
-    snippet_opt(cx, span).map(|s| !s.starts_with("pub"))
+fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> bool {
+    !span.check_source_text(cx, |src| src.starts_with("pub"))
 }
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index c4d64ee4609..7d9e58ad2f8 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -100,14 +100,14 @@ declare_clippy_lint! {
 
 pub struct WildcardImports {
     warn_on_all: bool,
-    allowed_segments: &'static FxHashSet<String>,
+    allowed_segments: FxHashSet<String>,
 }
 
 impl WildcardImports {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
             warn_on_all: conf.warn_on_all_wildcard_imports,
-            allowed_segments: &conf.allowed_wildcard_imports,
+            allowed_segments: conf.allowed_wildcard_imports.iter().cloned().collect(),
         }
     }
 }
@@ -181,7 +181,7 @@ impl WildcardImports {
     fn check_exceptions(&self, cx: &LateContext<'_>, item: &Item<'_>, segments: &[PathSegment<'_>]) -> bool {
         item.span.from_expansion()
             || is_prelude_import(segments)
-            || is_allowed_via_config(segments, self.allowed_segments)
+            || is_allowed_via_config(segments, &self.allowed_segments)
             || (is_super_only_import(segments) && is_in_test(cx.tcx, item.hir_id()))
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 54e7e92f0c4..ec5a5896fb2 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::is_in_test;
 use clippy_utils::macros::{format_arg_removal_span, root_macro_call_first_node, FormatArgsStorage, MacroCall};
-use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
+use clippy_utils::source::{expand_past_previous_comma, SpanRangeExt};
 use rustc_ast::token::LitKind;
 use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder,
@@ -397,7 +397,7 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &Ma
             format!("using `{name}!()` with a format string that ends in a single newline"),
             |diag| {
                 let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');
-                let Some(format_snippet) = snippet_opt(cx, format_string_span) else {
+                let Some(format_snippet) = format_string_span.get_source_text(cx) else {
                     return;
                 };
 
@@ -492,7 +492,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
             && let Some(arg) = format_args.arguments.by_index(index)
             && let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind
             && !arg.expr.span.from_expansion()
-            && let Some(value_string) = snippet_opt(cx, arg.expr.span)
+            && let Some(value_string) = arg.expr.span.get_source_text(cx)
         {
             let (replacement, replace_raw) = match lit.kind {
                 LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {
@@ -515,7 +515,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
                 _ => continue,
             };
 
-            let Some(format_string_snippet) = snippet_opt(cx, format_args.span) else {
+            let Some(format_string_snippet) = format_args.span.get_source_text(cx) else {
                 continue;
             };
             let format_string_is_raw = format_string_snippet.starts_with('r');
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 9fefd94d339..629ce9d04d4 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -8,7 +8,6 @@ publish = false
 clippy_config = { path = "../clippy_config" }
 arrayvec = { version = "0.7", default-features = false }
 itertools = "0.12"
-rustc-semver = "1.1"
 # FIXME(f16_f128): remove when no longer needed for parsing
 rustc_apfloat = "0.2.0"
 
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index d2200bcf710..42c8b218d14 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -7,7 +7,7 @@ use rustc_session::Session;
 use rustc_span::{sym, Span};
 use std::str::FromStr;
 
-use crate::source::snippet_opt;
+use crate::source::SpanRangeExt;
 use crate::tokenize_with_text;
 
 /// Deprecation status of attributes known by Clippy.
@@ -179,25 +179,23 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
 
 /// Checks if the given span contains a `#[cfg(..)]` attribute
 pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
-    let Some(snip) = snippet_opt(cx, s) else {
-        // Assume true. This would require either an invalid span, or one which crosses file boundaries.
-        return true;
-    };
-    let mut iter = tokenize_with_text(&snip);
+    s.check_source_text(cx, |src| {
+        let mut iter = tokenize_with_text(src);
 
-    // Search for the token sequence [`#`, `[`, `cfg`]
-    while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
-        let mut iter = iter.by_ref().skip_while(|(t, _)| {
-            matches!(
-                t,
-                TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
-            )
-        });
-        if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
-            && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
-        {
-            return true;
+        // Search for the token sequence [`#`, `[`, `cfg`]
+        while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
+            let mut iter = iter.by_ref().skip_while(|(t, _)| {
+                matches!(
+                    t,
+                    TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
+                )
+            });
+            if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
+                && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
+            {
+                return true;
+            }
         }
-    }
-    false
+        false
+    })
 }
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 7f2234b310b..2bd6837d973 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -123,16 +123,14 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
 
 fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) {
     let (head, tail) = match path.segments {
-        [head, .., tail] => (head, tail),
-        [p] => (p, p),
         [] => return (Pat::Str(""), Pat::Str("")),
+        [p] => (Pat::Sym(p.ident.name), p),
+        // QPath::Resolved can have a path that looks like `<Foo as Bar>::baz` where
+        // the path (`Bar::baz`) has it's span covering the whole QPath.
+        [.., tail] => (Pat::Str(""), tail),
     };
     (
-        if head.ident.name == kw::PathRoot {
-            Pat::Str("::")
-        } else {
-            Pat::Sym(head.ident.name)
-        },
+        head,
         if tail.args.is_some() {
             Pat::Str(">")
         } else {
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index e907e4058e5..760d5bc95f7 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -687,7 +687,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt)
                     && let expr_lo = expr_span.lo()
                     && expr_lo >= span.lo
-                    && let Some(src) = (span.lo..expr_lo).get_source_text(&self.tcx)
+                    && let Some(src) = (span.lo..expr_lo).get_source_range(&self.tcx)
                     && let Some(src) = src.as_str()
                 {
                     use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index f325e4eaf15..f61ef9ac1b0 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1,6 +1,6 @@
 use crate::consts::ConstEvalCtxt;
 use crate::macros::macro_backtrace;
-use crate::source::{snippet_opt, walk_span_to_context, SpanRange, SpanRangeExt};
+use crate::source::{walk_span_to_context, SpanRange, SpanRangeExt};
 use crate::tokenize_with_text;
 use rustc_ast::ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHasher;
@@ -588,10 +588,9 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'
             // block with an empty span.
             ([], None) if block.span.is_empty() => &ExprKind::Tup(&[]),
             // `{}` => `()`
-            ([], None) => match snippet_opt(cx, block.span) {
-                // Don't reduce if there are any tokens contained in the braces
-                Some(snip)
-                    if tokenize(&snip)
+            ([], None)
+                if block.span.check_source_text(cx, |src| {
+                    tokenize(src)
                         .map(|t| t.kind)
                         .filter(|t| {
                             !matches!(
@@ -599,11 +598,10 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'
                                 TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
                             )
                         })
-                        .ne([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().copied()) =>
-                {
-                    kind
-                },
-                _ => &ExprKind::Tup(&[]),
+                        .eq([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().copied())
+                }) =>
+            {
+                &ExprKind::Tup(&[])
             },
             ([], Some(expr)) => match expr.kind {
                 // `{ return .. }` => `return ..`
@@ -1191,9 +1189,9 @@ fn eq_span_tokens(
     pred: impl Fn(TokenKind) -> bool,
 ) -> bool {
     fn f(cx: &LateContext<'_>, left: Range<BytePos>, right: Range<BytePos>, pred: impl Fn(TokenKind) -> bool) -> bool {
-        if let Some(lsrc) = left.get_source_text(cx)
+        if let Some(lsrc) = left.get_source_range(cx)
             && let Some(lsrc) = lsrc.as_str()
-            && let Some(rsrc) = right.get_source_text(cx)
+            && let Some(rsrc) = right.get_source_range(cx)
             && let Some(rsrc) = rsrc.as_str()
         {
             let pred = |t: &(_, _)| pred(t.0);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 28755ae0710..5db14872c36 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -149,6 +149,7 @@ macro_rules! extract_msrv_attr {
 
 /// If the given expression is a local binding, find the initializer expression.
 /// If that initializer expression is another local binding, find its initializer again.
+///
 /// This process repeats as long as possible (but usually no more than once). Initializer
 /// expressions with adjustments are ignored. If this is not desired, use [`find_binding_init`]
 /// instead.
@@ -179,6 +180,7 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
 }
 
 /// Finds the initializer expression for a local binding. Returns `None` if the binding is mutable.
+///
 /// By only considering immutable bindings, we guarantee that the returned expression represents the
 /// value of the binding wherever it is referenced.
 ///
@@ -431,12 +433,12 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
         })
 }
 
-/// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the
+/// THIS METHOD IS DEPRECATED. Matches a `QPath` against a slice of segment string literals.
+///
+/// This method is deprecated and will eventually be removed since it does not match against the
 /// entire path or resolved `DefId`. Prefer using `match_def_path`. Consider getting a `DefId` from
 /// `QPath::Resolved.1.res.opt_def_id()`.
 ///
-/// Matches a `QPath` against a slice of segment string literals.
-///
 /// There is also `match_path` if you are dealing with a `rustc_hir::Path` instead of a
 /// `rustc_hir::QPath`.
 ///
@@ -485,12 +487,12 @@ pub fn is_path_diagnostic_item<'tcx>(
     path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.is_diagnostic_item(diag_item, id))
 }
 
-/// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the
+/// THIS METHOD IS DEPRECATED. Matches a `Path` against a slice of segment string literals.
+///
+/// This method is deprecated and will eventually be removed since it does not match against the
 /// entire path or resolved `DefId`. Prefer using `match_def_path`. Consider getting a `DefId` from
 /// `QPath::Resolved.1.res.opt_def_id()`.
 ///
-/// Matches a `Path` against a slice of segment string literals.
-///
 /// There is also `match_qpath` if you are dealing with a `rustc_hir::QPath` instead of a
 /// `rustc_hir::Path`.
 ///
@@ -905,6 +907,7 @@ pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) ->
 }
 
 /// Returns true if the expr is equal to `Default::default()` of it's type when evaluated.
+///
 /// It doesn't cover all cases, for example indirect function calls (some of std
 /// functions are supported) but it is the best we have.
 pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
@@ -1061,6 +1064,7 @@ impl std::ops::BitOrAssign for CaptureKind {
 }
 
 /// Given an expression referencing a local, determines how it would be captured in a closure.
+///
 /// Note as this will walk up to parent expressions until the capture can be determined it should
 /// only be used while making a closure somewhere a value is consumed. e.g. a block, match arm, or
 /// function argument (other than a receiver).
@@ -2365,8 +2369,9 @@ pub fn fn_def_id_with_node_args<'tcx>(
 }
 
 /// Returns `Option<String>` where String is a textual representation of the type encapsulated in
-/// the slice iff the given expression is a slice of primitives (as defined in the
-/// `is_recursively_primitive_type` function) and `None` otherwise.
+/// the slice iff the given expression is a slice of primitives.
+///
+/// (As defined in the `is_recursively_primitive_type` function.) Returns `None` otherwise.
 pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
     let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
     let expr_kind = expr_type.kind();
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 455239cc37f..1d7479bff82 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -150,10 +150,11 @@ pub fn first_node_macro_backtrace(cx: &LateContext<'_>, node: &impl HirNode) ->
 }
 
 /// If `node` is the "first node" in a macro expansion, returns `Some` with the `ExpnId` of the
-/// macro call site (i.e. the parent of the macro expansion). This generally means that `node`
-/// is the outermost node of an entire macro expansion, but there are some caveats noted below.
-/// This is useful for finding macro calls while visiting the HIR without processing the macro call
-/// at every node within its expansion.
+/// macro call site (i.e. the parent of the macro expansion).
+///
+/// This generally means that `node` is the outermost node of an entire macro expansion, but there
+/// are some caveats noted below. This is useful for finding macro calls while visiting the HIR
+/// without processing the macro call at every node within its expansion.
 ///
 /// If you already have immediate access to the parent node, it is simpler to
 /// just check the context of that span directly (e.g. `parent.span.from_expansion()`).
@@ -426,12 +427,8 @@ impl FormatArgsStorage {
     }
 }
 
-/// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value, if
-/// it cannot be found it will return the [`rustc_ast::Expr`].
-pub fn find_format_arg_expr<'hir, 'ast>(
-    start: &'hir Expr<'hir>,
-    target: &'ast FormatArgument,
-) -> Result<&'hir Expr<'hir>, &'ast rustc_ast::Expr> {
+/// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value
+pub fn find_format_arg_expr<'hir>(start: &'hir Expr<'hir>, target: &FormatArgument) -> Option<&'hir Expr<'hir>> {
     let SpanData {
         lo,
         hi,
@@ -449,7 +446,6 @@ pub fn find_format_arg_expr<'hir, 'ast>(
             ControlFlow::Continue(())
         }
     })
-    .ok_or(&target.expr)
 }
 
 /// Span of the `:` and format specifiers
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 95fbf0b2ea2..d9befb3c157 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -18,7 +18,6 @@ use rustc_middle::mir::{
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
-use rustc_semver::RustcVersion;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
@@ -391,11 +390,7 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
                     StableSince::Err => return false,
                 };
 
-                msrv.meets(RustcVersion::new(
-                    u32::from(const_stab_rust_version.major),
-                    u32::from(const_stab_rust_version.minor),
-                    u32::from(const_stab_rust_version.patch),
-                ))
+                msrv.meets(const_stab_rust_version)
             } else {
                 // Unstable const fn with the feature enabled.
                 msrv.current().is_none()
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index 96dd3c55d37..482e1e0147b 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -16,7 +16,7 @@ use rustc_span::{
 };
 use std::borrow::Cow;
 use std::fmt;
-use std::ops::Range;
+use std::ops::{Deref, Index, Range};
 
 pub trait HasSession {
     fn sess(&self) -> &Session;
@@ -94,10 +94,16 @@ impl IntoSpan for Range<BytePos> {
 }
 
 pub trait SpanRangeExt: SpanRange {
+    /// Attempts to get a handle to the source text. Returns `None` if either the span is malformed,
+    /// or the source text is not accessible.
+    fn get_source_text(self, cx: &impl HasSession) -> Option<SourceText> {
+        get_source_range(cx.sess().source_map(), self.into_range()).and_then(SourceText::new)
+    }
+
     /// Gets the source file, and range in the file, of the given span. Returns `None` if the span
     /// extends through multiple files, or is malformed.
-    fn get_source_text(self, cx: &impl HasSession) -> Option<SourceFileRange> {
-        get_source_text(cx.sess().source_map(), self.into_range())
+    fn get_source_range(self, cx: &impl HasSession) -> Option<SourceFileRange> {
+        get_source_range(cx.sess().source_map(), self.into_range())
     }
 
     /// Calls the given function with the source text referenced and returns the value. Returns
@@ -144,32 +150,70 @@ pub trait SpanRangeExt: SpanRange {
     fn trim_start(self, cx: &impl HasSession) -> Range<BytePos> {
         trim_start(cx.sess().source_map(), self.into_range())
     }
+}
+impl<T: SpanRange> SpanRangeExt for T {}
 
-    /// Writes the referenced source text to the given writer. Will return `Err` if the source text
-    /// could not be retrieved.
-    fn write_source_text_to(self, cx: &impl HasSession, dst: &mut impl fmt::Write) -> fmt::Result {
-        write_source_text_to(cx.sess().source_map(), self.into_range(), dst)
+/// Handle to a range of text in a source file.
+pub struct SourceText(SourceFileRange);
+impl SourceText {
+    /// Takes ownership of the source file handle if the source text is accessible.
+    pub fn new(text: SourceFileRange) -> Option<Self> {
+        if text.as_str().is_some() {
+            Some(Self(text))
+        } else {
+            None
+        }
     }
 
-    /// Extracts the referenced source text as an owned string.
-    fn source_text_to_string(self, cx: &impl HasSession) -> Option<String> {
-        self.with_source_text(cx, ToOwned::to_owned)
+    /// Gets the source text.
+    pub fn as_str(&self) -> &str {
+        self.0.as_str().unwrap()
+    }
+
+    /// Converts this into an owned string.
+    pub fn to_owned(&self) -> String {
+        self.as_str().to_owned()
+    }
+}
+impl Deref for SourceText {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.as_str()
+    }
+}
+impl AsRef<str> for SourceText {
+    fn as_ref(&self) -> &str {
+        self.as_str()
+    }
+}
+impl<T> Index<T> for SourceText
+where
+    str: Index<T>,
+{
+    type Output = <str as Index<T>>::Output;
+    fn index(&self, idx: T) -> &Self::Output {
+        &self.as_str()[idx]
+    }
+}
+impl fmt::Display for SourceText {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.as_str().fmt(f)
     }
 }
-impl<T: SpanRange> SpanRangeExt for T {}
 
-fn get_source_text(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {
+fn get_source_range(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {
     let start = sm.lookup_byte_offset(sp.start);
     let end = sm.lookup_byte_offset(sp.end);
     if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {
         return None;
     }
+    sm.ensure_source_file_source_present(&start.sf);
     let range = start.pos.to_usize()..end.pos.to_usize();
     Some(SourceFileRange { sf: start.sf, range })
 }
 
 fn with_source_text<T>(sm: &SourceMap, sp: Range<BytePos>, f: impl for<'a> FnOnce(&'a str) -> T) -> Option<T> {
-    if let Some(src) = get_source_text(sm, sp)
+    if let Some(src) = get_source_range(sm, sp)
         && let Some(src) = src.as_str()
     {
         Some(f(src))
@@ -183,7 +227,7 @@ fn with_source_text_and_range<T>(
     sp: Range<BytePos>,
     f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,
 ) -> Option<T> {
-    if let Some(src) = get_source_text(sm, sp)
+    if let Some(src) = get_source_range(sm, sp)
         && let Some(text) = &src.sf.src
     {
         Some(f(text, src.range))
@@ -198,7 +242,7 @@ fn map_range(
     sp: Range<BytePos>,
     f: impl for<'a> FnOnce(&'a str, Range<usize>) -> Option<Range<usize>>,
 ) -> Option<Range<BytePos>> {
-    if let Some(src) = get_source_text(sm, sp.clone())
+    if let Some(src) = get_source_range(sm, sp.clone())
         && let Some(text) = &src.sf.src
         && let Some(range) = f(text, src.range.clone())
     {
@@ -232,13 +276,6 @@ fn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {
     .unwrap_or(sp)
 }
 
-fn write_source_text_to(sm: &SourceMap, sp: Range<BytePos>, dst: &mut impl fmt::Write) -> fmt::Result {
-    match with_source_text(sm, sp, |src| dst.write_str(src)) {
-        Some(x) => x,
-        None => Err(fmt::Error),
-    }
-}
-
 pub struct SourceFileRange {
     pub sf: Lrc<SourceFile>,
     pub range: Range<usize>,
@@ -247,7 +284,11 @@ impl SourceFileRange {
     /// Attempts to get the text from the source file. This can fail if the source text isn't
     /// loaded.
     pub fn as_str(&self) -> Option<&str> {
-        self.sf.src.as_ref().and_then(|x| x.get(self.range.clone()))
+        self.sf
+            .src
+            .as_ref()
+            .or_else(|| self.sf.external_src.get().and_then(|src| src.get_source()))
+            .and_then(|x| x.get(self.range.clone()))
     }
 }
 
@@ -548,9 +589,10 @@ pub fn snippet_block_with_context<'a>(
     (reindent_multiline(snip, true, indent), from_macro)
 }
 
-/// Same as `snippet_with_applicability`, but first walks the span up to the given context. This
-/// will result in the macro call, rather than the expansion, if the span is from a child context.
-/// If the span is not from a child context, it will be used directly instead.
+/// Same as `snippet_with_applicability`, but first walks the span up to the given context.
+///
+/// This will result in the macro call, rather than the expansion, if the span is from a child
+/// context. If the span is not from a child context, it will be used directly instead.
 ///
 /// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR node
 /// would result in `box []`. If given the context of the address of expression, this function will
@@ -593,9 +635,10 @@ fn snippet_with_context_sess<'a>(
 }
 
 /// Walks the span up to the target context, thereby returning the macro call site if the span is
-/// inside a macro expansion, or the original span if it is not. Note this will return `None` in the
-/// case of the span being in a macro expansion, but the target context is from expanding a macro
-/// argument.
+/// inside a macro expansion, or the original span if it is not.
+///
+/// Note this will return `None` in the case of the span being in a macro expansion, but the target
+/// context is from expanding a macro argument.
 ///
 /// Given the following
 ///
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 2f6faba073e..f80981c11af 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -160,8 +160,10 @@ pub fn get_type_diagnostic_name(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Symb
 }
 
 /// Returns true if `ty` is a type on which calling `Clone` through a function instead of
-/// as a method, such as `Arc::clone()` is considered idiomatic. Lints should avoid suggesting to
-/// replace instances of `ty::Clone()` by `.clone()` for objects of those types.
+/// as a method, such as `Arc::clone()` is considered idiomatic.
+///
+/// Lints should avoid suggesting to replace instances of `ty::Clone()` by `.clone()` for objects
+/// of those types.
 pub fn should_call_clone_as_function(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     matches!(
         get_type_diagnostic_name(cx, ty),
@@ -398,8 +400,10 @@ fn is_normalizable_helper<'tcx>(
 }
 
 /// Returns `true` if the given type is a non aggregate primitive (a `bool` or `char`, any
-/// integer or floating-point number type). For checking aggregation of primitive types (e.g.
-/// tuples and slices of primitive type) see `is_recursively_primitive_type`
+/// integer or floating-point number type).
+///
+/// For checking aggregation of primitive types (e.g. tuples and slices of primitive type) see
+/// `is_recursively_primitive_type`
 pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool {
     matches!(ty.kind(), ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_))
 }
@@ -455,11 +459,6 @@ pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: LangItem)
     }
 }
 
-/// Gets the diagnostic name of the type, if it has one
-pub fn type_diagnostic_name(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Symbol> {
-    ty.ty_adt_def().and_then(|adt| cx.tcx.get_diagnostic_name(adt.did()))
-}
-
 /// Return `true` if the passed `typ` is `isize` or `usize`.
 pub fn is_isize_or_usize(typ: Ty<'_>) -> bool {
     matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))
@@ -476,9 +475,10 @@ pub fn match_type(cx: &LateContext<'_>, ty: Ty<'_>, path: &[&str]) -> bool {
     }
 }
 
-/// Checks if the drop order for a type matters. Some std types implement drop solely to
-/// deallocate memory. For these types, and composites containing them, changing the drop order
-/// won't result in any observable side effects.
+/// Checks if the drop order for a type matters.
+///
+/// Some std types implement drop solely to deallocate memory. For these types, and composites
+/// containing them, changing the drop order won't result in any observable side effects.
 pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     fn needs_ordered_drop_inner<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, seen: &mut FxHashSet<Ty<'tcx>>) -> bool {
         if !seen.insert(ty) {
@@ -1311,6 +1311,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl
 }
 
 /// Checks if a Ty<'_> has some inherent method Symbol.
+///
 /// This does not look for impls in the type's `Deref::Target` type.
 /// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`.
 pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> {
diff --git a/src/tools/clippy/declare_clippy_lint/src/lib.rs b/src/tools/clippy/declare_clippy_lint/src/lib.rs
index ca070f6c250..6aa24329b06 100644
--- a/src/tools/clippy/declare_clippy_lint/src/lib.rs
+++ b/src/tools/clippy/declare_clippy_lint/src/lib.rs
@@ -1,4 +1,4 @@
-#![feature(let_chains)]
+#![feature(let_chains, proc_macro_span)]
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
@@ -23,6 +23,7 @@ fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) ->
 
 struct ClippyLint {
     attrs: Vec<Attribute>,
+    version: Option<LitStr>,
     explanation: String,
     name: Ident,
     category: Ident,
@@ -41,8 +42,14 @@ impl Parse for ClippyLint {
                 let value = lit.value();
                 let line = value.strip_prefix(' ').unwrap_or(&value);
 
-                if line.starts_with("```") {
-                    explanation += "```\n";
+                if let Some(lang) = line.strip_prefix("```") {
+                    let tag = lang.split_once(',').map_or(lang, |(left, _)| left);
+                    if !in_code && matches!(tag, "" | "rust" | "ignore" | "should_panic" | "no_run" | "compile_fail") {
+                        explanation += "```rust\n";
+                    } else {
+                        explanation += line;
+                        explanation.push('\n');
+                    }
                     in_code = !in_code;
                 } else if !(in_code && line.starts_with("# ")) {
                     explanation += line;
@@ -68,6 +75,7 @@ impl Parse for ClippyLint {
 
         Ok(Self {
             attrs,
+            version,
             explanation,
             name,
             category,
@@ -123,6 +131,7 @@ impl Parse for ClippyLint {
 pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
     let ClippyLint {
         attrs,
+        version,
         explanation,
         name,
         category,
@@ -146,6 +155,14 @@ pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
     (&mut category[0..1]).make_ascii_uppercase();
     let category_variant = format_ident!("{category}");
 
+    let name_span = name.span().unwrap();
+    let location = format!("{}#L{}", name_span.source_file().path().display(), name_span.line());
+
+    let version = match version {
+        Some(version) => quote!(Some(#version)),
+        None => quote!(None),
+    };
+
     let output = quote! {
         rustc_session::declare_tool_lint! {
             #(#attrs)*
@@ -159,6 +176,8 @@ pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
             lint: &#name,
             category: crate::LintCategory::#category_variant,
             explanation: #explanation,
+            location: #location,
+            version: #version,
         };
     };
 
diff --git a/src/tools/clippy/lintcheck/src/json.rs b/src/tools/clippy/lintcheck/src/json.rs
index 4211bce90b2..ee0c80aea52 100644
--- a/src/tools/clippy/lintcheck/src/json.rs
+++ b/src/tools/clippy/lintcheck/src/json.rs
@@ -12,21 +12,21 @@ const TRUNCATION_TOTAL_TARGET: usize = 1000;
 
 #[derive(Debug, Deserialize, Serialize)]
 struct LintJson {
-    lint: String,
-    krate: String,
-    file_name: String,
-    byte_pos: (u32, u32),
-    file_link: String,
+    /// The lint name e.g. `clippy::bytes_nth`
+    name: String,
+    /// The filename and line number e.g. `anyhow-1.0.86/src/error.rs:42`
+    file_line: String,
+    file_url: String,
     rendered: String,
 }
 
 impl LintJson {
     fn key(&self) -> impl Ord + '_ {
-        (self.lint.as_str(), self.file_name.as_str(), self.byte_pos)
+        (self.name.as_str(), self.file_line.as_str())
     }
 
     fn info_text(&self, action: &str) -> String {
-        format!("{action} `{}` in `{}` at {}", self.lint, self.krate, self.file_link)
+        format!("{action} `{}` at [`{}`]({})", self.name, self.file_line, self.file_url)
     }
 }
 
@@ -36,13 +36,16 @@ pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
         .into_iter()
         .map(|warning| {
             let span = warning.span();
+            let file_name = span
+                .file_name
+                .strip_prefix("target/lintcheck/sources/")
+                .unwrap_or(&span.file_name);
+            let file_line = format!("{file_name}:{}", span.line_start);
             LintJson {
-                file_name: span.file_name.clone(),
-                byte_pos: (span.byte_start, span.byte_end),
-                krate: warning.krate,
-                file_link: warning.url,
-                lint: warning.lint,
-                rendered: warning.diag.rendered.unwrap(),
+                name: warning.name,
+                file_line,
+                file_url: warning.url,
+                rendered: warning.diag.rendered.unwrap().trim().to_string(),
             }
         })
         .collect();
@@ -63,7 +66,7 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
     let mut lint_warnings = vec![];
 
     for (name, changes) in &itertools::merge_join_by(old_warnings, new_warnings, |old, new| old.key().cmp(&new.key()))
-        .chunk_by(|change| change.as_ref().into_left().lint.to_string())
+        .chunk_by(|change| change.as_ref().into_left().name.clone())
     {
         let mut added = Vec::new();
         let mut removed = Vec::new();
@@ -162,7 +165,7 @@ fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
         return;
     }
 
-    print_h3(&warnings[0].lint, title);
+    print_h3(&warnings[0].name, title);
     println!();
 
     let warnings = truncate(warnings, truncate_after);
@@ -171,7 +174,7 @@ fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
         println!("{}", warning.info_text(title));
         println!();
         println!("```");
-        println!("{}", warning.rendered.trim_end());
+        println!("{}", warning.rendered);
         println!("```");
         println!();
     }
@@ -182,7 +185,7 @@ fn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {
         return;
     }
 
-    print_h3(&changed[0].0.lint, "Changed");
+    print_h3(&changed[0].0.name, "Changed");
     println!();
 
     let changed = truncate(changed, truncate_after);
@@ -191,7 +194,7 @@ fn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {
         println!("{}", new.info_text("Changed"));
         println!();
         println!("```diff");
-        for change in diff::lines(old.rendered.trim_end(), new.rendered.trim_end()) {
+        for change in diff::lines(&old.rendered, &new.rendered) {
             use diff::Result::{Both, Left, Right};
 
             match change {
diff --git a/src/tools/clippy/lintcheck/src/output.rs b/src/tools/clippy/lintcheck/src/output.rs
index 15378630695..e38036315c2 100644
--- a/src/tools/clippy/lintcheck/src/output.rs
+++ b/src/tools/clippy/lintcheck/src/output.rs
@@ -51,7 +51,7 @@ impl RustcIce {
 /// A single warning that clippy issued while checking a `Crate`
 #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct ClippyWarning {
-    pub lint: String,
+    pub name: String,
     pub diag: Diagnostic,
     pub krate: String,
     /// The URL that points to the file and line of the lint emission
@@ -60,8 +60,8 @@ pub struct ClippyWarning {
 
 impl ClippyWarning {
     pub fn new(mut diag: Diagnostic, base_url: &str, krate: &str) -> Option<Self> {
-        let lint = diag.code.clone()?.code;
-        if !(lint.contains("clippy") || diag.message.contains("clippy"))
+        let name = diag.code.clone()?.code;
+        if !(name.contains("clippy") || diag.message.contains("clippy"))
             || diag.message.contains("could not read cargo metadata")
         {
             return None;
@@ -92,7 +92,7 @@ impl ClippyWarning {
         };
 
         Some(Self {
-            lint,
+            name,
             diag,
             url,
             krate: krate.to_string(),
@@ -108,7 +108,7 @@ impl ClippyWarning {
         let mut file = span.file_name.clone();
         let file_with_pos = format!("{file}:{}:{}", span.line_start, span.line_end);
         match format {
-            OutputFormat::Text => format!("{file_with_pos} {} \"{}\"\n", self.lint, self.diag.message),
+            OutputFormat::Text => format!("{file_with_pos} {} \"{}\"\n", self.name, self.diag.message),
             OutputFormat::Markdown => {
                 if file.starts_with("target") {
                     file.insert_str(0, "../");
@@ -116,7 +116,7 @@ impl ClippyWarning {
 
                 let mut output = String::from("| ");
                 write!(output, "[`{file_with_pos}`]({file}#L{})", span.line_start).unwrap();
-                write!(output, r#" | `{:<50}` | "{}" |"#, self.lint, self.diag.message).unwrap();
+                write!(output, r#" | `{:<50}` | "{}" |"#, self.name, self.diag.message).unwrap();
                 output.push('\n');
                 output
             },
@@ -164,7 +164,7 @@ fn gather_stats(warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>)
     let mut counter: HashMap<&String, usize> = HashMap::new();
     warnings
         .iter()
-        .for_each(|wrn| *counter.entry(&wrn.lint).or_insert(0) += 1);
+        .for_each(|wrn| *counter.entry(&wrn.name).or_insert(0) += 1);
 
     // collect into a tupled list for sorting
     let mut stats: Vec<(&&String, &usize)> = counter.iter().collect();
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 5fbe4e544a9..0be2e81810e 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-08-08"
+channel = "nightly-2024-08-23"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 64253514fbe..9754254cdd0 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -1,25 +1,31 @@
-// We need this feature as it changes `dylib` linking behavior and allows us to link to
-// `rustc_driver`.
-#![feature(rustc_private)]
+#![feature(rustc_private, let_chains)]
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(unused_extern_crates)]
 
+use cargo_metadata::diagnostic::{Applicability, Diagnostic};
+use cargo_metadata::Message;
+use clippy_config::ClippyConfiguration;
+use clippy_lints::declared_lints::LINTS;
+use clippy_lints::deprecated_lints::{DEPRECATED, DEPRECATED_VERSION, RENAMED};
+use clippy_lints::LintInfo;
+use serde::{Deserialize, Serialize};
+use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::custom_flags::rustfix::RustfixMode;
+use ui_test::custom_flags::Flag;
 use ui_test::spanned::Spanned;
+use ui_test::test_result::TestRun;
 use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, OutputConflictHandling};
 
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
 use std::ffi::{OsStr, OsString};
-use std::fs;
+use std::fmt::Write;
 use std::path::{Path, PathBuf};
-use std::sync::LazyLock;
-use test_utils::IS_RUSTC_TEST_SUITE;
+use std::sync::mpsc::{channel, Sender};
+use std::{fs, iter, thread};
 
 // Test dependencies may need an `extern crate` here to ensure that they show up
 // in the depinfo file (otherwise cargo thinks they are unused)
-extern crate clippy_lints;
-extern crate clippy_utils;
 extern crate futures;
 extern crate if_chain;
 extern crate itertools;
@@ -55,7 +61,7 @@ static TEST_DEPENDENCIES: &[&str] = &[
 /// dependencies must be added to Cargo.toml at the project root. Test
 /// dependencies that are not *directly* used by this test module require an
 /// `extern crate` declaration.
-static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| {
+fn extern_flags() -> Vec<String> {
     let current_exe_depinfo = {
         let mut path = env::current_exe().unwrap();
         path.set_extension("d");
@@ -103,70 +109,93 @@ static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| {
         .into_iter()
         .map(|(name, path)| format!("--extern={name}={path}"))
         .collect()
-});
+}
 
 // whether to run internal tests or not
 const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
 
-fn base_config(test_dir: &str) -> (Config, Args) {
-    let mut args = Args::test().unwrap();
-    args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
-
-    let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
-    let mut config = Config {
-        output_conflict_handling: OutputConflictHandling::Error,
-        filter_files: env::var("TESTNAME")
-            .map(|filters| filters.split(',').map(str::to_string).collect())
-            .unwrap_or_default(),
-        target: None,
-        bless_command: Some("cargo uibless".into()),
-        out_dir: target_dir.join("ui_test"),
-        ..Config::rustc(Path::new("tests").join(test_dir))
-    };
-    config.comment_defaults.base().exit_status = None.into();
-    config.comment_defaults.base().require_annotations = None.into();
-    config
-        .comment_defaults
-        .base()
-        .set_custom("rustfix", RustfixMode::Everything);
-    config.comment_defaults.base().diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into();
-    config.with_args(&args);
-    let current_exe_path = env::current_exe().unwrap();
-    let deps_path = current_exe_path.parent().unwrap();
-    let profile_path = deps_path.parent().unwrap();
-
-    config.program.args.extend(
-        [
-            "--emit=metadata",
-            "-Aunused",
-            "-Ainternal_features",
-            "-Zui-testing",
-            "-Zdeduplicate-diagnostics=no",
-            "-Dwarnings",
-            &format!("-Ldependency={}", deps_path.display()),
-        ]
-        .map(OsString::from),
-    );
-
-    config.program.args.extend(EXTERN_FLAGS.iter().map(OsString::from));
-    // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
-    config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
+struct TestContext {
+    args: Args,
+    extern_flags: Vec<String>,
+    diagnostic_collector: Option<DiagnosticCollector>,
+    collector_thread: Option<thread::JoinHandle<()>>,
+}
 
-    if let Some(host_libs) = option_env!("HOST_LIBS") {
-        let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
-        config.program.args.push(dep.into());
+impl TestContext {
+    fn new() -> Self {
+        let mut args = Args::test().unwrap();
+        args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
+        let (diagnostic_collector, collector_thread) = var_os("COLLECT_METADATA")
+            .is_some()
+            .then(DiagnosticCollector::spawn)
+            .unzip();
+        Self {
+            args,
+            extern_flags: extern_flags(),
+            diagnostic_collector,
+            collector_thread,
+        }
     }
 
-    config.program.program = profile_path.join(if cfg!(windows) {
-        "clippy-driver.exe"
-    } else {
-        "clippy-driver"
-    });
-    (config, args)
+    fn base_config(&self, test_dir: &str) -> Config {
+        let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
+        let mut config = Config {
+            output_conflict_handling: OutputConflictHandling::Error,
+            filter_files: env::var("TESTNAME")
+                .map(|filters| filters.split(',').map(str::to_string).collect())
+                .unwrap_or_default(),
+            target: None,
+            bless_command: Some("cargo uibless".into()),
+            out_dir: target_dir.join("ui_test"),
+            ..Config::rustc(Path::new("tests").join(test_dir))
+        };
+        let defaults = config.comment_defaults.base();
+        defaults.exit_status = None.into();
+        defaults.require_annotations = None.into();
+        defaults.diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into();
+        defaults.set_custom("rustfix", RustfixMode::Everything);
+        if let Some(collector) = self.diagnostic_collector.clone() {
+            defaults.set_custom("diagnostic-collector", collector);
+        }
+        config.with_args(&self.args);
+        let current_exe_path = env::current_exe().unwrap();
+        let deps_path = current_exe_path.parent().unwrap();
+        let profile_path = deps_path.parent().unwrap();
+
+        config.program.args.extend(
+            [
+                "--emit=metadata",
+                "-Aunused",
+                "-Ainternal_features",
+                "-Zui-testing",
+                "-Zdeduplicate-diagnostics=no",
+                "-Dwarnings",
+                &format!("-Ldependency={}", deps_path.display()),
+            ]
+            .map(OsString::from),
+        );
+
+        config.program.args.extend(self.extern_flags.iter().map(OsString::from));
+        // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
+        config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
+
+        if let Some(host_libs) = option_env!("HOST_LIBS") {
+            let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
+            config.program.args.push(dep.into());
+        }
+
+        config.program.program = profile_path.join(if cfg!(windows) {
+            "clippy-driver.exe"
+        } else {
+            "clippy-driver"
+        });
+
+        config
+    }
 }
 
-fn run_ui() {
-    let (mut config, args) = base_config("ui");
+fn run_ui(cx: &TestContext) {
+    let mut config = cx.base_config("ui");
     config
         .program
         .envs
@@ -176,30 +205,29 @@ fn run_ui() {
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
-fn run_internal_tests() {
-    // only run internal tests with the internal-tests feature
+fn run_internal_tests(cx: &TestContext) {
     if !RUN_INTERNAL_TESTS {
         return;
     }
-    let (mut config, args) = base_config("ui-internal");
+    let mut config = cx.base_config("ui-internal");
     config.bless_command = Some("cargo uitest --features internal -- -- --bless".into());
 
     ui_test::run_tests_generic(
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
-fn run_ui_toml() {
-    let (mut config, args) = base_config("ui-toml");
+fn run_ui_toml(cx: &TestContext) {
+    let mut config = cx.base_config("ui-toml");
 
     config
         .comment_defaults
@@ -217,19 +245,19 @@ fn run_ui_toml() {
                 .envs
                 .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
         },
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
 // Allow `Default::default` as `OptWithSpan` is not nameable
 #[allow(clippy::default_trait_access)]
-fn run_ui_cargo() {
+fn run_ui_cargo(cx: &TestContext) {
     if IS_RUSTC_TEST_SUITE {
         return;
     }
 
-    let (mut config, args) = base_config("ui-cargo");
+    let mut config = cx.base_config("ui-cargo");
     config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;
     config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;
     config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
@@ -264,23 +292,25 @@ fn run_ui_cargo() {
                 .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path))
         },
         |_config, _file_contents| {},
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
 fn main() {
     set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
+
+    let cx = TestContext::new();
+
     // The SPEEDTEST_* env variables can be used to check Clippy's performance on your PR. It runs the
     // affected test 1000 times and gets the average.
     if let Ok(speedtest) = std::env::var("SPEEDTEST") {
         println!("----------- STARTING SPEEDTEST -----------");
         let f = match speedtest.as_str() {
-            "ui" => run_ui as fn(),
-            "cargo" => run_ui_cargo as fn(),
-            "toml" => run_ui_toml as fn(),
-            "internal" => run_internal_tests as fn(),
-            "ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(),
+            "ui" => run_ui,
+            "cargo" => run_ui_cargo,
+            "toml" => run_ui_toml,
+            "internal" => run_internal_tests,
 
             _ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"),
         };
@@ -297,7 +327,7 @@ fn main() {
         let mut sum = 0;
         for _ in 0..iterations {
             let start = std::time::Instant::now();
-            f();
+            f(&cx);
             sum += start.elapsed().as_millis();
         }
         println!(
@@ -306,11 +336,17 @@ fn main() {
             sum / u128::from(iterations)
         );
     } else {
-        run_ui();
-        run_ui_toml();
-        run_ui_cargo();
-        run_internal_tests();
+        run_ui(&cx);
+        run_ui_toml(&cx);
+        run_ui_cargo(&cx);
+        run_internal_tests(&cx);
+        drop(cx.diagnostic_collector);
+
         ui_cargo_toml_metadata();
+
+        if let Some(thread) = cx.collector_thread {
+            thread.join().unwrap();
+        }
     }
 }
 
@@ -349,3 +385,180 @@ fn ui_cargo_toml_metadata() {
         );
     }
 }
+
+#[derive(Deserialize)]
+#[serde(untagged)]
+enum DiagnosticOrMessage {
+    Diagnostic(Diagnostic),
+    Message(Message),
+}
+
+/// Collects applicabilities from the diagnostics produced for each UI test, producing the
+/// `util/gh-pages/lints.json` file used by <https://rust-lang.github.io/rust-clippy/>
+#[derive(Debug, Clone)]
+struct DiagnosticCollector {
+    sender: Sender<Vec<u8>>,
+}
+
+impl DiagnosticCollector {
+    #[allow(clippy::assertions_on_constants)]
+    fn spawn() -> (Self, thread::JoinHandle<()>) {
+        assert!(!IS_RUSTC_TEST_SUITE && !RUN_INTERNAL_TESTS);
+
+        let (sender, receiver) = channel::<Vec<u8>>();
+
+        let handle = thread::spawn(|| {
+            let mut applicabilities = HashMap::new();
+
+            for stderr in receiver {
+                for line in stderr.split(|&byte| byte == b'\n') {
+                    let diag = match serde_json::from_slice(line) {
+                        Ok(DiagnosticOrMessage::Diagnostic(diag)) => diag,
+                        Ok(DiagnosticOrMessage::Message(Message::CompilerMessage(message))) => message.message,
+                        _ => continue,
+                    };
+
+                    if let Some(lint) = diag.code.as_ref().and_then(|code| code.code.strip_prefix("clippy::")) {
+                        let applicability = applicabilities
+                            .entry(lint.to_string())
+                            .or_insert(Applicability::Unspecified);
+                        let diag_applicability = diag
+                            .children
+                            .iter()
+                            .flat_map(|child| &child.spans)
+                            .filter_map(|span| span.suggestion_applicability.clone())
+                            .max_by_key(applicability_ord);
+                        if let Some(diag_applicability) = diag_applicability
+                            && applicability_ord(&diag_applicability) > applicability_ord(applicability)
+                        {
+                            *applicability = diag_applicability;
+                        }
+                    }
+                }
+            }
+
+            let configs = clippy_config::get_configuration_metadata();
+            let mut metadata: Vec<LintMetadata> = LINTS
+                .iter()
+                .map(|lint| LintMetadata::new(lint, &applicabilities, &configs))
+                .chain(
+                    iter::zip(DEPRECATED, DEPRECATED_VERSION)
+                        .map(|((lint, reason), version)| LintMetadata::new_deprecated(lint, reason, version)),
+                )
+                .collect();
+            metadata.sort_unstable_by(|a, b| a.id.cmp(&b.id));
+
+            let json = serde_json::to_string_pretty(&metadata).unwrap();
+            fs::write("util/gh-pages/lints.json", json).unwrap();
+        });
+
+        (Self { sender }, handle)
+    }
+}
+
+fn applicability_ord(applicability: &Applicability) -> u8 {
+    match applicability {
+        Applicability::MachineApplicable => 4,
+        Applicability::HasPlaceholders => 3,
+        Applicability::MaybeIncorrect => 2,
+        Applicability::Unspecified => 1,
+        _ => unimplemented!(),
+    }
+}
+
+impl Flag for DiagnosticCollector {
+    fn post_test_action(
+        &self,
+        _config: &ui_test::per_test_config::TestConfig<'_>,
+        _cmd: &mut std::process::Command,
+        output: &std::process::Output,
+        _build_manager: &ui_test::build_manager::BuildManager<'_>,
+    ) -> Result<Vec<TestRun>, ui_test::Errored> {
+        if !output.stderr.is_empty() {
+            self.sender.send(output.stderr.clone()).unwrap();
+        }
+        Ok(Vec::new())
+    }
+
+    fn clone_inner(&self) -> Box<dyn Flag> {
+        Box::new(self.clone())
+    }
+
+    fn must_be_unique(&self) -> bool {
+        true
+    }
+}
+
+#[derive(Debug, Serialize)]
+struct LintMetadata {
+    id: String,
+    id_location: Option<&'static str>,
+    group: &'static str,
+    level: &'static str,
+    docs: String,
+    version: &'static str,
+    applicability: Applicability,
+}
+
+impl LintMetadata {
+    fn new(lint: &LintInfo, applicabilities: &HashMap<String, Applicability>, configs: &[ClippyConfiguration]) -> Self {
+        let name = lint.name_lower();
+        let applicability = applicabilities
+            .get(&name)
+            .cloned()
+            .unwrap_or(Applicability::Unspecified);
+        let past_names = RENAMED
+            .iter()
+            .filter(|(_, new_name)| new_name.strip_prefix("clippy::") == Some(&name))
+            .map(|(old_name, _)| old_name.strip_prefix("clippy::").unwrap())
+            .collect::<Vec<_>>();
+        let mut docs = lint.explanation.to_string();
+        if !past_names.is_empty() {
+            docs.push_str("\n### Past names\n\n");
+            for past_name in past_names {
+                writeln!(&mut docs, " * {past_name}").unwrap();
+            }
+        }
+        let configs: Vec<_> = configs
+            .iter()
+            .filter(|conf| conf.lints.contains(&name.as_str()))
+            .collect();
+        if !configs.is_empty() {
+            docs.push_str("\n### Configuration\n\n");
+            for config in configs {
+                writeln!(&mut docs, "{config}").unwrap();
+            }
+        }
+        Self {
+            id: name,
+            id_location: Some(lint.location),
+            group: lint.category_str(),
+            level: lint.lint.default_level.as_str(),
+            docs,
+            version: lint.version.unwrap(),
+            applicability,
+        }
+    }
+
+    fn new_deprecated(name: &str, reason: &str, version: &'static str) -> Self {
+        // The reason starts with a lowercase letter and ends without a period.
+        // This needs to be fixed for the website.
+        let mut reason = reason.to_owned();
+        if let Some(reason) = reason.get_mut(0..1) {
+            reason.make_ascii_uppercase();
+        }
+        Self {
+            id: name.strip_prefix("clippy::").unwrap().into(),
+            id_location: None,
+            group: "deprecated",
+            level: "none",
+            version,
+            docs: format!(
+                "### What it does\n\n\
+                Nothing. This lint has been deprecated\n\n\
+                ### Deprecation reason\n\n{reason}.\n",
+            ),
+            applicability: Applicability::Unspecified,
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/config-metadata.rs b/src/tools/clippy/tests/config-metadata.rs
new file mode 100644
index 00000000000..3e3711873ba
--- /dev/null
+++ b/src/tools/clippy/tests/config-metadata.rs
@@ -0,0 +1,78 @@
+#![feature(rustc_private)]
+
+use clippy_config::{get_configuration_metadata, ClippyConfiguration};
+use itertools::Itertools;
+use regex::Regex;
+use std::borrow::Cow;
+use std::{env, fs};
+
+fn metadata() -> impl Iterator<Item = ClippyConfiguration> {
+    get_configuration_metadata()
+        .into_iter()
+        .filter(|config| config.deprecation_reason.is_none())
+        .filter(|config| !config.lints.is_empty())
+}
+
+#[test]
+fn book() {
+    let path = "book/src/lint_configuration.md";
+    let current = fs::read_to_string(path).unwrap();
+
+    let configs = metadata().map(|conf| conf.to_markdown_paragraph()).join("\n");
+    let expected = format!(
+        r#"<!--
+This file is generated by `cargo bless --test config-metadata`.
+Please use that command to update the file and do not edit it by hand.
+-->
+
+# Lint Configuration Options
+
+The following list shows each configuration option, along with a description, its default value, an example
+and lints affected.
+
+---
+
+{}
+"#,
+        configs.trim(),
+    );
+
+    if current != expected {
+        if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") {
+            fs::write(path, expected).unwrap();
+        } else {
+            panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it");
+        }
+    }
+}
+
+#[test]
+fn changelog() {
+    let path = "CHANGELOG.md";
+    let current = fs::read_to_string(path).unwrap();
+
+    let configs = metadata().map(|conf| conf.to_markdown_link()).join("\n");
+
+    let re = Regex::new(
+        "(?s)\
+        (<!-- begin autogenerated links to configuration documentation -->)\
+        .*\
+        (<!-- end autogenerated links to configuration documentation -->)\
+        ",
+    )
+    .unwrap();
+    let expected = re.replace(&current, format!("$1\n{configs}\n$2"));
+
+    assert!(
+        matches!(expected, Cow::Owned(_)),
+        "failed to find configuration section in `{path}`"
+    );
+
+    if current != expected {
+        if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") {
+            fs::write(path, expected.as_bytes()).unwrap();
+        } else {
+            panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it");
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
index 1cc1034cd89..d24b0cd6162 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
@@ -1,29 +1,44 @@
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
    |
-LL |     std::f32::MAX;
-   |     ^^^^^^^^^^^^^
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::absolute-paths` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
    |
-LL |     core::f32::MAX;
-   |     ^^^^^^^^^^^^^^
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
    |
-LL |     ::core::f32::MAX;
-   |     ^^^^^^^^^^^^^^^^
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
    |
-LL |     ::std::f32::MAX;
-   |     ^^^^^^^^^^^^^^^
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr
new file mode 100644
index 00000000000..0cc6566af3a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr
@@ -0,0 +1,14 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr
new file mode 100644
index 00000000000..53aa9030e0d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr
@@ -0,0 +1,80 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
+   |
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13
+   |
+LL |     let _ = ::core::clone::Clone::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13
+   |
+LL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
+   |
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                 ^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18
+   |
+LL |         where T: core::clone::Clone
+   |                  ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                                ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5
+   |
+LL |     crate::m1::S
+   |     ^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
deleted file mode 100644
index f342ebf6632..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
+++ /dev/null
@@ -1,71 +0,0 @@
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5
-   |
-LL |     std::f32::MAX;
-   |     ^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::absolute-paths` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5
-   |
-LL |     core::f32::MAX;
-   |     ^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5
-   |
-LL |     ::core::f32::MAX;
-   |     ^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:5
-   |
-LL |     crate::a::b::c::C;
-   |     ^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:44:5
-   |
-LL |     crate::a::b::c::d::e::f::F;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:45:5
-   |
-LL |     crate::a::A;
-   |     ^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:46:5
-   |
-LL |     crate::a::b::B;
-   |     ^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:47:5
-   |
-LL |     crate::a::b::c::C::ZERO;
-   |     ^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:48:5
-   |
-LL |     helper::b::c::d::e::f();
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:49:5
-   |
-LL |     ::helper::b::c::d::e::f();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5
-   |
-LL |     ::std::f32::MAX;
-   |     ^^^^^^^^^^^^^^^
-
-error: aborting due to 11 previous errors
-
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
new file mode 100644
index 00000000000..70d71f6c4ea
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
@@ -0,0 +1,98 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
+   |
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13
+   |
+LL |     let _ = ::core::clone::Clone::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13
+   |
+LL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
+   |
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                 ^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18
+   |
+LL |         where T: core::clone::Clone
+   |                  ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                                ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14
+   |
+LL | pub const _: crate::S = {
+   |              ^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9
+   |
+LL |     let crate::S = m1::S;
+   |         ^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5
+   |
+LL |     crate::m1::S
+   |     ^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:122:14
+   |
+LL |     let _ = <crate::S as Clone>::clone(&m1::S);
+   |              ^^^^^^^^
+
+error: aborting due to 15 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
index a828701bcee..c024f2f513c 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
@@ -1,97 +1,123 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@aux-build:helper.rs
-//@revisions: allow_crates disallow_crates
+//@revisions: default allow_crates allow_long no_short
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default
 //@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
-//@[disallow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/disallow_crates
-#![allow(clippy::no_effect, clippy::legacy_numeric_constants, unused)]
-#![warn(clippy::absolute_paths)]
-#![feature(decl_macro)]
+//@[allow_long] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_long
+//@[no_short] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/no_short
+#![deny(clippy::absolute_paths)]
 
-extern crate helper;
-#[macro_use]
 extern crate proc_macros;
+use proc_macros::{external, inline_macros, with_span};
 
-pub mod a {
-    pub mod b {
-        pub mod c {
-            pub struct C;
+#[inline_macros]
+fn main() {
+    let _ = std::path::is_separator(' ');
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-            impl C {
-                pub const ZERO: u32 = 0;
-            }
+    // Make sure this is treated as having three path segments, not four.
+    let _ = ::std::path::MAIN_SEPARATOR;
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-            pub mod d {
-                pub mod e {
-                    pub mod f {
-                        pub struct F;
-                    }
-                }
-            }
-        }
+    let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); //~ absolute_paths
 
-        pub struct B;
-    }
+    // Note `std::path::Path::new` is treated as having three parts
+    let _: &std::path::Path = std::path::Path::new("");
+    //~[default]^ absolute_paths
+    //~[default]| absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
+    //~[no_short]| absolute_paths
 
-    pub struct A;
-}
+    // Treated as having three parts.
+    let _ = ::core::clone::Clone::clone(&0i32);
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+    let _ = <i32 as core::clone::Clone>::clone(&0i32);
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+    let _ = std::option::Option::None::<i32>;
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-fn main() {
-    f32::max(1.0, 2.0);
-    std::f32::MAX;
-    core::f32::MAX;
-    ::core::f32::MAX;
-    crate::a::b::c::C;
-    crate::a::b::c::d::e::f::F;
-    crate::a::A;
-    crate::a::b::B;
-    crate::a::b::c::C::ZERO;
-    helper::b::c::d::e::f();
-    ::helper::b::c::d::e::f();
-    fn b() -> a::b::B {
-        todo!()
+    {
+        // FIXME: macro calls should be checked.
+        let x = 1i32;
+        let _ = core::ptr::addr_of!(x);
     }
-    std::println!("a");
-    let x = 1;
-    std::ptr::addr_of!(x);
-    // Test we handle max segments with `PathRoot` properly; this has 4 segments but we should say it
-    // has 3
-    ::std::f32::MAX;
-    // Do not lint due to the above
-    ::helper::a();
-    // Do not lint
-    helper::a();
-    use crate::a::b::c::C;
-    use a::b;
-    use std::f32::MAX;
-    a::b::c::d::e::f::F;
-    b::c::C;
-    fn a() -> a::A {
-        todo!()
-    }
-    use a::b::c;
 
-    fn c() -> c::C {
-        todo!()
+    {
+        // FIXME: derive macro paths should be checked.
+        #[derive(core::clone::Clone)]
+        struct S;
     }
-    fn d() -> Result<(), ()> {
-        todo!()
+
+    {
+        use core::fmt;
+        use core::marker::PhantomData;
+
+        struct X<T>(PhantomData<T>);
+        impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+        //~[default]^ absolute_paths
+        //~[default]| absolute_paths
+        //~[no_short]| absolute_paths
+        //~[no_short]| absolute_paths
+        where T: core::clone::Clone
+        //~[no_short]^ absolute_paths
+        //~[default]| absolute_paths
+        {
+            fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+                Ok(())
+            }
+        }
     }
-    external! {
-        crate::a::b::c::C::ZERO;
+
+    {
+        mod m1 {
+            pub(crate) mod m2 {
+                pub(crate) const FOO: i32 = 0;
+            }
+        }
+        let _ = m1::m2::FOO;
     }
-    // For some reason, `path.span.from_expansion()` takes care of this for us
+
     with_span! {
         span
-        crate::a::b::c::C::ZERO;
+        let _ = std::path::is_separator(' ');
     }
-    macro_rules! local_crate {
-        () => {
-            crate::a::b::c::C::ZERO;
-        };
+
+    external! {
+        let _ = std::path::is_separator(' ');
     }
-    macro local_crate_2_0() {
-        crate::a::b::c::C::ZERO;
+
+    inline! {
+        let _ = std::path::is_separator(' ');
     }
-    local_crate!();
-    local_crate_2_0!();
+}
+
+pub use core::cmp::Ordering;
+pub use std::fs::File;
+
+#[derive(Clone)]
+pub struct S;
+mod m1 {
+    pub use crate::S;
+}
+
+//~[no_short]v absolute_paths
+pub const _: crate::S = {
+    let crate::S = m1::S; //~[no_short] absolute_paths
+
+    crate::m1::S
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+};
+
+pub fn f() {
+    let _ = <crate::S as Clone>::clone(&m1::S); //~[no_short] absolute_paths
 }
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr
new file mode 100644
index 00000000000..6fc495f0180
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr
@@ -0,0 +1,14 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:15:13
+   |
+LL |     let _ = ::m1::m2::X;
+   |             ^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:6:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs
new file mode 100644
index 00000000000..033c4780919
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs
@@ -0,0 +1,16 @@
+//@revisions: default allow_crates
+//@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default
+//@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
+//@edition:2015
+
+#![deny(clippy::absolute_paths)]
+
+mod m1 {
+    pub mod m2 {
+        pub struct X;
+    }
+}
+
+fn main() {
+    let _ = ::m1::m2::X; //~[default] absolute_paths
+}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
index 59a621e9d1d..9da49abcd31 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
@@ -1,2 +1 @@
-absolute-paths-max-segments = 2
-absolute-paths-allowed-crates = ["crate", "helper"]
+absolute-paths-allowed-crates = ["core", "crate"]
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml
new file mode 100644
index 00000000000..5992fd1ed82
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml
@@ -0,0 +1 @@
+absolute-paths-max-segments = 3
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs
deleted file mode 100644
index 8e2678f5fe6..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub fn a() {}
-
-pub mod b {
-    pub mod c {
-        pub mod d {
-            pub mod e {
-                pub fn f() {}
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml
deleted file mode 100644
index d44d648c641..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-absolute-paths-max-segments = 2
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml
new file mode 100644
index 00000000000..357524420c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml
@@ -0,0 +1 @@
+absolute-paths-max-segments = 0
diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
index a312df5a43a..3dafea56514 100644
--- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
+++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
@@ -1,7 +1,7 @@
 //! Tests macro_metavars_in_unsafe with default configuration
 #![feature(decl_macro)]
 #![warn(clippy::macro_metavars_in_unsafe)]
-#![allow(clippy::no_effect)]
+#![allow(clippy::no_effect, clippy::not_unsafe_ptr_arg_deref)]
 
 #[macro_export]
 macro_rules! allow_works {
@@ -237,6 +237,19 @@ macro_rules! nested_macros {
     }};
 }
 
+pub mod issue13219 {
+    #[macro_export]
+    macro_rules! m {
+        ($e:expr) => {
+            // Metavariable in a block tail expression
+            unsafe { $e }
+        };
+    }
+    pub fn f(p: *const i32) -> i32 {
+        m!(*p)
+    }
+}
+
 fn main() {
     allow_works!(1);
     simple!(1);
diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
index d6b97f6fde1..6f0ebcbba02 100644
--- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
@@ -1,4 +1,16 @@
 error: this macro expands metavariables in an unsafe block
+  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:245:13
+   |
+LL |             unsafe { $e }
+   |             ^^^^^^^^^^^^^
+   |
+   = note: this allows the user of the macro to write unsafe code outside of an unsafe block
+   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
+   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
+   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`
+
+error: this macro expands metavariables in an unsafe block
   --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9
    |
 LL | /         unsafe {
@@ -10,8 +22,6 @@ LL | |         }
    = note: this allows the user of the macro to write unsafe code outside of an unsafe block
    = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
    = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
-   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`
 
 error: this macro expands metavariables in an unsafe block
   --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:30:9
@@ -183,5 +193,5 @@ LL | |         }
    = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
    = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed
index b376d55a402..09732d1a50c 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.fixed
+++ b/src/tools/clippy/tests/ui/assigning_clones.fixed
@@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> {
         *self = Self(source.0.clone());
     }
 }
+
+#[cfg(test)]
+mod test {
+    #[derive(Default)]
+    struct Data {
+        field: String,
+    }
+
+    fn test_data() -> Data {
+        Data {
+            field: "default_value".to_string(),
+        }
+    }
+
+    #[test]
+    fn test() {
+        let mut data = test_data();
+        data.field = "override_value".to_owned();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs
index 11a5d4459c3..6be25ae17a5 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.rs
+++ b/src/tools/clippy/tests/ui/assigning_clones.rs
@@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> {
         *self = Self(source.0.clone());
     }
 }
+
+#[cfg(test)]
+mod test {
+    #[derive(Default)]
+    struct Data {
+        field: String,
+    }
+
+    fn test_data() -> Data {
+        Data {
+            field: "default_value".to_string(),
+        }
+    }
+
+    #[test]
+    fn test() {
+        let mut data = test_data();
+        data.field = "override_value".to_owned();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
index f7e659b10de..329be4d3662 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
@@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:13:13
    |
 LL |         if x.is_some() {
-   |         -------------- help: try: `if let Some(..) = x`
+   |         -------------- help: try: `if let Some(<item>) = x`
 LL |             // unnecessary
 LL |             x.unwrap();
    |             ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index ddd600418af..f7e338935a7 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9
    |
 LL |     if x.is_some() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 LL |         // unnecessary
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -17,7 +17,7 @@ error: called `expect` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9
    |
 LL |     if x.is_some() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 ...
 LL |         x.expect("an error message");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ error: called `unwrap` on `x` after checking its variant with `is_none`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:65:9
    |
 LL |     if x.is_none() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 ...
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -68,7 +68,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:13:13
    |
 LL |         if $a.is_some() {
-   |         --------------- help: try: `if let Some(..) = x`
+   |         --------------- help: try: `if let Some(<item>) = x`
 LL |             // unnecessary
 LL |             $a.unwrap();
    |             ^^^^^^^^^^^
@@ -82,7 +82,7 @@ error: called `unwrap` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:78:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Ok(..) = x`
+   |     ------------ help: try: `if let Ok(<item>) = x`
 LL |         // unnecessary
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -91,7 +91,7 @@ error: called `expect` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Ok(..) = x`
+   |     ------------ help: try: `if let Ok(<item>) = x`
 ...
 LL |         x.expect("an error message");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +127,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:94:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Err(..) = x`
+   |     ------------ help: try: `if let Err(<item>) = x`
 ...
 LL |         x.unwrap_err();
    |         ^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_err`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9
    |
 LL |     if x.is_err() {
-   |     ------------- help: try: `if let Err(..) = x`
+   |     ------------- help: try: `if let Err(<item>) = x`
 ...
 LL |         x.unwrap_err();
    |         ^^^^^^^^^^^^^^
@@ -154,7 +154,7 @@ error: called `unwrap` on `x` after checking its variant with `is_err`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9
    |
 LL |     if x.is_err() {
-   |     ------------- help: try: `if let Ok(..) = x`
+   |     ------------- help: try: `if let Ok(<item>) = x`
 ...
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -172,7 +172,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9
    |
 LL |     if option.is_some() {
-   |     ------------------- help: try: `if let Some(..) = &option`
+   |     ------------------- help: try: `if let Some(<item>) = &option`
 LL |         option.as_ref().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -189,7 +189,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:144:9
    |
 LL |     if result.is_ok() {
-   |     ----------------- help: try: `if let Ok(..) = &result`
+   |     ----------------- help: try: `if let Ok(<item>) = &result`
 LL |         result.as_ref().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -206,7 +206,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9
    |
 LL |     if option.is_some() {
-   |     ------------------- help: try: `if let Some(..) = &mut option`
+   |     ------------------- help: try: `if let Some(<item>) = &mut option`
 LL |         option.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -223,7 +223,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9
    |
 LL |     if result.is_ok() {
-   |     ----------------- help: try: `if let Ok(..) = &mut result`
+   |     ----------------- help: try: `if let Ok(<item>) = &mut result`
 LL |         result.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index 01944baee79..1da78b56239 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -223,7 +223,7 @@ help: the outer pattern can be modified to include the inner pattern
 LL |     if let Issue9647::A { a, .. } = x {
    |                           ^ replace this binding
 LL |         if let Some(u) = a {
-   |                ^^^^^^^ with this pattern, prefixed by a:
+   |                ^^^^^^^ with this pattern, prefixed by `a`:
 
 error: this `if let` can be collapsed into the outer `if let`
   --> tests/ui/collapsible_match.rs:292:9
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.fixed b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
new file mode 100644
index 00000000000..3f54b326979
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
@@ -0,0 +1,11 @@
+#![deny(clippy::implicit_hasher)]
+
+use std::collections::HashSet;
+
+fn main() {}
+
+pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
+    //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
+    let _ = [0u8; 0];
+    let _: HashSet<usize> = HashSet::default();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.rs b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
index 770f6cf448a..2890a9277c7 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3717.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
@@ -1,7 +1,5 @@
 #![deny(clippy::implicit_hasher)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::collections::HashSet;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
index 4b4618ee1bb..aac72c66965 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
@@ -1,5 +1,5 @@
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> tests/ui/crashes/ice-3717.rs:9:21
+  --> tests/ui/crashes/ice-3717.rs:7:21
    |
 LL | pub fn ice_3717(_: &HashSet<usize>) {
    |                     ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
index 56a8d22cb1c..9dafad8b784 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
@@ -3,6 +3,7 @@
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::fmt::Display;
+use std::ptr;
 use std::sync::atomic::AtomicUsize;
 use std::sync::Once;
 
@@ -53,4 +54,20 @@ mod issue_8493 {
     issue_8493!();
 }
 
+#[repr(C, align(8))]
+struct NoAtomic(usize);
+#[repr(C, align(8))]
+struct WithAtomic(AtomicUsize);
+
+const fn with_non_null() -> *const WithAtomic {
+    const NO_ATOMIC: NoAtomic = NoAtomic(0);
+    (&NO_ATOMIC as *const NoAtomic).cast()
+}
+const WITH_ATOMIC: *const WithAtomic = with_non_null();
+
+struct Generic<T>(T);
+impl<T> Generic<T> {
+    const RAW_POINTER: *const Cell<T> = ptr::null();
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
index 1f2b9561ce5..4a725147142 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
@@ -1,5 +1,5 @@
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:9:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:10:1
    |
 LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
    = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:10:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:11:1
    |
 LL | const CELL: Cell<usize> = Cell::new(6);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | const CELL: Cell<usize> = Cell::new(6);
    = help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:11:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:12:1
    |
 LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], V
    = help: consider making this a static item
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:16:9
+  --> tests/ui/declare_interior_mutable_const/others.rs:17:9
    |
 LL |         const $name: $ty = $e;
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | declare_const!(_ONCE: Once = Once::new());
    = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:44:13
+  --> tests/ui/declare_interior_mutable_const/others.rs:45:13
    |
 LL |             const _BAZ: Cell<usize> = Cell::new(0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed
new file mode 100644
index 00000000000..fb0f40b34a4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed
@@ -0,0 +1,13 @@
+// This test checks that words starting with capital letters and ending with "ified" don't
+// trigger the lint.
+
+#![deny(clippy::doc_markdown)]
+
+pub enum OutputFormat {
+    /// `HumaNified`
+    //~^ ERROR: item in documentation is missing backticks
+    Plain,
+    // Should not warn!
+    /// JSONified console output
+    Json,
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs
new file mode 100644
index 00000000000..8c1e1a3cd6c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs
@@ -0,0 +1,13 @@
+// This test checks that words starting with capital letters and ending with "ified" don't
+// trigger the lint.
+
+#![deny(clippy::doc_markdown)]
+
+pub enum OutputFormat {
+    /// HumaNified
+    //~^ ERROR: item in documentation is missing backticks
+    Plain,
+    // Should not warn!
+    /// JSONified console output
+    Json,
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
new file mode 100644
index 00000000000..ae68a767ec9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
@@ -0,0 +1,18 @@
+error: item in documentation is missing backticks
+  --> tests/ui/doc/doc_markdown-issue_13097.rs:7:9
+   |
+LL |     /// HumaNified
+   |         ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui/doc/doc_markdown-issue_13097.rs:4:9
+   |
+LL | #![deny(clippy::doc_markdown)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+help: try
+   |
+LL |     /// `HumaNified`
+   |         ~~~~~~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/double_must_use.rs b/src/tools/clippy/tests/ui/double_must_use.rs
index 615de3e2474..4460aeb075b 100644
--- a/src/tools/clippy/tests/ui/double_must_use.rs
+++ b/src/tools/clippy/tests/ui/double_must_use.rs
@@ -3,19 +3,19 @@
 
 #[must_use]
 pub fn must_use_result() -> Result<(), ()> {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
 #[must_use]
 pub fn must_use_tuple() -> (Result<(), ()>, u8) {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
 #[must_use]
 pub fn must_use_array() -> [Result<(), ()>; 1] {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
@@ -32,7 +32,7 @@ async fn async_must_use() -> usize {
 
 #[must_use]
 async fn async_must_use_result() -> Result<(), ()> {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     Ok(())
 }
 
diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr
index 0f2154ecbcf..b26d1e48a8b 100644
--- a/src/tools/clippy/tests/ui/double_must_use.stderr
+++ b/src/tools/clippy/tests/ui/double_must_use.stderr
@@ -1,36 +1,36 @@
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:5:1
    |
 LL | pub fn must_use_result() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
    = note: `-D clippy::double-must-use` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]`
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:11:1
    |
 LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:17:1
    |
 LL | pub fn must_use_array() -> [Result<(), ()>; 1] {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:34:1
    |
 LL | async fn async_must_use_result() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index f38b34c5a7c..1148f0f6c6a 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -153,3 +153,15 @@ fn main() {
     let r = &x;
     for _ in r {}
 }
+
+#[clippy::msrv = "1.79"]
+pub fn issue_13184() {
+    // https://github.com/rust-lang/rust-clippy/issues/13184
+    // No need to fix, as IntoIterator for Box is valid starting from 1.80
+    let mut values: Box<[u32]> = Box::new([1, 2]);
+    for _ in values.iter() {}
+    for _ in values.iter_mut() {}
+
+    let rvalues = &values;
+    for _ in rvalues.iter() {}
+}
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index 2e701ada5ac..4dda2f13e5b 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -153,3 +153,15 @@ fn main() {
     let r = &x;
     for _ in r.iter() {}
 }
+
+#[clippy::msrv = "1.79"]
+pub fn issue_13184() {
+    // https://github.com/rust-lang/rust-clippy/issues/13184
+    // No need to fix, as IntoIterator for Box is valid starting from 1.80
+    let mut values: Box<[u32]> = Box::new([1, 2]);
+    for _ in values.iter() {}
+    for _ in values.iter_mut() {}
+
+    let rvalues = &values;
+    for _ in rvalues.iter() {}
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.fixed b/src/tools/clippy/tests/ui/floating_point_abs.fixed
index 5312a8b29c6..33183c76972 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_abs.fixed
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal ops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.rs b/src/tools/clippy/tests/ui/floating_point_abs.rs
index 8619177130c..a08d5bbcef5 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.rs
+++ b/src/tools/clippy/tests/ui/floating_point_abs.rs
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal ops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.stderr b/src/tools/clippy/tests/ui/floating_point_abs.stderr
index f5a778c5b76..0c1f68f3b7f 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_abs.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of `abs` method
-  --> tests/ui/floating_point_abs.rs:15:5
+  --> tests/ui/floating_point_abs.rs:14:5
    |
 LL |     if num >= 0.0 { num } else { -num }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
@@ -8,43 +8,43 @@ LL |     if num >= 0.0 { num } else { -num }
    = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
 
 error: manual implementation of `abs` method
-  --> tests/ui/floating_point_abs.rs:19:5
+  --> tests/ui/floating_point_abs.rs:18:5
    |
 LL |     if 0.0 < num { num } else { -num }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
 
 error: manual implementation of `abs` method
-  --> tests/ui/floating_point_abs.rs:23:5
+  --> tests/ui/floating_point_abs.rs:22:5
    |
 LL |     if a.a > 0.0 { a.a } else { -a.a }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
 
 error: manual implementation of `abs` method
-  --> tests/ui/floating_point_abs.rs:27:5
+  --> tests/ui/floating_point_abs.rs:26:5
    |
 LL |     if 0.0 >= num { -num } else { num }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
 
 error: manual implementation of `abs` method
-  --> tests/ui/floating_point_abs.rs:31:5
+  --> tests/ui/floating_point_abs.rs:30:5
    |
 LL |     if a.a < 0.0 { -a.a } else { a.a }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
 
 error: manual implementation of negation of `abs` method
-  --> tests/ui/floating_point_abs.rs:35:5
+  --> tests/ui/floating_point_abs.rs:34:5
    |
 LL |     if num < 0.0 { num } else { -num }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
 
 error: manual implementation of negation of `abs` method
-  --> tests/ui/floating_point_abs.rs:39:5
+  --> tests/ui/floating_point_abs.rs:38:5
    |
 LL |     if 0.0 >= num { num } else { -num }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
 
 error: manual implementation of negation of `abs` method
-  --> tests/ui/floating_point_abs.rs:44:12
+  --> tests/ui/floating_point_abs.rs:43:12
    |
 LL |         a: if a.a >= 0.0 { -a.a } else { a.a },
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()`
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
index 3ce2edf2c71..164aac2601a 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal_ops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
index b5e4a8db4db..ae024b7f224 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal_ops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
index 3e1a071de73..9c75909f715 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
@@ -1,5 +1,5 @@
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:20:13
+  --> tests/ui/floating_point_mul_add.rs:19:13
    |
 LL |     let _ = a * b + c;
    |             ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
@@ -8,73 +8,73 @@ LL |     let _ = a * b + c;
    = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:21:13
+  --> tests/ui/floating_point_mul_add.rs:20:13
    |
 LL |     let _ = a * b - c;
    |             ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:22:13
+  --> tests/ui/floating_point_mul_add.rs:21:13
    |
 LL |     let _ = c + a * b;
    |             ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:23:13
+  --> tests/ui/floating_point_mul_add.rs:22:13
    |
 LL |     let _ = c - a * b;
    |             ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:24:13
+  --> tests/ui/floating_point_mul_add.rs:23:13
    |
 LL |     let _ = a + 2.0 * 4.0;
    |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:25:13
+  --> tests/ui/floating_point_mul_add.rs:24:13
    |
 LL |     let _ = a + 2. * 4.;
    |             ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:27:13
+  --> tests/ui/floating_point_mul_add.rs:26:13
    |
 LL |     let _ = (a * b) + c;
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:28:13
+  --> tests/ui/floating_point_mul_add.rs:27:13
    |
 LL |     let _ = c + (a * b);
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:29:13
+  --> tests/ui/floating_point_mul_add.rs:28:13
    |
 LL |     let _ = a * b * c + d;
    |             ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:31:13
+  --> tests/ui/floating_point_mul_add.rs:30:13
    |
 LL |     let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:32:13
+  --> tests/ui/floating_point_mul_add.rs:31:13
    |
 LL |     let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:34:13
+  --> tests/ui/floating_point_mul_add.rs:33:13
    |
 LL |     let _ = (a * a + b).sqrt();
    |             ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
 
 error: multiply and add expressions can be calculated more efficiently and accurately
-  --> tests/ui/floating_point_mul_add.rs:37:13
+  --> tests/ui/floating_point_mul_add.rs:36:13
    |
 LL |     let _ = a - (b * u as f64);
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed
index a710bd9bd60..2f93d233cb4 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal_flops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs
index 14656f021df..9690effc4e1 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.rs
+++ b/src/tools/clippy/tests/ui/floating_point_rad.rs
@@ -1,4 +1,3 @@
-#![feature(const_fn_floating_point_arithmetic)]
 #![warn(clippy::suboptimal_flops)]
 
 /// Allow suboptimal_flops in constant context
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.stderr b/src/tools/clippy/tests/ui/floating_point_rad.stderr
index 64674342c2b..b834f5374e0 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_rad.stderr
@@ -1,5 +1,5 @@
 error: conversion to radians can be done more accurately
-  --> tests/ui/floating_point_rad.rs:11:13
+  --> tests/ui/floating_point_rad.rs:10:13
    |
 LL |     let _ = degrees as f64 * std::f64::consts::PI / 180.0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`
@@ -8,43 +8,43 @@ LL |     let _ = degrees as f64 * std::f64::consts::PI / 180.0;
    = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
 
 error: conversion to degrees can be done more accurately
-  --> tests/ui/floating_point_rad.rs:12:13
+  --> tests/ui/floating_point_rad.rs:11:13
    |
 LL |     let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`
 
 error: conversion to degrees can be done more accurately
-  --> tests/ui/floating_point_rad.rs:17:13
+  --> tests/ui/floating_point_rad.rs:16:13
    |
 LL |     let _ = x * 180f32 / std::f32::consts::PI;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`
 
 error: conversion to degrees can be done more accurately
-  --> tests/ui/floating_point_rad.rs:18:13
+  --> tests/ui/floating_point_rad.rs:17:13
    |
 LL |     let _ = 90. * 180f64 / std::f64::consts::PI;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`
 
 error: conversion to degrees can be done more accurately
-  --> tests/ui/floating_point_rad.rs:19:13
+  --> tests/ui/floating_point_rad.rs:18:13
    |
 LL |     let _ = 90.5 * 180f64 / std::f64::consts::PI;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`
 
 error: conversion to radians can be done more accurately
-  --> tests/ui/floating_point_rad.rs:20:13
+  --> tests/ui/floating_point_rad.rs:19:13
    |
 LL |     let _ = x * std::f32::consts::PI / 180f32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`
 
 error: conversion to radians can be done more accurately
-  --> tests/ui/floating_point_rad.rs:21:13
+  --> tests/ui/floating_point_rad.rs:20:13
    |
 LL |     let _ = 90. * std::f32::consts::PI / 180f32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`
 
 error: conversion to radians can be done more accurately
-  --> tests/ui/floating_point_rad.rs:22:13
+  --> tests/ui/floating_point_rad.rs:21:13
    |
 LL |     let _ = 90.5 * std::f32::consts::PI / 180f32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
index 5778f8f526f..4c324587c96 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
@@ -15,6 +15,14 @@ struct Foo {
     z: i32,
 }
 
+#[derive(Default)]
+#[allow(clippy::inconsistent_struct_constructor)]
+struct Bar {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
 mod without_base {
     use super::Foo;
 
@@ -70,4 +78,17 @@ mod with_base {
     }
 }
 
+mod with_allow_ty_def {
+    use super::Bar;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`
+        Bar { y, x, z };
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
index 9efaf068934..d49f236b9b0 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
@@ -15,6 +15,14 @@ struct Foo {
     z: i32,
 }
 
+#[derive(Default)]
+#[allow(clippy::inconsistent_struct_constructor)]
+struct Bar {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
 mod without_base {
     use super::Foo;
 
@@ -74,4 +82,17 @@ mod with_base {
     }
 }
 
+mod with_allow_ty_def {
+    use super::Bar;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`
+        Bar { y, x, z };
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
index 1192271f911..97bb7c789a7 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
@@ -1,5 +1,5 @@
 error: struct constructor field order is inconsistent with struct definition field order
-  --> tests/ui/inconsistent_struct_constructor.rs:28:9
+  --> tests/ui/inconsistent_struct_constructor.rs:36:9
    |
 LL |         Foo { y, x, z };
    |         ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
@@ -8,7 +8,7 @@ LL |         Foo { y, x, z };
    = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]`
 
 error: struct constructor field order is inconsistent with struct definition field order
-  --> tests/ui/inconsistent_struct_constructor.rs:55:9
+  --> tests/ui/inconsistent_struct_constructor.rs:63:9
    |
 LL | /         Foo {
 LL | |             z,
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
index 2dccadd9fce..c8409d78ed7 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
@@ -17,7 +17,7 @@ mod multiple {
     //~^ ERROR: `clippy::msrv` is defined multiple times
 
     mod foo {
-        #![clippy::msrv = "1"]
+        #![clippy::msrv = "1.0"]
         #![clippy::msrv = "1.0.0"]
         //~^ ERROR: `clippy::msrv` is defined multiple times
     }
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
index b4cb1b5713f..dbc276ed89d 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
@@ -31,8 +31,8 @@ LL |         #![clippy::msrv = "1.0.0"]
 note: first definition found here
   --> tests/ui/min_rust_version_invalid_attr.rs:20:9
    |
-LL |         #![clippy::msrv = "1"]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL |         #![clippy::msrv = "1.0"]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs
index 440a86b104a..1d1911aaa1d 100644
--- a/src/tools/clippy/tests/ui/string_slice.rs
+++ b/src/tools/clippy/tests/ui/string_slice.rs
@@ -1,3 +1,5 @@
+use std::borrow::Cow;
+
 #[warn(clippy::string_slice)]
 #[allow(clippy::no_effect)]
 
@@ -11,4 +13,7 @@ fn main() {
     let s = String::from(m);
     &s[0..2];
     //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
+    let a = Cow::Borrowed("foo");
+    &a[0..3];
+    //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
 }
diff --git a/src/tools/clippy/tests/ui/string_slice.stderr b/src/tools/clippy/tests/ui/string_slice.stderr
index 7a4596b5f2d..bc0fcde34b8 100644
--- a/src/tools/clippy/tests/ui/string_slice.stderr
+++ b/src/tools/clippy/tests/ui/string_slice.stderr
@@ -1,5 +1,5 @@
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:5:6
+  --> tests/ui/string_slice.rs:7:6
    |
 LL |     &"Ölkanne"[1..];
    |      ^^^^^^^^^^^^^^
@@ -8,16 +8,22 @@ LL |     &"Ölkanne"[1..];
    = help: to override `-D warnings` add `#[allow(clippy::string_slice)]`
 
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:9:6
+  --> tests/ui/string_slice.rs:11:6
    |
 LL |     &m[2..5];
    |      ^^^^^^^
 
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:12:6
+  --> tests/ui/string_slice.rs:14:6
    |
 LL |     &s[0..2];
    |      ^^^^^^^
 
-error: aborting due to 3 previous errors
+error: indexing into a string may panic if the index is within a UTF-8 character
+  --> tests/ui/string_slice.rs:17:6
+   |
+LL |     &a[0..3];
+   |      ^^^^^^^
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed
new file mode 100644
index 00000000000..d4a0cdf3447
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// A very short summary.
+///
+/// A much longer explanation that goes into a lot more detail about
+/// how the thing works, possibly with doclinks and so one,
+/// and probably spanning a many rows. Blablabla, it needs to be over
+/// 200 characters so I needed to write something longeeeeeeer.
+pub struct Foo;
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs
new file mode 100644
index 00000000000..5a3b6c42a32
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// A very short summary.
+/// A much longer explanation that goes into a lot more detail about
+/// how the thing works, possibly with doclinks and so one,
+/// and probably spanning a many rows. Blablabla, it needs to be over
+/// 200 characters so I needed to write something longeeeeeeer.
+pub struct Foo;
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
new file mode 100644
index 00000000000..6403265a39c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
@@ -0,0 +1,20 @@
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1
+   |
+LL | / /// A very short summary.
+LL | | /// A much longer explanation that goes into a lot more detail about
+LL | | /// how the thing works, possibly with doclinks and so one,
+LL | | /// and probably spanning a many rows. Blablabla, it needs to be over
+LL | | /// 200 characters so I needed to write something longeeeeeeer.
+   | |_
+   |
+   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
+help: add an empty line
+   |
+LL ~ /// A very short summary.
+LL + ///
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
new file mode 100644
index 00000000000..1042249c5b7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
@@ -0,0 +1,53 @@
+//@no-rustfix
+
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub struct Bar;
+
+// Should not warn! (not an item visible on mod page)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+impl Bar {}
+
+// Should not warn! (less than 80 characters)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+///
+/// Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub enum Enum {
+    A,
+}
+
+/// Lorem
+/// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub union Union {
+    a: u8,
+    b: u8,
+}
+
+// Should not warn! (title)
+/// # bla
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub union Union2 {
+    a: u8,
+    b: u8,
+}
+
+// Should not warn! (not public)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+fn f() {}
+
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
new file mode 100644
index 00000000000..7f48e5cf884
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
@@ -0,0 +1,22 @@
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph.rs:5:1
+   |
+LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+LL | | /// gravida non lacinia at, rhoncus eu lacus.
+   | |_
+   |
+   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
+
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph.rs:26:1
+   |
+LL | / /// Lorem
+LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+LL | | /// gravida non lacinia at, rhoncus eu lacus.
+   | |_
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index fcd60f48bcc..bcdf65b217e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -2,316 +2,432 @@ error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:83:13
    |
 LL |     let _ = opt.unwrap_or_else(|| 2);
-   |             ^^^^--------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(2);
+   |                 ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:84:13
    |
 LL |     let _ = opt.unwrap_or_else(|| astronomers_pi);
-   |             ^^^^---------------------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(astronomers_pi);
+   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:85:13
    |
 LL |     let _ = opt.unwrap_or_else(|| ext_str.some_field);
-   |             ^^^^-------------------------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(ext_str.some_field);
+   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:87:13
    |
 LL |     let _ = opt.and_then(|_| ext_opt);
-   |             ^^^^---------------------
-   |                 |
-   |                 help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = opt.and(ext_opt);
+   |                 ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:88:13
    |
 LL |     let _ = opt.or_else(|| ext_opt);
-   |             ^^^^-------------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(ext_opt);
+   |                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:89:13
    |
 LL |     let _ = opt.or_else(|| None);
-   |             ^^^^----------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(None)`
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(None);
+   |                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:90:13
    |
 LL |     let _ = opt.get_or_insert_with(|| 2);
-   |             ^^^^------------------------
-   |                 |
-   |                 help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = opt.get_or_insert(2);
+   |                 ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:91:13
    |
 LL |     let _ = opt.ok_or_else(|| 2);
-   |             ^^^^----------------
-   |                 |
-   |                 help: use `ok_or(..)` instead: `ok_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _ = opt.ok_or(2);
+   |                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:92:13
    |
 LL |     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
-   |             ^^^^^^^^^^^^^^^^^-------------------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));
+   |                              ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:93:13
    |
 LL |     let _ = cond.then(|| astronomers_pi);
-   |             ^^^^^-----------------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = cond.then_some(astronomers_pi);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:94:13
    |
 LL |     let _ = true.then(|| -> _ {});
-   |             ^^^^^----------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({})`
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({});
+   |                  ~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:95:13
    |
 LL |     let _ = true.then(|| {});
-   |             ^^^^^-----------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({})`
+   |             ^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({});
+   |                  ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:99:13
    |
 LL |     let _ = Some(1).unwrap_or_else(|| *r);
-   |             ^^^^^^^^---------------------
-   |                     |
-   |                     help: use `unwrap_or(..)` instead: `unwrap_or(*r)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).unwrap_or(*r);
+   |                     ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:101:13
    |
 LL |     let _ = Some(1).unwrap_or_else(|| *b);
-   |             ^^^^^^^^---------------------
-   |                     |
-   |                     help: use `unwrap_or(..)` instead: `unwrap_or(*b)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).unwrap_or(*b);
+   |                     ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:103:13
    |
 LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &r);
-   |             ^^^^^^^^^^^^^^^^^---------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(&r)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).as_ref().unwrap_or(&r);
+   |                              ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:104:13
    |
 LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &b);
-   |             ^^^^^^^^^^^^^^^^^---------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(&b)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).as_ref().unwrap_or(&b);
+   |                              ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:107:13
    |
 LL |     let _ = Some(10).unwrap_or_else(|| 2);
-   |             ^^^^^^^^^--------------------
-   |                      |
-   |                      help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(10).unwrap_or(2);
+   |                      ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:108:13
    |
 LL |     let _ = Some(10).and_then(|_| ext_opt);
-   |             ^^^^^^^^^---------------------
-   |                      |
-   |                      help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = Some(10).and(ext_opt);
+   |                      ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:109:28
    |
 LL |     let _: Option<usize> = None.or_else(|| ext_opt);
-   |                            ^^^^^-------------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(ext_opt)`
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(ext_opt);
+   |                                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:110:13
    |
 LL |     let _ = None.get_or_insert_with(|| 2);
-   |             ^^^^^------------------------
-   |                  |
-   |                  help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = None.get_or_insert(2);
+   |                  ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:111:35
    |
 LL |     let _: Result<usize, usize> = None.ok_or_else(|| 2);
-   |                                   ^^^^^----------------
-   |                                        |
-   |                                        help: use `ok_or(..)` instead: `ok_or(2)`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _: Result<usize, usize> = None.ok_or(2);
+   |                                        ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:112:28
    |
 LL |     let _: Option<usize> = None.or_else(|| None);
-   |                            ^^^^^----------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(None)`
+   |                            ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(None);
+   |                                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:115:13
    |
 LL |     let _ = deep.0.unwrap_or_else(|| 2);
-   |             ^^^^^^^--------------------
-   |                    |
-   |                    help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = deep.0.unwrap_or(2);
+   |                    ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:116:13
    |
 LL |     let _ = deep.0.and_then(|_| ext_opt);
-   |             ^^^^^^^---------------------
-   |                    |
-   |                    help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = deep.0.and(ext_opt);
+   |                    ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:117:13
    |
 LL |     let _ = deep.0.or_else(|| None);
-   |             ^^^^^^^----------------
-   |                    |
-   |                    help: use `or(..)` instead: `or(None)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = deep.0.or(None);
+   |                    ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:118:13
    |
 LL |     let _ = deep.0.get_or_insert_with(|| 2);
-   |             ^^^^^^^------------------------
-   |                    |
-   |                    help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = deep.0.get_or_insert(2);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:119:13
    |
 LL |     let _ = deep.0.ok_or_else(|| 2);
-   |             ^^^^^^^----------------
-   |                    |
-   |                    help: use `ok_or(..)` instead: `ok_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _ = deep.0.ok_or(2);
+   |                    ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:150:28
    |
 LL |     let _: Option<usize> = None.or_else(|| Some(3));
-   |                            ^^^^^-------------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(Some(3))`
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(Some(3));
+   |                                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:151:13
    |
 LL |     let _ = deep.0.or_else(|| Some(3));
-   |             ^^^^^^^-------------------
-   |                    |
-   |                    help: use `or(..)` instead: `or(Some(3))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = deep.0.or(Some(3));
+   |                    ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:152:13
    |
 LL |     let _ = opt.or_else(|| Some(3));
-   |             ^^^^-------------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(Some(3))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(Some(3));
+   |                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:158:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| 2);
-   |             ^^^^^---------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(2);
+   |                  ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:159:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| astronomers_pi);
-   |             ^^^^^----------------------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(astronomers_pi);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:160:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| ext_str.some_field);
-   |             ^^^^^--------------------------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(ext_str.some_field);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:182:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(2));
-   |                                   ^^^^--------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(2))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(2));
+   |                                       ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:183:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
-   |                                   ^^^^---------------------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(astronomers_pi))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(astronomers_pi));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:184:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
-   |                                   ^^^^-------------------------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(ext_str.some_field))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(ext_str.some_field));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:186:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(2));
-   |                                   ^^^^------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(2))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(2));
+   |                                       ~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:187:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
-   |                                   ^^^^-------------------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(astronomers_pi))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:188:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
-   |                                   ^^^^-----------------------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:189:35
@@ -324,193 +440,265 @@ LL | |     // some lines
 ...  |
 LL | |     // some lines
 LL | |     or_else(|_| Ok(ext_str.some_field));
-   | |_____----------------------------------^
-   |       |
-   |       help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
+   | |_______________________________________^
+   |
+help: use `or` instead
+   |
+LL |     or(Ok(ext_str.some_field));
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:219:14
    |
 LL |     let _x = false.then(|| i32::MAX + 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX + 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX + 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:221:14
    |
 LL |     let _x = false.then(|| i32::MAX * 2);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX * 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX * 2);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:223:14
    |
 LL |     let _x = false.then(|| i32::MAX - 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX - 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX - 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:225:14
    |
 LL |     let _x = false.then(|| i32::MIN - 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN - 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN - 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:227:14
    |
 LL |     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
-   |              ^^^^^^-------------------------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some((1 + 2 * 3 - 2 / 3 + 9) << 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:229:14
    |
 LL |     let _x = false.then(|| 255u8 << 7);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 << 7)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 << 7);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:231:14
    |
 LL |     let _x = false.then(|| 255u8 << 8);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 << 8)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 << 8);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:233:14
    |
 LL |     let _x = false.then(|| 255u8 >> 8);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 >> 8)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 >> 8);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:236:14
    |
 LL |     let _x = false.then(|| i32::MAX + -1);
-   |              ^^^^^^----------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX + -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX + -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:238:14
    |
 LL |     let _x = false.then(|| -i32::MAX);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(-i32::MAX)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(-i32::MAX);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:240:14
    |
 LL |     let _x = false.then(|| -i32::MIN);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(-i32::MIN)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(-i32::MIN);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:243:14
    |
 LL |     let _x = false.then(|| 255 >> -7);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255 >> -7)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255 >> -7);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:245:14
    |
 LL |     let _x = false.then(|| 255 << -1);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255 << -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255 << -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:247:14
    |
 LL |     let _x = false.then(|| 1 / 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(1 / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(1 / 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:249:14
    |
 LL |     let _x = false.then(|| x << -1);
-   |              ^^^^^^----------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x << -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x << -1);
+   |                    ~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:251:14
    |
 LL |     let _x = false.then(|| x << 2);
-   |              ^^^^^^---------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x << 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x << 2);
+   |                    ~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:261:14
    |
 LL |     let _x = false.then(|| x / 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x / 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:263:14
    |
 LL |     let _x = false.then(|| x % 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x % 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x % 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:266:14
    |
 LL |     let _x = false.then(|| 1 / -1);
-   |              ^^^^^^---------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(1 / -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(1 / -1);
+   |                    ~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:268:14
    |
 LL |     let _x = false.then(|| i32::MIN / -1);
-   |              ^^^^^^----------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN / -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN / -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:271:14
    |
 LL |     let _x = false.then(|| i32::MIN / 0);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN / 0);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:273:14
    |
 LL |     let _x = false.then(|| 4 / 2);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(4 / 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(4 / 2);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:281:14
    |
 LL |     let _x = false.then(|| f1 + f2);
-   |              ^^^^^^----------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(f1 + f2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(f1 + f2);
+   |                    ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 63 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
index b566b119571..390235b2124 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
@@ -2,36 +2,47 @@ error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:13:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|()| 2);
-   |             ^^^^^^----------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|e::E| 2);
-   |             ^^^^^^------------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
-   |             ^^^^^^-------------------------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13
    |
 LL |     let _ = true.then(|| -> &[u8] { &[] });
-   |             ^^^^^-------------------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({ &[] })`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({ &[] });
+   |                  ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index dcf00e4e384..99b3560a064 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -20,6 +20,7 @@ new_pr = true
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
+    "flip1995",
     "matthiaskrgr",
     "giraffate",
 ]
diff --git a/src/tools/clippy/util/gh-pages/index.html b/src/tools/clippy/util/gh-pages/index.html
index 300c9de178f..f3d7e504fdf 100644
--- a/src/tools/clippy/util/gh-pages/index.html
+++ b/src/tools/clippy/util/gh-pages/index.html
@@ -23,378 +23,25 @@ Otherwise, have a great day =^.^=
     <link id="styleHighlight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/highlight.css">
     <link id="styleNight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/tomorrow-night.css" disabled="true">
     <link id="styleAyu" rel="stylesheet" href="https://rust-lang.github.io/mdBook/ayu-highlight.css" disabled="true">
-    <style>
-        blockquote { font-size: 1em; }
-        [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
-
-        .dropdown-menu {
-            color: var(--fg);
-            background: var(--theme-popup-bg);
-            border: 1px solid var(--theme-popup-border);
-        }
-
-        .dropdown-menu .divider {
-            background-color: var(--theme-popup-border);
-        }
-
-        .dropdown-menu .checkbox {
-            display: block;
-            white-space: nowrap;
-            margin: 0;
-        }
-        .dropdown-menu .checkbox label {
-            padding: 3px 20px;
-            width: 100%;
-        }
-
-        .dropdown-menu .checkbox input {
-            position: relative;
-            margin: 0 0.5rem 0;
-            padding: 0;
-        }
-
-        .dropdown-menu .checkbox:hover {
-            background-color: var(--theme-hover);
-        }
-
-        div.panel div.panel-body button {
-            background: var(--searchbar-bg);
-            color: var(--searchbar-fg);
-            border-color: var(--theme-popup-border);
-        }
-
-        div.panel div.panel-body button:hover {
-            box-shadow: 0 0 3px var(--searchbar-shadow-color);
-        }
-
-        div.panel div.panel-body  button.open {
-            filter: brightness(90%);
-        }
-
-        .dropdown-toggle .badge {
-            background-color: #777;
-        }
-
-        .panel-heading { cursor: pointer; }
-
-        .panel-title { display: flex; flex-wrap: wrap;}
-        .panel-title .label { display: inline-block; }
-
-        .panel-title-name { flex: 1; min-width: 400px;}
-        .panel-title-name span { vertical-align: bottom; }
-
-        .panel .panel-title-name .anchor { display: none; }
-        .panel:hover .panel-title-name .anchor { display: inline;}
-
-        .search-control {
-            margin-top: 15px;
-        }
-
-        @media (min-width: 992px) {
-            .search-control {
-                margin-top: 0;
-            }
-        }
-
-        @media (min-width: 405px) {
-            #upper-filters {
-                display: flex;
-                flex-wrap: wrap;
-            }
-        }
-
-        @media (max-width: 430px) {
-            /* Turn the version filter list to the left */
-            #version-filter-selector {
-                right: 0;
-                left: auto;
-            }
-        }
-
-        @media (max-width: 412px) {
-            #upper-filters,
-            .panel-body .search-control  {
-                padding-right: 8px;
-                padding-left: 8px;
-            }
-        }
-
-        .label {
-            padding-top: 0.3em;
-            padding-bottom: 0.3em;
-        }
-
-        .label-lint-group {
-            min-width: 8em;
-        }
-        .label-lint-level {
-            min-width: 4em;
-        }
-
-        .label-lint-level-allow {
-            background-color: #5cb85c;
-        }
-        .label-lint-level-warn {
-            background-color: #f0ad4e;
-        }
-        .label-lint-level-deny {
-            background-color: #d9534f;
-        }
-        .label-lint-level-none {
-            background-color: #777777;
-            opacity: 0.5;
-        }
-
-        .label-group-deprecated {
-            opacity: 0.5;
-        }
-
-        .label-doc-folding {
-            color: #000;
-            background-color: #fff;
-            border: 1px solid var(--theme-popup-border);
-        }
-        .label-doc-folding:hover {
-            background-color: #e6e6e6;
-        }
-
-        .lint-doc-md > h3 {
-            border-top: 1px solid var(--theme-popup-border);
-            padding: 10px 15px;
-            margin: 0 -15px;
-            font-size: 18px;
-        }
-        .lint-doc-md > h3:first-child {
-            border-top: none;
-            padding-top: 0px;
-        }
-
-        @media (max-width:749px) {
-            .lint-additional-info-container {
-                display: flex;
-                flex-flow: column;
-            }
-            .lint-additional-info-item + .lint-additional-info-item {
-                border-top: 1px solid var(--theme-popup-border);
-            }
-        }
-        @media (min-width:750px) {
-            .lint-additional-info-container {
-                display: flex;
-                flex-flow: row;
-            }
-            .lint-additional-info-item + .lint-additional-info-item {
-                border-left: 1px solid var(--theme-popup-border);
-            }
-        }
-
-        .lint-additional-info-item {
-            display: inline-flex;
-            min-width: 200px;
-            flex-grow: 1;
-            padding: 9px 5px 5px 15px;
-        }
-
-        .label-applicability {
-            background-color: #777777;
-            margin: auto 5px;
-        }
-
-        .label-version {
-            background-color: #777777;
-            margin: auto 5px;
-            font-family: monospace;
-        }
-
-        details {
-            border-radius: 4px;
-            padding: .5em .5em 0;
-        }
-
-        code {
-            white-space: pre !important;
-        }
-
-        summary {
-            font-weight: bold;
-            margin: -.5em -.5em 0;
-            padding: .5em;
-            display: revert;
-        }
-
-        details[open] {
-            padding: .5em;
-        }
-    </style>
-    <style>
-        /* Expanding the mdBoom theme*/
-        .light {
-            --inline-code-bg: #f6f7f6;
-        }
-        .rust {
-            --inline-code-bg: #f6f7f6;
-        }
-        .coal {
-            --inline-code-bg: #1d1f21;
-        }
-        .navy {
-            --inline-code-bg: #1d1f21;
-        }
-        .ayu {
-            --inline-code-bg: #191f26;
-        }
-
-        .theme-dropdown {
-            position: absolute;
-            margin: 0.7em;
-            z-index: 10;
-        }
-
-        /* Applying the mdBook theme */
-        .theme-icon {
-            text-align: center;
-            width: 2em;
-            height: 2em;
-            line-height: 2em;
-            border: solid 1px var(--icons);
-            border-radius: 5px;
-            user-select: none;
-            cursor: pointer;
-        }
-        .theme-icon:hover {
-            background: var(--theme-hover);
-        }
-        .theme-choice {
-            display: none;
-            list-style: none;
-            border: 1px solid var(--theme-popup-border);
-            border-radius: 5px;
-            color: var(--fg);
-            background: var(--theme-popup-bg);
-            padding: 0 0;
-            overflow: hidden;
-        }
-
-        .theme-dropdown.open .theme-choice {
-            display: block;
-        }
-
-        .theme-choice > li {
-            padding: 5px 10px;
-            font-size: 0.8em;
-            user-select: none;
-            cursor: pointer;
-        }
-
-        .theme-choice > li:hover {
-            background: var(--theme-hover);
-        }
-
-        .alert {
-            color: var(--fg);
-            background: var(--theme-hover);
-            border: 1px solid var(--theme-popup-border);
-        }
-        .page-header {
-            border-color: var(--theme-popup-border);
-        }
-        .panel-default > .panel-heading {
-            background: var(--theme-hover);
-            color: var(--fg);
-            border: 1px solid var(--theme-popup-border);
-        }
-        .panel-default > .panel-heading:hover {
-            filter: brightness(90%);
-        }
-        .list-group-item {
-            background: 0%;
-            border: 1px solid var(--theme-popup-border);
-        }
-        .panel, pre, hr {
-            background: var(--bg);
-            border: 1px solid var(--theme-popup-border);
-        }
-
-        #version-filter-selector .checkbox {
-            display: flex;
-        }
-
-        #version-filter {
-            min-width: available;
-        }
-
-        #version-filter li label {
-            padding-right: 0;
-            width: 35%;
-        }
-
-        .version-filter-input {
-            height: 60%;
-            width: 30%;
-            text-align: center;
-            border: none;
-            border-bottom: 1px solid #000000;
-        }
-
-        #filter-label, .filter-clear {
-            background: var(--searchbar-bg);
-            color: var(--searchbar-fg);
-            border-color: var(--theme-popup-border);
-            filter: brightness(95%);
-        }
-        #filter-label:hover, .filter-clear:hover {
-            filter: brightness(90%);
-        }
-        .filter-input {
-            background: var(--searchbar-bg);
-            color: var(--searchbar-fg);
-            border-color: var(--theme-popup-border);
-        }
-
-        .filter-input::-webkit-input-placeholder,
-        .filter-input::-moz-placeholder {
-            color: var(--searchbar-fg);
-            opacity: 30%;
-        }
-
-        .expansion-group {
-            margin-top: 15px;
-            padding: 0px 8px;
-            display: flex;
-            flex-wrap: nowrap;
-        }
-
-        @media (min-width: 992px) {
-            .expansion-group {
-                margin-top: 0;
-                padding: 0px 15px;
-            }
-        }
-
-        .expansion-control {
-            width: 50%;
-        }
-
-        :not(pre) > code {
-            color: var(--inline-code-color);
-            background-color: var(--inline-code-bg);
-        }
-        html {
-            scrollbar-color: var(--scrollbar) var(--bg);
-        }
-        body {
-            background: var(--bg);
-            color: var(--fg);
-        }
-
-    </style>
+    <link rel="stylesheet" href="style.css">
 </head>
 <body ng-app="clippy" ng-controller="lintList">
-    <div theme-dropdown class="theme-dropdown">
-        <div id="theme-icon" class="theme-icon">&#128396;</div>
-        <ul id="theme-menu" class="theme-choice">
-            <li id="{{id}}" ng-repeat="(id, name) in themes" ng-click="selectTheme(id)">{{name}}</li>
-        </ul>
+    <div id="settings-dropdown">
+        <div class="settings-icon" tabindex="-1"></div>
+        <div class="settings-menu" tabindex="-1">
+            <div class="setting-radio-name">Theme</div>
+            <select id="theme-choice" onchange="setTheme(this.value, true)">
+                <option value="ayu">Ayu</option>
+                <option value="coal">Coal</option>
+                <option value="light">Light</option>
+                <option value="navy">Navy</option>
+                <option value="rust">Rust</option>
+            </select>
+            <label>
+                <input type="checkbox" id="disable-shortcuts" onchange="changeSetting(this)">
+                <span>Disable keyboard shortcuts</span>
+            </label>
+        </div>
     </div>
 
     <div class="container">
@@ -592,7 +239,7 @@ Otherwise, have a great day =^.^=
                         <!-- Applicability -->
                         <div class="lint-additional-info-item">
                             <span> Applicability: </span>
-                            <span class="label label-default label-applicability">{{lint.applicability.applicability}}</span>
+                            <span class="label label-default label-applicability">{{lint.applicability}}</span>
                             <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants">(?)</a>
                         </div>
                         <!-- Clippy version -->
@@ -605,8 +252,8 @@ Otherwise, have a great day =^.^=
                             <a href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}">Related Issues</a>
                         </div>
                         <!-- Jump to source -->
-                        <div class="lint-additional-info-item" ng-if="lint.id_span">
-                            <a href="https://github.com/rust-lang/rust-clippy/blob/{{docVersion}}/clippy_lints/{{lint.id_span.path}}#L{{lint.id_span.line}}">View Source</a>
+                        <div class="lint-additional-info-item" ng-if="lint.id_location">
+                            <a href="https://github.com/rust-lang/rust-clippy/blob/{{docVersion}}/{{lint.id_location}}">View Source</a>
                         </div>
                     </div>
                 </div>
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index ed1e090e1b5..1a5330bc0e5 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -50,24 +50,6 @@
                 );
             };
         })
-        .directive('themeDropdown', function ($document) {
-            return {
-                restrict: 'A',
-                link: function ($scope, $element, $attr) {
-                    $element.bind('click', function () {
-                        $element.toggleClass('open');
-                        $element.addClass('open-recent');
-                    });
-
-                    $document.bind('click', function () {
-                        if (!$element.hasClass('open-recent')) {
-                            $element.removeClass('open');
-                        }
-                        $element.removeClass('open-recent');
-                    })
-                }
-            }
-        })
         .directive('filterDropdown', function ($document) {
             return {
                 restrict: 'A',
@@ -114,28 +96,19 @@
                 cargo: true,
                 complexity: true,
                 correctness: true,
-                deprecated: false,
                 nursery: true,
                 pedantic: true,
                 perf: true,
                 restriction: true,
                 style: true,
                 suspicious: true,
+                deprecated: false,
             }
 
             $scope.groups = {
                 ...GROUPS_FILTER_DEFAULT
             };
 
-            const THEMES_DEFAULT = {
-                light: "Light",
-                rust: "Rust",
-                coal: "Coal",
-                navy: "Navy",
-                ayu: "Ayu"
-            };
-            $scope.themes = THEMES_DEFAULT;
-
             $scope.versionFilters = {
                 "≥": {enabled: false, minorVersion: null },
                 "≤": {enabled: false, minorVersion: null },
@@ -153,11 +126,10 @@
             );
 
             const APPLICABILITIES_FILTER_DEFAULT = {
-                Unspecified: true,
-                Unresolved: true,
                 MachineApplicable: true,
                 MaybeIncorrect: true,
-                HasPlaceholders: true
+                HasPlaceholders: true,
+                Unspecified: true,
             };
 
             $scope.applicabilities = {
@@ -321,10 +293,6 @@
                 $location.path($scope.search);
             }
 
-            $scope.selectTheme = function (theme) {
-                setTheme(theme, true);
-            }
-
             $scope.toggleLevels = function (value) {
                 const levels = $scope.levels;
                 for (const key in levels) {
@@ -456,7 +424,7 @@
             }
 
             $scope.byApplicabilities = function (lint) {
-                return $scope.applicabilities[lint.applicability.applicability];
+                return $scope.applicabilities[lint.applicability];
             };
 
             // Show details for one lint
@@ -537,6 +505,16 @@ function getQueryVariable(variable) {
     }
 }
 
+function storeValue(settingName, value) {
+    try {
+        localStorage.setItem(`clippy-lint-list-${settingName}`, value);
+    } catch (e) { }
+}
+
+function loadValue(settingName) {
+    return localStorage.getItem(`clippy-lint-list-${settingName}`);
+}
+
 function setTheme(theme, store) {
     let enableHighlight = false;
     let enableNight = false;
@@ -569,14 +547,14 @@ function setTheme(theme, store) {
     document.getElementById("styleAyu").disabled = !enableAyu;
 
     if (store) {
-        try {
-            localStorage.setItem('clippy-lint-list-theme', theme);
-        } catch (e) { }
+        storeValue("theme", theme);
+    } else {
+        document.getElementById(`theme-choice`).value = theme;
     }
 }
 
 function handleShortcut(ev) {
-    if (ev.ctrlKey || ev.altKey || ev.metaKey) {
+    if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {
         return;
     }
 
@@ -601,11 +579,51 @@ function handleShortcut(ev) {
 document.addEventListener("keypress", handleShortcut);
 document.addEventListener("keydown", handleShortcut);
 
+function changeSetting(elem) {
+    if (elem.id === "disable-shortcuts") {
+        disableShortcuts = elem.checked;
+        storeValue(elem.id, elem.checked);
+    }
+}
+
+function onEachLazy(lazyArray, func) {
+    const arr = Array.prototype.slice.call(lazyArray);
+    for (const el of arr) {
+        func(el);
+    }
+}
+
+function handleBlur(event) {
+    const parent = document.getElementById("settings-dropdown");
+    if (!parent.contains(document.activeElement) &&
+        !parent.contains(event.relatedTarget)
+    ) {
+        parent.classList.remove("open");
+    }
+}
+
+function generateSettings() {
+    const settings = document.getElementById("settings-dropdown");
+    const settingsButton = settings.querySelector(".settings-icon")
+    settingsButton.onclick = () => settings.classList.toggle("open");
+    settingsButton.onblur = handleBlur;
+    const settingsMenu = settings.querySelector(".settings-menu");
+    settingsMenu.onblur = handleBlur;
+    onEachLazy(
+        settingsMenu.querySelectorAll("input"),
+        el => el.onblur = handleBlur,
+    );
+}
+
+generateSettings();
+
 // loading the theme after the initial load
 const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
-const theme = localStorage.getItem('clippy-lint-list-theme');
+const theme = loadValue('theme');
 if (prefersDark.matches && !theme) {
     setTheme("coal", false);
 } else {
     setTheme(theme, false);
 }
+let disableShortcuts = loadValue('disable-shortcuts') === "true";
+document.getElementById("disable-shortcuts").checked = disableShortcuts;
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
new file mode 100644
index 00000000000..a9485d51104
--- /dev/null
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -0,0 +1,398 @@
+blockquote { font-size: 1em; }
+
+[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
+    display: none !important;
+}
+
+.dropdown-menu {
+    color: var(--fg);
+    background: var(--theme-popup-bg);
+    border: 1px solid var(--theme-popup-border);
+}
+
+.dropdown-menu .divider {
+    background-color: var(--theme-popup-border);
+}
+
+.dropdown-menu .checkbox {
+    display: block;
+    white-space: nowrap;
+    margin: 0;
+}
+.dropdown-menu .checkbox label {
+    padding: 3px 20px;
+    width: 100%;
+}
+
+.dropdown-menu .checkbox input {
+    position: relative;
+    margin: 0 0.5rem 0;
+    padding: 0;
+}
+
+.dropdown-menu .checkbox:hover {
+    background-color: var(--theme-hover);
+}
+
+div.panel div.panel-body button {
+    background: var(--searchbar-bg);
+    color: var(--searchbar-fg);
+    border-color: var(--theme-popup-border);
+}
+
+div.panel div.panel-body button:hover {
+    box-shadow: 0 0 3px var(--searchbar-shadow-color);
+}
+
+div.panel div.panel-body  button.open {
+    filter: brightness(90%);
+}
+
+.dropdown-toggle .badge {
+    background-color: #777;
+}
+
+.panel-heading { cursor: pointer; }
+
+.panel-title { display: flex; flex-wrap: wrap;}
+.panel-title .label { display: inline-block; }
+
+.panel-title-name { flex: 1; min-width: 400px;}
+.panel-title-name span { vertical-align: bottom; }
+
+.panel .panel-title-name .anchor { display: none; }
+.panel:hover .panel-title-name .anchor { display: inline;}
+
+.search-control {
+    margin-top: 15px;
+}
+
+@media (min-width: 992px) {
+    .search-control {
+        margin-top: 0;
+    }
+}
+
+@media (min-width: 405px) {
+    #upper-filters {
+        display: flex;
+        flex-wrap: wrap;
+    }
+}
+
+@media (max-width: 430px) {
+    /* Turn the version filter list to the left */
+    #version-filter-selector {
+        right: 0;
+        left: auto;
+    }
+}
+
+@media (max-width: 412px) {
+    #upper-filters,
+    .panel-body .search-control  {
+        padding-right: 8px;
+        padding-left: 8px;
+    }
+}
+
+.label {
+    padding-top: 0.3em;
+    padding-bottom: 0.3em;
+}
+
+.label-lint-group {
+    min-width: 8em;
+}
+.label-lint-level {
+    min-width: 4em;
+}
+
+.label-lint-level-allow {
+    background-color: #5cb85c;
+}
+.label-lint-level-warn {
+    background-color: #f0ad4e;
+}
+.label-lint-level-deny {
+    background-color: #d9534f;
+}
+.label-lint-level-none {
+    background-color: #777777;
+    opacity: 0.5;
+}
+
+.label-group-deprecated {
+    opacity: 0.5;
+}
+
+.label-doc-folding {
+    color: #000;
+    background-color: #fff;
+    border: 1px solid var(--theme-popup-border);
+}
+.label-doc-folding:hover {
+    background-color: #e6e6e6;
+}
+
+.lint-doc-md > h3 {
+    border-top: 1px solid var(--theme-popup-border);
+    padding: 10px 15px;
+    margin: 0 -15px;
+    font-size: 18px;
+}
+.lint-doc-md > h3:first-child {
+    border-top: none;
+    padding-top: 0px;
+}
+
+@media (max-width:749px) {
+    .lint-additional-info-container {
+        display: flex;
+        flex-flow: column;
+    }
+    .lint-additional-info-item + .lint-additional-info-item {
+        border-top: 1px solid var(--theme-popup-border);
+    }
+}
+@media (min-width:750px) {
+    .lint-additional-info-container {
+        display: flex;
+        flex-flow: row;
+    }
+    .lint-additional-info-item + .lint-additional-info-item {
+        border-left: 1px solid var(--theme-popup-border);
+    }
+}
+
+.lint-additional-info-item {
+    display: inline-flex;
+    min-width: 200px;
+    flex-grow: 1;
+    padding: 9px 5px 5px 15px;
+}
+
+.label-applicability {
+    background-color: #777777;
+    margin: auto 5px;
+}
+
+.label-version {
+    background-color: #777777;
+    margin: auto 5px;
+    font-family: monospace;
+}
+
+details {
+    border-radius: 4px;
+    padding: .5em .5em 0;
+}
+
+code {
+    white-space: pre !important;
+}
+
+summary {
+    font-weight: bold;
+    margin: -.5em -.5em 0;
+    padding: .5em;
+    display: revert;
+}
+
+details[open] {
+    padding: .5em;
+}
+
+/* Expanding the mdBook theme*/
+.light {
+    --inline-code-bg: #f6f7f6;
+}
+.rust {
+    --inline-code-bg: #f6f7f6;
+}
+.coal {
+    --inline-code-bg: #1d1f21;
+}
+.navy {
+    --inline-code-bg: #1d1f21;
+}
+.ayu {
+    --inline-code-bg: #191f26;
+}
+
+#settings-dropdown {
+    position: absolute;
+    margin: 0.7em;
+    z-index: 10;
+    display: flex;
+}
+
+/* Applying the mdBook theme */
+.settings-icon {
+    text-align: center;
+    width: 2em;
+    height: 2em;
+    line-height: 2em;
+    border: solid 1px var(--icons);
+    border-radius: 5px;
+    user-select: none;
+    cursor: pointer;
+    background: var(--theme-hover);
+}
+.settings-menu {
+    display: none;
+    list-style: none;
+    border: 1px solid var(--theme-popup-border);
+    border-radius: 5px;
+    color: var(--fg);
+    background: var(--theme-popup-bg);
+    overflow: hidden;
+    padding: 9px;
+    width: 207px;
+    position: absolute;
+    top: 28px;
+}
+
+.settings-icon::before {
+    /* Wheel <https://www.svgrepo.com/svg/384069/settings-cog-gear> */
+    content: url('data:image/svg+xml,<svg width="18" height="18" viewBox="0 0 12 12" \
+enable-background="new 0 0 12 12" xmlns="http://www.w3.org/2000/svg">\
+<path d="M10.25,6c0-0.1243286-0.0261841-0.241333-0.0366211-0.362915l1.6077881-1.5545654l\
+-1.25-2.1650391  c0,0-1.2674561,0.3625488-2.1323853,0.6099854c-0.2034912-0.1431885-0.421875\
+-0.2639771-0.6494751-0.3701782L7.25,0h-2.5 c0,0-0.3214111,1.2857666-0.5393066,2.1572876\
+C3.9830933,2.2634888,3.7647095,2.3842773,3.5612183,2.5274658L1.428833,1.9174805 \
+l-1.25,2.1650391c0,0,0.9641113,0.9321899,1.6077881,1.5545654C1.7761841,5.758667,\
+1.75,5.8756714,1.75,6  s0.0261841,0.241333,0.0366211,0.362915L0.178833,7.9174805l1.25,\
+2.1650391l2.1323853-0.6099854  c0.2034912,0.1432495,0.421875,0.2639771,0.6494751,0.3701782\
+L4.75,12h2.5l0.5393066-2.1572876  c0.2276001-0.1062012,0.4459839-0.2269287,0.6494751\
+-0.3701782l2.1323853,0.6099854l1.25-2.1650391L10.2133789,6.362915  C10.2238159,6.241333,\
+10.25,6.1243286,10.25,6z M6,7.5C5.1715698,7.5,4.5,6.8284302,4.5,6S5.1715698,4.5,6,4.5S7.5\
+,5.1715698,7.5,6  S6.8284302,7.5,6,7.5z" fill="black"/></svg>');
+  width: 18px;
+  height: 18px;
+  display: block;
+  filter: invert(0.7);
+  padding-left: 4px;
+  padding-top: 3px;
+}
+
+.settings-menu * {
+    font-weight: normal;
+}
+
+.settings-menu label {
+    cursor: pointer;
+}
+
+#settings-dropdown.open .settings-menu {
+    display: block;
+}
+
+#theme-choice {
+    margin-bottom: 10px;
+    background: var(--searchbar-bg);
+    color: var(--searchbar-fg);
+    border-color: var(--theme-popup-border);
+    border-radius: 5px;
+    cursor: pointer;
+    width: 100%;
+    border-width: 1px;
+    padding: 5px;
+}
+
+.alert {
+    color: var(--fg);
+    background: var(--theme-hover);
+    border: 1px solid var(--theme-popup-border);
+}
+.page-header {
+    border-color: var(--theme-popup-border);
+}
+.panel-default > .panel-heading {
+    background: var(--theme-hover);
+    color: var(--fg);
+    border: 1px solid var(--theme-popup-border);
+}
+.panel-default > .panel-heading:hover {
+    filter: brightness(90%);
+}
+.list-group-item {
+    background: 0%;
+    border: 1px solid var(--theme-popup-border);
+}
+.panel, pre, hr {
+    background: var(--bg);
+    border: 1px solid var(--theme-popup-border);
+}
+
+#version-filter-selector .checkbox {
+    display: flex;
+}
+
+#version-filter {
+    min-width: available;
+}
+
+#version-filter li label {
+    padding-right: 0;
+    width: 35%;
+}
+
+.version-filter-input {
+    height: 60%;
+    width: 30%;
+    text-align: center;
+    border: none;
+    border-bottom: 1px solid #000000;
+}
+
+#filter-label, .filter-clear {
+    background: var(--searchbar-bg);
+    color: var(--searchbar-fg);
+    border-color: var(--theme-popup-border);
+    filter: brightness(95%);
+}
+#filter-label:hover, .filter-clear:hover {
+    filter: brightness(90%);
+}
+.filter-input {
+    background: var(--searchbar-bg);
+    color: var(--searchbar-fg);
+    border-color: var(--theme-popup-border);
+}
+
+.filter-input::-webkit-input-placeholder,
+.filter-input::-moz-placeholder {
+    color: var(--searchbar-fg);
+    opacity: 30%;
+}
+
+.expansion-group {
+    margin-top: 15px;
+    padding: 0px 8px;
+    display: flex;
+    flex-wrap: nowrap;
+}
+
+@media (min-width: 992px) {
+    .expansion-group {
+        margin-top: 0;
+        padding: 0px 15px;
+    }
+}
+
+.expansion-control {
+    width: 50%;
+}
+
+:not(pre) > code {
+    color: var(--inline-code-color);
+    background-color: var(--inline-code-bg);
+}
+html {
+    scrollbar-color: var(--scrollbar) var(--bg);
+}
+body {
+    background: var(--bg);
+    color: var(--fg);
+}
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/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 72448c1180a..fa77ab1e011 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -6,8 +6,10 @@
 //! script is to check all relative links in our documentation to make sure they
 //! actually point to a valid place.
 //!
-//! Currently this doesn't actually do any HTML parsing or anything fancy like
-//! that, it just has a simple "regex" to search for `href` and `id` tags.
+//! Currently uses a combination of HTML parsing to
+//! extract the `href` and `id` attributes,
+//! and regex search on the orignal markdown to handle intra-doc links.
+//!
 //! These values are then translated to file URLs if possible and then the
 //! destination is asserted to exist.
 //!
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index e12f3f9012f..4b7f3483ff7 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -20,7 +20,7 @@ doctest = false # and no doc tests
 [dependencies]
 getrandom = { version = "0.2", features = ["std"] }
 rand = "0.8"
-smallvec = "1.7"
+smallvec = { version = "1.7", features = ["drain_filter"] }
 aes = { version = "0.8.3", features = ["hazmat"] }
 measureme = "11"
 ctrlc = "3.2.5"
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index c3f4f4b5d82..1eca86baeaa 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-f24a6ba06f4190d8ec4f22d1baa800e64b1900cb
+fdf61d499c8a8421ecf98e7924bb87caf43a9938
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index 90bd1103218..56643c6cbe8 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -10,7 +10,7 @@
 //!   and the relative position of the access;
 //! - idempotency properties asserted in `perms.rs` (for optimizations)
 
-use std::fmt;
+use std::{fmt, mem};
 
 use smallvec::SmallVec;
 
@@ -699,8 +699,7 @@ impl<'tcx> Tree {
 /// Integration with the BorTag garbage collector
 impl Tree {
     pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) {
-        let root_is_needed = self.keep_only_needed(self.root, live_tags); // root can't be removed
-        assert!(root_is_needed);
+        self.remove_useless_children(self.root, live_tags);
         // Right after the GC runs is a good moment to check if we can
         // merge some adjacent ranges that were made equal by the removal of some
         // tags (this does not necessarily mean that they have identical internal representations,
@@ -708,9 +707,16 @@ impl Tree {
         self.rperms.merge_adjacent_thorough();
     }
 
+    /// Checks if a node is useless and should be GC'ed.
+    /// A node is useless if it has no children and also the tag is no longer live.
+    fn is_useless(&self, idx: UniIndex, live: &FxHashSet<BorTag>) -> bool {
+        let node = self.nodes.get(idx).unwrap();
+        node.children.is_empty() && !live.contains(&node.tag)
+    }
+
     /// Traverses the entire tree looking for useless tags.
-    /// Returns true iff the tag it was called on is still live or has live children,
-    /// and removes from the tree all tags that have no live children.
+    /// Removes from the tree all useless child nodes of root.
+    /// It will not delete the root itself.
     ///
     /// NOTE: This leaves in the middle of the tree tags that are unreachable but have
     /// reachable children. There is a potential for compacting the tree by reassigning
@@ -721,42 +727,60 @@ impl Tree {
     /// `child: Reserved`. This tree can exist. If we blindly delete `parent` and reassign
     /// `child` to be a direct child of `root` then Writes to `child` are now permitted
     /// whereas they were not when `parent` was still there.
-    fn keep_only_needed(&mut self, idx: UniIndex, live: &FxHashSet<BorTag>) -> bool {
-        let node = self.nodes.get(idx).unwrap();
-        // FIXME: this function does a lot of cloning, a 2-pass approach is possibly
-        // more efficient. It could consist of
-        // 1. traverse the Tree, collect all useless tags in a Vec
-        // 2. traverse the Vec, remove all tags previously selected
-        // Bench it.
-        let children: SmallVec<_> = node
-            .children
-            .clone()
-            .into_iter()
-            .filter(|child| self.keep_only_needed(*child, live))
-            .collect();
-        let no_children = children.is_empty();
-        let node = self.nodes.get_mut(idx).unwrap();
-        node.children = children;
-        if !live.contains(&node.tag) && no_children {
-            // All of the children and this node are unreachable, delete this tag
-            // from the tree (the children have already been deleted by recursive
-            // calls).
-            // Due to the API of UniMap we must absolutely call
-            // `UniValMap::remove` for the key of this tag on *all* maps that used it
-            // (which are `self.nodes` and every range of `self.rperms`)
-            // before we can safely apply `UniValMap::forget` to truly remove
-            // the tag from the mapping.
-            let tag = node.tag;
-            self.nodes.remove(idx);
-            for (_perms_range, perms) in self.rperms.iter_mut_all() {
-                perms.remove(idx);
+    fn remove_useless_children(&mut self, root: UniIndex, live: &FxHashSet<BorTag>) {
+        // To avoid stack overflows, we roll our own stack.
+        // Each element in the stack consists of the current tag, and the number of the
+        // next child to be processed.
+
+        // The other functions are written using the `TreeVisitorStack`, but that does not work here
+        // since we need to 1) do a post-traversal and 2) remove nodes from the tree.
+        // Since we do a post-traversal (by deleting nodes only after handling all children),
+        // we also need to be a bit smarter than "pop node, push all children."
+        let mut stack = vec![(root, 0)];
+        while let Some((tag, nth_child)) = stack.last_mut() {
+            let node = self.nodes.get(*tag).unwrap();
+            if *nth_child < node.children.len() {
+                // Visit the child by pushing it to the stack.
+                // Also increase `nth_child` so that when we come back to the `tag` node, we
+                // look at the next child.
+                let next_child = node.children[*nth_child];
+                *nth_child += 1;
+                stack.push((next_child, 0));
+                continue;
+            } else {
+                // We have processed all children of `node`, so now it is time to process `node` itself.
+                // First, get the current children of `node`. To appease the borrow checker,
+                // we have to temporarily move the list out of the node, and then put the
+                // list of remaining children back in.
+                let mut children_of_node =
+                    mem::take(&mut self.nodes.get_mut(*tag).unwrap().children);
+                // Remove all useless children, and save them for later.
+                // The closure needs `&self` and the loop below needs `&mut self`, so we need to `collect`
+                // in to a temporary list.
+                let to_remove: Vec<_> =
+                    children_of_node.drain_filter(|x| self.is_useless(*x, live)).collect();
+                // Put back the now-filtered vector.
+                self.nodes.get_mut(*tag).unwrap().children = children_of_node;
+                // Now, all that is left is unregistering the children saved in `to_remove`.
+                for idx in to_remove {
+                    // Note: In the rest of this comment, "this node" refers to `idx`.
+                    // This node has no more children (if there were any, they have already been removed).
+                    // It is also unreachable as determined by the GC, so we can remove it everywhere.
+                    // Due to the API of UniMap we must make sure to call
+                    // `UniValMap::remove` for the key of this node on *all* maps that used it
+                    // (which are `self.nodes` and every range of `self.rperms`)
+                    // before we can safely apply `UniKeyMap::remove` to truly remove
+                    // this tag from the `tag_mapping`.
+                    let node = self.nodes.remove(idx).unwrap();
+                    for (_perms_range, perms) in self.rperms.iter_mut_all() {
+                        perms.remove(idx);
+                    }
+                    self.tag_mapping.remove(&node.tag);
+                }
+                // We are done, the parent can continue.
+                stack.pop();
+                continue;
             }
-            self.tag_mapping.remove(&tag);
-            // The tag has been deleted, inform the caller
-            false
-        } else {
-            // The tag is still live or has live children, it must be kept
-            true
         }
     }
 }
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
index f45b2d9e00a..92bae6203b3 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
@@ -12,7 +12,7 @@
 
 #![allow(dead_code)]
 
-use std::hash::Hash;
+use std::{hash::Hash, mem};
 
 use rustc_data_structures::fx::FxHashMap;
 
@@ -187,13 +187,16 @@ impl<V> UniValMap<V> {
         self.data.get_mut(idx.idx as usize).and_then(Option::as_mut)
     }
 
-    /// Delete any value associated with this index. Ok even if the index
-    /// has no associated value.
-    pub fn remove(&mut self, idx: UniIndex) {
+    /// Delete any value associated with this index.
+    /// Returns None if the value was not present, otherwise
+    /// returns the previously stored value.
+    pub fn remove(&mut self, idx: UniIndex) -> Option<V> {
         if idx.idx as usize >= self.data.len() {
-            return;
+            return None;
         }
-        self.data[idx.idx as usize] = None;
+        let mut res = None;
+        mem::swap(&mut res, &mut self.data[idx.idx as usize]);
+        res
     }
 }
 
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/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index f72591f0c4b..a4d3e3f7af3 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -1157,7 +1157,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     }
 
     #[inline]
-    fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&[u8]>
+    fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&'c [u8]>
     where
         'tcx: 'c,
     {
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/src/machine.rs b/src/tools/miri/src/machine.rs
index a7493d48d6a..264b7b269de 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -947,15 +947,47 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     }
 
     #[inline(always)]
-    fn enforce_abi(_ecx: &MiriInterpCx<'tcx>) -> bool {
-        true
-    }
-
-    #[inline(always)]
     fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'tcx>) -> bool {
         !ecx.tcx.sess.overflow_checks()
     }
 
+    fn check_fn_target_features(
+        ecx: &MiriInterpCx<'tcx>,
+        instance: ty::Instance<'tcx>,
+    ) -> InterpResult<'tcx> {
+        let attrs = ecx.tcx.codegen_fn_attrs(instance.def_id());
+        if attrs
+            .target_features
+            .iter()
+            .any(|feature| !ecx.tcx.sess.target_features.contains(&feature.name))
+        {
+            let unavailable = attrs
+                .target_features
+                .iter()
+                .filter(|&feature| {
+                    !feature.implied && !ecx.tcx.sess.target_features.contains(&feature.name)
+                })
+                .fold(String::new(), |mut s, feature| {
+                    if !s.is_empty() {
+                        s.push_str(", ");
+                    }
+                    s.push_str(feature.name.as_str());
+                    s
+                });
+            let msg = format!(
+                "calling a function that requires unavailable target features: {unavailable}"
+            );
+            // On WASM, this is not UB, but instead gets rejected during validation of the module
+            // (see #84988).
+            if ecx.tcx.sess.target.is_like_wasm {
+                throw_machine_stop!(TerminationInfo::Abort(msg));
+            } else {
+                throw_ub_format!("{msg}");
+            }
+        }
+        Ok(())
+    }
+
     #[inline(always)]
     fn find_mir_or_eval_fn(
         ecx: &mut MiriInterpCx<'tcx>,
@@ -1060,6 +1092,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         ecx.generate_nan(inputs)
     }
 
+    fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> {
+        Ok(ecx.tcx.sess.ub_checks())
+    }
+
     fn thread_local_static_pointer(
         ecx: &mut MiriInterpCx<'tcx>,
         def_id: DefId,
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 80f4b89bf34..e00758bb98d 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -1204,14 +1204,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         )?;
                     }
                     "freebsd" => {
-                        this.write_int(ino, &this.project_field_named(&entry_place, "d_fileno")?)?;
-                        // `d_off` only exists on FreeBSD 12+, but we support v11 as well.
-                        // `libc` uses a build script to determine which version of the API to use,
-                        // and cross-builds always end up using v11.
-                        // To support both v11 and v12+, we dynamically check whether the field exists.
-                        if this.projectable_has_field(&entry_place, "d_off") {
-                            this.write_int(0, &this.project_field_named(&entry_place, "d_off")?)?;
-                        }
+                        #[rustfmt::skip]
+                        this.write_int_fields_named(
+                            &[
+                                ("d_fileno", ino.into()),
+                                ("d_off", 0),
+                            ],
+                            &entry_place,
+                        )?;
                     }
                     _ => unreachable!(),
                 }
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index c1117e4d811..305e59fa0cd 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -15,6 +15,7 @@ mod aesni;
 mod avx;
 mod avx2;
 mod bmi;
+mod sha;
 mod sse;
 mod sse2;
 mod sse3;
@@ -105,6 +106,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this, link_name, abi, args, dest,
                 );
             }
+            name if name.starts_with("sha") => {
+                return sha::EvalContextExt::emulate_x86_sha_intrinsic(
+                    this, link_name, abi, args, dest,
+                );
+            }
             name if name.starts_with("sse.") => {
                 return sse::EvalContextExt::emulate_x86_sse_intrinsic(
                     this, link_name, abi, args, dest,
diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs
new file mode 100644
index 00000000000..e9cc28be34c
--- /dev/null
+++ b/src/tools/miri/src/shims/x86/sha.rs
@@ -0,0 +1,221 @@
+//! Implements sha256 SIMD instructions of x86 targets
+//!
+//! The functions that actually compute SHA256 were copied from [RustCrypto's sha256 module].
+//!
+//! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs
+
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use crate::*;
+
+impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
+pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+    fn emulate_x86_sha_intrinsic(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx>],
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx, EmulateItemResult> {
+        let this = self.eval_context_mut();
+        this.expect_target_feature_for_intrinsic(link_name, "sha")?;
+        // Prefix should have already been checked.
+        let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sha").unwrap();
+
+        fn read<'c>(this: &mut MiriInterpCx<'c>, reg: &MPlaceTy<'c>) -> InterpResult<'c, [u32; 4]> {
+            let mut res = [0; 4];
+            // We reverse the order because x86 is little endian but the copied implementation uses
+            // big endian.
+            for (i, dst) in res.iter_mut().rev().enumerate() {
+                let projected = &this.project_index(reg, i.try_into().unwrap())?;
+                *dst = this.read_scalar(projected)?.to_u32()?
+            }
+            Ok(res)
+        }
+
+        fn write<'c>(
+            this: &mut MiriInterpCx<'c>,
+            dest: &MPlaceTy<'c>,
+            val: [u32; 4],
+        ) -> InterpResult<'c, ()> {
+            // We reverse the order because x86 is little endian but the copied implementation uses
+            // big endian.
+            for (i, part) in val.into_iter().rev().enumerate() {
+                let projected = &this.project_index(dest, i.try_into().unwrap())?;
+                this.write_scalar(Scalar::from_u32(part), projected)?;
+            }
+            Ok(())
+        }
+
+        match unprefixed_name {
+            // Used to implement the _mm_sha256rnds2_epu32 function.
+            "256rnds2" => {
+                let [a, b, k] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (a_reg, a_len) = this.operand_to_simd(a)?;
+                let (b_reg, b_len) = this.operand_to_simd(b)?;
+                let (k_reg, k_len) = this.operand_to_simd(k)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
+
+                assert_eq!(a_len, 4);
+                assert_eq!(b_len, 4);
+                assert_eq!(k_len, 4);
+                assert_eq!(dest_len, 4);
+
+                let a = read(this, &a_reg)?;
+                let b = read(this, &b_reg)?;
+                let k = read(this, &k_reg)?;
+
+                let result = sha256_digest_round_x2(a, b, k);
+                write(this, &dest, result)?;
+            }
+            // Used to implement the _mm_sha256msg1_epu32 function.
+            "256msg1" => {
+                let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (a_reg, a_len) = this.operand_to_simd(a)?;
+                let (b_reg, b_len) = this.operand_to_simd(b)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
+
+                assert_eq!(a_len, 4);
+                assert_eq!(b_len, 4);
+                assert_eq!(dest_len, 4);
+
+                let a = read(this, &a_reg)?;
+                let b = read(this, &b_reg)?;
+
+                let result = sha256msg1(a, b);
+                write(this, &dest, result)?;
+            }
+            // Used to implement the _mm_sha256msg2_epu32 function.
+            "256msg2" => {
+                let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (a_reg, a_len) = this.operand_to_simd(a)?;
+                let (b_reg, b_len) = this.operand_to_simd(b)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
+
+                assert_eq!(a_len, 4);
+                assert_eq!(b_len, 4);
+                assert_eq!(dest_len, 4);
+
+                let a = read(this, &a_reg)?;
+                let b = read(this, &b_reg)?;
+
+                let result = sha256msg2(a, b);
+                write(this, &dest, result)?;
+            }
+            _ => return Ok(EmulateItemResult::NotSupported),
+        }
+        Ok(EmulateItemResult::NeedsReturn)
+    }
+}
+
+#[inline(always)]
+fn shr(v: [u32; 4], o: u32) -> [u32; 4] {
+    [v[0] >> o, v[1] >> o, v[2] >> o, v[3] >> o]
+}
+
+#[inline(always)]
+fn shl(v: [u32; 4], o: u32) -> [u32; 4] {
+    [v[0] << o, v[1] << o, v[2] << o, v[3] << o]
+}
+
+#[inline(always)]
+fn or(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    [a[0] | b[0], a[1] | b[1], a[2] | b[2], a[3] | b[3]]
+}
+
+#[inline(always)]
+fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
+}
+
+#[inline(always)]
+fn add(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
+    [
+        a[0].wrapping_add(b[0]),
+        a[1].wrapping_add(b[1]),
+        a[2].wrapping_add(b[2]),
+        a[3].wrapping_add(b[3]),
+    ]
+}
+
+fn sha256load(v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
+    [v3[3], v2[0], v2[1], v2[2]]
+}
+
+fn sha256_digest_round_x2(cdgh: [u32; 4], abef: [u32; 4], wk: [u32; 4]) -> [u32; 4] {
+    macro_rules! big_sigma0 {
+        ($a:expr) => {
+            ($a.rotate_right(2) ^ $a.rotate_right(13) ^ $a.rotate_right(22))
+        };
+    }
+    macro_rules! big_sigma1 {
+        ($a:expr) => {
+            ($a.rotate_right(6) ^ $a.rotate_right(11) ^ $a.rotate_right(25))
+        };
+    }
+    macro_rules! bool3ary_202 {
+        ($a:expr, $b:expr, $c:expr) => {
+            $c ^ ($a & ($b ^ $c))
+        };
+    } // Choose, MD5F, SHA1C
+    macro_rules! bool3ary_232 {
+        ($a:expr, $b:expr, $c:expr) => {
+            ($a & $b) ^ ($a & $c) ^ ($b & $c)
+        };
+    } // Majority, SHA1M
+
+    let [_, _, wk1, wk0] = wk;
+    let [a0, b0, e0, f0] = abef;
+    let [c0, d0, g0, h0] = cdgh;
+
+    // a round
+    let x0 =
+        big_sigma1!(e0).wrapping_add(bool3ary_202!(e0, f0, g0)).wrapping_add(wk0).wrapping_add(h0);
+    let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0));
+    let (a1, b1, c1, d1, e1, f1, g1, h1) =
+        (x0.wrapping_add(y0), a0, b0, c0, x0.wrapping_add(d0), e0, f0, g0);
+
+    // a round
+    let x1 =
+        big_sigma1!(e1).wrapping_add(bool3ary_202!(e1, f1, g1)).wrapping_add(wk1).wrapping_add(h1);
+    let y1 = big_sigma0!(a1).wrapping_add(bool3ary_232!(a1, b1, c1));
+    let (a2, b2, _, _, e2, f2, _, _) =
+        (x1.wrapping_add(y1), a1, b1, c1, x1.wrapping_add(d1), e1, f1, g1);
+
+    [a2, b2, e2, f2]
+}
+
+fn sha256msg1(v0: [u32; 4], v1: [u32; 4]) -> [u32; 4] {
+    // sigma 0 on vectors
+    #[inline]
+    fn sigma0x4(x: [u32; 4]) -> [u32; 4] {
+        let t1 = or(shr(x, 7), shl(x, 25));
+        let t2 = or(shr(x, 18), shl(x, 14));
+        let t3 = shr(x, 3);
+        xor(xor(t1, t2), t3)
+    }
+
+    add(v0, sigma0x4(sha256load(v0, v1)))
+}
+
+fn sha256msg2(v4: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
+    macro_rules! sigma1 {
+        ($a:expr) => {
+            $a.rotate_right(17) ^ $a.rotate_right(19) ^ ($a >> 10)
+        };
+    }
+
+    let [x3, x2, x1, x0] = v4;
+    let [w15, w14, _, _] = v3;
+
+    let w16 = x0.wrapping_add(sigma1!(w14));
+    let w17 = x1.wrapping_add(sigma1!(w15));
+    let w18 = x2.wrapping_add(sigma1!(w16));
+    let w19 = x3.wrapping_add(sigma1!(w17));
+
+    [w19, w18, w17, w16]
+}
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index e94bef52952..bbead878223 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -119,9 +119,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.155"
+version = "0.2.158"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
 
 [[package]]
 name = "linux-raw-sys"
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 19c62913b4c..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)]
 
@@ -13,7 +15,5 @@ use std::alloc::{Allocator, Global, Layout, System};
 fn main() {
     let l = Layout::from_size_align(1, 1).unwrap();
     let ptr = Global.allocate(l).unwrap().as_non_null_ptr();
-    unsafe {
-        System.deallocate(ptr, l);
-    }
+    unsafe { System.deallocate(ptr, l) };
 }
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 7006b96ee1e..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,12 +7,12 @@ 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
    |
-LL |         System.deallocate(ptr, l);
+LL |     unsafe { System.deallocate(ptr, l) };
    | ^
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
new file mode 100644
index 00000000000..aed5cb11258
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
@@ -0,0 +1,19 @@
+//@revisions: stack tree
+//@[tree]compile-flags: -Zmiri-tree-borrows
+//@[tree]error-in-other-file: /deallocation .* is forbidden/
+use std::alloc::{alloc, dealloc, Layout};
+
+// `x` is strongly protected but covers zero bytes.
+// Let's see if deallocating the allocation x points to is UB:
+// in TB, it is UB, but in SB it is not.
+fn test(_x: &mut (), ptr: *mut u8, l: Layout) {
+    unsafe { dealloc(ptr, l) };
+}
+
+fn main() {
+    let l = Layout::from_size_align(1, 1).unwrap();
+    let ptr = unsafe { alloc(l) };
+    unsafe { test(&mut *ptr.cast::<()>(), ptr, l) };
+    // In SB the test would pass if it weren't for this line.
+    unsafe { std::hint::unreachable_unchecked() }; //~[stack] ERROR: unreachable
+}
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr
new file mode 100644
index 00000000000..672682ff294
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: entering unreachable code
+  --> $DIR/zero-sized-protected.rs:LL:CC
+   |
+LL |     unsafe { std::hint::unreachable_unchecked() };
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code
+   |
+   = 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 `main` at $DIR/zero-sized-protected.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/fail/both_borrows/zero-sized-protected.tree.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr
new file mode 100644
index 00000000000..ef981038e55
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr
@@ -0,0 +1,36 @@
+error: Undefined Behavior: deallocation through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
+  --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+   |
+LL |     unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
+   |
+   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
+   = help: the allocation of the accessed tag <TAG> (root of the allocation) also contains the strongly protected tag <TAG>
+   = help: the strongly protected tag <TAG> disallows deallocations
+help: the accessed tag <TAG> was created here
+  --> $DIR/zero-sized-protected.rs:LL:CC
+   |
+LL |     let ptr = unsafe { alloc(l) };
+   |                        ^^^^^^^^
+help: the strongly protected tag <TAG> was created here, in the initial state Reserved
+  --> $DIR/zero-sized-protected.rs:LL:CC
+   |
+LL | fn test(_x: &mut (), ptr: *mut u8, l: Layout) {
+   |         ^^
+   = note: BACKTRACE (of the first span):
+   = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+note: inside `test`
+  --> $DIR/zero-sized-protected.rs:LL:CC
+   |
+LL |     unsafe { dealloc(ptr, l) };
+   |              ^^^^^^^^^^^^^^^
+note: inside `main`
+  --> $DIR/zero-sized-protected.rs:LL:CC
+   |
+LL |     unsafe { test(&mut *ptr.cast::<()>(), ptr, l) };
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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/fail/function_calls/exported_symbol_bad_unwind1.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
index 42beed4ecde..a11a2b95689 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/exported_symbol_bad_unwind1.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/exported_symbol_bad_unwind1.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
index 112a9687837..12425cc4892 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
index 112a9687837..12425cc4892 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
index bc3e4858716..f9e299bf5d2 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
index a2fa4c1d590..83efc9974e8 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/return_pointer_on_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
   --> $DIR/return_pointer_on_unwind.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr
index 8dd76edafea..67fd60e572e 100644
--- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 aborted execution: attempted to instantiate uninhabited type `!`
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread caused non-unwinding panic. aborting.
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr
index 55f66a275b6..f89a1fc4bbb 100644
--- a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 aborted execution: attempted to zero-initialize type `fn()`, which is invalid
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread caused non-unwinding panic. aborting.
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC
diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr
index 230e8337c7c..c08fe5153b1 100644
--- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr
+++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/bad_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/bad_unwind.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr
index 5829c1897bb..0395fe418d9 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/double_panic.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
 first
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
 second
 stack backtrace:
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
index d4abf19cd1e..6c7cac23bec 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/panic_abort1.rs:LL:CC:
 panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/panic_abort/src/lib.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
index 507f17abf4e..1eda5449d1b 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/panic_abort2.rs:LL:CC:
 42-panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/panic_abort/src/lib.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
index a5d8b4d2eeb..5c7c5e17bee 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/panic_abort3.rs:LL:CC:
 panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/panic_abort/src/lib.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
index 62fbbf942cb..c8104f570f6 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/panic_abort4.rs:LL:CC:
 42-panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 error: abnormal termination: the program aborted execution
   --> RUSTLIB/panic_abort/src/lib.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr
index a5fa0b3e07a..6384689c563 100644
--- a/src/tools/miri/tests/fail/terminate-terminator.stderr
+++ b/src/tools/miri/tests/fail/terminate-terminator.stderr
@@ -3,7 +3,7 @@ warning: You have explicitly enabled MIR optimizations, overriding Miri's defaul
 thread 'main' panicked at $DIR/terminate-terminator.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
index 547d550d3d0..fd67bdf4a90 100644
--- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr
+++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/unwind-action-terminate.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
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/panic/alloc_error_handler_hook.stderr b/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
index 5b309ed09bb..319a10febb3 100644
--- a/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
+++ b/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
@@ -1,5 +1,5 @@
 thread 'main' panicked at $DIR/alloc_error_handler_hook.rs:LL:CC:
 alloc error hook called
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 yes we are unwinding!
diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
index 3d5457799f6..2cdff03f10f 100644
--- a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
+++ b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
@@ -1,5 +1,5 @@
 thread 'main' panicked at RUSTLIB/std/src/alloc.rs:LL:CC:
 memory allocation of 4 bytes failed
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 yes we are unwinding!
diff --git a/src/tools/miri/tests/panic/div-by-zero-2.stderr b/src/tools/miri/tests/panic/div-by-zero-2.stderr
index f0b84ea6fd6..ed394f76b0e 100644
--- a/src/tools/miri/tests/panic/div-by-zero-2.stderr
+++ b/src/tools/miri/tests/panic/div-by-zero-2.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/div-by-zero-2.rs:LL:CC:
 attempt to divide by zero
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
index f77f6f01119..6733f2e42c1 100644
--- a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
+++ b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
 explicit panic
 thread 'main' panicked at $DIR/exported_symbol_good_unwind.rs:LL:CC:
diff --git a/src/tools/miri/tests/panic/oob_subslice.stderr b/src/tools/miri/tests/panic/oob_subslice.stderr
index c116f8eb525..46f0f643a47 100644
--- a/src/tools/miri/tests/panic/oob_subslice.stderr
+++ b/src/tools/miri/tests/panic/oob_subslice.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/oob_subslice.rs:LL:CC:
 range end index 5 out of range for slice of length 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
index 1d057ea5eb4..be822bd0285 100644
--- a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
+++ b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/overflowing-lsh-neg.rs:LL:CC:
 attempt to shift left with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
index d1a79400bfa..fc090aba5fd 100644
--- a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
+++ b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/overflowing-rsh-1.rs:LL:CC:
 attempt to shift right with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
index 612b0c0c4c2..77160e1870f 100644
--- a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
+++ b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/overflowing-rsh-2.rs:LL:CC:
 attempt to shift right with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic2.stderr b/src/tools/miri/tests/panic/panic2.stderr
index 792c71346fd..f7408310093 100644
--- a/src/tools/miri/tests/panic/panic2.stderr
+++ b/src/tools/miri/tests/panic/panic2.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/panic2.rs:LL:CC:
 42-panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic3.stderr b/src/tools/miri/tests/panic/panic3.stderr
index f8016bc3912..32ba400e025 100644
--- a/src/tools/miri/tests/panic/panic3.stderr
+++ b/src/tools/miri/tests/panic/panic3.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/panic3.rs:LL:CC:
 panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic4.stderr b/src/tools/miri/tests/panic/panic4.stderr
index 67410bf3b1a..a8a23ee3ce1 100644
--- a/src/tools/miri/tests/panic/panic4.stderr
+++ b/src/tools/miri/tests/panic/panic4.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/panic4.rs:LL:CC:
 42-panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs b/src/tools/miri/tests/panic/target_feature_wasm.rs
index 5056f32de44..c67d2983f78 100644
--- a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs
+++ b/src/tools/miri/tests/panic/target_feature_wasm.rs
@@ -2,7 +2,9 @@
 //@compile-flags: -C target-feature=-simd128
 
 fn main() {
-    // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
+    // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988.
+    // But if the compiler actually uses the target feature, it will lead to an error when the module is loaded.
+    // We emulate this with an "unsupported" error.
     assert!(!cfg!(target_feature = "simd128"));
     simd128_fn();
 }
diff --git a/src/tools/miri/tests/panic/transmute_fat2.stderr b/src/tools/miri/tests/panic/transmute_fat2.stderr
index 2ee01d46931..021ca1c4b32 100644
--- a/src/tools/miri/tests/panic/transmute_fat2.stderr
+++ b/src/tools/miri/tests/panic/transmute_fat2.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/transmute_fat2.rs:LL:CC:
 index out of bounds: the len is 0 but the index is 0
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr
index d0a7d8dafc5..fcc4220bfce 100644
--- a/src/tools/miri/tests/panic/unsupported_foreign_function.stderr
+++ b/src/tools/miri/tests/panic/unsupported_foreign_function.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/unsupported_foreign_function.rs:LL:CC:
 unsupported Miri functionality: can't call foreign function `foo` on $OS
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/unsupported_syscall.stderr b/src/tools/miri/tests/panic/unsupported_syscall.stderr
index f802159cb1c..660cfba8900 100644
--- a/src/tools/miri/tests/panic/unsupported_syscall.stderr
+++ b/src/tools/miri/tests/panic/unsupported_syscall.stderr
@@ -1,4 +1,4 @@
 thread 'main' panicked at $DIR/unsupported_syscall.rs:LL:CC:
 unsupported Miri functionality: can't execute syscall with ID 0
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs
index e28cafd3c28..052ce73de23 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll.rs
@@ -1,8 +1,7 @@
 //@only-target-linux
 
-#![feature(exposed_provenance)] // Needed for fn test_pointer()
+#![feature(strict_provenance)]
 use std::convert::TryInto;
-use std::mem::MaybeUninit;
 
 fn main() {
     test_epoll_socketpair();
@@ -17,7 +16,6 @@ fn main() {
     test_no_notification_for_unregister_flag();
     test_epoll_ctl_mod();
     test_epoll_ctl_del();
-    test_pointer();
     test_two_same_fd_in_same_epoll_instance();
     test_epoll_wait_maxevent_zero();
     test_socketpair_epollerr();
@@ -261,24 +259,6 @@ fn test_epoll_eventfd() {
     check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
 }
 
-fn test_pointer() {
-    // Create an epoll instance.
-    let epfd = unsafe { libc::epoll_create1(0) };
-    assert_ne!(epfd, -1);
-
-    // Create a socketpair instance.
-    let mut fds = [-1, -1];
-    let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
-    assert_eq!(res, 0);
-
-    // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET
-    let data = MaybeUninit::<u64>::uninit().as_ptr();
-    let mut ev =
-        libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: data.expose_provenance() as u64 };
-    let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
-    assert_eq!(res, 0);
-}
-
 // When read/write happened on one side of the socketpair, only the other side will be notified.
 fn test_epoll_socketpair_both_sides() {
     // Create an epoll instance.
@@ -543,9 +523,9 @@ fn test_epoll_wait_maxevent_zero() {
     // Create an epoll instance.
     let epfd = unsafe { libc::epoll_create1(0) };
     assert_ne!(epfd, -1);
-    // It is ok to use uninitialised pointer here because it will error out before the
-    // pointer actually get accessed.
-    let array_ptr = MaybeUninit::<libc::epoll_event>::uninit().as_mut_ptr();
+    // It is ok to use a dangling pointer here because it will error out before the
+    // pointer actually gets accessed.
+    let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100);
     let res = unsafe { libc::epoll_wait(epfd, array_ptr, 0, 0) };
     let e = std::io::Error::last_os_error();
     assert_eq!(e.raw_os_error(), Some(libc::EINVAL));
diff --git a/src/tools/miri/tests/pass/panic/catch_panic.stderr b/src/tools/miri/tests/pass/panic/catch_panic.stderr
index a472a5d80cb..f61b39493ed 100644
--- a/src/tools/miri/tests/pass/panic/catch_panic.stderr
+++ b/src/tools/miri/tests/pass/panic/catch_panic.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/catch_panic.rs:LL:CC:
 Hello from std::panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 Caught panic message (&str): Hello from std::panic
 thread 'main' panicked at $DIR/catch_panic.rs:LL:CC:
 Hello from std::panic: 1
diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
index b2a5cf4922c..fe0d16ca78a 100644
--- a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
+++ b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
@@ -3,7 +3,7 @@ Thread 1 reported it has started
 thread '<unnamed>' panicked at $DIR/concurrent-panic.rs:LL:CC:
 panic in thread 2
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 Thread 2 blocking on thread 1
 Thread 2 reported it has started
 Unlocking mutex
diff --git a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
index 3efb4be40f9..a346d31f645 100644
--- a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
+++ b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
@@ -1,7 +1,7 @@
 thread 'main' panicked at $DIR/nested_panic_caught.rs:LL:CC:
 once
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'main' panicked at $DIR/nested_panic_caught.rs:LL:CC:
 twice
 stack backtrace:
diff --git a/src/tools/miri/tests/pass/panic/thread_panic.stderr b/src/tools/miri/tests/pass/panic/thread_panic.stderr
index bdfe4f98ba3..0fde5922c19 100644
--- a/src/tools/miri/tests/pass/panic/thread_panic.stderr
+++ b/src/tools/miri/tests/pass/panic/thread_panic.stderr
@@ -1,6 +1,6 @@
 thread '<unnamed>' panicked at $DIR/thread_panic.rs:LL:CC:
 Hello!
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-note: in Miri, you may have to set `-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
+note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 thread 'childthread' panicked at $DIR/thread_panic.rs:LL:CC:
 Hello, world!
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs
new file mode 100644
index 00000000000..e65fdc3fbed
--- /dev/null
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs
@@ -0,0 +1,270 @@
+// Ignore everything except x86 and x86_64
+// Any new targets that are added to CI should be ignored here.
+// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.)
+//@ignore-target-aarch64
+//@ignore-target-arm
+//@ignore-target-avr
+//@ignore-target-s390x
+//@ignore-target-thumbv7em
+//@ignore-target-wasm32
+//@compile-flags: -C target-feature=+sha,+sse2,+ssse3,+sse4.1
+
+#[cfg(target_arch = "x86")]
+use std::arch::x86::*;
+#[cfg(target_arch = "x86_64")]
+use std::arch::x86_64::*;
+
+macro_rules! rounds4 {
+    ($abef:ident, $cdgh:ident, $rest:expr, $i:expr) => {{
+        let k = K32X4[$i];
+        let kv = _mm_set_epi32(k[0] as i32, k[1] as i32, k[2] as i32, k[3] as i32);
+        let t1 = _mm_add_epi32($rest, kv);
+        $cdgh = _mm_sha256rnds2_epu32($cdgh, $abef, t1);
+        let t2 = _mm_shuffle_epi32(t1, 0x0E);
+        $abef = _mm_sha256rnds2_epu32($abef, $cdgh, t2);
+    }};
+}
+
+macro_rules! schedule_rounds4 {
+    (
+        $abef:ident, $cdgh:ident,
+        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
+        $i: expr
+    ) => {{
+        $w4 = schedule($w0, $w1, $w2, $w3);
+        rounds4!($abef, $cdgh, $w4, $i);
+    }};
+}
+
+fn main() {
+    assert!(is_x86_feature_detected!("sha"));
+    assert!(is_x86_feature_detected!("sse2"));
+    assert!(is_x86_feature_detected!("ssse3"));
+    assert!(is_x86_feature_detected!("sse4.1"));
+
+    unsafe {
+        test_sha256rnds2();
+        test_sha256msg1();
+        test_sha256msg2();
+        test_sha256();
+    }
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn test_sha256rnds2() {
+    let test_vectors = [
+        (
+            [0x3c6ef372, 0xa54ff53a, 0x1f83d9ab, 0x5be0cd19],
+            [0x6a09e667, 0xbb67ae85, 0x510e527f, 0x9b05688c],
+            [0x592340c6, 0x17386142, 0x91a0b7b1, 0x94ffa30c],
+            [0xeef39c6c, 0x4e7dfbc1, 0x467a98f3, 0xeb3d5616],
+        ),
+        (
+            [0x6a09e667, 0xbb67ae85, 0x510e527f, 0x9b05688c],
+            [0xeef39c6c, 0x4e7dfbc1, 0x467a98f3, 0xeb3d5616],
+            [0x91a0b7b1, 0x94ffa30c, 0x592340c6, 0x17386142],
+            [0x7e7f3c9d, 0x78db9a20, 0xd82fe6ed, 0xaf1f2704],
+        ),
+        (
+            [0xeef39c6c, 0x4e7dfbc1, 0x467a98f3, 0xeb3d5616],
+            [0x7e7f3c9d, 0x78db9a20, 0xd82fe6ed, 0xaf1f2704],
+            [0x1a89c3f6, 0xf3b6e817, 0x7a5a8511, 0x8bcc35cf],
+            [0xc9292f7e, 0x49137bd9, 0x7e5f9e08, 0xd10f9247],
+        ),
+    ];
+    for (cdgh, abef, wk, expected) in test_vectors {
+        let output_reg = _mm_sha256rnds2_epu32(set_arr(cdgh), set_arr(abef), set_arr(wk));
+        let mut output = [0u32; 4];
+        _mm_storeu_si128(output.as_mut_ptr().cast(), output_reg);
+        // The values are stored as little endian, so we need to reverse them
+        output.reverse();
+        assert_eq!(output, expected);
+    }
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn test_sha256msg1() {
+    let test_vectors = [
+        (
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x2da4b536, 0x77f29328, 0x541a4d59, 0x6afb680c],
+        ),
+        (
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x2da4b536, 0x77f29328, 0x541a4d59, 0x6afb680c],
+        ),
+        (
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0x2da4b536, 0x77f29328, 0x541a4d59, 0x6afb680c],
+        ),
+    ];
+    for (v0, v1, expected) in test_vectors {
+        let output_reg = _mm_sha256msg1_epu32(set_arr(v0), set_arr(v1));
+        let mut output = [0u32; 4];
+        _mm_storeu_si128(output.as_mut_ptr().cast(), output_reg);
+        // The values are stored as little endian, so we need to reverse them
+        output.reverse();
+        assert_eq!(output, expected);
+    }
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn test_sha256msg2() {
+    let test_vectors = [
+        (
+            [0x801a28aa, 0xe75ff849, 0xb591b2cc, 0x8b64db2c],
+            [0x6f6d6521, 0x61776573, 0x20697320, 0x52757374],
+            [0xe7c46c4e, 0x8ce92ccc, 0xd3c0f3ce, 0xe9745c78],
+        ),
+        (
+            [0x171911ae, 0xe75ff849, 0xb591b2cc, 0x8b64db2c],
+            [0xe7c46c4e, 0x8ce92ccc, 0xd3c0f3ce, 0xe9745c78],
+            [0xc17c6ea3, 0xc4d10083, 0x712910cd, 0x3f41c8ce],
+        ),
+        (
+            [0x6ce67e04, 0x5fb6ff76, 0xe1037a25, 0x3ebc5bda],
+            [0xc17c6ea3, 0xc4d10083, 0x712910cd, 0x3f41c8ce],
+            [0xf5ab4eff, 0x83d732a5, 0x9bb941af, 0xdf1d0a8c],
+        ),
+    ];
+    for (v4, v3, expected) in test_vectors {
+        let output_reg = _mm_sha256msg2_epu32(set_arr(v4), set_arr(v3));
+        let mut output = [0u32; 4];
+        _mm_storeu_si128(output.as_mut_ptr().cast(), output_reg);
+        // The values are stored as little endian, so we need to reverse them
+        output.reverse();
+        assert_eq!(output, expected);
+    }
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn set_arr(x: [u32; 4]) -> __m128i {
+    _mm_set_epi32(x[0] as i32, x[1] as i32, x[2] as i32, x[3] as i32)
+}
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn test_sha256() {
+    use std::fmt::Write;
+
+    /// The initial state of the hash engine.
+    const INITIAL_STATE: [u32; 8] = [
+        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
+        0x5be0cd19,
+    ];
+
+    // We don't want to bother with hash finalization algorithm so we just feed constant data.
+    // This is the content that's being hashed - you can feed it to sha256sum and it'll output
+    // the same hash (beware of newlines though).
+    let first_block = *b"Rust is awesome!Rust is awesome!Rust is awesome!Rust is awesome!";
+    // sha256 is fianlized by appending 0x80, then zeros and finally the data lenght at the
+    // end.
+    let mut final_block = [0; 64];
+    final_block[0] = 0x80;
+    final_block[(64 - 8)..].copy_from_slice(&(8u64 * 64).to_be_bytes());
+
+    let mut state = INITIAL_STATE;
+    digest_blocks(&mut state, &[first_block, final_block]);
+
+    // We compare strings because it's easier to check the hex and the output of panic.
+    let mut hash = String::new();
+    for chunk in &state {
+        write!(hash, "{:08x}", chunk).expect("writing to String doesn't fail");
+    }
+    assert_eq!(hash, "1b2293d21b17a0cb0c18737307c37333dea775eded18cefed45e50389f9f8184");
+}
+
+// Almost full SHA256 implementation copied from RustCrypto's sha2 crate
+// https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/x86.rs
+
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn schedule(v0: __m128i, v1: __m128i, v2: __m128i, v3: __m128i) -> __m128i {
+    let t1 = _mm_sha256msg1_epu32(v0, v1);
+    let t2 = _mm_alignr_epi8(v3, v2, 4);
+    let t3 = _mm_add_epi32(t1, t2);
+    _mm_sha256msg2_epu32(t3, v3)
+}
+
+// we use unaligned loads with `__m128i` pointers
+#[allow(clippy::cast_ptr_alignment)]
+#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
+unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
+    #[allow(non_snake_case)]
+    let MASK: __m128i =
+        _mm_set_epi64x(0x0C0D_0E0F_0809_0A0Bu64 as i64, 0x0405_0607_0001_0203u64 as i64);
+
+    let state_ptr: *const __m128i = state.as_ptr().cast();
+    let dcba = _mm_loadu_si128(state_ptr.add(0));
+    let efgh = _mm_loadu_si128(state_ptr.add(1));
+
+    let cdab = _mm_shuffle_epi32(dcba, 0xB1);
+    let efgh = _mm_shuffle_epi32(efgh, 0x1B);
+    let mut abef = _mm_alignr_epi8(cdab, efgh, 8);
+    let mut cdgh = _mm_blend_epi16(efgh, cdab, 0xF0);
+
+    for block in blocks {
+        let abef_save = abef;
+        let cdgh_save = cdgh;
+
+        let block_ptr: *const __m128i = block.as_ptr().cast();
+        let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(0)), MASK);
+        let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(1)), MASK);
+        let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(2)), MASK);
+        let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(3)), MASK);
+        let mut w4;
+
+        rounds4!(abef, cdgh, w0, 0);
+        rounds4!(abef, cdgh, w1, 1);
+        rounds4!(abef, cdgh, w2, 2);
+        rounds4!(abef, cdgh, w3, 3);
+        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 4);
+        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 5);
+        schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 6);
+        schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 7);
+        schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 8);
+        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 9);
+        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 10);
+        schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 11);
+        schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 12);
+        schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 13);
+        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 14);
+        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 15);
+
+        abef = _mm_add_epi32(abef, abef_save);
+        cdgh = _mm_add_epi32(cdgh, cdgh_save);
+    }
+
+    let feba = _mm_shuffle_epi32(abef, 0x1B);
+    let dchg = _mm_shuffle_epi32(cdgh, 0xB1);
+    let dcba = _mm_blend_epi16(feba, dchg, 0xF0);
+    let hgef = _mm_alignr_epi8(dchg, feba, 8);
+
+    let state_ptr_mut: *mut __m128i = state.as_mut_ptr().cast();
+    _mm_storeu_si128(state_ptr_mut.add(0), dcba);
+    _mm_storeu_si128(state_ptr_mut.add(1), hgef);
+}
+
+/// Swapped round constants for SHA-256 family of digests
+pub static K32X4: [[u32; 4]; 16] = {
+    let mut res = [[0u32; 4]; 16];
+    let mut i = 0;
+    while i < 16 {
+        res[i] = [K32[4 * i + 3], K32[4 * i + 2], K32[4 * i + 1], K32[4 * i]];
+        i += 1;
+    }
+    res
+};
+
+/// Round constants for SHA-256 family of digests
+pub static K32: [u32; 64] = [
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+];
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/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 1a13d56b0e4..77df6e7beb5 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -12,3 +12,4 @@ regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
 gimli = "0.31.0"
 build_helper = { path = "../build_helper" }
 serde_json = "1.0"
+libc = "0.2"
diff --git a/src/tools/run-make-support/src/env.rs b/src/tools/run-make-support/src/env.rs
index e6460fb93d3..9acbb16d73e 100644
--- a/src/tools/run-make-support/src/env.rs
+++ b/src/tools/run-make-support/src/env.rs
@@ -24,3 +24,11 @@ pub fn env_var_os(name: &str) -> OsString {
 pub fn no_debug_assertions() -> bool {
     std::env::var_os("NO_DEBUG_ASSERTIONS").is_some()
 }
+
+/// A wrapper around [`std::env::set_current_dir`] which includes the directory
+/// path in the panic message.
+#[track_caller]
+pub fn set_current_dir<P: AsRef<std::path::Path>>(dir: P) {
+    std::env::set_current_dir(dir.as_ref())
+        .expect(&format!("could not set current directory to \"{}\"", dir.as_ref().display()));
+}
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index fc20fd3b2e8..989d00d4c2f 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -36,6 +36,7 @@ pub mod rfs {
 // Re-exports of third-party library crates.
 pub use bstr;
 pub use gimli;
+pub use libc;
 pub use object;
 pub use regex;
 pub use serde_json;
@@ -64,7 +65,7 @@ pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
 pub use diff::{diff, Diff};
 
 /// Panic-on-fail [`std::env::var`] and [`std::env::var_os`] wrappers.
-pub use env::{env_var, env_var_os};
+pub use env::{env_var, env_var_os, set_current_dir};
 
 /// Convenience helpers for running binaries and other commands.
 pub use run::{cmd, run, run_fail, run_with_args};
diff --git a/src/tools/run-make-support/src/path_helpers.rs b/src/tools/run-make-support/src/path_helpers.rs
index 1e6e44c4584..87901793a92 100644
--- a/src/tools/run-make-support/src/path_helpers.rs
+++ b/src/tools/run-make-support/src/path_helpers.rs
@@ -21,6 +21,7 @@ pub fn cwd() -> PathBuf {
 /// # Example
 ///
 /// ```rust
+/// # use run_make_support::path;
 /// let p = path("support_file.txt");
 /// ```
 pub fn path<P: AsRef<Path>>(p: P) -> PathBuf {
diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs
index 12088e5d3b5..3eeba6fd526 100644
--- a/src/tools/run-make-support/src/run.rs
+++ b/src/tools/run-make-support/src/run.rs
@@ -29,6 +29,7 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
         }
         env::join_paths(paths.iter()).unwrap()
     });
+    cmd.env("LC_ALL", "C"); // force english locale
 
     if is_windows() {
         let mut paths = vec![];
@@ -84,5 +85,6 @@ pub fn run_fail(name: &str) -> CompletedProcess {
 pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command {
     let mut command = Command::new(program);
     set_host_rpath(&mut command);
+    command.env("LC_ALL", "C"); // force english locale
     command
 }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index f55abb513b8..22d1e93bf39 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -6,9 +6,7 @@ run-make/incr-add-rust-src-component/Makefile
 run-make/issue-84395-lto-embed-bitcode/Makefile
 run-make/jobserver-error/Makefile
 run-make/libs-through-symlinks/Makefile
-run-make/libtest-thread-limit/Makefile
 run-make/macos-deployment-target/Makefile
 run-make/split-debuginfo/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/translation/Makefile
-run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
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/struct-target-features.rs b/tests/assembly/struct-target-features.rs
new file mode 100644
index 00000000000..cc86fbaa840
--- /dev/null
+++ b/tests/assembly/struct-target-features.rs
@@ -0,0 +1,37 @@
+//@ compile-flags: -O
+//@ assembly-output: emit-asm
+//@ only-x86_64
+
+#![crate_type = "lib"]
+#![feature(struct_target_features)]
+
+// Check that a struct_target_features type causes the compiler to effectively inline intrinsics.
+
+use std::arch::x86_64::*;
+
+#[target_feature(enable = "avx")]
+struct Avx {}
+
+#[target_feature(enable = "fma")]
+struct Fma {}
+
+pub fn add_simple(_: Avx, v: __m256) -> __m256 {
+    // CHECK-NOT: call
+    // CHECK: vaddps
+    unsafe { _mm256_add_ps(v, v) }
+}
+
+pub fn add_complex_type(_: (&Avx, ()), v: __m256) -> __m256 {
+    // CHECK-NOT: call
+    // CHECK: vaddps
+    unsafe { _mm256_add_ps(v, v) }
+}
+
+pub fn add_fma_combined(_: (&Avx, &Fma), v: __m256) -> (__m256, __m256) {
+    // CHECK-NOT: call
+    // CHECK-DAG: vaddps
+    let r1 = unsafe { _mm256_add_ps(v, v) };
+    // CHECK-DAG: vfmadd213ps
+    let r2 = unsafe { _mm256_fmadd_ps(v, v, v) };
+    (r1, r2)
+}
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/assembly/x86_64-cmp.rs b/tests/assembly/x86_64-cmp.rs
index 31efdda1bfa..67b7ff99ae2 100644
--- a/tests/assembly/x86_64-cmp.rs
+++ b/tests/assembly/x86_64-cmp.rs
@@ -1,6 +1,9 @@
-//@ revisions: DEBUG OPTIM
+//@ revisions: DEBUG LLVM-PRE-20-OPTIM LLVM-20-OPTIM
 //@ [DEBUG] compile-flags: -C opt-level=0
-//@ [OPTIM] compile-flags: -C opt-level=3
+//@ [LLVM-PRE-20-OPTIM] compile-flags: -C opt-level=3
+//@ [LLVM-PRE-20-OPTIM] ignore-llvm-version: 20 - 99
+//@ [LLVM-20-OPTIM] compile-flags: -C opt-level=3
+//@ [LLVM-20-OPTIM] min-llvm-version: 20
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -C llvm-args=-x86-asm-syntax=intel
 //@ only-x86_64
@@ -21,12 +24,18 @@ pub fn signed_cmp(a: i16, b: i16) -> std::cmp::Ordering {
     // DEBUG: and
     // DEBUG: sub
 
-    // OPTIM: xor
-    // OPTIM: cmp
-    // OPTIM: setne
-    // OPTIM: mov
-    // OPTIM: cmovge
-    // OPTIM: ret
+    // LLVM-PRE-20-OPTIM: xor
+    // LLVM-PRE-20-OPTIM: cmp
+    // LLVM-PRE-20-OPTIM: setne
+    // LLVM-PRE-20-OPTIM: mov
+    // LLVM-PRE-20-OPTIM: cmovge
+    // LLVM-PRE-20-OPTIM: ret
+    //
+    // LLVM-20-OPTIM: cmp
+    // LLVM-20-OPTIM: setl
+    // LLVM-20-OPTIM: setg
+    // LLVM-20-OPTIM: sub
+    // LLVM-20-OPTIM: ret
     three_way_compare(a, b)
 }
 
@@ -41,11 +50,16 @@ pub fn unsigned_cmp(a: u16, b: u16) -> std::cmp::Ordering {
     // DEBUG: and
     // DEBUG: sub
 
-    // OPTIM: xor
-    // OPTIM: cmp
-    // OPTIM: setne
-    // OPTIM: mov
-    // OPTIM: cmovae
-    // OPTIM: ret
+    // LLVM-PRE-20-OPTIM: xor
+    // LLVM-PRE-20-OPTIM: cmp
+    // LLVM-PRE-20-OPTIM: setne
+    // LLVM-PRE-20-OPTIM: mov
+    // LLVM-PRE-20-OPTIM: cmovae
+    // LLVM-PRE-20-OPTIM: ret
+    //
+    // LLVM-20-OPTIM: cmp
+    // LLVM-20-OPTIM: seta
+    // LLVM-20-OPTIM: sbb
+    // LLVM-20-OPTIM: ret
     three_way_compare(a, b)
 }
diff --git a/tests/codegen/integer-cmp.rs b/tests/codegen/integer-cmp.rs
index bba112b246f..8df68d8d490 100644
--- a/tests/codegen/integer-cmp.rs
+++ b/tests/codegen/integer-cmp.rs
@@ -1,6 +1,9 @@
 // This is test for more optimal Ord implementation for integers.
 // See <https://github.com/rust-lang/rust/issues/63758> for more info.
 
+//@ revisions: llvm-pre-20 llvm-20
+//@ [llvm-20] min-llvm-version: 20
+//@ [llvm-pre-20] ignore-llvm-version: 20 - 99
 //@ compile-flags: -C opt-level=3
 
 #![crate_type = "lib"]
@@ -10,19 +13,21 @@ use std::cmp::Ordering;
 // CHECK-LABEL: @cmp_signed
 #[no_mangle]
 pub fn cmp_signed(a: i64, b: i64) -> Ordering {
-    // CHECK: icmp slt
-    // CHECK: icmp ne
-    // CHECK: zext i1
-    // CHECK: select i1
+    // llvm-20: @llvm.scmp.i8.i64
+    // llvm-pre-20: icmp slt
+    // llvm-pre-20: icmp ne
+    // llvm-pre-20: zext i1
+    // llvm-pre-20: select i1
     a.cmp(&b)
 }
 
 // CHECK-LABEL: @cmp_unsigned
 #[no_mangle]
 pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
-    // CHECK: icmp ult
-    // CHECK: icmp ne
-    // CHECK: zext i1
-    // CHECK: select i1
+    // llvm-20: @llvm.ucmp.i8.i32
+    // llvm-pre-20: icmp ult
+    // llvm-pre-20: icmp ne
+    // llvm-pre-20: zext i1
+    // llvm-pre-20: select i1
     a.cmp(&b)
 }
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
new file mode 100644
index 00000000000..d5faac44836
--- /dev/null
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -0,0 +1,20 @@
+//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
+//@ needs-asm-support
+//@ ignore-arm no "ret" mnemonic
+
+#![crate_type = "lib"]
+#![feature(naked_functions, fn_align)]
+use std::arch::asm;
+
+// CHECK: Function Attrs: naked
+// CHECK-NEXT: define{{.*}}void @naked_empty()
+// CHECK: align 16
+#[repr(align(16))]
+#[no_mangle]
+#[naked]
+pub unsafe extern "C" fn naked_empty() {
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: call void asm
+    // CHECK-NEXT: unreachable
+    asm!("ret", options(noreturn));
+}
diff --git a/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs b/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
new file mode 100644
index 00000000000..a54a6d84a80
--- /dev/null
+++ b/tests/codegen/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
@@ -0,0 +1,10 @@
+// Verifies that "cfi-normalize-integers" module flag is added.
+//
+//@ needs-sanitizer-cfi
+//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+
+#![crate_type = "lib"]
+
+pub fn foo() {}
+
+// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
diff --git a/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs b/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs
new file mode 100644
index 00000000000..d48e4016a16
--- /dev/null
+++ b/tests/codegen/sanitizer/kcfi/add-cfi-normalize-integers-flag.rs
@@ -0,0 +1,21 @@
+// Verifies that "cfi-normalize-integers" module flag is added.
+//
+//@ revisions: aarch64 x86_64
+//@ [aarch64] compile-flags: --target aarch64-unknown-none
+//@ [aarch64] needs-llvm-components: aarch64
+//@ [x86_64] compile-flags: --target x86_64-unknown-none
+//@ [x86_64] needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub fn foo() {}
+
+// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs
new file mode 100644
index 00000000000..b4924719f4c
--- /dev/null
+++ b/tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs
@@ -0,0 +1,21 @@
+// Verifies that "kcfi-offset" module flag is added.
+//
+//@ revisions: aarch64 x86_64
+//@ [aarch64] compile-flags: --target aarch64-unknown-none
+//@ [aarch64] needs-llvm-components: aarch64
+//@ [x86_64] compile-flags: --target x86_64-unknown-none
+//@ [x86_64] needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Z patchable-function-entry=4,3
+
+#![feature(no_core, lang_items, patchable_function_entry)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+pub fn foo() {}
+
+// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-offset", i32 3}
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
index 1b4596ae2cb..1b2b63c3d1a 100644
--- a/tests/codegen/tied-features-strength.rs
+++ b/tests/codegen/tied-features-strength.rs
@@ -3,21 +3,21 @@
 //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
 //@ needs-llvm-components: aarch64
 
-// The "+v8a" feature is matched as optional as it isn't added when we
-// are targeting older LLVM versions. Once the min supported version
-// is LLVM-14 we can remove the optional regex matching for this feature.
+// The "+fpmr" feature is matched as optional as it is only an explicit
+// feature in LLVM 18. Once the min supported version is LLVM-19 the optional
+// regex matching for this feature can be removed.
 
 //@ [ENABLE_SVE] compile-flags: -C target-feature=+sve -Copt-level=0
-// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
+// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
 
 //@ [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
-// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-sve,?)|(\+neon,?))*}}" }
+// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-sve,?)|(\+neon,?))*}}" }
 
 //@ [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
-// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
+// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
 
 //@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
-// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
+// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
 
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/tests/crashes/123693.rs b/tests/crashes/123693.rs
index c2e192092be..c3236322c6e 100644
--- a/tests/crashes/123693.rs
+++ b/tests/crashes/123693.rs
@@ -3,11 +3,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::NOTHING }>,
+        Dst: TransmuteFrom<Src, { Assume::NOTHING }>,
     {
     }
 }
diff --git a/tests/crashes/124207.rs b/tests/crashes/124207.rs
index a4e1c551890..a11eedb140a 100644
--- a/tests/crashes/124207.rs
+++ b/tests/crashes/124207.rs
@@ -4,6 +4,6 @@
 trait OpaqueTrait {}
 type OpaqueType = impl OpaqueTrait;
 trait AnotherTrait {}
-impl<T: std::mem::BikeshedIntrinsicFrom<(), ()>> AnotherTrait for T {}
+impl<T: std::mem::TransmuteFrom<(), ()>> AnotherTrait for T {}
 impl AnotherTrait for OpaqueType {}
 pub fn main() {}
diff --git a/tests/crashes/125881.rs b/tests/crashes/125881.rs
index 98331d3c974..a38f1891b61 100644
--- a/tests/crashes/125881.rs
+++ b/tests/crashes/125881.rs
@@ -3,6 +3,6 @@
 #![feature(transmutability)]
 #![feature(unboxed_closures,effects)]
 
-const fn test() -> impl std::mem::BikeshedIntrinsicFrom() {
+const fn test() -> impl std::mem::TransmuteFrom() {
     || {}
 }
diff --git a/tests/crashes/126267.rs b/tests/crashes/126267.rs
index c0604b90a67..728578179ed 100644
--- a/tests/crashes/126267.rs
+++ b/tests/crashes/126267.rs
@@ -14,11 +14,11 @@ pub enum Error {
 }
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>, // safety is NOT assumed
+        Dst: TransmuteFrom<Src>, // safety is NOT assumed
     {
     }
 }
diff --git a/tests/crashes/126377.rs b/tests/crashes/126377.rs
index f8b9b693b65..f6727bcc0a4 100644
--- a/tests/crashes/126377.rs
+++ b/tests/crashes/126377.rs
@@ -4,7 +4,7 @@
 #![feature(generic_const_exprs)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<
         Src,
@@ -15,7 +15,7 @@ mod assert {
         const ASSUME_VALIDITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             {  }
         >,
diff --git a/tests/crashes/126966.rs b/tests/crashes/126966.rs
index edeedc68c40..2c9f1a70f4f 100644
--- a/tests/crashes/126966.rs
+++ b/tests/crashes/126966.rs
@@ -1,10 +1,10 @@
 //@ known-bug: rust-lang/rust#126966
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>,
+        Dst: TransmuteFrom<Src>,
     {
     }
 }
diff --git a/tests/crashes/127972.rs b/tests/crashes/127972.rs
index d0764f875db..797dd7e6020 100644
--- a/tests/crashes/127972.rs
+++ b/tests/crashes/127972.rs
@@ -1,5 +1,5 @@
 //@ known-bug: #127962
-#![feature(generic_const_exprs)]
+#![feature(generic_const_exprs, const_arg_path)]
 
 fn zero_init<const usize: usize>() -> Substs1<{ (N) }> {
     Substs1([0; { (usize) }])
diff --git a/tests/crashes/128016.rs b/tests/crashes/128016.rs
deleted file mode 100644
index d23721ae14e..00000000000
--- a/tests/crashes/128016.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #128016
-macro_rules! len {
-    () => {
-        target
-    };
-}
-
-fn main() {
-    let val: [str; len!()] = [];
-}
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/incremental/decl_macro.rs b/tests/incremental/decl_macro.rs
new file mode 100644
index 00000000000..74810ae4227
--- /dev/null
+++ b/tests/incremental/decl_macro.rs
@@ -0,0 +1,34 @@
+//@ revisions: rpass1 rpass2
+
+// issue#112680
+
+#![feature(decl_macro)]
+
+pub trait T {
+    type Key;
+    fn index_from_key(key: Self::Key) -> usize;
+}
+
+pub macro m($key_ty:ident, $val_ty:ident) {
+    struct $key_ty {
+        inner: usize,
+    }
+
+    impl T for $val_ty {
+        type Key = $key_ty;
+
+        fn index_from_key(key: Self::Key) -> usize {
+            key.inner
+        }
+    }
+}
+
+m!(TestId, Test);
+
+#[cfg(rpass1)]
+struct Test(u32);
+
+#[cfg(rpass2)]
+struct Test;
+
+fn main() {}
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/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs
index 13585edf6cc..95a9011669e 100644
--- a/tests/run-make/crate-loading/rmake.rs
+++ b/tests/run-make/crate-loading/rmake.rs
@@ -27,7 +27,7 @@ fn main() {
    |     |
    |     required by a bound introduced by this call
    |
-help: there are multiple different versions of crate `dependency` the your dependency graph
+help: there are multiple different versions of crate `dependency` in the dependency graph
   --> multiple-dep-versions.rs:1:1
    |
 1  | extern crate dep_2_reexport;
diff --git a/tests/run-make/debugger-visualizer-dep-info/foo.py b/tests/run-make/debugger-visualizer-dep-info/foo.py
deleted file mode 100644
index 1bb8bf6d7fd..00000000000
--- a/tests/run-make/debugger-visualizer-dep-info/foo.py
+++ /dev/null
@@ -1 +0,0 @@
-# empty
diff --git a/tests/run-make/debugger-visualizer-dep-info/main.rs b/tests/run-make/debugger-visualizer-dep-info/main.rs
index 3aede2215ea..3539b305be3 100644
--- a/tests/run-make/debugger-visualizer-dep-info/main.rs
+++ b/tests/run-make/debugger-visualizer-dep-info/main.rs
@@ -1,4 +1,4 @@
-#![debugger_visualizer(gdb_script_file = "foo.py")]
+#![debugger_visualizer(gdb_script_file = "my_gdb_script.py")]
 
 fn main() {
     const _UNUSED: u32 = {
diff --git a/tests/run-make/debugger-visualizer-dep-info/my_gdb_script.py b/tests/run-make/debugger-visualizer-dep-info/my_gdb_script.py
new file mode 100644
index 00000000000..d319792657e
--- /dev/null
+++ b/tests/run-make/debugger-visualizer-dep-info/my_gdb_script.py
@@ -0,0 +1,6 @@
+# This is a Python script, but we don't actually run it.
+# So if you're trying to remove Python scripts from the test suite,
+# be aware that there's no value in trying to get rid of this one.
+#
+# It just needs to exist so that the compiler can embed it via
+# `#![debugger_visualizer(gdb_script_file = "...")]`.
diff --git a/tests/run-make/debugger-visualizer-dep-info/rmake.rs b/tests/run-make/debugger-visualizer-dep-info/rmake.rs
index 65ffb2373e7..f5cf39157ac 100644
--- a/tests/run-make/debugger-visualizer-dep-info/rmake.rs
+++ b/tests/run-make/debugger-visualizer-dep-info/rmake.rs
@@ -6,6 +6,6 @@ use run_make_support::{invalid_utf8_contains, rustc};
 
 fn main() {
     rustc().emit("dep-info").input("main.rs").run();
-    invalid_utf8_contains("main.d", "foo.py");
+    invalid_utf8_contains("main.d", "my_gdb_script.py");
     invalid_utf8_contains("main.d", "my_visualizers/bar.natvis");
 }
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/emit-shared-files/rmake.rs b/tests/run-make/emit-shared-files/rmake.rs
index e5482af10bb..483f298776c 100644
--- a/tests/run-make/emit-shared-files/rmake.rs
+++ b/tests/run-make/emit-shared-files/rmake.rs
@@ -20,6 +20,7 @@ fn main() {
         .input("x.rs")
         .run();
     assert!(Path::new("invocation-only/search-index-xxx.js").exists());
+    assert!(Path::new("invocation-only/crates-xxx.js").exists());
     assert!(Path::new("invocation-only/settings.html").exists());
     assert!(Path::new("invocation-only/x/all.html").exists());
     assert!(Path::new("invocation-only/x/index.html").exists());
diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py
index 0d9b34a3cf7..f92473751b0 100755
--- a/tests/run-make/libtest-junit/validate_junit.py
+++ b/tests/run-make/libtest-junit/validate_junit.py
@@ -1,5 +1,15 @@
 #!/usr/bin/env python
 
+# Trivial Python script that reads lines from stdin, and checks that each line
+# is a well-formed XML document.
+#
+# This takes advantage of the fact that Python has a built-in XML parser,
+# whereas doing the same check in Rust would require us to pull in an XML
+# crate just for this relatively-minor test.
+#
+# If you're trying to remove Python scripts from the test suite, think twice
+# before removing this one. You could do so, but it's probably not worth it.
+
 import sys
 import xml.etree.ElementTree as ET
 
diff --git a/tests/run-make/libtest-thread-limit/Makefile b/tests/run-make/libtest-thread-limit/Makefile
deleted file mode 100644
index 9496fa30159..00000000000
--- a/tests/run-make/libtest-thread-limit/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../tools.mk
-
-# only-linux
-
-all:
-	$(RUSTC) test.rs --test --target $(TARGET)
-	$(shell ulimit -p 0 && $(call RUN,test))
diff --git a/tests/run-make/libtest-thread-limit/rmake.rs b/tests/run-make/libtest-thread-limit/rmake.rs
new file mode 100644
index 00000000000..be0eeaf1717
--- /dev/null
+++ b/tests/run-make/libtest-thread-limit/rmake.rs
@@ -0,0 +1,64 @@
+// libtest used to panic if it hit the thread limit. This often resulted in spurious test failures
+// (thread 'main' panicked at 'called Result::unwrap() on an Err value: Os
+// { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }' ...
+// error: test failed, to rerun pass '--lib').
+// Since the fix in #81546, the test should continue to run synchronously
+// if it runs out of threads. Therefore, this test's final execution step
+// should succeed without an error.
+// See https://github.com/rust-lang/rust/pull/81546
+
+//@ only-linux
+// Reason: thread limit modification
+//@ ignore-cross-compile
+// Reason: this test fails armhf-gnu, reasons unknown
+
+use std::ffi::{self, CStr, CString};
+use std::path::PathBuf;
+
+use run_make_support::{libc, run, rustc};
+
+fn main() {
+    rustc().input("test.rs").arg("--test").run();
+
+    // We need to emulate an environment for libtest where threads are exhausted and spawning
+    // new threads are guaranteed to fail. This was previously achieved by ulimit shell builtin
+    // that called out to prlimit64 underneath to set resource limits (specifically thread
+    // number limits). Now that we don't have a shell, we need to implement that ourselves.
+    // See https://linux.die.net/man/2/setrlimit
+
+    // The fork + exec is required because we cannot first try to limit the number of
+    // processes/threads to 1 and then try to spawn a new process to run the test. We need to
+    // setrlimit and run the libtest test program in the same process.
+    let pid = unsafe { libc::fork() };
+    assert!(pid >= 0);
+
+    // If the process ID is 0, this is the child process responsible for running the test
+    // program.
+    if pid == 0 {
+        let test = CString::new("test").unwrap();
+        // The argv array should be terminated with a NULL pointer.
+        let argv = [test.as_ptr(), std::ptr::null()];
+        // rlim_cur is soft limit, rlim_max is hard limit.
+        // By setting the limit very low (max 1), we ensure that libtest is unable to create new
+        // threads.
+        let rlimit = libc::rlimit { rlim_cur: 1, rlim_max: 1 };
+        // RLIMIT_NPROC: The maximum number of processes (or, more precisely on Linux,
+        // threads) that can be created for the real user ID of the calling process. Upon
+        // encountering this limit, fork(2) fails with the error EAGAIN.
+        // Therefore, set the resource limit to RLIMIT_NPROC.
+        let ret = unsafe { libc::setrlimit(libc::RLIMIT_NPROC, &rlimit as *const libc::rlimit) };
+        assert_eq!(ret, 0);
+
+        // Finally, execute the 2 tests in test.rs.
+        let ret = unsafe { libc::execv(test.as_ptr(), argv.as_ptr()) };
+        assert_eq!(ret, 0);
+    } else {
+        // Otherwise, other process IDs indicate that this is the parent process.
+
+        let mut status: libc::c_int = 0;
+        let ret = unsafe { libc::waitpid(pid, &mut status as *mut libc::c_int, 0) };
+        assert_eq!(ret, pid);
+        assert!(libc::WIFEXITED(status));
+        assert_eq!(libc::WEXITSTATUS(status), 0);
+    }
+}
diff --git a/tests/run-make/libtest-thread-limit/test.rs b/tests/run-make/libtest-thread-limit/test.rs
index 87e1d519171..d4eb1242615 100644
--- a/tests/run-make/libtest-thread-limit/test.rs
+++ b/tests/run-make/libtest-thread-limit/test.rs
@@ -10,7 +10,12 @@ fn spawn_thread_would_block() {
     THREAD_ID.set(thread::current().id()).unwrap();
 }
 
+// Tests are run in alphabetical order, and the second test is dependent on the
+// first to set THREAD_ID. Do not rename the tests in such a way that `test_run_in_same_thread`
+// would run before `spawn_thread_would_block`.
+// See https://doc.rust-lang.org/rustc/tests/index.html#--shuffle
+
 #[test]
-fn run_in_same_thread() {
+fn test_run_in_same_thread() {
     assert_eq!(*THREAD_ID.get().unwrap(), thread::current().id());
 }
diff --git a/tests/run-make/msvc-wholearchive/c.c b/tests/run-make/msvc-wholearchive/c.c
new file mode 100644
index 00000000000..d6847845c68
--- /dev/null
+++ b/tests/run-make/msvc-wholearchive/c.c
@@ -0,0 +1 @@
+// This page is intentionally left blank
diff --git a/tests/run-make/msvc-wholearchive/dll.def b/tests/run-make/msvc-wholearchive/dll.def
new file mode 100644
index 00000000000..d55819e0d5e
--- /dev/null
+++ b/tests/run-make/msvc-wholearchive/dll.def
@@ -0,0 +1,4 @@
+LIBRARY dll
+EXPORTS
+        hello
+        number
diff --git a/tests/run-make/msvc-wholearchive/rmake.rs b/tests/run-make/msvc-wholearchive/rmake.rs
new file mode 100644
index 00000000000..98586fd8cc8
--- /dev/null
+++ b/tests/run-make/msvc-wholearchive/rmake.rs
@@ -0,0 +1,52 @@
+//! This is a regression test for #129020
+//! It ensures we can use `/WHOLEARCHIVE` to link a rust staticlib into DLL
+//! using the MSVC linker
+
+//@ only-msvc
+// Reason: this is testing the MSVC linker
+
+use std::path::PathBuf;
+
+use run_make_support::{cc, cmd, env_var, extra_c_flags, rustc};
+
+fn main() {
+    // Build the staticlib
+    rustc().crate_type("staticlib").input("static.rs").output("static.lib").run();
+    // Build an empty object to pass to the linker.
+    cc().input("c.c").output("c.obj").args(["-c"]).run();
+
+    // Find the C toolchain's linker.
+    let mut linker = PathBuf::from(env_var("CC"));
+    let linker_flavour = if linker.file_stem().is_some_and(|s| s == "cl") {
+        linker.set_file_name("link.exe");
+        "msvc"
+    } else if linker.file_stem().is_some_and(|s| s == "clang-cl") {
+        linker.set_file_name("lld-link.exe");
+        "llvm"
+    } else {
+        panic!("unknown C toolchain");
+    };
+
+    // As a sanity check, make sure this works without /WHOLEARCHIVE.
+    // Otherwise the actual test failure may be caused by something else.
+    cmd(&linker)
+        .args(["c.obj", "./static.lib", "-dll", "-def:dll.def", "-out:dll.dll"])
+        .args(extra_c_flags())
+        .run();
+
+    // FIXME(@ChrisDenton): this doesn't currently work with llvm's lld-link for other reasons.
+    // May need LLVM patches.
+    if linker_flavour == "msvc" {
+        // Link in the staticlib using `/WHOLEARCHIVE` and produce a DLL.
+        cmd(&linker)
+            .args([
+                "c.obj",
+                "-WHOLEARCHIVE:./static.lib",
+                "-dll",
+                "-def:dll.def",
+                "-out:dll_whole_archive.dll",
+            ])
+            .args(extra_c_flags())
+            .run();
+    }
+}
diff --git a/tests/run-make/msvc-wholearchive/static.rs b/tests/run-make/msvc-wholearchive/static.rs
new file mode 100644
index 00000000000..881c8856573
--- /dev/null
+++ b/tests/run-make/msvc-wholearchive/static.rs
@@ -0,0 +1,9 @@
+#[no_mangle]
+pub extern "C" fn hello() {
+    println!("Hello world!");
+}
+
+#[no_mangle]
+pub extern "C" fn number() -> u32 {
+    42
+}
diff --git a/tests/run-make/remove-dir-all-race/rmake.rs b/tests/run-make/remove-dir-all-race/rmake.rs
new file mode 100644
index 00000000000..03c94b76127
--- /dev/null
+++ b/tests/run-make/remove-dir-all-race/rmake.rs
@@ -0,0 +1,62 @@
+//@ ignore-windows
+
+// This test attempts to make sure that running `remove_dir_all`
+// doesn't result in a NotFound error one of the files it
+// is deleting is deleted concurrently.
+//
+// The windows implementation for `remove_dir_all` is significantly
+// more complicated, and has not yet been brought up to par with
+// the implementation on other platforms, so this test is marked as
+// `ignore-windows` until someone more expirenced with windows can
+// sort that out.
+
+use std::fs::remove_dir_all;
+use std::path::Path;
+use std::thread;
+use std::time::Duration;
+
+use run_make_support::rfs::{create_dir, write};
+use run_make_support::run_in_tmpdir;
+
+fn main() {
+    let mut race_happened = false;
+    run_in_tmpdir(|| {
+        for i in 0..150 {
+            create_dir("outer");
+            create_dir("outer/inner");
+            write("outer/inner.txt", b"sometext");
+
+            thread::scope(|scope| {
+                let t1 = scope.spawn(|| {
+                    thread::sleep(Duration::from_nanos(i));
+                    remove_dir_all("outer").unwrap();
+                });
+
+                let race_happened_ref = &race_happened;
+                let t2 = scope.spawn(|| {
+                    let r1 = remove_dir_all("outer/inner");
+                    let r2 = remove_dir_all("outer/inner.txt");
+                    if r1.is_ok() && r2.is_err() {
+                        race_happened = true;
+                    }
+                });
+            });
+
+            assert!(!Path::new("outer").exists());
+
+            // trying to remove a nonexistant top-level directory should
+            // still result in an error.
+            let Err(err) = remove_dir_all("outer") else {
+                panic!("removing nonexistant dir did not result in an error");
+            };
+            assert_eq!(err.kind(), std::io::ErrorKind::NotFound);
+        }
+    });
+    if !race_happened {
+        eprintln!(
+            "WARNING: multithreaded deletion never raced, \
+                   try increasing the number of attempts or \
+                   adjusting the sleep timing"
+        );
+    }
+}
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/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
deleted file mode 100644
index 3c88ec34f43..00000000000
--- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-include ../tools.mk
-
-#only-x86_64-fortanix-unknown-sgx
-
-# For cargo setting
-export RUSTC := $(RUSTC_ORIGINAL)
-export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
-# We need to be outside of 'src' dir in order to run cargo
-export WORK_DIR := $(TMPDIR)
-export TEST_DIR := $(shell pwd)
-
-## clean up unused env variables which might cause harm.
-unexport RUSTC_LINKER
-unexport RUSTC_BOOTSTRAP
-unexport RUST_BUILD_STAGE
-unexport RUST_TEST_THREADS
-unexport RUST_TEST_TMPDIR
-unexport AR
-unexport CC
-unexport CXX
-
-all:
-	bash script.sh
diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
new file mode 100644
index 00000000000..130781a4293
--- /dev/null
+++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/rmake.rs
@@ -0,0 +1,96 @@
+// ignore-tidy-linelength
+// Reason: intel.com link
+
+// This security test checks that the disassembled form of certain symbols
+// is "hardened" - that means, the assembly instructions match a pattern that
+// mitigate potential Load Value Injection vulnerabilities.
+// To do so, a test crate is compiled, and certain symbols are found, disassembled
+// and checked one by one.
+// See https://github.com/rust-lang/rust/pull/77008
+
+// On load value injection:
+// https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/load-value-injection.html
+
+//@ only-x86_64-fortanix-unknown-sgx
+
+use run_make_support::{cmd, cwd, llvm_filecheck, llvm_objdump, regex, set_current_dir, target};
+
+fn main() {
+    let main_dir = cwd();
+    set_current_dir("enclave");
+    // HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features.
+    // These come from the top-level Rust workspace, that this crate is not a
+    // member of, but Cargo tries to load the workspace `Cargo.toml` anyway.
+    cmd("cargo")
+        .env("RUSTC_BOOTSTRAP", "1")
+        .arg("-v")
+        .arg("run")
+        .arg("--target")
+        .arg(target())
+        .run();
+    set_current_dir(&main_dir);
+    // Rust has various ways of adding code to a binary:
+    // - Rust code
+    // - Inline assembly
+    // - Global assembly
+    // - C/C++ code compiled as part of Rust crates
+    // For those different kinds, we do have very small code examples that should be
+    // mitigated in some way. Mostly we check that ret instructions should no longer be present.
+    check("unw_getcontext", "unw_getcontext.checks");
+    check("__libunwind_Registers_x86_64_jumpto", "jumpto.checks");
+
+    check("std::io::stdio::_print::[[:alnum:]]+", "print.with_frame_pointers.checks");
+
+    check("rust_plus_one_global_asm", "rust_plus_one_global_asm.checks");
+
+    check("cc_plus_one_c", "cc_plus_one_c.checks");
+    check("cc_plus_one_c_asm", "cc_plus_one_c_asm.checks");
+    check("cc_plus_one_cxx", "cc_plus_one_cxx.checks");
+    check("cc_plus_one_cxx_asm", "cc_plus_one_cxx_asm.checks");
+    check("cc_plus_one_asm", "cc_plus_one_asm.checks");
+
+    check("cmake_plus_one_c", "cmake_plus_one_c.checks");
+    check("cmake_plus_one_c_asm", "cmake_plus_one_c_asm.checks");
+    check("cmake_plus_one_c_global_asm", "cmake_plus_one_c_global_asm.checks");
+    check("cmake_plus_one_cxx", "cmake_plus_one_cxx.checks");
+    check("cmake_plus_one_cxx_asm", "cmake_plus_one_cxx_asm.checks");
+    check("cmake_plus_one_cxx_global_asm", "cmake_plus_one_cxx_global_asm.checks");
+    check("cmake_plus_one_asm", "cmake_plus_one_asm.checks");
+}
+
+fn check(func_re: &str, mut checks: &str) {
+    let dump = llvm_objdump()
+        .input("enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave")
+        .args(&["--syms", "--demangle"])
+        .run()
+        .stdout_utf8();
+    let re = regex::Regex::new(&format!("[[:blank:]]+{func_re}")).unwrap();
+    let func = re.find_iter(&dump).map(|m| m.as_str().trim()).collect::<Vec<&str>>().join(",");
+    assert!(!func.is_empty());
+    let dump = llvm_objdump()
+        .input("enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave")
+        .args(&["--demangle", &format!("--disassemble-symbols={func}")])
+        .run()
+        .stdout_utf8();
+    let dump = dump.as_bytes();
+
+    // Unique case, must succeed at one of two possible tests.
+    // This is because frame pointers are optional, and them being enabled requires
+    // an additional `popq` in the pattern checking file.
+    if func_re == "std::io::stdio::_print::[[:alnum:]]+" {
+        let output = llvm_filecheck().stdin(&dump).patterns(checks).run_unchecked();
+        if !output.status().success() {
+            checks = "print.without_frame_pointers.checks";
+            llvm_filecheck().stdin(&dump).patterns(checks).run();
+        }
+    } else {
+        llvm_filecheck().stdin(&dump).patterns(checks).run();
+    }
+    if !["rust_plus_one_global_asm", "cmake_plus_one_c_global_asm", "cmake_plus_one_cxx_global_asm"]
+        .contains(&func_re)
+    {
+        // The assembler cannot avoid explicit `ret` instructions. Sequences
+        // of `shlq $0x0, (%rsp); lfence; retq` are used instead.
+        llvm_filecheck().args(&["--implicit-check-not", "ret"]).stdin(dump).patterns(checks).run();
+    }
+}
diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh
deleted file mode 100644
index a7c4ae13ecb..00000000000
--- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-set -exuo pipefail
-
-function build {
-    CRATE=enclave
-
-    mkdir -p "${WORK_DIR}"
-    pushd "${WORK_DIR}"
-        rm -rf "${CRATE}"
-        cp -a "${TEST_DIR}"/enclave .
-        pushd $CRATE
-            echo "${WORK_DIR}"
-            # HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features.
-            # These come from the top-level Rust workspace, that this crate is not a
-            # member of, but Cargo tries to load the workspace `Cargo.toml` anyway.
-            env RUSTC_BOOTSTRAP=1
-                cargo -v run --target "${TARGET}"
-        popd
-    popd
-}
-
-function check {
-    local func_re="$1"
-    local checks="${TEST_DIR}/$2"
-    local asm=""
-    local objdump="${LLVM_BIN_DIR}/llvm-objdump"
-    local filecheck="${LLVM_BIN_DIR}/FileCheck"
-    local enclave=${WORK_DIR}/enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave
-
-    asm=$(mktemp)
-    func="$(${objdump} --syms --demangle "${enclave}" | \
-            grep --only-matching -E "[[:blank:]]+${func_re}\$" | \
-            sed -e 's/^[[:space:]]*//' )"
-    ${objdump} --disassemble-symbols="${func}" --demangle \
-      "${enclave}" > "${asm}"
-    ${filecheck} --input-file "${asm}" "${checks}"
-
-    if [ "${func_re}" != "rust_plus_one_global_asm" ] &&
-         [ "${func_re}" != "cmake_plus_one_c_global_asm" ] &&
-         [ "${func_re}" != "cmake_plus_one_cxx_global_asm" ]; then
-        # The assembler cannot avoid explicit `ret` instructions. Sequences
-        # of `shlq $0x0, (%rsp); lfence; retq` are used instead.
-        # https://www.intel.com/content/www/us/en/developer/articles/technical/
-        #     software-security-guidance/technical-documentation/load-value-injection.html
-        ${filecheck} --implicit-check-not ret --input-file "${asm}" "${checks}"
-    fi
-}
-
-build
-
-check "unw_getcontext" unw_getcontext.checks
-check "__libunwind_Registers_x86_64_jumpto" jumpto.checks
-check 'std::io::stdio::_print::[[:alnum:]]+' print.with_frame_pointers.checks ||
-    check 'std::io::stdio::_print::[[:alnum:]]+' print.without_frame_pointers.checks
-check rust_plus_one_global_asm rust_plus_one_global_asm.checks
-
-check cc_plus_one_c cc_plus_one_c.checks
-check cc_plus_one_c_asm cc_plus_one_c_asm.checks
-check cc_plus_one_cxx cc_plus_one_cxx.checks
-check cc_plus_one_cxx_asm cc_plus_one_cxx_asm.checks
-check cc_plus_one_asm cc_plus_one_asm.checks
-
-check cmake_plus_one_c cmake_plus_one_c.checks
-check cmake_plus_one_c_asm cmake_plus_one_c_asm.checks
-check cmake_plus_one_c_global_asm cmake_plus_one_c_global_asm.checks
-check cmake_plus_one_cxx cmake_plus_one_cxx.checks
-check cmake_plus_one_cxx_asm cmake_plus_one_cxx_asm.checks
-check cmake_plus_one_cxx_global_asm cmake_plus_one_cxx_global_asm.checks
-check cmake_plus_one_asm cmake_plus_one_asm.checks
diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml
index 82bd34ed274..92846f8e01d 100644
--- a/tests/rustdoc-gui/target.goml
+++ b/tests/rustdoc-gui/target.goml
@@ -11,7 +11,7 @@ define-function: (
     [theme, background, border],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
-        assert-css: ("#method\.a_method:target", {
+        wait-for-css: ("#method\.a_method:target", {
             "background-color": |background|,
             "border-right": "3px solid " + |border|,
         })
diff --git a/tests/rustdoc-js-std/exact-case.js b/tests/rustdoc-js-std/exact-case.js
new file mode 100644
index 00000000000..d9faff22fff
--- /dev/null
+++ b/tests/rustdoc-js-std/exact-case.js
@@ -0,0 +1,7 @@
+const EXPECTED = {
+    'query': 'Copy',
+    'others': [
+        { 'path': 'std::marker', 'name': 'Copy' },
+        { 'path': 'std::fs', 'name': 'copy' },
+    ],
+}
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/rustdoc/doc-hidden-crate.rs b/tests/rustdoc/doc-hidden-crate.rs
new file mode 100644
index 00000000000..dac557107a9
--- /dev/null
+++ b/tests/rustdoc/doc-hidden-crate.rs
@@ -0,0 +1,27 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/126796>.
+// `doc(hidden)` should still be able to hide extern crates, only the local crates
+// cannot be hidden because we still need to generate its `index.html` file.
+
+#![crate_name = "foo"]
+#![doc(hidden)]
+
+//@ has 'foo/index.html'
+// First we check that the page contains the crate name (`foo`).
+//@ has - '//*' 'foo'
+// But doesn't contain any of the other items.
+//@ !has - '//*' 'other'
+//@ !has - '//*' 'marker'
+//@ !has - '//*' 'PhantomData'
+
+#[doc(inline)]
+pub use std as other;
+
+#[doc(inline)]
+pub use std::marker;
+
+#[doc(inline)]
+pub use std::marker::PhantomData;
+
+//@ !has - '//*' 'myself'
+#[doc(inline)]
+pub use crate as myself;
diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive-tuple-variadic.rs
index 4b2fb786a89..b15e996f929 100644
--- a/tests/rustdoc/primitive-tuple-variadic.rs
+++ b/tests/rustdoc/primitive-tuple-variadic.rs
@@ -16,3 +16,20 @@ pub trait Bar {}
 //@ has - '//section[@id="impl-Bar-for-(U,)"]/h3' 'impl<U: Foo> Bar for (U₁, U₂, …, Uₙ)'
 #[doc(fake_variadic)]
 impl<U: Foo> Bar for (U,) {}
+
+pub trait Baz<T> { fn baz(&self) -> T { todo!() } }
+
+//@ has foo/trait.Baz.html
+//@ has - '//section[@id="impl-Baz%3C(T,)%3E-for-%5BT;+1%5D"]/h3' 'impl<T> Baz<(T₁, T₂, …, Tₙ)> for [T; N]'
+#[doc(fake_variadic)]
+impl<T> Baz<(T,)> for [T; 1] {}
+
+//@ has foo/trait.Baz.html
+//@ has - '//section[@id="impl-Baz%3C%5BT;+1%5D%3E-for-(T,)"]/h3' 'impl<T> Baz<[T; N]> for (T₁, T₂, …, Tₙ)'
+#[doc(fake_variadic)]
+impl<T> Baz<[T; 1]> for (T,) {}
+
+//@ has foo/trait.Baz.html
+//@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl<T> Baz<T> for (T₁, T₂, …, Tₙ)'
+#[doc(fake_variadic)]
+impl<T> Baz<T> for (T,) {}
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs
index 5fcff74064a..442f9d72c3f 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs
@@ -117,4 +117,11 @@ pub fn skipped_because_of_annotation<'a>(dcx: DiagCtxtHandle<'a>) {
 fn f(_x: impl Into<DiagMessage>, _y: impl Into<SubdiagMessage>) {}
 fn g() {
     f(crate::fluent_generated::no_crate_example, crate::fluent_generated::no_crate_example);
+    f("untranslatable diagnostic", crate::fluent_generated::no_crate_example);
+    //~^ ERROR diagnostics should be created using translatable messages
+    f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic");
+    //~^ ERROR diagnostics should be created using translatable messages
+    f("untranslatable diagnostic", "untranslatable diagnostic");
+    //~^ ERROR diagnostics should be created using translatable messages
+    //~^^ ERROR diagnostics should be created using translatable messages
 }
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
index 669324ce5d4..36dd3cf4be7 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -1,8 +1,8 @@
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:43:9
+  --> $DIR/diagnostics.rs:43:31
    |
 LL |         Diag::new(dcx, level, "untranslatable diagnostic")
-   |         ^^^^^^^^^
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/diagnostics.rs:7:9
@@ -11,16 +11,16 @@ LL | #![deny(rustc::untranslatable_diagnostic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:64:14
+  --> $DIR/diagnostics.rs:64:19
    |
 LL |         diag.note("untranslatable diagnostic");
-   |              ^^^^
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:85:14
+  --> $DIR/diagnostics.rs:85:19
    |
 LL |         diag.note("untranslatable diagnostic");
-   |              ^^^^
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
   --> $DIR/diagnostics.rs:99:21
@@ -41,10 +41,34 @@ LL |     let _diag = dcx.struct_err("untranslatable diagnostic");
    |                     ^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:102:21
+  --> $DIR/diagnostics.rs:102:32
    |
 LL |     let _diag = dcx.struct_err("untranslatable diagnostic");
-   |                     ^^^^^^^^^^
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+  --> $DIR/diagnostics.rs:120:7
+   |
+LL |     f("untranslatable diagnostic", crate::fluent_generated::no_crate_example);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+  --> $DIR/diagnostics.rs:122:50
+   |
+LL |     f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic");
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+  --> $DIR/diagnostics.rs:124:7
+   |
+LL |     f("untranslatable diagnostic", "untranslatable diagnostic");
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: diagnostics should be created using translatable messages
+  --> $DIR/diagnostics.rs:124:36
+   |
+LL |     f("untranslatable diagnostic", "untranslatable diagnostic");
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs
index 5e3f2557566..5449c09d35a 100644
--- a/tests/ui-fulldeps/stable-mir/check_instance.rs
+++ b/tests/ui-fulldeps/stable-mir/check_instance.rs
@@ -17,12 +17,14 @@ extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate stable_mir;
 
-use mir::{mono::Instance, TerminatorKind::*};
+use std::io::Write;
+use std::ops::ControlFlow;
+
+use mir::mono::Instance;
+use mir::TerminatorKind::*;
 use rustc_smir::rustc_internal;
 use stable_mir::ty::{RigidTy, TyKind};
 use stable_mir::*;
-use std::io::Write;
-use std::ops::ControlFlow;
 
 const CRATE_NAME: &str = "input";
 
@@ -33,7 +35,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     // Get all items and split generic vs monomorphic items.
     let (generic, mono): (Vec<_>, Vec<_>) =
         items.into_iter().partition(|item| item.requires_monomorphization());
-    assert_eq!(mono.len(), 3, "Expected 3 mono functions");
+    assert_eq!(mono.len(), 4, "Expected 3 mono functions");
     assert_eq!(generic.len(), 2, "Expected 2 generic functions");
 
     // For all monomorphic items, get the correspondent instances.
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/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs
new file mode 100644
index 00000000000..687fe1ad73d
--- /dev/null
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs
@@ -0,0 +1,48 @@
+//@ needs-asm-support
+#![feature(naked_functions)]
+#![feature(fn_align)]
+#![crate_type = "lib"]
+use std::arch::asm;
+
+#[repr(C)]
+//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
+#[naked]
+extern "C" fn example1() {
+    //~^ NOTE not a struct, enum, or union
+    unsafe { asm!("", options(noreturn)) }
+}
+
+#[repr(transparent)]
+//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
+#[naked]
+extern "C" fn example2() {
+    //~^ NOTE not a struct, enum, or union
+    unsafe { asm!("", options(noreturn)) }
+}
+
+#[repr(align(16), C)]
+//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
+#[naked]
+extern "C" fn example3() {
+    //~^ NOTE not a struct, enum, or union
+    unsafe { asm!("", options(noreturn)) }
+}
+
+// note: two errors because of packed and C
+#[repr(C, packed)]
+//~^ ERROR attribute should be applied to a struct or union [E0517]
+//~| ERROR attribute should be applied to a struct, enum, or union [E0517]
+#[naked]
+extern "C" fn example4() {
+    //~^ NOTE not a struct, enum, or union
+    //~| NOTE not a struct or union
+    unsafe { asm!("", options(noreturn)) }
+}
+
+#[repr(u8)]
+//~^ ERROR attribute should be applied to an enum [E0517]
+#[naked]
+extern "C" fn example5() {
+    //~^ NOTE not an enum
+    unsafe { asm!("", options(noreturn)) }
+}
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
new file mode 100644
index 00000000000..3740f17a9dc
--- /dev/null
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
@@ -0,0 +1,77 @@
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/naked-with-invalid-repr-attr.rs:7:8
+   |
+LL |   #[repr(C)]
+   |          ^
+...
+LL | / extern "C" fn example1() {
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/naked-with-invalid-repr-attr.rs:15:8
+   |
+LL |   #[repr(transparent)]
+   |          ^^^^^^^^^^^
+...
+LL | / extern "C" fn example2() {
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/naked-with-invalid-repr-attr.rs:23:19
+   |
+LL |   #[repr(align(16), C)]
+   |                     ^
+...
+LL | / extern "C" fn example3() {
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/naked-with-invalid-repr-attr.rs:32:8
+   |
+LL |   #[repr(C, packed)]
+   |          ^
+...
+LL | / extern "C" fn example4() {
+LL | |
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/naked-with-invalid-repr-attr.rs:32:11
+   |
+LL |   #[repr(C, packed)]
+   |             ^^^^^^
+...
+LL | / extern "C" fn example4() {
+LL | |
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not a struct or union
+
+error[E0517]: attribute should be applied to an enum
+  --> $DIR/naked-with-invalid-repr-attr.rs:42:8
+   |
+LL |   #[repr(u8)]
+   |          ^^
+...
+LL | / extern "C" fn example5() {
+LL | |
+LL | |     unsafe { asm!("", options(noreturn)) }
+LL | | }
+   | |_- not an enum
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0517`.
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
index a495e94bd9a..cf5d8f614dd 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
@@ -4,11 +4,6 @@ error[E0391]: cycle detected when computing predicates of `Foo`
 LL | struct Foo {
    | ^^^^^^^^^^
    |
-note: ...which requires computing predicates of `Foo`...
-  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
-   |
-LL | struct Foo {
-   | ^^^^^^^^^^
 note: ...which requires computing inferred outlives predicates of `Foo`...
   --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
index e7292c08ebd..e97a5df9d49 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
@@ -4,11 +4,6 @@ error[E0391]: cycle detected when computing predicates of `user`
 LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: ...which requires computing predicates of `user`...
-  --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
-   |
-LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires computing explicit predicates of `user`...
   --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
    |
diff --git a/tests/ui/attributes/rustc_pub_transparent.rs b/tests/ui/attributes/rustc_pub_transparent.rs
new file mode 100644
index 00000000000..4508fa39baf
--- /dev/null
+++ b/tests/ui/attributes/rustc_pub_transparent.rs
@@ -0,0 +1,25 @@
+#![feature(rustc_attrs, transparent_unions)]
+
+#[rustc_pub_transparent]
+#[repr(transparent)]
+union E<T: Copy> {
+    value: T,
+    uninit: (),
+}
+
+#[repr(transparent)]
+#[rustc_pub_transparent]
+struct S<T>(T);
+
+#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
+#[repr(C)]
+struct S1 {
+    A: u8,
+}
+
+#[rustc_pub_transparent] //~ ERROR attribute should be applied to `#[repr(transparent)]` types
+struct S2<T> {
+    value: T,
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/rustc_pub_transparent.stderr b/tests/ui/attributes/rustc_pub_transparent.stderr
new file mode 100644
index 00000000000..1d1f9437cb2
--- /dev/null
+++ b/tests/ui/attributes/rustc_pub_transparent.stderr
@@ -0,0 +1,23 @@
+error: attribute should be applied to `#[repr(transparent)]` types
+  --> $DIR/rustc_pub_transparent.rs:14:1
+   |
+LL |   #[rustc_pub_transparent]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^
+LL |   #[repr(C)]
+LL | / struct S1 {
+LL | |     A: u8,
+LL | | }
+   | |_- not a `#[repr(transparent)]` type
+
+error: attribute should be applied to `#[repr(transparent)]` types
+  --> $DIR/rustc_pub_transparent.rs:20:1
+   |
+LL |   #[rustc_pub_transparent]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / struct S2<T> {
+LL | |     value: T,
+LL | | }
+   | |_- not a `#[repr(transparent)]` type
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
index 54d8f26f4ea..5f0347bdb4d 100644
--- a/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
+++ b/tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -30,9 +30,9 @@ note: the lifetime `'c` as defined here...
 LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
    |                        ^^
 note: ...does not necessarily outlive the lifetime `'c` as defined here
-  --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:12:24
    |
-LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+LL |     fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
    |                        ^^
 
 error[E0308]: method not compatible with trait
@@ -44,16 +44,15 @@ LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d
    = note: expected signature `fn(&'a _, Inv<'c>, Inv<'c>, Inv<'_>)`
               found signature `fn(&'a _, Inv<'_>, Inv<'c>, Inv<'_>)`
 note: the lifetime `'c` as defined here...
-  --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:12:24
    |
-LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+LL |     fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
    |                        ^^
 note: ...does not necessarily outlive the lifetime `'c` as defined here
   --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
    |
 LL |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
    |                        ^^
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration
   --> $DIR/regions-bound-missing-bound-in-impl.rs:42:20
diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr
index 520cffc4b02..9b6448fe5a0 100644
--- a/tests/ui/check-cfg/mix.stderr
+++ b/tests/ui/check-cfg/mix.stderr
@@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra`
 LL |     cfg!(target_feature = "zebra");
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 201 more
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 239 more
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 27 warnings emitted
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index d780e04e729..56423d8c307 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_feature = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
    = 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`
@@ -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/coercion/cast-higher-ranked-unsafe-fn-ptr.rs b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs
new file mode 100644
index 00000000000..19723bee4d4
--- /dev/null
+++ b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+fn higher_ranked_fndef(ctx: &mut ()) {}
+
+fn test(higher_ranked_fnptr: fn(&mut ())) {
+    fn as_unsafe<T>(_: unsafe fn(T)) {}
+
+    // Make sure that we can cast higher-ranked fn items and pointers to
+    // a non-higher-ranked target.
+    as_unsafe(higher_ranked_fndef);
+    as_unsafe(higher_ranked_fnptr);
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs
index e07fa78463c..cdfeb9c434e 100644
--- a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs
+++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs
@@ -5,7 +5,9 @@
 #![feature(with_negative_coherence)]
 trait Trait {}
 impl<const N: u8> Trait for [(); N] {}
+//~^ ERROR: mismatched types
 impl<const N: i8> Trait for [(); N] {}
 //~^ ERROR: conflicting implementations of trait `Trait`
+//~| ERROR: mismatched types
 
 fn main() {}
diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr
index 2087be8e711..d65450845bc 100644
--- a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr
+++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr
@@ -1,11 +1,25 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `[(); _]`
-  --> $DIR/generic_const_type_mismatch.rs:8:1
+  --> $DIR/generic_const_type_mismatch.rs:9:1
    |
 LL | impl<const N: u8> Trait for [(); N] {}
    | ----------------------------------- first implementation here
+LL |
 LL | impl<const N: i8> Trait for [(); N] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[(); _]`
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/generic_const_type_mismatch.rs:7:34
+   |
+LL | impl<const N: u8> Trait for [(); N] {}
+   |                                  ^ expected `usize`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/generic_const_type_mismatch.rs:9:34
+   |
+LL | impl<const N: i8> Trait for [(); N] {}
+   |                                  ^ expected `usize`, found `i8`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0308.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
index 569e57fa326..401267a0f16 100644
--- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
@@ -4,11 +4,11 @@
 #![allow(incomplete_features, unstable_features)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
+        Dst: TransmuteFrom<Src, Context, ASSUME>,
         //~^ ERROR trait takes at most 2 generic arguments but 3 generic arguments were supplied
     {
     }
diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
index 5c04c4c9d5b..96716685614 100644
--- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
@@ -1,8 +1,8 @@
 error[E0107]: trait takes at most 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/transmutable-ice-110969.rs:11:14
    |
-LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
-   |              ^^^^^^^^^^^^^^^^^^^^^             -------- help: remove the unnecessary generic argument
+LL |         Dst: TransmuteFrom<Src, Context, ASSUME>,
+   |              ^^^^^^^^^^^^^             -------- help: remove the unnecessary generic argument
    |              |
    |              expected at most 2 generic arguments
 
diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs
index cc2ff9b8dea..c4e74596e9f 100644
--- a/tests/ui/const-generics/bad-subst-const-kind.rs
+++ b/tests/ui/const-generics/bad-subst-const-kind.rs
@@ -7,6 +7,7 @@ trait Q {
 
 impl<const N: u64> Q for [u8; N] {
     //~^ ERROR: the constant `N` is not of type `usize`
+    //~| ERROR: mismatched types
     const ASSOC: usize = 1;
 }
 
diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr
index 5c8d9c90363..21ec8f0768c 100644
--- a/tests/ui/const-generics/bad-subst-const-kind.stderr
+++ b/tests/ui/const-generics/bad-subst-const-kind.stderr
@@ -5,7 +5,7 @@ LL | impl<const N: u64> Q for [u8; N] {
    |                          ^^^^^^^ expected `usize`, found `u64`
 
 error: the constant `13` is not of type `u64`
-  --> $DIR/bad-subst-const-kind.rs:13:24
+  --> $DIR/bad-subst-const-kind.rs:14:24
    |
 LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
    |                        ^^^^^^^^ expected `u64`, found `usize`
@@ -18,5 +18,12 @@ LL | impl<const N: u64> Q for [u8; N] {
    |      |
    |      unsatisfied trait bound introduced here
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/bad-subst-const-kind.rs:8:31
+   |
+LL | impl<const N: u64> Q for [u8; N] {
+   |                               ^ expected `usize`, found `u64`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-nested.rs
new file mode 100644
index 00000000000..f9730cf8566
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+
+// This is a regression test for #128016.
+
+macro_rules! len_inner {
+    () => {
+        BAR
+    };
+}
+
+macro_rules! len {
+    () => {
+        len_inner!()
+    };
+}
+
+const BAR: usize = 0;
+
+fn main() {
+    let val: [bool; len!()] = [];
+}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-param.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-param.rs
new file mode 100644
index 00000000000..f123e55c028
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-param.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+macro_rules! len {
+    ($x:ident) => {
+        $x
+    };
+}
+
+fn bar<const N: usize>() {
+    let val: [bool; len!(N)] = [true; N];
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.rs b/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.rs
new file mode 100644
index 00000000000..f218caac0cf
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.rs
@@ -0,0 +1,13 @@
+// This is a regression test for #128016.
+
+macro_rules! len {
+    () => {
+        target
+        //~^ ERROR cannot find value `target`
+    };
+}
+
+fn main() {
+    let val: [str; len!()] = [];
+    //~^ ERROR the size for values
+}
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.stderr
new file mode 100644
index 00000000000..ab289e5a6b7
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro-res-error.stderr
@@ -0,0 +1,24 @@
+error[E0425]: cannot find value `target` in this scope
+  --> $DIR/trivial-const-arg-macro-res-error.rs:5:9
+   |
+LL |         target
+   |         ^^^^^^ not found in this scope
+...
+LL |     let val: [str; len!()] = [];
+   |                    ------ in this macro invocation
+   |
+   = note: this error originates in the macro `len` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/trivial-const-arg-macro-res-error.rs:11:14
+   |
+LL |     let val: [str; len!()] = [];
+   |              ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: slice and array elements must have `Sized` type
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro.rs b/tests/ui/const-generics/early/trivial-const-arg-macro.rs
new file mode 100644
index 00000000000..a19d9abfdcb
--- /dev/null
+++ b/tests/ui/const-generics/early/trivial-const-arg-macro.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+
+// This is a regression test for #128016.
+
+macro_rules! len {
+    () => {
+        BAR
+    };
+}
+
+const BAR: usize = 0;
+
+fn main() {
+    let val: [bool; len!()] = [];
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
index 8e5e23b2337..a45deabbb0f 100644
--- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
+++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
@@ -8,6 +8,7 @@ trait Q {
 impl<const N: u64> Q for [u8; N] {}
 //~^ ERROR not all trait items implemented
 //~| ERROR the constant `N` is not of type `usize`
+//~| ERROR mismatched types
 
 pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
 //~^ ERROR the constant `13` is not of type `u64`
diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
index e03580ec007..68870a8d38d 100644
--- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
@@ -14,7 +14,7 @@ LL | impl<const N: u64> Q for [u8; N] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
 
 error: the constant `13` is not of type `u64`
-  --> $DIR/type_mismatch.rs:12:26
+  --> $DIR/type_mismatch.rs:13:26
    |
 LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
    |                          ^^^^^^^^ expected `u64`, found `usize`
@@ -28,14 +28,20 @@ LL | impl<const N: u64> Q for [u8; N] {}
    |      unsatisfied trait bound introduced here
 
 error[E0308]: mismatched types
-  --> $DIR/type_mismatch.rs:12:20
+  --> $DIR/type_mismatch.rs:13:20
    |
 LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
    |        ------      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; <[u8; 13] as Q>::ASSOC]`, found `()`
    |        |
    |        implicitly returns `()` as its body has no tail or `return` expression
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:8:31
+   |
+LL | impl<const N: u64> Q for [u8; N] {}
+   |                               ^ expected `usize`, found `u64`
+
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0046, E0308.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
index 8b7ee577569..05a3487ffca 100644
--- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
+++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
@@ -14,8 +14,8 @@ mod v20 {
     //~^ ERROR cannot find value `v8` in this scope
     //~| ERROR cannot find function `v6` in this scope
     pub struct v17<const v10: usize, const v7: v11> {
-    //~^ WARN type `v17` should have an upper camel case name
-    //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
+        //~^ WARN type `v17` should have an upper camel case name
+        //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
         _p: (),
     }
 
@@ -25,10 +25,10 @@ mod v20 {
     }
 
     impl<const v10: usize> v17<v10, v2> {
-    //~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
-    //~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
+        //~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
+        //~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
         pub const fn v21() -> v18 {
-        //~^ ERROR cannot find type `v18` in this scope
+            //~^ ERROR cannot find type `v18` in this scope
             v18 { _p: () }
             //~^ ERROR cannot find struct, variant or union type `v18` in this scope
         }
diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
index 15d3c472585..39f022fbee9 100644
--- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
@@ -72,13 +72,13 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
 LL + #![feature(adt_const_params)]
    |
 
-error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
+error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
   --> $DIR/unevaluated-const-ice-119731.rs:27:37
    |
 LL |     impl<const v10: usize> v17<v10, v2> {
    |                                     ^^
 
-error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
+error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
   --> $DIR/unevaluated-const-ice-119731.rs:27:37
    |
 LL |     impl<const v10: usize> v17<v10, v2> {
diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs
index 59b77c678e8..a9b297ffb62 100644
--- a/tests/ui/const-generics/transmute-fail.rs
+++ b/tests/ui/const-generics/transmute-fail.rs
@@ -2,108 +2,108 @@
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
 
-fn foo<const W: usize, const H: usize>(v: [[u32;H+1]; W]) -> [[u32; W+1]; H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR cannot transmute
-  }
+fn foo<const W: usize, const H: usize>(v: [[u32; H + 1]; W]) -> [[u32; W + 1]; H] {
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR cannot transmute
+    }
 }
 
 fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
-  //~^ ERROR the constant `W` is not of type `usize`
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR the constant `W` is not of type `usize`
-  }
+    //~^ ERROR: the constant `W` is not of type `usize`
+    //~| ERROR: mismatched types
+    //~| ERROR: mismatched types
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: the constant `W` is not of type `usize`
+    }
 }
 
 fn baz<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H * H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR cannot transmute
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR cannot transmute
+    }
 }
 
 fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 8888888] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR cannot transmute
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR cannot transmute
+    }
 }
 
-fn transpose<const W: usize, const H: usize>(v: [[u32;H]; W]) -> [[u32; W]; H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+fn transpose<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn ident<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [[u32; H]; W] {
-  unsafe {
-    std::mem::transmute(v)
-  }
+    unsafe { std::mem::transmute(v) }
 }
 
 fn flatten<const W: usize, const H: usize>(v: [[u32; H]; W]) -> [u32; W * H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
-fn coagulate<const W: usize, const H: usize>(v: [u32; H*W]) -> [[u32; W];H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+fn coagulate<const W: usize, const H: usize>(v: [u32; H * W]) -> [[u32; W]; H] {
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn flatten_3d<const W: usize, const H: usize, const D: usize>(
-  v: [[[u32; D]; H]; W]
+    v: [[[u32; D]; H]; W],
 ) -> [u32; D * W * H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn flatten_somewhat<const W: usize, const H: usize, const D: usize>(
-  v: [[[u32; D]; H]; W]
+    v: [[[u32; D]; H]; W],
 ) -> [[u32; D * W]; H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn known_size<const L: usize>(v: [u16; L]) -> [u8; L * 2] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn condense_bytes<const L: usize>(v: [u8; L * 2]) -> [u16; L] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
-fn singleton_each<const L: usize>(v: [u8; L]) -> [[u8;1]; L] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+fn singleton_each<const L: usize>(v: [u8; L]) -> [[u8; 1]; L] {
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn transpose_with_const<const W: usize, const H: usize>(
-  v: [[u32; 2 * H]; W + W]
+    v: [[u32; 2 * H]; W + W],
 ) -> [[u32; W + W]; 2 * H] {
-  unsafe {
-    std::mem::transmute(v)
-    //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
-  }
+    unsafe {
+        std::mem::transmute(v)
+        //~^ ERROR: cannot transmute between types of different sizes, or dependently-sized types
+    }
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr
index b40fb23c331..124fbee8850 100644
--- a/tests/ui/const-generics/transmute-fail.stderr
+++ b/tests/ui/const-generics/transmute-fail.stderr
@@ -5,119 +5,132 @@ LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
    |                                          ^^^^^^^^^^^^^ expected `usize`, found `bool`
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:7:5
+  --> $DIR/transmute-fail.rs:7:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `[[u32; H+1]; W]` (size can vary because of [u32; H+1])
-   = note: target type: `[[u32; W+1]; H]` (size can vary because of [u32; W+1])
+   = note: source type: `[[u32; H + 1]; W]` (size can vary because of [u32; H + 1])
+   = note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1])
 
 error: the constant `W` is not of type `usize`
-  --> $DIR/transmute-fail.rs:15:5
+  --> $DIR/transmute-fail.rs:17:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool`
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:22:5
+  --> $DIR/transmute-fail.rs:24:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
    = note: target type: `[u32; W * H * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:29:5
+  --> $DIR/transmute-fail.rs:31:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[u32; 8888888]; 9999999]` are too big for the current architecture)
    = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[u32; 9999999]; 777777777]` are too big for the current architecture)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:36:5
+  --> $DIR/transmute-fail.rs:38:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
    = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:49:5
+  --> $DIR/transmute-fail.rs:49:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
    = note: target type: `[u32; W * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:56:5
+  --> $DIR/transmute-fail.rs:56:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `[u32; H*W]` (this type does not have a fixed size)
+   = note: source type: `[u32; H * W]` (this type does not have a fixed size)
    = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:65:5
+  --> $DIR/transmute-fail.rs:65:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[[u32; D]; H]; W]` (size can vary because of [u32; D])
    = note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:74:5
+  --> $DIR/transmute-fail.rs:74:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[[u32; D]; H]; W]` (size can vary because of [u32; D])
    = note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:81:5
+  --> $DIR/transmute-fail.rs:81:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[u16; L]` (this type does not have a fixed size)
    = note: target type: `[u8; L * 2]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:88:5
+  --> $DIR/transmute-fail.rs:88:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[u8; L * 2]` (this type does not have a fixed size)
    = note: target type: `[u16; L]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:95:5
+  --> $DIR/transmute-fail.rs:95:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[u8; L]` (this type does not have a fixed size)
    = note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/transmute-fail.rs:104:5
+  --> $DIR/transmute-fail.rs:104:9
    |
-LL |     std::mem::transmute(v)
-   |     ^^^^^^^^^^^^^^^^^^^
+LL |         std::mem::transmute(v)
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `[[u32; 2 * H]; W + W]` (size can vary because of [u32; 2 * H])
    = note: target type: `[[u32; W + W]; 2 * H]` (size can vary because of [u32; W + W])
 
-error: aborting due to 14 previous errors
+error[E0308]: mismatched types
+  --> $DIR/transmute-fail.rs:12:53
+   |
+LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
+   |                                                     ^ expected `usize`, found `bool`
+
+error[E0308]: mismatched types
+  --> $DIR/transmute-fail.rs:12:67
+   |
+LL | fn bar<const W: bool, const H: usize>(v: [[u32; H]; W]) -> [[u32; W]; H] {
+   |                                                                   ^ expected `usize`, found `bool`
+
+error: aborting due to 16 previous errors
 
-For more information about this error, try `rustc --explain E0512`.
+Some errors have detailed explanations: E0308, E0512.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/type_mismatch.rs b/tests/ui/const-generics/type_mismatch.rs
index 8187c785cd1..9c7217cd83e 100644
--- a/tests/ui/const-generics/type_mismatch.rs
+++ b/tests/ui/const-generics/type_mismatch.rs
@@ -1,10 +1,12 @@
 fn foo<const N: usize>() -> [u8; N] {
     bar::<N>()
     //~^ ERROR the constant `N` is not of type `u8`
+    //~| ERROR: mismatched types
 }
 
 fn bar<const N: u8>() -> [u8; N] {}
 //~^ ERROR the constant `N` is not of type `usize`
+//~| ERROR: mismatched types
 //~| ERROR mismatched types
 
 fn main() {}
diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr
index d1bb5c1242f..77e9f5e2b44 100644
--- a/tests/ui/const-generics/type_mismatch.stderr
+++ b/tests/ui/const-generics/type_mismatch.stderr
@@ -1,5 +1,5 @@
 error: the constant `N` is not of type `usize`
-  --> $DIR/type_mismatch.rs:6:26
+  --> $DIR/type_mismatch.rs:7:26
    |
 LL | fn bar<const N: u8>() -> [u8; N] {}
    |                          ^^^^^^^ expected `usize`, found `u8`
@@ -11,19 +11,31 @@ LL |     bar::<N>()
    |           ^ expected `u8`, found `usize`
    |
 note: required by a const generic parameter in `bar`
-  --> $DIR/type_mismatch.rs:6:8
+  --> $DIR/type_mismatch.rs:7:8
    |
 LL | fn bar<const N: u8>() -> [u8; N] {}
    |        ^^^^^^^^^^^ required by this const generic parameter in `bar`
 
 error[E0308]: mismatched types
-  --> $DIR/type_mismatch.rs:6:26
+  --> $DIR/type_mismatch.rs:7:26
    |
 LL | fn bar<const N: u8>() -> [u8; N] {}
    |    ---                   ^^^^^^^ expected `[u8; N]`, found `()`
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:2:11
+   |
+LL |     bar::<N>()
+   |           ^ expected `u8`, found `usize`
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:7:31
+   |
+LL | fn bar<const N: u8>() -> [u8; N] {}
+   |                               ^ expected `usize`, found `u8`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.rs b/tests/ui/consts/const-eval/const_fn_target_feature.rs
index ee669abb51e..8db41ba11c0 100644
--- a/tests/ui/consts/const-eval/const_fn_target_feature.rs
+++ b/tests/ui/consts/const-eval/const_fn_target_feature.rs
@@ -1,6 +1,7 @@
 //@ only-x86_64
 // Set the base cpu explicitly, in case the default has been changed.
 //@ compile-flags: -C target-cpu=x86-64 -C target-feature=+ssse3
+//@ check-pass
 
 #![crate_type = "lib"]
 
@@ -9,7 +10,8 @@ const A: () = unsafe { ssse3_fn() };
 
 // error (avx2 not enabled at compile time)
 const B: () = unsafe { avx2_fn() };
-//~^ ERROR evaluation of constant value failed
+// FIXME: currently we do not detect this UB, since we don't want the result of const-eval
+// to depend on `tcx.sess` which can differ between crates in a crate graph.
 
 #[target_feature(enable = "ssse3")]
 const unsafe fn ssse3_fn() {}
diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.stderr b/tests/ui/consts/const-eval/const_fn_target_feature.stderr
deleted file mode 100644
index d3a00b57ebb..00000000000
--- a/tests/ui/consts/const-eval/const_fn_target_feature.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const_fn_target_feature.rs:11:24
-   |
-LL | const B: () = unsafe { avx2_fn() };
-   |                        ^^^^^^^^^ calling a function that requires unavailable target features: avx2
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs
index deed09e4b2a..8ddfe61943c 100644
--- a/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs
+++ b/tests/ui/consts/const-eval/const_fn_target_feature_wasm.rs
@@ -7,7 +7,9 @@
 #[cfg(target_feature = "simd128")]
 compile_error!("simd128 target feature should be disabled");
 
-// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988
+// Calling functions with `#[target_feature]` is not unsound on WASM, see #84988.
+// (It can still lead to a runtime error though so we'd be in our right to abort execution,
+// just not to declare it UB.)
 const A: () = simd128_fn();
 
 #[target_feature(enable = "simd128")]
diff --git a/tests/ui/consts/const-eval/ub-write-through-immutable.rs b/tests/ui/consts/const-eval/ub-write-through-immutable.rs
index 945367f1823..9860b8fde4a 100644
--- a/tests/ui/consts/const-eval/ub-write-through-immutable.rs
+++ b/tests/ui/consts/const-eval/ub-write-through-immutable.rs
@@ -1,6 +1,5 @@
 //! Ensure we catch UB due to writing through a shared reference.
 #![feature(const_mut_refs, const_refs_to_cell)]
-#![deny(writes_through_immutable_pointer)]
 #![allow(invalid_reference_casting)]
 
 use std::mem;
@@ -9,15 +8,15 @@ use std::cell::UnsafeCell;
 const WRITE_AFTER_CAST: () = unsafe {
     let mut x = 0;
     let ptr = &x as *const i32 as *mut i32;
-    *ptr = 0; //~ERROR: writes_through_immutable_pointer
-    //~^ previously accepted
+    *ptr = 0; //~ERROR: evaluation of constant value failed
+    //~| immutable
 };
 
 const WRITE_AFTER_TRANSMUTE: () = unsafe {
     let mut x = 0;
     let ptr: *mut i32 = mem::transmute(&x);
-    *ptr = 0; //~ERROR: writes_through_immutable_pointer
-    //~^ previously accepted
+    *ptr = 0; //~ERROR: evaluation of constant value failed
+    //~| immutable
 };
 
 // it's okay when there is interior mutability;
diff --git a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
index 27eb2d2c0d1..dbcd35e0b88 100644
--- a/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
+++ b/tests/ui/consts/const-eval/ub-write-through-immutable.stderr
@@ -1,55 +1,15 @@
-error: writing through a pointer that was derived from a shared (immutable) reference
-  --> $DIR/ub-write-through-immutable.rs:12:5
+error[E0080]: evaluation of constant value failed
+  --> $DIR/ub-write-through-immutable.rs:11:5
    |
 LL |     *ptr = 0;
-   |     ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
-note: the lint level is defined here
-  --> $DIR/ub-write-through-immutable.rs:3:9
-   |
-LL | #![deny(writes_through_immutable_pointer)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
 
-error: writing through a pointer that was derived from a shared (immutable) reference
-  --> $DIR/ub-write-through-immutable.rs:19:5
+error[E0080]: evaluation of constant value failed
+  --> $DIR/ub-write-through-immutable.rs:18:5
    |
 LL |     *ptr = 0;
-   |     ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
+   |     ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
 
 error: aborting due to 2 previous errors
 
-Future incompatibility report: Future breakage diagnostic:
-error: writing through a pointer that was derived from a shared (immutable) reference
-  --> $DIR/ub-write-through-immutable.rs:12:5
-   |
-LL |     *ptr = 0;
-   |     ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
-note: the lint level is defined here
-  --> $DIR/ub-write-through-immutable.rs:3:9
-   |
-LL | #![deny(writes_through_immutable_pointer)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Future breakage diagnostic:
-error: writing through a pointer that was derived from a shared (immutable) reference
-  --> $DIR/ub-write-through-immutable.rs:19:5
-   |
-LL |     *ptr = 0;
-   |     ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
-note: the lint level is defined here
-  --> $DIR/ub-write-through-immutable.rs:3:9
-   |
-LL | #![deny(writes_through_immutable_pointer)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
index c7078e46fa6..efc0a1c2fba 100644
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+++ b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
@@ -1,9 +1,5 @@
 #![feature(const_extern_fn)]
 
-const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] { x }
-const unsafe extern "C" fn closure() -> fn() { || {} }
-const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
-//~^ ERROR floating point arithmetic
 const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
 //~^ ERROR pointers cannot be cast to integers
 
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
index 29fa90d611c..9cdeec159be 100644
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+++ b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
@@ -1,15 +1,5 @@
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const-extern-fn-min-const-fn.rs:5:42
-   |
-LL | const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
-   |                                          ^^^^^^^^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error: pointers cannot be cast to integers during const eval
-  --> $DIR/const-extern-fn-min-const-fn.rs:7:48
+  --> $DIR/const-extern-fn-min-const-fn.rs:3:48
    |
 LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
    |                                                ^^^^^^^^^^^^
@@ -17,6 +7,5 @@ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
    = note: at compile-time, pointers do not have an integer value
    = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn.rs b/tests/ui/consts/const-extern-fn/const-extern-fn.rs
index 57f5da8d0af..4b164767064 100644
--- a/tests/ui/consts/const-extern-fn/const-extern-fn.rs
+++ b/tests/ui/consts/const-extern-fn/const-extern-fn.rs
@@ -17,6 +17,19 @@ const unsafe extern "C" fn bar2(val: bool) -> bool {
     !val
 }
 
+#[allow(improper_ctypes_definitions)]
+const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] {
+    x
+}
+
+#[allow(improper_ctypes_definitions)]
+const unsafe extern "C" fn closure() -> fn() {
+    || {}
+}
+
+const unsafe extern "C" fn use_float() -> f32 {
+    1.0 + 1.0
+}
 
 fn main() {
     let a: [u8; foo1(25) as usize] = [0; 26];
@@ -32,4 +45,8 @@ fn main() {
     let _foo2_cast: extern "C" fn(u8) -> u8 = foo2;
     let _bar1_cast: unsafe extern "C" fn(bool) -> bool = bar1;
     let _bar2_cast: unsafe extern "C" fn(bool) -> bool = bar2;
+
+    unsize(&[0, 1, 2]);
+    unsafe { closure(); }
+    unsafe { use_float(); }
 }
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/const_fn_floating_point_arithmetic.gated.stderr b/tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
deleted file mode 100644
index e1b8154a287..00000000000
--- a/tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: fatal error triggered by #[rustc_error]
-  --> $DIR/const_fn_floating_point_arithmetic.rs:20:1
-   |
-LL | fn main() {}
-   | ^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/consts/const_fn_floating_point_arithmetic.rs b/tests/ui/consts/const_fn_floating_point_arithmetic.rs
deleted file mode 100644
index b0d0bc6b9f4..00000000000
--- a/tests/ui/consts/const_fn_floating_point_arithmetic.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// gate-test-const_fn_floating_point_arithmetic
-
-//@ revisions: stock gated
-
-#![feature(rustc_attrs)]
-#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]
-
-const fn add(f: f32) -> f32 { f + 2.0 }
-//[stock]~^ floating point arithmetic
-const fn sub(f: f32) -> f32 { 2.0 - f }
-//[stock]~^ floating point arithmetic
-const fn mul(f: f32, g: f32) -> f32 { f * g }
-//[stock]~^ floating point arithmetic
-const fn div(f: f32, g: f32) -> f32 { f / g }
-//[stock]~^ floating point arithmetic
-const fn neg(f: f32) -> f32 { -f }
-//[stock]~^ floating point arithmetic
-
-#[rustc_error]
-fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
diff --git a/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr b/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
deleted file mode 100644
index b5b94786ebb..00000000000
--- a/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
+++ /dev/null
@@ -1,53 +0,0 @@
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const_fn_floating_point_arithmetic.rs:8:31
-   |
-LL | const fn add(f: f32) -> f32 { f + 2.0 }
-   |                               ^^^^^^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const_fn_floating_point_arithmetic.rs:10:31
-   |
-LL | const fn sub(f: f32) -> f32 { 2.0 - f }
-   |                               ^^^^^^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const_fn_floating_point_arithmetic.rs:12:39
-   |
-LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
-   |                                       ^^^^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const_fn_floating_point_arithmetic.rs:14:39
-   |
-LL | const fn div(f: f32, g: f32) -> f32 { f / g }
-   |                                       ^^^^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: floating point arithmetic is not allowed in constant functions
-  --> $DIR/const_fn_floating_point_arithmetic.rs:16:31
-   |
-LL | const fn neg(f: f32) -> f32 { -f }
-   |                               ^^
-   |
-   = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
-   = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/const_let_eq_float.rs b/tests/ui/consts/const_let_eq_float.rs
index 30d839cdc2a..c9ca6b8b7ea 100644
--- a/tests/ui/consts/const_let_eq_float.rs
+++ b/tests/ui/consts/const_let_eq_float.rs
@@ -1,7 +1,5 @@
 //@ run-pass
 
-#![feature(const_fn_floating_point_arithmetic)]
-
 struct Foo<T>(T);
 struct Bar<T> { x: T }
 struct W(f32);
diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr
index 52d3e003f0a..8a7a0981f41 100644
--- a/tests/ui/consts/issue-36163.stderr
+++ b/tests/ui/consts/issue-36163.stderr
@@ -1,10 +1,10 @@
-error[E0391]: cycle detected when simplifying constant for the type system `Foo::{constant#0}`
+error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}`
   --> $DIR/issue-36163.rs:4:9
    |
 LL |     B = A,
    |         ^
    |
-note: ...which requires const-evaluating + checking `Foo::{constant#0}`...
+note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`...
   --> $DIR/issue-36163.rs:4:9
    |
 LL |     B = A,
@@ -19,7 +19,7 @@ note: ...which requires const-evaluating + checking `A`...
    |
 LL | const A: isize = Foo::B as isize;
    |                  ^^^^^^^^^^^^^^^
-   = note: ...which again requires simplifying constant for the type system `Foo::{constant#0}`, completing the cycle
+   = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle
 note: cycle used when checking that `Foo` is well-formed
   --> $DIR/issue-36163.rs:3:1
    |
diff --git a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs
index a97eeadd92f..fe92787aec1 100644
--- a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs
+++ b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs
@@ -1,6 +1,4 @@
 //@ run-pass
-#![feature(rustc_allow_const_fn_unstable)]
-
 #![feature(rustc_attrs, staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
index bb240fb4ad6..480b16b28a5 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
+++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
@@ -3,7 +3,7 @@
             we're apparently really bad at it",
             issue = "none")]
 
-#![feature(const_fn_floating_point_arithmetic, foo, foo2)]
+#![feature(const_refs_to_cell, foo, foo2)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -25,9 +25,15 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
-// Const-stable functions cannot rely on unstable const-eval features.
-const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+// conformity is required
+const fn bar3() -> u32 {
+    let x = std::cell::Cell::new(0u32);
+    x.get();
+    //~^ ERROR const-stable function cannot use `#[feature(const_refs_to_cell)]`
+    //~| ERROR cannot call non-const fn
+    foo()
+    //~^ ERROR is not yet stable as a const fn
+}
 
 // check whether this function cannot be called even with the feature gate active
 #[unstable(feature = "foo2", issue = "none")]
diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
index 7ec2508ca93..019deda063c 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
@@ -14,30 +14,47 @@ LL | const fn bar2() -> u32 { foo2() }
    |
    = help: const-stable functions can only call other const-stable functions
 
-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
-  --> $DIR/min_const_fn_libstd_stability.rs:29:26
+error: const-stable function cannot use `#[feature(const_refs_to_cell)]`
+  --> $DIR/min_const_fn_libstd_stability.rs:31:5
    |
-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-   |                          ^^^^^^^^^^^^^
+LL |     x.get();
+   |     ^
    |
 help: if it is not part of the public API, make this function unstably const
    |
 LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+LL | const fn bar3() -> u32 {
    |
-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
    |
-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)]
+LL | const fn bar3() -> u32 {
    |
 
+error[E0015]: cannot call non-const fn `Cell::<u32>::get` in constant functions
+  --> $DIR/min_const_fn_libstd_stability.rs:31:7
+   |
+LL |     x.get();
+   |       ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error: `foo` is not yet stable as a const fn
+  --> $DIR/min_const_fn_libstd_stability.rs:34:5
+   |
+LL |     foo()
+   |     ^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
 error: `foo2_gated` is not yet stable as a const fn
-  --> $DIR/min_const_fn_libstd_stability.rs:39:32
+  --> $DIR/min_const_fn_libstd_stability.rs:45:32
    |
 LL | const fn bar2_gated() -> u32 { foo2_gated() }
    |                                ^^^^^^^^^^^^
    |
    = help: const-stable functions can only call other const-stable functions
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
index 03084c8674d..f2a54b8a13d 100644
--- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
+++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
@@ -3,7 +3,7 @@
             we're apparently really bad at it",
             issue = "none")]
 
-#![feature(const_fn_floating_point_arithmetic, foo, foo2)]
+#![feature(const_refs_to_cell, foo, foo2)]
 #![feature(staged_api)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -23,12 +23,6 @@ const unsafe fn foo2() -> u32 { 42 }
 // can't call non-min_const_fn
 const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as a const fn
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
-// conformity is required
-const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
-
 // check whether this function cannot be called even with the feature gate active
 #[unstable(feature = "foo2", issue = "none")]
 const unsafe fn foo2_gated() -> u32 { 42 }
diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
index 72c1f175d1d..353b117efbc 100644
--- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -14,30 +14,13 @@ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
    |
    = help: const-stable functions can only call other const-stable functions
 
-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
-   |
-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-   |                                 ^^^^^^^^^^^^^
-   |
-help: if it is not part of the public API, make this function unstably const
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-   |
-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
-   |
-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
-   |
-
 error: `foo2_gated` is not yet stable as a const fn
-  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:39:48
+  --> $DIR/min_const_unsafe_fn_libstd_stability.rs:33:48
    |
 LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
    |                                                ^^^^^^^^^^^^
    |
    = help: const-stable functions can only call other const-stable functions
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
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/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
index d4fc1717538..ec01225c6bf 100644
--- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
+++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
@@ -48,10 +48,10 @@ LL |     const STATIC: &str = "";
    = note: expected reference `&'static _`
               found reference `&_`
 note: the anonymous lifetime as defined here...
-  --> $DIR/elided-lifetime.rs:15:18
+  --> $DIR/elided-lifetime.rs:16:19
    |
-LL | impl Bar for Foo<'_> {
-   |                  ^^
+LL |     const STATIC: &str = "";
+   |                   ^
    = note: ...does not necessarily outlive the static lifetime
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
index 8e4c27875ab..b8e2f412b49 100644
--- a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
@@ -30,10 +30,10 @@ LL |     const STATIC: &str = "";
    = note: expected reference `&_`
               found reference `&_`
 note: the anonymous lifetime as defined here...
-  --> $DIR/static-trait-impl.rs:8:10
+  --> $DIR/static-trait-impl.rs:9:19
    |
-LL | impl Bar<'_> for A {
-   |          ^^
+LL |     const STATIC: &str = "";
+   |                   ^
 note: ...does not necessarily outlive the anonymous lifetime as defined here
   --> $DIR/static-trait-impl.rs:8:10
    |
diff --git a/tests/ui/delegation/inner-attr.stderr b/tests/ui/delegation/inner-attr.stderr
index f3b53e331ad..257ab760ffc 100644
--- a/tests/ui/delegation/inner-attr.stderr
+++ b/tests/ui/delegation/inner-attr.stderr
@@ -8,11 +8,6 @@ LL | fn main() {}
    | ------------ the inner attribute doesn't annotate this function
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the function, change the attribute from inner to outer style
-   |
-LL - reuse a as b { #![rustc_dummy] self }
-LL + reuse a as b { #[rustc_dummy] self }
-   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/dst/dst-rvalue.stderr b/tests/ui/dst/dst-rvalue.stderr
index 8d0a82b707d..d8c529617f7 100644
--- a/tests/ui/dst/dst-rvalue.stderr
+++ b/tests/ui/dst/dst-rvalue.stderr
@@ -9,6 +9,11 @@ LL |     let _x: Box<str> = Box::new(*"hello world");
    = help: the trait `Sized` is not implemented for `str`
 note: required by a bound in `Box::<T>::new`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let _x: Box<str> = Box::new(*"hello world");
+LL +     let _x: Box<str> = Box::new("hello world");
+   |
 
 error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
   --> $DIR/dst-rvalue.rs:8:37
@@ -21,6 +26,11 @@ LL |     let _x: Box<[isize]> = Box::new(*array);
    = help: the trait `Sized` is not implemented for `[isize]`
 note: required by a bound in `Box::<T>::new`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let _x: Box<[isize]> = Box::new(*array);
+LL +     let _x: Box<[isize]> = Box::new(array);
+   |
 
 error: aborting due to 2 previous errors
 
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/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs
new file mode 100644
index 00000000000..19b5edb620f
--- /dev/null
+++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs
@@ -0,0 +1,14 @@
+//@ edition: 2021
+
+trait Trait {}
+
+impl dyn Trait {
+    const CONST: () = ();
+}
+
+fn main() {
+    match () {
+        Trait::CONST => {}
+        //~^ ERROR trait objects must include the `dyn` keyword
+    }
+}
diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr
new file mode 100644
index 00000000000..4446a89b63b
--- /dev/null
+++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr
@@ -0,0 +1,14 @@
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-dyn-on-bare-trait-in-pat.rs:11:9
+   |
+LL |         Trait::CONST => {}
+   |         ^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL |         <dyn Trait>::CONST => {}
+   |         ++++      +
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/error-codes/E0208.rs b/tests/ui/error-codes/E0208.rs
index 74c138af483..2713ba6ed6c 100644
--- a/tests/ui/error-codes/E0208.rs
+++ b/tests/ui/error-codes/E0208.rs
@@ -1,7 +1,7 @@
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-struct Foo<'a, T> { //~ ERROR [+, o]
+struct Foo<'a, T> { //~ ERROR ['a: +, T: o]
     t: &'a mut T,
 }
 
diff --git a/tests/ui/error-codes/E0208.stderr b/tests/ui/error-codes/E0208.stderr
index 77b6ceae4dc..a39e93afab3 100644
--- a/tests/ui/error-codes/E0208.stderr
+++ b/tests/ui/error-codes/E0208.stderr
@@ -1,4 +1,4 @@
-error: [+, o]
+error: ['a: +, T: o]
   --> $DIR/E0208.rs:4:1
    |
 LL | struct Foo<'a, T> {
diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
index 83492988479..044c1ae2dd4 100644
--- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
+++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
@@ -1,21 +1,21 @@
-warning: `extern` fn uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
+warning: `extern` fn uses type `CStr`, which is not FFI-safe
   --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12
    |
 LL | type Foo = extern "C" fn(::std::ffi::CStr);
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
-   = help: consider using a raw pointer instead
-   = note: slices have no C equivalent
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
    = note: `#[warn(improper_ctypes_definitions)]` on by default
 
-warning: `extern` block uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
+warning: `extern` block uses type `CStr`, which is not FFI-safe
   --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18
    |
 LL |     fn meh(blah: Foo);
    |                  ^^^ not FFI-safe
    |
-   = help: consider using a raw pointer instead
-   = note: slices have no C equivalent
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
    = note: `#[warn(improper_ctypes)]` on by default
 
 warning: 2 warnings emitted
diff --git a/tests/ui/feature-gates/feature-gate-const-arg-path.rs b/tests/ui/feature-gates/feature-gate-const-arg-path.rs
new file mode 100644
index 00000000000..0938c5733a2
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-const-arg-path.rs
@@ -0,0 +1,5 @@
+//@ check-pass
+
+// this doesn't really have any user facing impact....
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-repr-simd.stderr b/tests/ui/feature-gates/feature-gate-repr-simd.stderr
index 5b490c0c0c3..5a0ceb2dd74 100644
--- a/tests/ui/feature-gates/feature-gate-repr-simd.stderr
+++ b/tests/ui/feature-gates/feature-gate-repr-simd.stderr
@@ -35,3 +35,17 @@ error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0566, E0658.
 For more information about an error, try `rustc --explain E0566`.
+Future incompatibility report: Future breakage diagnostic:
+error[E0566]: conflicting representation hints
+  --> $DIR/feature-gate-repr-simd.rs:4:8
+   |
+LL | #[repr(C)]
+   |        ^
+LL |
+LL | #[repr(simd)]
+   |        ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
+
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.rs b/tests/ui/feature-gates/feature-gate-struct-target-features.rs
new file mode 100644
index 00000000000..85494881146
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-struct-target-features.rs
@@ -0,0 +1,4 @@
+#[target_feature(enable = "avx")] //~ ERROR attribute should be applied to a function definition
+struct Avx {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-struct-target-features.stderr b/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
new file mode 100644
index 00000000000..1e18d3ee1e1
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-struct-target-features.stderr
@@ -0,0 +1,10 @@
+error: attribute should be applied to a function definition
+  --> $DIR/feature-gate-struct-target-features.rs:1:1
+   |
+LL | #[target_feature(enable = "avx")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct Avx {}
+   | ------------- not a function definition
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
index d1decc0c3f1..37491ca12b0 100644
--- a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
@@ -51,7 +51,7 @@ LL |     type A<'a> where Self: 'a;
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
              Fooy
              Fooer<T>
-   = note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A = &'a ()> + 'static)>`
+   = note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A<'a> = &'a ()> + 'static)>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr
index bb14e297174..88c08051da7 100644
--- a/tests/ui/generic-associated-types/issue-76535.base.stderr
+++ b/tests/ui/generic-associated-types/issue-76535.base.stderr
@@ -47,7 +47,7 @@ LL |     type SubType<'a>: SubTrait where Self: 'a;
    = help: consider moving `SubType` to another trait
    = help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead
    = note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type
-   = note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
+   = note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType<'_> = SubStruct<'_>>>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr
index bcc6382cf7c..551ad2a8fdf 100644
--- a/tests/ui/generic-associated-types/issue-79422.base.stderr
+++ b/tests/ui/generic-associated-types/issue-79422.base.stderr
@@ -49,7 +49,7 @@ LL |     type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
    = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead:
              std::collections::BTreeMap<K, V>
              Source
-   = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
+   = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont<'_> = (dyn RefCont<'_, u8> + 'static)>>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr
index ae1526296a7..031f8d8d851 100644
--- a/tests/ui/generic-associated-types/issue-79422.extended.stderr
+++ b/tests/ui/generic-associated-types/issue-79422.extended.stderr
@@ -28,7 +28,7 @@ LL |     type VRefCont<'a> = &'a V where Self: 'a;
    = note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
                  found reference `&u8`
    = help: `&u8` implements `RefCont` so you could box the found value and coerce it to the trait object `Box<dyn RefCont>`, you will have to change the expected type as well
-   = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
+   = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont<'_> = (dyn RefCont<'_, u8> + 'static)>>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
index 9c067cb6934..2fde0f200c0 100644
--- a/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
+++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
@@ -6,13 +6,13 @@ trait Bar<'a> {
 }
 
 fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
-    //~^ ERROR [o, o]
+    //~^ ERROR ['a: o, T: o]
     // captures both T and 'a invariantly
     ()
 }
 
 fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
-    //~^ ERROR [o, o, o]
+    //~^ ERROR ['a: o, T: o, 'a: o]
     // captures both T and 'a invariantly, and also duplicates `'a`
     // i.e. the opaque looks like `impl Into<<T as Bar<'a>>::Assoc> + 'a_duplicated`
     ()
diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
index 9d52001b024..fe8a2772a00 100644
--- a/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
+++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
@@ -1,10 +1,10 @@
-error: [o, o]
+error: ['a: o, T: o]
   --> $DIR/capture-lifetime-not-in-hir.rs:8:29
    |
 LL | fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
    |                             ^^^^^^^^^^^^^^^^^^^
 
-error: [o, o, o]
+error: ['a: o, T: o, 'a: o]
   --> $DIR/capture-lifetime-not-in-hir.rs:14:30
    |
 LL | fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr
index 080750f8497..3adf78322d2 100644
--- a/tests/ui/impl-trait/implicit-capture-late.stderr
+++ b/tests/ui/impl-trait/implicit-capture-late.stderr
@@ -10,7 +10,7 @@ note: lifetime declared here
 LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
    |                                    ^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/implicit-capture-late.rs:10:55
    |
 LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
diff --git a/tests/ui/impl-trait/in-trait/refine-err.rs b/tests/ui/impl-trait/in-trait/refine-err.rs
new file mode 100644
index 00000000000..7518cee97c4
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/refine-err.rs
@@ -0,0 +1,14 @@
+#![deny(refining_impl_trait)]
+
+trait FromRow {
+    fn prepare(self) -> impl Fn() -> T;
+    //~^ ERROR cannot find type `T` in this scope
+}
+
+impl<T> FromRow for T {
+    fn prepare(self) -> impl Fn() -> T {
+        || todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/refine-err.stderr b/tests/ui/impl-trait/in-trait/refine-err.stderr
new file mode 100644
index 00000000000..6b4ef74d50a
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/refine-err.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/refine-err.rs:4:38
+   |
+LL |     fn prepare(self) -> impl Fn() -> T;
+   |                                      ^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
index 7a51037324f..ab21dae7dc5 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
@@ -14,7 +14,6 @@ impl<'a, I: 'a + Iterable> Iterable for &'a I {
     //~^ ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR `()` is not an iterator
-    //~| WARNING impl trait in impl method signature does not match trait method signature
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
index 67c4df0f3a9..d8a2eef94a1 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
@@ -32,24 +32,7 @@ LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missin
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-warning: impl trait in impl method signature does not match trait method signature
-  --> $DIR/span-bug-issue-121457.rs:13:51
-   |
-LL |     fn iter(&self) -> impl Iterator;
-   |                       ------------- return type from trait method defined here
-...
-LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
-   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this bound is stronger than that defined on the trait
-   |
-   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
-   = note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
-   = note: `#[warn(refining_impl_trait_reachable)]` on by default
-help: replace the return type so that it matches the trait
-   |
-LL |     fn iter(&self) -> impl Iterator {}
-   |                       ~~~~~~~~~~~~~
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0195, E0277, E0582.
 For more information about an error, try `rustc --explain E0195`.
diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs
index 65565dcc2a6..0ac44bf7546 100644
--- a/tests/ui/impl-trait/in-trait/variance.rs
+++ b/tests/ui/impl-trait/in-trait/variance.rs
@@ -7,14 +7,16 @@ impl<T> Captures<'_> for T {}
 
 trait Foo<'i> {
     fn implicit_capture_early<'a: 'a>() -> impl Sized {}
-    //~^ [o, *, *, o, o]
-    // Self, 'i, 'a, 'i_duplicated, 'a_duplicated
+    //~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
 
-    fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
+    fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+    //~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
 
-    fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
+    fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
+    //~^ [Self: o, 'i: *, 'a: o, 'i: o]
 
-    fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
+    fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+    //~^ [Self: o, 'i: *, 'a: o, 'i: o]
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/variance.stderr b/tests/ui/impl-trait/in-trait/variance.stderr
index 8cae5a92f0d..54e0afbaa95 100644
--- a/tests/ui/impl-trait/in-trait/variance.stderr
+++ b/tests/ui/impl-trait/in-trait/variance.stderr
@@ -1,23 +1,23 @@
-error: [o, *, *, o, o]
+error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:9:44
    |
 LL |     fn implicit_capture_early<'a: 'a>() -> impl Sized {}
    |                                            ^^^^^^^^^^
 
-error: [o, *, *, o, o]
-  --> $DIR/variance.rs:13:44
+error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
+  --> $DIR/variance.rs:12:44
    |
 LL |     fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, *, o, o]
+error: [Self: o, 'i: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:15:48
    |
 LL |     fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
    |                                                ^^^^^^^^^^
 
-error: [o, *, o, o]
-  --> $DIR/variance.rs:17:48
+error: [Self: o, 'i: *, 'a: o, 'i: o]
+  --> $DIR/variance.rs:18:48
    |
 LL |     fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
    |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^
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/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr
index 17245055744..011ab3259c4 100644
--- a/tests/ui/impl-trait/variance.e2024.stderr
+++ b/tests/ui/impl-trait/variance.e2024.stderr
@@ -1,22 +1,22 @@
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:14:36
    |
 LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
    |                                    ^^^^^^^^^^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:19:32
    |
 LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/variance.rs:21:40
    |
 LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
    |                                        ^^^^^^^^^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/variance.rs:26:36
    |
 LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
diff --git a/tests/ui/impl-trait/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr
index 17245055744..011ab3259c4 100644
--- a/tests/ui/impl-trait/variance.new.stderr
+++ b/tests/ui/impl-trait/variance.new.stderr
@@ -1,22 +1,22 @@
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:14:36
    |
 LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
    |                                    ^^^^^^^^^^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:19:32
    |
 LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/variance.rs:21:40
    |
 LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
    |                                        ^^^^^^^^^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/variance.rs:26:36
    |
 LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
diff --git a/tests/ui/impl-trait/variance.old.stderr b/tests/ui/impl-trait/variance.old.stderr
index 9410b54b491..ac3bcd2723f 100644
--- a/tests/ui/impl-trait/variance.old.stderr
+++ b/tests/ui/impl-trait/variance.old.stderr
@@ -1,10 +1,10 @@
-error: [*]
+error: ['a: *]
   --> $DIR/variance.rs:14:36
    |
 LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
    |                                    ^^^^^^^^^^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:19:32
    |
 LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
@@ -16,7 +16,7 @@ error: []
 LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
    |                                        ^^^^^^^^^^
 
-error: [o]
+error: ['a: o]
   --> $DIR/variance.rs:26:36
    |
 LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs
index 72b4a831bad..43f7207a904 100644
--- a/tests/ui/impl-trait/variance.rs
+++ b/tests/ui/impl-trait/variance.rs
@@ -12,17 +12,17 @@ trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
 fn not_captured_early<'a: 'a>() -> impl Sized {}
-//[old]~^ [*]
-//[new]~^^ [*, o]
-//[e2024]~^^^ [*, o]
+//[old]~^ ['a: *]
+//[new]~^^ ['a: *, 'a: o]
+//[e2024]~^^^ ['a: *, 'a: o]
 
-fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
+fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o]
 
 fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
 //[old]~^ []
-//[new]~^^ [o]
-//[e2024]~^^^ [o]
+//[new]~^^ ['a: o]
+//[e2024]~^^^ ['a: o]
 
-fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]
+fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o]
 
 fn main() {}
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
index c8d1614a7f3..f498257e12f 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
@@ -5,9 +5,9 @@ LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:8:12
    |
-LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+LL |     fn get<'s>(s: &'s str, _: ()) -> &'static str;
    |            ^^
 note: ...so that the method type is compatible with trait
   --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.rs b/tests/ui/inference/detect-old-time-version-format_description-parse.rs
new file mode 100644
index 00000000000..453a795e768
--- /dev/null
+++ b/tests/ui/inference/detect-old-time-version-format_description-parse.rs
@@ -0,0 +1,8 @@
+#![crate_name = "time"]
+
+fn main() {
+    let items = Box::new(vec![]); //~ ERROR E0282
+    //~^ NOTE type must be known at this point
+    //~| NOTE this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35`
+    items.into();
+}
diff --git a/tests/ui/inference/detect-old-time-version-format_description-parse.stderr b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
new file mode 100644
index 00000000000..2949a5dcfec
--- /dev/null
+++ b/tests/ui/inference/detect-old-time-version-format_description-parse.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed for `Box<Vec<_>>`
+  --> $DIR/detect-old-time-version-format_description-parse.rs:4:9
+   |
+LL |     let items = Box::new(vec![]);
+   |         ^^^^^   ---------------- type must be known at this point
+   |
+   = note: this is an inference error on crate `time` caused by an API change in Rust 1.80.0; update `time` to version `>=0.3.35` by calling `cargo update`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/internal/internal-unstable-const.rs b/tests/ui/internal/internal-unstable-const.rs
deleted file mode 100644
index 4ec2426dfee..00000000000
--- a/tests/ui/internal/internal-unstable-const.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Don't allow unstable features in stable functions without `allow_internal_unstable`.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-#![feature(staged_api)]
-#![feature(const_fn_floating_point_arithmetic)]
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
-pub const fn foo() -> f32 {
-    1.0 + 1.0 //~ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
-}
-
-fn main() {}
diff --git a/tests/ui/internal/internal-unstable-const.stderr b/tests/ui/internal/internal-unstable-const.stderr
deleted file mode 100644
index ed9196d2b63..00000000000
--- a/tests/ui/internal/internal-unstable-const.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
-  --> $DIR/internal-unstable-const.rs:10:5
-   |
-LL |     1.0 + 1.0
-   |     ^^^^^^^^^
-   |
-help: if it is not part of the public API, make this function unstably const
-   |
-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
-LL | pub const fn foo() -> f32 {
-   |
-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
-   |
-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
-LL | pub const fn foo() -> f32 {
-   |
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
index ab46fd796c5..99f98c3f27a 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
@@ -13,5 +13,13 @@ const RAW_EQ_PTR: bool = unsafe {
 //~| unable to turn pointer into integer
 };
 
+const RAW_EQ_NOT_ALIGNED: bool = unsafe {
+    let arr = [0u8; 4];
+    let aref = &*arr.as_ptr().cast::<i32>();
+    std::intrinsics::raw_eq(aref, aref)
+//~^ ERROR evaluation of constant value failed
+//~| alignment
+};
+
 pub fn main() {
 }
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
index af16c2bc64a..bedfc8283ea 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
@@ -13,6 +13,12 @@ LL |     std::intrinsics::raw_eq(&(&0), &(&1))
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 
-error: aborting due to 2 previous errors
+error[E0080]: evaluation of constant value failed
+  --> $DIR/intrinsic-raw_eq-const-bad.rs:19:5
+   |
+LL |     std::intrinsics::raw_eq(aref, aref)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
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/issues/issue-17651.stderr b/tests/ui/issues/issue-17651.stderr
index 0c95a3c0c40..9519507320d 100644
--- a/tests/ui/issues/issue-17651.stderr
+++ b/tests/ui/issues/issue-17651.stderr
@@ -9,6 +9,11 @@ LL |     (|| Box::new(*(&[0][..])))();
    = help: the trait `Sized` is not implemented for `[{integer}]`
 note: required by a bound in `Box::<T>::new`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     (|| Box::new(*(&[0][..])))();
+LL +     (|| Box::new((&[0][..])))();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr
index 60721f001b7..fe310998f09 100644
--- a/tests/ui/issues/issue-20831-debruijn.stderr
+++ b/tests/ui/issues/issue-20831-debruijn.stderr
@@ -5,10 +5,10 @@ LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the anonymous lifetime as defined here...
-  --> $DIR/issue-20831-debruijn.rs:28:18
+  --> $DIR/issue-20831-debruijn.rs:28:67
    |
 LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
-   |                  ^
+   |                                                                   ^^^^^^^^^
 note: ...but the lifetime must also be valid for the lifetime `'a` as defined here...
   --> $DIR/issue-20831-debruijn.rs:26:6
    |
diff --git a/tests/ui/issues/issue-37884.stderr b/tests/ui/issues/issue-37884.stderr
index b7c0095d682..17037d2180d 100644
--- a/tests/ui/issues/issue-37884.stderr
+++ b/tests/ui/issues/issue-37884.stderr
@@ -7,10 +7,7 @@ LL |     fn next(&'a mut self) -> Option<Self::Item>
    = note: expected signature `fn(&mut RepeatMut<'_, _>) -> Option<_>`
               found signature `fn(&'a mut RepeatMut<'_, _>) -> Option<_>`
 note: the anonymous lifetime as defined here...
-  --> $DIR/issue-37884.rs:6:5
-   |
-LL |     fn next(&'a mut self) -> Option<Self::Item>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 note: ...does not necessarily outlive the lifetime `'a` as defined here
   --> $DIR/issue-37884.rs:3:6
    |
diff --git a/tests/ui/issues/issue-47094.stderr b/tests/ui/issues/issue-47094.stderr
index 970e3184710..1c6693403b8 100644
--- a/tests/ui/issues/issue-47094.stderr
+++ b/tests/ui/issues/issue-47094.stderr
@@ -23,3 +23,28 @@ LL | #[repr(u8)]
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0566`.
+Future incompatibility report: Future breakage diagnostic:
+error[E0566]: conflicting representation hints
+  --> $DIR/issue-47094.rs:1:8
+   |
+LL | #[repr(C, u8)]
+   |        ^  ^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
+
+Future breakage diagnostic:
+error[E0566]: conflicting representation hints
+  --> $DIR/issue-47094.rs:8:8
+   |
+LL | #[repr(C)]
+   |        ^
+LL |
+LL | #[repr(u8)]
+   |        ^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
+
diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs
index bcacd01474f..8461d92fc33 100644
--- a/tests/ui/lifetimes/issue-95023.rs
+++ b/tests/ui/lifetimes/issue-95023.rs
@@ -2,12 +2,13 @@ struct ErrorKind;
 struct Error(ErrorKind);
 impl Fn(&isize) for Error {
     //~^ ERROR manual implementations of `Fn` are experimental [E0183]
-    //~^^ ERROR associated item constraints are not allowed here [E0229]
+    //~| ERROR associated item constraints are not allowed here [E0229]
     //~| ERROR not all trait items implemented
     //~| ERROR expected a `FnMut(&isize)` closure, found `Error`
     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
     //~^ ERROR associated function in `impl` without body
-    //~^^ ERROR method `foo` is not a member of trait `Fn` [E0407]
-    //~^^^ ERROR associated type `B` not found for `Self` [E0220]
+    //~| ERROR method `foo` is not a member of trait `Fn` [E0407]
+    //~| ERROR associated type `B` not found for `Self` [E0220]
+    //~| ERROR: associated type `B` not found for `Self`
 }
 fn main() {}
diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr
index cbc0eeebee1..310dee51406 100644
--- a/tests/ui/lifetimes/issue-95023.stderr
+++ b/tests/ui/lifetimes/issue-95023.stderr
@@ -56,7 +56,15 @@ error[E0220]: associated type `B` not found for `Self`
 LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
    |                                            ^ help: `Self` has the following associated type: `Output`
 
-error: aborting due to 7 previous errors
+error[E0220]: associated type `B` not found for `Self`
+  --> $DIR/issue-95023.rs:8:44
+   |
+LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
+   |                                            ^ help: `Self` has the following associated type: `Output`
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0046, E0183, E0220, E0229, E0277, E0407.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/lint/dropping_copy_types-macros.fixed b/tests/ui/lint/dropping_copy_types-macros.fixed
new file mode 100644
index 00000000000..a8ceedadc80
--- /dev/null
+++ b/tests/ui/lint/dropping_copy_types-macros.fixed
@@ -0,0 +1,12 @@
+//@ check-fail
+//@ run-rustfix
+
+#![deny(dropping_copy_types)]
+
+use std::fmt::Write;
+
+fn main() {
+    let mut msg = String::new();
+    let _ = writeln!(&mut msg, "test");
+    //~^ ERROR calls to `std::mem::drop`
+}
diff --git a/tests/ui/lint/dropping_copy_types-macros.rs b/tests/ui/lint/dropping_copy_types-macros.rs
new file mode 100644
index 00000000000..b249b0c868f
--- /dev/null
+++ b/tests/ui/lint/dropping_copy_types-macros.rs
@@ -0,0 +1,12 @@
+//@ check-fail
+//@ run-rustfix
+
+#![deny(dropping_copy_types)]
+
+use std::fmt::Write;
+
+fn main() {
+    let mut msg = String::new();
+    drop(writeln!(&mut msg, "test"));
+    //~^ ERROR calls to `std::mem::drop`
+}
diff --git a/tests/ui/lint/dropping_copy_types-macros.stderr b/tests/ui/lint/dropping_copy_types-macros.stderr
new file mode 100644
index 00000000000..117e9f4fe09
--- /dev/null
+++ b/tests/ui/lint/dropping_copy_types-macros.stderr
@@ -0,0 +1,21 @@
+error: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/dropping_copy_types-macros.rs:10:5
+   |
+LL |     drop(writeln!(&mut msg, "test"));
+   |     ^^^^^--------------------------^
+   |          |
+   |          argument has type `Result<(), std::fmt::Error>`
+   |
+note: the lint level is defined here
+  --> $DIR/dropping_copy_types-macros.rs:4:9
+   |
+LL | #![deny(dropping_copy_types)]
+   |         ^^^^^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the expression or result
+   |
+LL -     drop(writeln!(&mut msg, "test"));
+LL +     let _ = writeln!(&mut msg, "test");
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/lint-ctypes-cstr.rs b/tests/ui/lint/lint-ctypes-cstr.rs
new file mode 100644
index 00000000000..b04decd0bca
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-cstr.rs
@@ -0,0 +1,36 @@
+#![crate_type = "lib"]
+#![deny(improper_ctypes, improper_ctypes_definitions)]
+
+use std::ffi::{CStr, CString};
+
+extern "C" {
+    fn take_cstr(s: CStr);
+    //~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
+    //~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+    fn take_cstr_ref(s: &CStr);
+    //~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
+    //~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+    fn take_cstring(s: CString);
+    //~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
+    //~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+    fn take_cstring_ref(s: &CString);
+    //~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
+    //~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+
+    fn no_special_help_for_mut_cstring(s: *mut CString);
+    //~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
+    //~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+
+    fn no_special_help_for_mut_cstring_ref(s: &mut CString);
+    //~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
+    //~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+}
+
+extern "C" fn rust_take_cstr_ref(s: &CStr) {}
+//~^ ERROR `extern` fn uses type `CStr`, which is not FFI-safe
+//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+extern "C" fn rust_take_cstring(s: CString) {}
+//~^ ERROR `extern` fn uses type `CString`, which is not FFI-safe
+//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+extern "C" fn rust_no_special_help_for_mut_cstring(s: *mut CString) {}
+extern "C" fn rust_no_special_help_for_mut_cstring_ref(s: &mut CString) {}
diff --git a/tests/ui/lint/lint-ctypes-cstr.stderr b/tests/ui/lint/lint-ctypes-cstr.stderr
new file mode 100644
index 00000000000..8957758d577
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-cstr.stderr
@@ -0,0 +1,84 @@
+error: `extern` block uses type `CStr`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:7:21
+   |
+LL |     fn take_cstr(s: CStr);
+   |                     ^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+note: the lint level is defined here
+  --> $DIR/lint-ctypes-cstr.rs:2:9
+   |
+LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
+   |         ^^^^^^^^^^^^^^^
+
+error: `extern` block uses type `CStr`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:10:25
+   |
+LL |     fn take_cstr_ref(s: &CStr);
+   |                         ^^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+
+error: `extern` block uses type `CString`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:13:24
+   |
+LL |     fn take_cstring(s: CString);
+   |                        ^^^^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+
+error: `extern` block uses type `CString`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:16:28
+   |
+LL |     fn take_cstring_ref(s: &CString);
+   |                            ^^^^^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+
+error: `extern` block uses type `CString`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:20:43
+   |
+LL |     fn no_special_help_for_mut_cstring(s: *mut CString);
+   |                                           ^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` block uses type `CString`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:24:47
+   |
+LL |     fn no_special_help_for_mut_cstring_ref(s: &mut CString);
+   |                                               ^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `CStr`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:29:37
+   |
+LL | extern "C" fn rust_take_cstr_ref(s: &CStr) {}
+   |                                     ^^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+note: the lint level is defined here
+  --> $DIR/lint-ctypes-cstr.rs:2:26
+   |
+LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `CString`, which is not FFI-safe
+  --> $DIR/lint-ctypes-cstr.rs:32:36
+   |
+LL | extern "C" fn rust_take_cstring(s: CString) {}
+   |                                    ^^^^^^^ not FFI-safe
+   |
+   = help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
+   = note: `CStr`/`CString` do not have a guaranteed layout
+
+error: aborting due to 8 previous errors
+
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/parser/attribute/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr
index 1ba130e20b5..bd860841b80 100644
--- a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr
+++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr
@@ -359,11 +359,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
    |                        previous outer attribute
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the item macro invocation, change the attribute from inner to outer style
-   |
-LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); }
-LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); }
-   |
 
 error: an inner attribute is not permitted following an outer attribute
   --> $DIR/attr-stmt-expr-attr-bad.rs:77:32
@@ -375,11 +370,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
    |                        previous outer attribute
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the item macro invocation, change the attribute from inner to outer style
-   |
-LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; }
-LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; }
-   |
 
 error: an inner attribute is not permitted following an outer attribute
   --> $DIR/attr-stmt-expr-attr-bad.rs:79:32
@@ -391,11 +381,6 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
    |                        previous outer attribute
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the item macro invocation, change the attribute from inner to outer style
-   |
-LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; }
-LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; }
-   |
 
 error[E0586]: inclusive range with no end
   --> $DIR/attr-stmt-expr-attr-bad.rs:85:35
diff --git a/tests/ui/parser/attribute/attr.stderr b/tests/ui/parser/attribute/attr.stderr
index 2e0b16efb6c..a79a5246c2a 100644
--- a/tests/ui/parser/attribute/attr.stderr
+++ b/tests/ui/parser/attribute/attr.stderr
@@ -7,11 +7,6 @@ LL | fn foo() {}
    | ----------- the inner attribute doesn't annotate this function
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the function, change the attribute from inner to outer style
-   |
-LL - #![lang = "foo"]
-LL + #[lang = "foo"]
-   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/inner-attr-after-doc-comment.stderr b/tests/ui/parser/inner-attr-after-doc-comment.stderr
index 6dbc0fd93fd..f087c2e4d65 100644
--- a/tests/ui/parser/inner-attr-after-doc-comment.stderr
+++ b/tests/ui/parser/inner-attr-after-doc-comment.stderr
@@ -13,11 +13,6 @@ LL |   fn main() {}
    |   ------------ the inner attribute doesn't annotate this function
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the function, change the attribute from inner to outer style
-   |
-LL - #![recursion_limit="100"]
-LL + #[recursion_limit="100"]
-   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/inner-attr.stderr b/tests/ui/parser/inner-attr.stderr
index 57ca164fc15..18a82ea4c38 100644
--- a/tests/ui/parser/inner-attr.stderr
+++ b/tests/ui/parser/inner-attr.stderr
@@ -10,11 +10,6 @@ LL | fn main() {}
    | ------------ the inner attribute doesn't annotate this function
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
-help: to annotate the function, change the attribute from inner to outer style
-   |
-LL - #![recursion_limit="100"]
-LL + #[recursion_limit="100"]
-   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.rs b/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.rs
new file mode 100644
index 00000000000..26541a89a56
--- /dev/null
+++ b/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.rs
@@ -0,0 +1,10 @@
+#![allow(dead_code)]
+fn foo() {}
+
+#![feature(iter_array_chunks)] //~ ERROR an inner attribute is not permitted in this context
+fn bar() {}
+
+fn main() {
+    foo();
+    bar();
+}
diff --git a/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.stderr b/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.stderr
new file mode 100644
index 00000000000..d6daa21e741
--- /dev/null
+++ b/tests/ui/parser/issues/isgg-invalid-outer-attttr-issue-127930.stderr
@@ -0,0 +1,12 @@
+error: an inner attribute is not permitted in this context
+  --> $DIR/isgg-invalid-outer-attttr-issue-127930.rs:4:1
+   |
+LL | #![feature(iter_array_chunks)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn bar() {}
+   | ----------- the inner attribute doesn't annotate this function
+   |
+   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/issues/issue-30318.fixed b/tests/ui/parser/issues/issue-30318.fixed
index d1661be5193..d4720834746 100644
--- a/tests/ui/parser/issues/issue-30318.fixed
+++ b/tests/ui/parser/issues/issue-30318.fixed
@@ -6,7 +6,7 @@ fn foo() { }
 //~^ ERROR expected outer doc comment
 fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
 
-#[test] //~ ERROR an inner attribute is not permitted in this context
+#[cfg(test)] //~ ERROR an inner attribute is not permitted in this context
 fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
 //~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
 
diff --git a/tests/ui/parser/issues/issue-30318.rs b/tests/ui/parser/issues/issue-30318.rs
index 6f055cd4f7e..0555379836a 100644
--- a/tests/ui/parser/issues/issue-30318.rs
+++ b/tests/ui/parser/issues/issue-30318.rs
@@ -6,7 +6,7 @@ fn foo() { }
 //~^ ERROR expected outer doc comment
 fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function
 
-#![test] //~ ERROR an inner attribute is not permitted in this context
+#![cfg(test)] //~ ERROR an inner attribute is not permitted in this context
 fn baz() { } //~ NOTE the inner attribute doesn't annotate this function
 //~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually
 
diff --git a/tests/ui/parser/issues/issue-30318.stderr b/tests/ui/parser/issues/issue-30318.stderr
index c441a92abad..56bc200db1d 100644
--- a/tests/ui/parser/issues/issue-30318.stderr
+++ b/tests/ui/parser/issues/issue-30318.stderr
@@ -15,16 +15,16 @@ LL | /// Misplaced comment...
 error: an inner attribute is not permitted in this context
   --> $DIR/issue-30318.rs:9:1
    |
-LL | #![test]
-   | ^^^^^^^^
+LL | #![cfg(test)]
+   | ^^^^^^^^^^^^^
 LL | fn baz() { }
    | ------------ the inner attribute doesn't annotate this function
    |
    = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
 help: to annotate the function, change the attribute from inner to outer style
    |
-LL - #![test]
-LL + #[test]
+LL - #![cfg(test)]
+LL + #[cfg(test)]
    |
 
 error[E0753]: expected outer doc comment
diff --git a/tests/ui/regions/explicit-static-bound-on-trait.rs b/tests/ui/regions/explicit-static-bound-on-trait.rs
new file mode 100644
index 00000000000..835da34d1bb
--- /dev/null
+++ b/tests/ui/regions/explicit-static-bound-on-trait.rs
@@ -0,0 +1,13 @@
+struct Hello<'a> {
+    value: Box<dyn std::any::Any + 'a>,
+    //~^ ERROR lifetime bound not satisfied
+}
+
+impl<'a> Hello<'a> {
+    fn new<T: 'a>(value: T) -> Self {
+        Self { value: Box::new(value) }
+        //~^ ERROR the parameter type `T` may not live long enough
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/regions/explicit-static-bound-on-trait.stderr b/tests/ui/regions/explicit-static-bound-on-trait.stderr
new file mode 100644
index 00000000000..30d39c6e86e
--- /dev/null
+++ b/tests/ui/regions/explicit-static-bound-on-trait.stderr
@@ -0,0 +1,32 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/explicit-static-bound-on-trait.rs:2:12
+   |
+LL |     value: Box<dyn std::any::Any + 'a>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/explicit-static-bound-on-trait.rs:1:14
+   |
+LL | struct Hello<'a> {
+   |              ^^
+note: but lifetime parameter must outlive the static lifetime
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/explicit-static-bound-on-trait.rs:8:23
+   |
+LL |         Self { value: Box::new(value) }
+   |                       ^^^^^^^^^^^^^^^
+   |                       |
+   |                       the parameter type `T` must be valid for the static lifetime...
+   |                       ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     fn new<T: 'a + 'static>(value: T) -> Self {
+   |                  +++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0310, E0478.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/repr/conflicting-repr-hints.stderr b/tests/ui/repr/conflicting-repr-hints.stderr
index 4dcd8f4fc28..fbfa69e7fb1 100644
--- a/tests/ui/repr/conflicting-repr-hints.stderr
+++ b/tests/ui/repr/conflicting-repr-hints.stderr
@@ -81,3 +81,25 @@ error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0566, E0587, E0634.
 For more information about an error, try `rustc --explain E0566`.
+Future incompatibility report: Future breakage diagnostic:
+error[E0566]: conflicting representation hints
+  --> $DIR/conflicting-repr-hints.rs:13:8
+   |
+LL | #[repr(C, u64)]
+   |        ^  ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
+
+Future breakage diagnostic:
+error[E0566]: conflicting representation hints
+  --> $DIR/conflicting-repr-hints.rs:19:8
+   |
+LL | #[repr(u32, u64)]
+   |        ^^^  ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
+
diff --git a/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs
new file mode 100644
index 00000000000..6ab34719f06
--- /dev/null
+++ b/tests/ui/repr/repr-transparent-non-exhaustive-transparent-in-prose.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![feature(sync_unsafe_cell)]
+#![allow(unused)]
+#![deny(repr_transparent_external_private_fields)]
+
+// https://github.com/rust-lang/rust/issues/129470
+
+struct ZST;
+
+#[repr(transparent)]
+struct TransparentWithManuallyDropZST {
+    value: i32,
+    md: std::mem::ManuallyDrop<ZST>,
+    mu: std::mem::MaybeUninit<ZST>,
+    p: std::pin::Pin<ZST>,
+    pd: std::marker::PhantomData<ZST>,
+    pp: std::marker::PhantomPinned,
+    c: std::cell::Cell<ZST>,
+    uc: std::cell::UnsafeCell<ZST>,
+    suc: std::cell::SyncUnsafeCell<ZST>,
+    zst: ZST,
+}
+
+fn main() {}
diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.fixed b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed
index a5a13399825..43a9907a9b4 100644
--- a/tests/ui/return/return-from-residual-sugg-issue-125997.fixed
+++ b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed
@@ -9,7 +9,6 @@ use std::io::prelude::*;
 fn test1() -> Result<(), Box<dyn std::error::Error>> {
     let mut _file = File::create("foo.txt")?;
     //~^ ERROR the `?` operator can only be used in a function
-
     Ok(())
 }
 
@@ -17,7 +16,6 @@ fn test2() -> Result<(), Box<dyn std::error::Error>> {
     let mut _file = File::create("foo.txt")?;
     //~^ ERROR the `?` operator can only be used in a function
     println!();
-
     Ok(())
 }
 
@@ -27,9 +25,8 @@ macro_rules! mac {
             let mut _file = File::create("foo.txt")?;
             //~^ ERROR the `?` operator can only be used in a function
             println!();
-        
-    Ok(())
-}
+            Ok(())
+        }
     };
 }
 
@@ -39,23 +36,20 @@ impl A {
     fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
         let mut _file = File::create("foo.txt")?;
         //~^ ERROR the `?` operator can only be used in a method
-    
-    Ok(())
-}
+        Ok(())
+    }
 
     fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
         let mut _file = File::create("foo.txt")?;
         //~^ ERROR the `?` operator can only be used in a method
         println!();
-    
-    Ok(())
-}
+        Ok(())
+    }
 }
 
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let mut _file = File::create("foo.txt")?;
     //~^ ERROR the `?` operator can only be used in a function
     mac!();
-
     Ok(())
 }
diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr
index a59f38c2ec6..e22f33fd242 100644
--- a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr
+++ b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr
@@ -12,9 +12,7 @@ help: consider adding return type
 LL ~ fn test1() -> Result<(), Box<dyn std::error::Error>> {
 LL |     let mut _file = File::create("foo.txt")?;
 LL |
-LL + 
 LL +     Ok(())
-LL + }
    |
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
@@ -32,9 +30,7 @@ LL ~ fn test2() -> Result<(), Box<dyn std::error::Error>> {
 LL |     let mut _file = File::create("foo.txt")?;
 LL |
 LL |     println!();
-LL + 
 LL +     Ok(())
-LL + }
    |
 
 error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
@@ -51,9 +47,8 @@ help: consider adding return type
 LL ~     fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
 LL |         let mut _file = File::create("foo.txt")?;
 LL |
-LL ~     
-LL +     Ok(())
-LL + }
+LL ~         Ok(())
+LL ~     }
    |
 
 error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
@@ -71,9 +66,8 @@ LL ~     fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
 LL |         let mut _file = File::create("foo.txt")?;
 LL |
 LL |         println!();
-LL ~     
-LL +     Ok(())
-LL + }
+LL ~         Ok(())
+LL ~     }
    |
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
@@ -91,9 +85,7 @@ LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
 LL |     let mut _file = File::create("foo.txt")?;
 LL |
 LL |     mac!();
-LL + 
 LL +     Ok(())
-LL + }
    |
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
@@ -115,9 +107,8 @@ LL ~         fn test3() -> Result<(), Box<dyn std::error::Error>> {
 LL |             let mut _file = File::create("foo.txt")?;
 LL |
 LL |             println!();
-LL ~         
-LL +     Ok(())
-LL + }
+LL ~             Ok(())
+LL ~         }
    |
 
 error: aborting due to 6 previous errors
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/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs
index 637a24f53bc..6c320c0462e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs
@@ -1,4 +1,4 @@
-//@ check-pass
+//~ ERROR the trait bound
 //@ compile-flags: -Znext-solver
 
 #![allow(incomplete_features)]
@@ -17,6 +17,6 @@ impl Foo for S {
 }
 
 impl const Bar for S {}
-//FIXME ~^ ERROR the trait bound
+// FIXME(effects) bad span
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr
new file mode 100644
index 00000000000..9a907bbee0a
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `Maybe: TyCompat<<(Foo::{synthetic#0},) as std::marker::effects::Intersection>::Output>` is not satisfied
+   |
+note: required by a bound in `Bar::{synthetic#0}`
+  --> $DIR/super-traits-fail.rs:11:1
+   |
+LL | #[const_trait]
+   | ^^^^^^^^^^^^^^ required by this bound in `Bar::{synthetic#0}`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
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);
+    }
 }
diff --git a/tests/ui/sized/unsized-binding.stderr b/tests/ui/sized/unsized-binding.stderr
index 7c3276032c2..8de236cd0b6 100644
--- a/tests/ui/sized/unsized-binding.stderr
+++ b/tests/ui/sized/unsized-binding.stderr
@@ -7,6 +7,11 @@ LL |     let x = *"";
    = help: the trait `Sized` is not implemented for `str`
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let x = *"";
+LL +     let x = "";
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.rs b/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.rs
new file mode 100644
index 00000000000..35abbb80d99
--- /dev/null
+++ b/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.rs
@@ -0,0 +1,30 @@
+fn foo() -> impl Sized {
+//~^ ERROR the size for values of type `str` cannot be known at compilation time
+//~| HELP the trait `Sized` is not implemented for `str`
+    *"" //~ HELP consider not dereferencing the expression
+}
+fn bar(_: impl Sized) {}
+struct S;
+
+impl S {
+    fn baz(&self, _: impl Sized) {}
+}
+
+fn main() {
+    let _ = foo();
+    let x = *"";
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| HELP consider not dereferencing the expression
+    //~| HELP the trait `Sized` is not implemented for `str`
+    //~| HELP unsized locals are gated as an unstable feature
+    bar(x);
+    S.baz(x);
+    bar(*"");
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| HELP consider not dereferencing the expression
+    //~| HELP the trait `Sized` is not implemented for `str`
+    S.baz(*"");
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| HELP consider not dereferencing the expression
+    //~| HELP the trait `Sized` is not implemented for `str`
+}
diff --git a/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.stderr b/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.stderr
new file mode 100644
index 00000000000..9b7258aff12
--- /dev/null
+++ b/tests/ui/sized/unsized-str-in-return-expr-arg-and-local.stderr
@@ -0,0 +1,74 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:1:13
+   |
+LL | fn foo() -> impl Sized {
+   |             ^^^^^^^^^^ doesn't have a size known at compile-time
+...
+LL |     *""
+   |     --- return type was inferred to be `str` here
+   |
+   = help: the trait `Sized` is not implemented for `str`
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     *""
+LL +     ""
+   |
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:15:9
+   |
+LL |     let x = *"";
+   |         ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let x = *"";
+LL +     let x = "";
+   |
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:22:9
+   |
+LL |     bar(*"");
+   |     --- ^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Sized` is not implemented for `str`
+note: required by a bound in `bar`
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:6:16
+   |
+LL | fn bar(_: impl Sized) {}
+   |                ^^^^^ required by this bound in `bar`
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     bar(*"");
+LL +     bar("");
+   |
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:26:11
+   |
+LL |     S.baz(*"");
+   |       --- ^^^ doesn't have a size known at compile-time
+   |       |
+   |       required by a bound introduced by this call
+   |
+   = help: the trait `Sized` is not implemented for `str`
+note: required by a bound in `S::baz`
+  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:10:27
+   |
+LL |     fn baz(&self, _: impl Sized) {}
+   |                           ^^^^^ required by this bound in `S::baz`
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     S.baz(*"");
+LL +     S.baz("");
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs
index fb962ad24bf..858fba2132a 100644
--- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs
+++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.rs
@@ -14,5 +14,6 @@ struct Wrapper<const C: <i32 as Trait>::Type> {}
 
 impl<const C: usize> Wrapper<C> {}
 //~^ ERROR the constant `C` is not of type `<i32 as Trait>::Type`
+//~| ERROR: mismatched types
 
 fn main() {}
diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr
index 7094ee8c67c..71d4277275f 100644
--- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr
+++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr
@@ -20,5 +20,17 @@ note: required by a const generic parameter in `Wrapper`
 LL | struct Wrapper<const C: <i32 as Trait>::Type> {}
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30
+   |
+LL | impl<const C: usize> Wrapper<C> {}
+   |                              ^ expected associated type, found `usize`
+   |
+   = note: expected associated type `<i32 as Trait>::Type`
+                         found type `usize`
+   = help: consider constraining the associated type `<i32 as Trait>::Type` to `usize`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
index a0ee7714417..f89a463bc58 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
@@ -6,6 +6,7 @@
 struct S<const L: usize>;
 
 impl<const N: i32> Copy for S<N> {}
+//~^ ERROR: mismatched types
 impl<const M: usize> Copy for S<M> {}
 //~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
 
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
index 2953bc95917..1dac58e1f69 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
@@ -1,11 +1,19 @@
 error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
-  --> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
    |
 LL | impl<const N: i32> Copy for S<N> {}
    | -------------------------------- first implementation here
+LL |
 LL | impl<const M: usize> Copy for S<M> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
+   |
+LL | impl<const N: i32> Copy for S<N> {}
+   |                               ^ expected `usize`, found `i32`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0308.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr
index 4fd063e4692..c1ef1cd428e 100644
--- a/tests/ui/suggestions/issue-84973-blacklist.stderr
+++ b/tests/ui/suggestions/issue-84973-blacklist.stderr
@@ -66,6 +66,11 @@ note: required by a bound in `f_sized`
    |
 LL | fn f_sized<T: Sized>(t: T) {}
    |               ^^^^^ required by this bound in `f_sized`
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     f_sized(*ref_cl);
+LL +     f_sized(ref_cl);
+   |
 
 error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
   --> $DIR/issue-84973-blacklist.rs:27:12
diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs
index 94d79d56c59..5c4fb847932 100644
--- a/tests/ui/target-feature/gate.rs
+++ b/tests/ui/target-feature/gate.rs
@@ -17,6 +17,7 @@
 // gate-test-ermsb_target_feature
 // gate-test-bpf_target_feature
 // gate-test-aarch64_ver_target_feature
+// gate-test-aarch64_unstable_target_feature
 // gate-test-csky_target_feature
 // gate-test-loongarch_target_feature
 // gate-test-lahfsahf_target_feature
diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr
index a69020e6864..37c5ed01688 100644
--- a/tests/ui/target-feature/gate.stderr
+++ b/tests/ui/target-feature/gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the target feature `avx512bw` is currently unstable
-  --> $DIR/gate.rs:26:18
+  --> $DIR/gate.rs:27:18
    |
 LL | #[target_feature(enable = "avx512bw")]
    |                  ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/target-feature/struct-target-features.rs b/tests/ui/target-feature/struct-target-features.rs
new file mode 100644
index 00000000000..feb479b6dc8
--- /dev/null
+++ b/tests/ui/target-feature/struct-target-features.rs
@@ -0,0 +1,98 @@
+//@ only-x86_64
+#![feature(struct_target_features)]
+//~^ WARNING the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
+#![feature(target_feature_11)]
+
+use std::arch::x86_64::*;
+
+#[target_feature(enable = "avx")]
+//~^ ERROR attribute should be applied to a function definition or unit struct
+struct Invalid(u32);
+
+#[target_feature(enable = "avx")]
+struct Avx {}
+
+#[target_feature(enable = "sse")]
+struct Sse();
+
+#[target_feature(enable = "avx")]
+fn avx() {}
+
+trait TFAssociatedType {
+    type Assoc;
+}
+
+impl TFAssociatedType for () {
+    type Assoc = Avx;
+}
+
+fn avx_self(_: <() as TFAssociatedType>::Assoc) {
+    avx();
+}
+
+fn avx_avx(_: Avx) {
+    avx();
+}
+
+extern "C" fn bad_fun(_: Avx) {}
+//~^ ERROR cannot use a struct with target features in a function with non-Rust ABI
+
+#[inline(always)]
+//~^ ERROR cannot use `#[inline(always)]` with `#[target_feature]`
+fn inline_fun(_: Avx) {}
+//~^ ERROR cannot use a struct with target features in a #[inline(always)] function
+
+trait Simd {
+    fn do_something(&self);
+}
+
+impl Simd for Avx {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm256_setzero_ps());
+        }
+    }
+}
+
+impl Simd for Sse {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm_setzero_ps());
+        }
+    }
+}
+
+struct WithAvx {
+    #[allow(dead_code)]
+    avx: Avx,
+}
+
+impl Simd for WithAvx {
+    fn do_something(&self) {
+        unsafe {
+            println!("{:?}", _mm256_setzero_ps());
+        }
+    }
+}
+
+#[inline(never)]
+fn dosomething<S: Simd>(simd: &S) {
+    simd.do_something();
+}
+
+fn avxfn(_: &Avx) {}
+
+fn main() {
+    Avx {};
+    //~^ ERROR initializing type with `target_feature` attr is unsafe and requires unsafe function or block [E0133]
+
+    if is_x86_feature_detected!("avx") {
+        let avx = unsafe { Avx {} };
+        avxfn(&avx);
+        dosomething(&avx);
+        dosomething(&WithAvx { avx });
+    }
+    if is_x86_feature_detected!("sse") {
+        dosomething(&unsafe { Sse {} })
+    }
+}
diff --git a/tests/ui/target-feature/struct-target-features.stderr b/tests/ui/target-feature/struct-target-features.stderr
new file mode 100644
index 00000000000..5ef863f504e
--- /dev/null
+++ b/tests/ui/target-feature/struct-target-features.stderr
@@ -0,0 +1,47 @@
+warning: the feature `struct_target_features` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/struct-target-features.rs:2:12
+   |
+LL | #![feature(struct_target_features)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #129107 <https://github.com/rust-lang/rust/issues/129107> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: attribute should be applied to a function definition or unit struct
+  --> $DIR/struct-target-features.rs:8:1
+   |
+LL | #[target_feature(enable = "avx")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct Invalid(u32);
+   | -------------------- not a function definition or a unit struct
+
+error: cannot use a struct with target features in a function with non-Rust ABI
+  --> $DIR/struct-target-features.rs:37:1
+   |
+LL | extern "C" fn bad_fun(_: Avx) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a struct with target features in a #[inline(always)] function
+  --> $DIR/struct-target-features.rs:42:1
+   |
+LL | fn inline_fun(_: Avx) {}
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use `#[inline(always)]` with `#[target_feature]`
+  --> $DIR/struct-target-features.rs:40:1
+   |
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^
+
+error[E0133]: initializing type with `target_feature` attr is unsafe and requires unsafe function or block
+  --> $DIR/struct-target-features.rs:86:5
+   |
+LL |     Avx {};
+   |     ^^^^^^ initializing type with `target_feature` attr
+   |
+   = note: this struct can only be constructed if the corresponding `target_feature`s are available
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/traits/object/pretty.rs b/tests/ui/traits/object/pretty.rs
index 8958871ed5d..6660ff040f7 100644
--- a/tests/ui/traits/object/pretty.rs
+++ b/tests/ui/traits/object/pretty.rs
@@ -18,6 +18,10 @@ trait FixedHrtb: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> {}
 trait AnyDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super {}
 trait FixedDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super<Assoc = u8> {}
 
+trait HasGat<Outer> {
+    type Assoc<Inner> where Self: Sized;
+}
+
 fn dyn_super(x: &dyn Super<Assoc = u8>) { x } //~ERROR mismatched types
 fn dyn_any(x: &dyn Any<Assoc = u8>) { x } //~ERROR mismatched types
 fn dyn_fixed(x: &dyn Fixed) { x } //~ERROR mismatched types
@@ -34,4 +38,7 @@ fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x } //~ERROR mismatched types
 fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x } //~ERROR mismatched types
 fn dyn_fixed_different_binders(x: &dyn FixedDifferentBinders) { x } //~ERROR mismatched types
 
+fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x } //~ERROR mismatched types
+//~^ WARN unnecessary associated type bound
+
 fn main() {}
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index bc645e5f967..6964d97c08e 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -1,5 +1,14 @@
+warning: unnecessary associated type bound for not object safe associated type
+  --> $DIR/pretty.rs:41:35
+   |
+LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
+   |                                   ^^^^^^^^^^^^^^^^ help: remove this bound
+   |
+   = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+   = note: `#[warn(unused_associated_type_bounds)]` on by default
+
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:21:43
+  --> $DIR/pretty.rs:25:43
    |
 LL | fn dyn_super(x: &dyn Super<Assoc = u8>) { x }
    |                                        -  ^ expected `()`, found `&dyn Super<Assoc = u8>`
@@ -10,7 +19,7 @@ LL | fn dyn_super(x: &dyn Super<Assoc = u8>) { x }
               found reference `&dyn Super<Assoc = u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:22:39
+  --> $DIR/pretty.rs:26:39
    |
 LL | fn dyn_any(x: &dyn Any<Assoc = u8>) { x }
    |                                    -  ^ expected `()`, found `&dyn Any<Assoc = u8>`
@@ -21,7 +30,7 @@ LL | fn dyn_any(x: &dyn Any<Assoc = u8>) { x }
               found reference `&dyn Any<Assoc = u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:23:31
+  --> $DIR/pretty.rs:27:31
    |
 LL | fn dyn_fixed(x: &dyn Fixed) { x }
    |                            -  ^ expected `()`, found `&dyn Fixed`
@@ -32,7 +41,7 @@ LL | fn dyn_fixed(x: &dyn Fixed) { x }
               found reference `&dyn Fixed`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:24:50
+  --> $DIR/pretty.rs:28:50
    |
 LL | fn dyn_fixed_multi(x: &dyn Fixed<Assoc = u16>) { x }
    |                                               -  ^ expected `()`, found `&dyn Fixed<Assoc = u16>`
@@ -43,7 +52,7 @@ LL | fn dyn_fixed_multi(x: &dyn Fixed<Assoc = u16>) { x }
               found reference `&dyn Fixed<Assoc = u16>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:25:38
+  --> $DIR/pretty.rs:29:38
    |
 LL | fn dyn_fixed_sub(x: &dyn FixedSub) { x }
    |                                   -  ^ expected `()`, found `&dyn FixedSub`
@@ -54,7 +63,7 @@ LL | fn dyn_fixed_sub(x: &dyn FixedSub) { x }
               found reference `&dyn FixedSub`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:26:44
+  --> $DIR/pretty.rs:30:44
    |
 LL | fn dyn_fixed_static(x: &dyn FixedStatic) { x }
    |                                         -  ^ expected `()`, found `&dyn FixedStatic`
@@ -65,7 +74,7 @@ LL | fn dyn_fixed_static(x: &dyn FixedStatic) { x }
               found reference `&dyn FixedStatic`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:28:75
+  --> $DIR/pretty.rs:32:75
    |
 LL | fn dyn_super_generic(x: &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>) { x }
    |                                                                        -  ^ expected `()`, found `&dyn SuperGeneric<'a, Assoc2 = &u8>`
@@ -76,7 +85,7 @@ LL | fn dyn_super_generic(x: &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>) { x
               found reference `&dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:29:71
+  --> $DIR/pretty.rs:33:71
    |
 LL | fn dyn_any_generic(x: &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>) { x }
    |                                                                    -  ^ expected `()`, found `&dyn AnyGeneric<'a, Assoc2 = &u8>`
@@ -87,7 +96,7 @@ LL | fn dyn_any_generic(x: &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>) { x }
               found reference `&dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:30:60
+  --> $DIR/pretty.rs:34:60
    |
 LL | fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x }
    |                                                         -  ^ expected `()`, found `&dyn FixedGeneric1<'a>`
@@ -98,7 +107,7 @@ LL | fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x }
               found reference `&dyn for<'a> FixedGeneric1<'a>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:31:60
+  --> $DIR/pretty.rs:35:60
    |
 LL | fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x }
    |                                                         -  ^ expected `()`, found `&dyn FixedGeneric2<'a>`
@@ -109,7 +118,7 @@ LL | fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x }
               found reference `&dyn for<'a> FixedGeneric2<'a>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:32:79
+  --> $DIR/pretty.rs:36:79
    |
 LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x }
    |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = ...>`
@@ -120,7 +129,7 @@ LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>)
               found reference `&dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:33:40
+  --> $DIR/pretty.rs:37:40
    |
 LL | fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x }
    |                                     -  ^ expected `()`, found `&dyn FixedHrtb`
@@ -131,7 +140,7 @@ LL | fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x }
               found reference `&dyn FixedHrtb`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:34:73
+  --> $DIR/pretty.rs:38:73
    |
 LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x }
    |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = ...>`
@@ -142,7 +151,7 @@ LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x }
               found reference `&dyn AnyDifferentBinders<Assoc = u8>`
 
 error[E0308]: mismatched types
-  --> $DIR/pretty.rs:35:65
+  --> $DIR/pretty.rs:39:65
    |
 LL | fn dyn_fixed_different_binders(x: &dyn FixedDifferentBinders) { x }
    |                                                              -  ^ expected `()`, found `&dyn FixedDifferentBinders`
@@ -152,6 +161,17 @@ LL | fn dyn_fixed_different_binders(x: &dyn FixedDifferentBinders) { x }
    = note: expected unit type `()`
               found reference `&dyn FixedDifferentBinders`
 
-error: aborting due to 14 previous errors
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:41:56
+   |
+LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
+   |                                                     -  ^ expected `()`, found `&dyn HasGat<u8, Assoc<bool> = ()>`
+   |                                                     |
+   |                                                     help: try adding a return type: `-> &dyn HasGat<u8, Assoc<bool> = ()>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
+
+error: aborting due to 15 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/transmutability/abstraction/abstracted_assume.rs b/tests/ui/transmutability/abstraction/abstracted_assume.rs
index 897e1b4b50a..7fd91e31a04 100644
--- a/tests/ui/transmutability/abstraction/abstracted_assume.rs
+++ b/tests/ui/transmutability/abstraction/abstracted_assume.rs
@@ -8,7 +8,7 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<
         Src,
@@ -16,7 +16,7 @@ mod assert {
         const ASSUME: std::mem::Assume,
     >()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             ASSUME,
         >,
diff --git a/tests/ui/transmutability/abstraction/const_generic_fn.rs b/tests/ui/transmutability/abstraction/const_generic_fn.rs
index 0a5f0de0214..1ea978ce1ba 100644
--- a/tests/ui/transmutability/abstraction/const_generic_fn.rs
+++ b/tests/ui/transmutability/abstraction/const_generic_fn.rs
@@ -6,12 +6,12 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn array_like<T, E, const N: usize>()
     where
-        T: BikeshedIntrinsicFrom<[E; N], { Assume::SAFETY }>,
-        [E; N]: BikeshedIntrinsicFrom<T, { Assume::SAFETY }>
+        T: TransmuteFrom<[E; N], { Assume::SAFETY }>,
+        [E; N]: TransmuteFrom<T, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/alignment/align-fail.rs b/tests/ui/transmutability/alignment/align-fail.rs
index d88f1285c11..4c1a69b0128 100644
--- a/tests/ui/transmutability/alignment/align-fail.rs
+++ b/tests/ui/transmutability/alignment/align-fail.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr
index f05e55fb024..b9801e511b2 100644
--- a/tests/ui/transmutability/alignment/align-fail.stderr
+++ b/tests/ui/transmutability/alignment/align-fail.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: false,
diff --git a/tests/ui/transmutability/alignment/align-pass.rs b/tests/ui/transmutability/alignment/align-pass.rs
index aecf7b02d62..feecf5edaa1 100644
--- a/tests/ui/transmutability/alignment/align-pass.rs
+++ b/tests/ui/transmutability/alignment/align-pass.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/arrays/huge-len.rs b/tests/ui/transmutability/arrays/huge-len.rs
index 3fe254ebef4..dec24a559d3 100644
--- a/tests/ui/transmutability/arrays/huge-len.rs
+++ b/tests/ui/transmutability/arrays/huge-len.rs
@@ -1,11 +1,11 @@
 #![crate_type = "lib"]
 #![feature(transmutability)]
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>,
+        Dst: TransmuteFrom<Src>,
     {
     }
 }
diff --git a/tests/ui/transmutability/arrays/huge-len.stderr b/tests/ui/transmutability/arrays/huge-len.stderr
index 3fc652f47c1..1fa16c649d4 100644
--- a/tests/ui/transmutability/arrays/huge-len.stderr
+++ b/tests/ui/transmutability/arrays/huge-len.stderr
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded`
   --> $DIR/huge-len.rs:21:41
    |
 LL |     assert::is_maybe_transmutable::<(), ExplicitlyPadded>();
-   |                                         ^^^^^^^^^^^^^^^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
+   |                                         ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14
@@ -10,14 +10,14 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src>,
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
   --> $DIR/huge-len.rs:24:55
    |
 LL |     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
-   |                                                       ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
+   |                                                       ^^ values of the type `ExplicitlyPadded` are too big for the current architecture
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14
@@ -25,8 +25,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src>,
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/transmutability/arrays/issue-103783-array-length.rs b/tests/ui/transmutability/arrays/issue-103783-array-length.rs
index 7fcbcc01075..3537a39259c 100644
--- a/tests/ui/transmutability/arrays/issue-103783-array-length.rs
+++ b/tests/ui/transmutability/arrays/issue-103783-array-length.rs
@@ -3,11 +3,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
         >,
diff --git a/tests/ui/transmutability/arrays/should_have_correct_length.rs b/tests/ui/transmutability/arrays/should_have_correct_length.rs
index 747897d49d7..00c0c1122ef 100644
--- a/tests/ui/transmutability/arrays/should_have_correct_length.rs
+++ b/tests/ui/transmutability/arrays/should_have_correct_length.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
     {}
 }
 
diff --git a/tests/ui/transmutability/arrays/should_inherit_alignment.rs b/tests/ui/transmutability/arrays/should_inherit_alignment.rs
index d95c51e3361..70d2f07c449 100644
--- a/tests/ui/transmutability/arrays/should_inherit_alignment.rs
+++ b/tests/ui/transmutability/arrays/should_inherit_alignment.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs b/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs
index 5345b199f6e..29e8ad136ee 100644
--- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs
+++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
index b4cd70142c4..e9420cd393e 100644
--- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
@@ -31,7 +31,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
@@ -52,7 +52,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
@@ -73,7 +73,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
@@ -94,7 +94,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
@@ -115,7 +115,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/enums/niche_optimization.rs b/tests/ui/transmutability/enums/niche_optimization.rs
index 23f57ecad75..802d1747568 100644
--- a/tests/ui/transmutability/enums/niche_optimization.rs
+++ b/tests/ui/transmutability/enums/niche_optimization.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: false,
@@ -21,7 +21,7 @@ mod assert {
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/enums/repr/padding_differences.rs b/tests/ui/transmutability/enums/repr/padding_differences.rs
index d0e1502b5e2..9d2380c613e 100644
--- a/tests/ui/transmutability/enums/repr/padding_differences.rs
+++ b/tests/ui/transmutability/enums/repr/padding_differences.rs
@@ -7,11 +7,11 @@
 use std::mem::MaybeUninit;
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: false,
@@ -23,7 +23,7 @@ mod assert {
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
index d3d463e7929..a8f4cccc73e 100644
--- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
+++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
index 6c88bf4ff96..c975ff276c8 100644
--- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
+++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -32,7 +32,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -54,7 +54,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -76,7 +76,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -98,7 +98,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -120,7 +120,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -142,7 +142,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -164,7 +164,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -186,7 +186,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -208,7 +208,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -230,7 +230,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -252,7 +252,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -274,7 +274,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -296,7 +296,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -318,7 +318,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -340,7 +340,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -362,7 +362,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -384,7 +384,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -406,7 +406,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -428,7 +428,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
diff --git a/tests/ui/transmutability/enums/repr/should_handle_all.rs b/tests/ui/transmutability/enums/repr/should_handle_all.rs
index a8ec86fa40d..dec0126f22d 100644
--- a/tests/ui/transmutability/enums/repr/should_handle_all.rs
+++ b/tests/ui/transmutability/enums/repr/should_handle_all.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/enums/should_order_correctly.rs b/tests/ui/transmutability/enums/should_order_correctly.rs
index d51a033f1a6..cea2055e148 100644
--- a/tests/ui/transmutability/enums/should_order_correctly.rs
+++ b/tests/ui/transmutability/enums/should_order_correctly.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/enums/should_pad_variants.rs b/tests/ui/transmutability/enums/should_pad_variants.rs
index 81ef9e8a567..82bafe85415 100644
--- a/tests/ui/transmutability/enums/should_pad_variants.rs
+++ b/tests/ui/transmutability/enums/should_pad_variants.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr
index da4294bdbce..bb26281c2f0 100644
--- a/tests/ui/transmutability/enums/should_pad_variants.stderr
+++ b/tests/ui/transmutability/enums/should_pad_variants.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/enums/should_respect_endianness.rs b/tests/ui/transmutability/enums/should_respect_endianness.rs
index 8e52274710a..9cf4de06ad2 100644
--- a/tests/ui/transmutability/enums/should_respect_endianness.rs
+++ b/tests/ui/transmutability/enums/should_respect_endianness.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr
index 9f88bb06813..1b9099b297b 100644
--- a/tests/ui/transmutability/enums/should_respect_endianness.stderr
+++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/enums/uninhabited_optimization.rs b/tests/ui/transmutability/enums/uninhabited_optimization.rs
index c2d5b67ab2c..5b9de3a3963 100644
--- a/tests/ui/transmutability/enums/uninhabited_optimization.rs
+++ b/tests/ui/transmutability/enums/uninhabited_optimization.rs
@@ -4,7 +4,7 @@
 
 fn assert_transmutable<T>()
 where
-    (): std::mem::BikeshedIntrinsicFrom<T>
+    (): std::mem::TransmuteFrom<T>
 {}
 
 enum Uninhabited {}
diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs
index 20bd7917e53..fcc1db073ee 100644
--- a/tests/ui/transmutability/issue-101739-1.rs
+++ b/tests/ui/transmutability/issue-101739-1.rs
@@ -1,12 +1,13 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, const ASSUME_ALIGNMENT: bool>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
-        //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume`
+        Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
+                                                           //~| the constant `ASSUME_ALIGNMENT` is not of type `Assume`
+                                                           //~| ERROR: mismatched types
     {
     }
 }
diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr
index ba18a980f4d..3687631dc51 100644
--- a/tests/ui/transmutability/issue-101739-1.stderr
+++ b/tests/ui/transmutability/issue-101739-1.stderr
@@ -1,18 +1,25 @@
 error[E0412]: cannot find type `Dst` in this scope
   --> $DIR/issue-101739-1.rs:8:9
    |
-LL |         Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>,
+LL |         Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>,
    |         ^^^ not found in this scope
 
 error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
   --> $DIR/issue-101739-1.rs:8:14
    |
-LL |         Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
+LL |         Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>,
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
    |
-note: required by a const generic parameter in `BikeshedIntrinsicFrom`
+note: required by a const generic parameter in `TransmuteFrom`
   --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-1.rs:8:33
+   |
+LL |         Dst: TransmuteFrom<Src, ASSUME_ALIGNMENT>,
+   |                                 ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs
index 8b36bf3dcb1..02aa4669e05 100644
--- a/tests/ui/transmutability/issue-101739-2.rs
+++ b/tests/ui/transmutability/issue-101739-2.rs
@@ -3,7 +3,7 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<
         Src,
@@ -14,19 +14,23 @@ mod assert {
         const ASSUME_VISIBILITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
-            Src,
-            ASSUME_ALIGNMENT,
-            ASSUME_LIFETIMES,
-            ASSUME_VALIDITY,
-            ASSUME_VISIBILITY,
-        >,
-    {}
+        Dst: TransmuteFrom<
+                //~^ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
+                Src,
+                ASSUME_ALIGNMENT, //~ ERROR: mismatched types
+                ASSUME_LIFETIMES,
+                ASSUME_VALIDITY,
+                ASSUME_VISIBILITY,
+            >,
+    {
+    }
 }
 
 fn via_const() {
-    #[repr(C)] struct Src;
-    #[repr(C)] struct Dst;
+    #[repr(C)]
+    struct Src;
+    #[repr(C)]
+    struct Dst;
 
     const FALSE: bool = false;
 
diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr
index 6b0a36a414b..526fcabe14e 100644
--- a/tests/ui/transmutability/issue-101739-2.stderr
+++ b/tests/ui/transmutability/issue-101739-2.stderr
@@ -1,16 +1,23 @@
 error[E0107]: trait takes at most 2 generic arguments but 5 generic arguments were supplied
   --> $DIR/issue-101739-2.rs:17:14
    |
-LL |           Dst: BikeshedIntrinsicFrom<
-   |                ^^^^^^^^^^^^^^^^^^^^^ expected at most 2 generic arguments
-LL |               Src,
-LL |               ASSUME_ALIGNMENT,
-   |  _____________________________-
-LL | |             ASSUME_LIFETIMES,
-LL | |             ASSUME_VALIDITY,
-LL | |             ASSUME_VISIBILITY,
-   | |_____________________________- help: remove the unnecessary generic arguments
+LL |           Dst: TransmuteFrom<
+   |                ^^^^^^^^^^^^^ expected at most 2 generic arguments
+...
+LL |                   ASSUME_ALIGNMENT,
+   |  _________________________________-
+LL | |                 ASSUME_LIFETIMES,
+LL | |                 ASSUME_VALIDITY,
+LL | |                 ASSUME_VISIBILITY,
+   | |_________________________________- help: remove the unnecessary generic arguments
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-2.rs:20:17
+   |
+LL |                 ASSUME_ALIGNMENT,
+   |                 ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/transmutability/issue-110467.rs b/tests/ui/transmutability/issue-110467.rs
index 1f9e521c24b..4acea5f766d 100644
--- a/tests/ui/transmutability/issue-110467.rs
+++ b/tests/ui/transmutability/issue-110467.rs
@@ -1,11 +1,11 @@
 //@ check-pass
 #![crate_type = "lib"]
 #![feature(transmutability)]
-use std::mem::BikeshedIntrinsicFrom;
+use std::mem::TransmuteFrom;
 
 pub fn is_maybe_transmutable<Src, Dst>()
 where
-    Dst: BikeshedIntrinsicFrom<Src>,
+    Dst: TransmuteFrom<Src>,
 {
 }
 
diff --git a/tests/ui/transmutability/issue-110892.rs b/tests/ui/transmutability/issue-110892.rs
index 9713684c959..ad1b9e7af10 100644
--- a/tests/ui/transmutability/issue-110892.rs
+++ b/tests/ui/transmutability/issue-110892.rs
@@ -3,7 +3,7 @@
 #![allow(incomplete_features)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<
         Src,
@@ -14,7 +14,7 @@ mod assert {
         const ASSUME_VALIDITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
         >,
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs
index 30c381745d0..07133aa5614 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-use std::mem::BikeshedIntrinsicFrom;
+use std::mem::TransmuteFrom;
 //~^ ERROR use of unstable library feature 'transmutability' [E0658]
 
 use std::mem::Assume;
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr
index 9f221907172..a2096cd53e5 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr
+++ b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature 'transmutability'
   --> $DIR/feature-missing.rs:5:5
    |
-LL | use std::mem::BikeshedIntrinsicFrom;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | use std::mem::TransmuteFrom;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
    = help: add `#![feature(transmutability)]` to the crate attributes to enable
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
index bcfbc1430a8..b8828c59d35 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>
+        Dst: TransmuteFrom<Src>
     {}
 }
 
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.rs
new file mode 100644
index 00000000000..2285d2f532e
--- /dev/null
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.rs
@@ -0,0 +1,26 @@
+// An unknown destination type should be gracefully handled.
+
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(incomplete_features)]
+
+mod assert {
+    use std::mem::TransmuteFrom;
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: TransmuteFrom<Src>
+    {}
+}
+
+fn should_gracefully_handle_unknown_dst_field() {
+    #[repr(C)] struct Src;
+    #[repr(C)] struct Dst(Missing); //~ cannot find type
+    assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
+}
+
+fn should_gracefully_handle_unknown_dst_ref_field() {
+    #[repr(C)] struct Src(&'static Src);
+    #[repr(C)] struct Dst(&'static Missing); //~ cannot find type
+    assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.stderr
new file mode 100644
index 00000000000..564aee687a5
--- /dev/null
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst_field.stderr
@@ -0,0 +1,46 @@
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/unknown_dst_field.rs:18:27
+   |
+LL |     #[repr(C)] struct Dst(Missing);
+   |                           ^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/unknown_dst_field.rs:24:36
+   |
+LL |     #[repr(C)] struct Dst(&'static Missing);
+   |                                    ^^^^^^^ not found in this scope
+
+error[E0277]: `should_gracefully_handle_unknown_dst_field::Src` cannot be safely transmuted into `should_gracefully_handle_unknown_dst_field::Dst`
+  --> $DIR/unknown_dst_field.rs:19:36
+   |
+LL |     assert::is_transmutable::<Src, Dst>();
+   |                                    ^^^ `should_gracefully_handle_unknown_dst_field::Dst` has an unknown layout
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/unknown_dst_field.rs:12:14
+   |
+LL |     pub fn is_transmutable<Src, Dst>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error[E0277]: `should_gracefully_handle_unknown_dst_ref_field::Src` cannot be safely transmuted into `should_gracefully_handle_unknown_dst_ref_field::Dst`
+  --> $DIR/unknown_dst_field.rs:25:36
+   |
+LL |     assert::is_transmutable::<Src, Dst>();
+   |                                    ^^^ `should_gracefully_handle_unknown_dst_ref_field::Dst` has an unknown layout
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/unknown_dst_field.rs:12:14
+   |
+LL |     pub fn is_transmutable<Src, Dst>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
index bd7c3fc7fb5..10ba7a61b87 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>
+        Dst: TransmuteFrom<Src>
     {}
 }
 
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
index 58c16d773e1..598e04971e2 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
@@ -5,16 +5,22 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>
+        Dst: TransmuteFrom<Src>
     {}
 }
 
-fn should_gracefully_handle_unknown_dst_field() {
-    #[repr(C)] struct Src;
-    #[repr(C)] struct Dst(Missing); //~ cannot find type
+fn should_gracefully_handle_unknown_src_field() {
+    #[repr(C)] struct Src(Missing); //~ cannot find type
+    #[repr(C)] struct Dst();
+    assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
+}
+
+fn should_gracefully_handle_unknown_src_ref_field() {
+    #[repr(C)] struct Src(&'static Missing); //~ cannot find type
+    #[repr(C)] struct Dst(&'static Dst);
     assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
 }
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
index cabc7bcfef7..1156391c301 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
@@ -1,14 +1,35 @@
 error[E0412]: cannot find type `Missing` in this scope
-  --> $DIR/unknown_src_field.rs:18:27
+  --> $DIR/unknown_src_field.rs:17:27
    |
-LL |     #[repr(C)] struct Dst(Missing);
+LL |     #[repr(C)] struct Src(Missing);
    |                           ^^^^^^^ not found in this scope
 
-error[E0277]: `Src` cannot be safely transmuted into `Dst`
+error[E0412]: cannot find type `Missing` in this scope
+  --> $DIR/unknown_src_field.rs:23:36
+   |
+LL |     #[repr(C)] struct Src(&'static Missing);
+   |                                    ^^^^^^^ not found in this scope
+
+error[E0277]: `should_gracefully_handle_unknown_src_field::Src` cannot be safely transmuted into `should_gracefully_handle_unknown_src_field::Dst`
   --> $DIR/unknown_src_field.rs:19:36
    |
 LL |     assert::is_transmutable::<Src, Dst>();
-   |                                    ^^^ analyzing the transmutability of `Dst` is not yet supported
+   |                                    ^^^ `should_gracefully_handle_unknown_src_field::Src` has an unknown layout
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/unknown_src_field.rs:12:14
+   |
+LL |     pub fn is_transmutable<Src, Dst>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error[E0277]: `should_gracefully_handle_unknown_src_ref_field::Src` cannot be safely transmuted into `should_gracefully_handle_unknown_src_ref_field::Dst`
+  --> $DIR/unknown_src_field.rs:25:36
+   |
+LL |     assert::is_transmutable::<Src, Dst>();
+   |                                    ^^^ `should_gracefully_handle_unknown_src_ref_field::Src` has an unknown layout
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/unknown_src_field.rs:12:14
@@ -16,10 +37,10 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0412.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
index 608366fa089..df925975bad 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs
@@ -8,7 +8,7 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<
         Src,
@@ -19,7 +19,7 @@ mod assert {
         const ASSUME_VALIDITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
         >,
diff --git a/tests/ui/transmutability/maybeuninit.rs b/tests/ui/transmutability/maybeuninit.rs
index 77c3381c774..7b60785b7e0 100644
--- a/tests/ui/transmutability/maybeuninit.rs
+++ b/tests/ui/transmutability/maybeuninit.rs
@@ -5,11 +5,11 @@
 use std::mem::MaybeUninit;
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/maybeuninit.stderr b/tests/ui/transmutability/maybeuninit.stderr
index be7dcaf35ea..897c2df10a8 100644
--- a/tests/ui/transmutability/maybeuninit.stderr
+++ b/tests/ui/transmutability/maybeuninit.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/primitives/bool-mut.rs b/tests/ui/transmutability/primitives/bool-mut.rs
index 09b6d582d87..0a7dad37aaf 100644
--- a/tests/ui/transmutability/primitives/bool-mut.rs
+++ b/tests/ui/transmutability/primitives/bool-mut.rs
@@ -2,11 +2,11 @@
 
 #![feature(transmutability)]
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/primitives/bool-mut.stderr b/tests/ui/transmutability/primitives/bool-mut.stderr
index a6cf146659e..fcf60bc979c 100644
--- a/tests/ui/transmutability/primitives/bool-mut.stderr
+++ b/tests/ui/transmutability/primitives/bool-mut.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/primitives/bool.current.stderr b/tests/ui/transmutability/primitives/bool.current.stderr
index da6a4a44e95..2945cdaad40 100644
--- a/tests/ui/transmutability/primitives/bool.current.stderr
+++ b/tests/ui/transmutability/primitives/bool.current.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/primitives/bool.next.stderr b/tests/ui/transmutability/primitives/bool.next.stderr
index da6a4a44e95..2945cdaad40 100644
--- a/tests/ui/transmutability/primitives/bool.next.stderr
+++ b/tests/ui/transmutability/primitives/bool.next.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs
index 19236a1ae2e..6fac8ba1ad1 100644
--- a/tests/ui/transmutability/primitives/bool.rs
+++ b/tests/ui/transmutability/primitives/bool.rs
@@ -4,16 +4,16 @@
 
 #![feature(transmutability)]
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
     {}
 }
 
diff --git a/tests/ui/transmutability/primitives/numbers.current.stderr b/tests/ui/transmutability/primitives/numbers.current.stderr
index 0a9b9d182f8..efb2ce8c772 100644
--- a/tests/ui/transmutability/primitives/numbers.current.stderr
+++ b/tests/ui/transmutability/primitives/numbers.current.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u16`
   --> $DIR/numbers.rs:65:40
@@ -25,8 +25,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:66:40
@@ -40,8 +40,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:67:40
@@ -55,8 +55,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:68:40
@@ -70,8 +70,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:69:40
@@ -85,8 +85,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:70:40
@@ -100,8 +100,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:71:40
@@ -115,8 +115,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:72:39
@@ -130,8 +130,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:73:39
@@ -145,8 +145,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i16`
   --> $DIR/numbers.rs:75:40
@@ -160,8 +160,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u16`
   --> $DIR/numbers.rs:76:40
@@ -175,8 +175,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:77:40
@@ -190,8 +190,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:78:40
@@ -205,8 +205,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:79:40
@@ -220,8 +220,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:80:40
@@ -235,8 +235,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:81:40
@@ -250,8 +250,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:82:40
@@ -265,8 +265,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:83:39
@@ -280,8 +280,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:84:39
@@ -295,8 +295,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:86:40
@@ -310,8 +310,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:87:40
@@ -325,8 +325,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:88:40
@@ -340,8 +340,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:89:40
@@ -355,8 +355,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:90:40
@@ -370,8 +370,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:91:40
@@ -385,8 +385,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:92:39
@@ -400,8 +400,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:93:39
@@ -415,8 +415,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:95:40
@@ -430,8 +430,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:96:40
@@ -445,8 +445,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:97:40
@@ -460,8 +460,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:98:40
@@ -475,8 +475,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:99:40
@@ -490,8 +490,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:100:40
@@ -505,8 +505,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:101:39
@@ -520,8 +520,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:102:39
@@ -535,8 +535,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:104:40
@@ -550,8 +550,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:105:40
@@ -565,8 +565,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:106:40
@@ -580,8 +580,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:107:39
@@ -595,8 +595,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:108:39
@@ -610,8 +610,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:110:40
@@ -625,8 +625,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:111:40
@@ -640,8 +640,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:112:40
@@ -655,8 +655,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:113:39
@@ -670,8 +670,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:114:39
@@ -685,8 +685,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:116:40
@@ -700,8 +700,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:117:40
@@ -715,8 +715,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:118:40
@@ -730,8 +730,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:119:39
@@ -745,8 +745,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:120:39
@@ -760,8 +760,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:122:39
@@ -775,8 +775,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:123:39
@@ -790,8 +790,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:125:39
@@ -805,8 +805,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:126:39
@@ -820,8 +820,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:128:39
@@ -835,8 +835,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:129:39
@@ -850,8 +850,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 57 previous errors
 
diff --git a/tests/ui/transmutability/primitives/numbers.next.stderr b/tests/ui/transmutability/primitives/numbers.next.stderr
index 0a9b9d182f8..efb2ce8c772 100644
--- a/tests/ui/transmutability/primitives/numbers.next.stderr
+++ b/tests/ui/transmutability/primitives/numbers.next.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u16`
   --> $DIR/numbers.rs:65:40
@@ -25,8 +25,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:66:40
@@ -40,8 +40,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:67:40
@@ -55,8 +55,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:68:40
@@ -70,8 +70,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:69:40
@@ -85,8 +85,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:70:40
@@ -100,8 +100,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:71:40
@@ -115,8 +115,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:72:39
@@ -130,8 +130,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i8` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:73:39
@@ -145,8 +145,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i16`
   --> $DIR/numbers.rs:75:40
@@ -160,8 +160,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u16`
   --> $DIR/numbers.rs:76:40
@@ -175,8 +175,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:77:40
@@ -190,8 +190,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:78:40
@@ -205,8 +205,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:79:40
@@ -220,8 +220,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:80:40
@@ -235,8 +235,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:81:40
@@ -250,8 +250,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:82:40
@@ -265,8 +265,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:83:39
@@ -280,8 +280,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u8` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:84:39
@@ -295,8 +295,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:86:40
@@ -310,8 +310,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:87:40
@@ -325,8 +325,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:88:40
@@ -340,8 +340,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:89:40
@@ -355,8 +355,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:90:40
@@ -370,8 +370,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:91:40
@@ -385,8 +385,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:92:39
@@ -400,8 +400,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i16` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:93:39
@@ -415,8 +415,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i32`
   --> $DIR/numbers.rs:95:40
@@ -430,8 +430,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `f32`
   --> $DIR/numbers.rs:96:40
@@ -445,8 +445,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u32`
   --> $DIR/numbers.rs:97:40
@@ -460,8 +460,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:98:40
@@ -475,8 +475,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:99:40
@@ -490,8 +490,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:100:40
@@ -505,8 +505,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:101:39
@@ -520,8 +520,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u16` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:102:39
@@ -535,8 +535,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:104:40
@@ -550,8 +550,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:105:40
@@ -565,8 +565,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:106:40
@@ -580,8 +580,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:107:39
@@ -595,8 +595,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:108:39
@@ -610,8 +610,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:110:40
@@ -625,8 +625,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:111:40
@@ -640,8 +640,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:112:40
@@ -655,8 +655,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:113:39
@@ -670,8 +670,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:114:39
@@ -685,8 +685,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `u64`
   --> $DIR/numbers.rs:116:40
@@ -700,8 +700,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `i64`
   --> $DIR/numbers.rs:117:40
@@ -715,8 +715,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `f64`
   --> $DIR/numbers.rs:118:40
@@ -730,8 +730,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:119:39
@@ -745,8 +745,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u32` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:120:39
@@ -760,8 +760,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:122:39
@@ -775,8 +775,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `u64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:123:39
@@ -790,8 +790,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:125:39
@@ -805,8 +805,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `i64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:126:39
@@ -820,8 +820,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f64` cannot be safely transmuted into `u128`
   --> $DIR/numbers.rs:128:39
@@ -835,8 +835,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `f64` cannot be safely transmuted into `i128`
   --> $DIR/numbers.rs:129:39
@@ -850,8 +850,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src>
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 57 previous errors
 
diff --git a/tests/ui/transmutability/primitives/numbers.rs b/tests/ui/transmutability/primitives/numbers.rs
index 401502474cf..b5c21c992b6 100644
--- a/tests/ui/transmutability/primitives/numbers.rs
+++ b/tests/ui/transmutability/primitives/numbers.rs
@@ -7,11 +7,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>
+        Dst: TransmuteFrom<Src>
     {}
 }
 
diff --git a/tests/ui/transmutability/primitives/unit.current.stderr b/tests/ui/transmutability/primitives/unit.current.stderr
index 52b708d680e..4bfb229832b 100644
--- a/tests/ui/transmutability/primitives/unit.current.stderr
+++ b/tests/ui/transmutability/primitives/unit.current.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/primitives/unit.next.stderr b/tests/ui/transmutability/primitives/unit.next.stderr
index 52b708d680e..4bfb229832b 100644
--- a/tests/ui/transmutability/primitives/unit.next.stderr
+++ b/tests/ui/transmutability/primitives/unit.next.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/primitives/unit.rs b/tests/ui/transmutability/primitives/unit.rs
index 44216950f55..93b21e0b586 100644
--- a/tests/ui/transmutability/primitives/unit.rs
+++ b/tests/ui/transmutability/primitives/unit.rs
@@ -9,11 +9,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs
index 3bdd7256791..edad02fc96d 100644
--- a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs
+++ b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs
@@ -4,11 +4,11 @@
 
 #![feature(transmutability, core_intrinsics)]
 
-use std::mem::{Assume, BikeshedIntrinsicFrom};
+use std::mem::{Assume, TransmuteFrom};
 
 unsafe fn transmute<Src, Dst>(src: Src) -> Dst
 where
-    Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::LIFETIMES) }>,
+    Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::LIFETIMES) }>,
 {
     core::intrinsics::transmute_unchecked(src)
 }
@@ -82,7 +82,7 @@ mod hrtb {
 
     unsafe fn extend_hrtb<'a>(src: &'a u8) -> &'static u8
     where
-        for<'b> &'b u8: BikeshedIntrinsicFrom<&'a u8, { Assume::LIFETIMES }>,
+        for<'b> &'b u8: TransmuteFrom<&'a u8, { Assume::LIFETIMES }>,
     {
         core::intrinsics::transmute_unchecked(src)
     }
diff --git a/tests/ui/transmutability/references/accept_unexercised_lifetime_extension.rs b/tests/ui/transmutability/references/accept_unexercised_lifetime_extension.rs
index 559ee23a446..5734575e90b 100644
--- a/tests/ui/transmutability/references/accept_unexercised_lifetime_extension.rs
+++ b/tests/ui/transmutability/references/accept_unexercised_lifetime_extension.rs
@@ -4,11 +4,11 @@
 
 #![feature(transmutability, core_intrinsics)]
 
-use std::mem::{Assume, BikeshedIntrinsicFrom};
+use std::mem::{Assume, TransmuteFrom};
 
 unsafe fn transmute<Src, Dst>(src: Src) -> Dst
 where
-    Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>,
+    Dst: TransmuteFrom<Src, { Assume::SAFETY }>,
 {
     core::intrinsics::transmute_unchecked(src)
 }
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs
index ba2db755e3b..92068ee0d4f 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
index 4b2866dc4f0..1698021d554 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs
index cd70c278285..8e2da3518a9 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs
index 2f264e8339e..01b176cc3c1 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
index 2b7cab1660d..dbd3e39b365 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs
index 28f4d6661cb..53dedeb6388 100644
--- a/tests/ui/transmutability/references/recursive-wrapper-types.rs
+++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/references/reject_extension.rs b/tests/ui/transmutability/references/reject_extension.rs
index 161da5772e8..dd02e5c01c4 100644
--- a/tests/ui/transmutability/references/reject_extension.rs
+++ b/tests/ui/transmutability/references/reject_extension.rs
@@ -6,11 +6,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             {
                 Assume {
diff --git a/tests/ui/transmutability/references/reject_extension.stderr b/tests/ui/transmutability/references/reject_extension.stderr
index 88dd0313e3c..182106acf12 100644
--- a/tests/ui/transmutability/references/reject_extension.stderr
+++ b/tests/ui/transmutability/references/reject_extension.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<
+LL |           Dst: TransmuteFrom<
    |  ______________^
 LL | |             Src,
 LL | |             {
diff --git a/tests/ui/transmutability/references/reject_lifetime_extension.rs b/tests/ui/transmutability/references/reject_lifetime_extension.rs
index 79bb4e1e556..ff9290c34af 100644
--- a/tests/ui/transmutability/references/reject_lifetime_extension.rs
+++ b/tests/ui/transmutability/references/reject_lifetime_extension.rs
@@ -4,11 +4,11 @@
 
 #![feature(transmutability, core_intrinsics)]
 
-use std::mem::{Assume, BikeshedIntrinsicFrom};
+use std::mem::{Assume, TransmuteFrom};
 
 unsafe fn transmute<Src, Dst>(src: Src) -> Dst
 where
-    Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>,
+    Dst: TransmuteFrom<Src, { Assume::SAFETY }>,
 {
     core::intrinsics::transmute_unchecked(src)
 }
@@ -82,7 +82,7 @@ mod hrtb {
 
     unsafe fn extend_hrtb<'a>(src: &'a u8) -> &'static u8
     where
-        for<'b> &'b u8: BikeshedIntrinsicFrom<&'a u8>,
+        for<'b> &'b u8: TransmuteFrom<&'a u8>,
     {
         core::intrinsics::transmute_unchecked(src)
     }
diff --git a/tests/ui/transmutability/references/reject_lifetime_extension.stderr b/tests/ui/transmutability/references/reject_lifetime_extension.stderr
index df1b81f26d2..a597041c6ca 100644
--- a/tests/ui/transmutability/references/reject_lifetime_extension.stderr
+++ b/tests/ui/transmutability/references/reject_lifetime_extension.stderr
@@ -70,8 +70,8 @@ LL |         unsafe { extend_hrtb(src) }
 note: due to current limitations in the borrow checker, this implies a `'static` lifetime
   --> $DIR/reject_lifetime_extension.rs:85:25
    |
-LL |         for<'b> &'b u8: BikeshedIntrinsicFrom<&'a u8>,
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         for<'b> &'b u8: TransmuteFrom<&'a u8>,
+   |                         ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/transmutability/references/u8-to-unit.rs b/tests/ui/transmutability/references/u8-to-unit.rs
index 017b73d9595..98deb6457cb 100644
--- a/tests/ui/transmutability/references/u8-to-unit.rs
+++ b/tests/ui/transmutability/references/u8-to-unit.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: false,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/references/unit-to-itself.rs b/tests/ui/transmutability/references/unit-to-itself.rs
index 40aec8418fe..789455c03ea 100644
--- a/tests/ui/transmutability/references/unit-to-itself.rs
+++ b/tests/ui/transmutability/references/unit-to-itself.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: false,
diff --git a/tests/ui/transmutability/references/unit-to-u8.rs b/tests/ui/transmutability/references/unit-to-u8.rs
index 973d3206c12..575a40e3622 100644
--- a/tests/ui/transmutability/references/unit-to-u8.rs
+++ b/tests/ui/transmutability/references/unit-to-u8.rs
@@ -2,11 +2,11 @@
 #![feature(transmutability)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/references/unit-to-u8.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr
index 5d73dfdc8eb..b5a79b1917f 100644
--- a/tests/ui/transmutability/references/unit-to-u8.stderr
+++ b/tests/ui/transmutability/references/unit-to-u8.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
diff --git a/tests/ui/transmutability/references/unsafecell.rs b/tests/ui/transmutability/references/unsafecell.rs
index a8a1f969fb4..4001f139770 100644
--- a/tests/ui/transmutability/references/unsafecell.rs
+++ b/tests/ui/transmutability/references/unsafecell.rs
@@ -5,11 +5,11 @@
 use std::cell::UnsafeCell;
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/references/unsafecell.stderr b/tests/ui/transmutability/references/unsafecell.stderr
index 8bb32359355..6664d8a7d6f 100644
--- a/tests/ui/transmutability/references/unsafecell.stderr
+++ b/tests/ui/transmutability/references/unsafecell.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error[E0277]: `&UnsafeCell<u8>` cannot be safely transmuted into `&UnsafeCell<u8>`
   --> $DIR/unsafecell.rs:29:62
@@ -25,8 +25,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/transmutability/region-infer.rs b/tests/ui/transmutability/region-infer.rs
index 0632bc53176..c164f35c447 100644
--- a/tests/ui/transmutability/region-infer.rs
+++ b/tests/ui/transmutability/region-infer.rs
@@ -1,13 +1,13 @@
 #![feature(transmutability)]
 
-use std::mem::{Assume, BikeshedIntrinsicFrom};
+use std::mem::{Assume, TransmuteFrom};
 
 #[repr(C)]
 struct W<'a>(&'a ());
 
 fn test<'a>()
 where
-    W<'a>: BikeshedIntrinsicFrom<
+    W<'a>: TransmuteFrom<
             (),
             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
         >,
diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr
index 03c46823838..09ecf484bc8 100644
--- a/tests/ui/transmutability/region-infer.stderr
+++ b/tests/ui/transmutability/region-infer.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `test`
 LL |   fn test<'a>()
    |      ---- required by a bound in this function
 LL |   where
-LL |       W<'a>: BikeshedIntrinsicFrom<
+LL |       W<'a>: TransmuteFrom<
    |  ____________^
 LL | |             (),
 LL | |             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_dst_has_safety_invariant.rs b/tests/ui/transmutability/safety/assume/should_accept_if_dst_has_safety_invariant.rs
index cb3c1cdf46c..0113049f51e 100644
--- a/tests/ui/transmutability/safety/assume/should_accept_if_dst_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/assume/should_accept_if_dst_has_safety_invariant.rs
@@ -8,11 +8,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs
index b12c4a10d12..eca7a06559d 100644
--- a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs
@@ -8,11 +8,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/assume/should_accept_if_src_has_safety_invariant.rs
index ff01462ffec..46e84b48044 100644
--- a/tests/ui/transmutability/safety/assume/should_accept_if_src_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/assume/should_accept_if_src_has_safety_invariant.rs
@@ -8,11 +8,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/should_accept_if_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/should_accept_if_src_has_safety_invariant.rs
index d516e9a7da5..aaba6febde4 100644
--- a/tests/ui/transmutability/safety/should_accept_if_src_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/should_accept_if_src_has_safety_invariant.rs
@@ -8,11 +8,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
+        Dst: TransmuteFrom<Src> // safety is NOT assumed
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.rs b/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.rs
index 4f0aee31548..6f8e383db1f 100644
--- a/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
+        Dst: TransmuteFrom<Src> // safety is NOT assumed
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.stderr b/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.stderr
index 2339c268326..6445b1e146e 100644
--- a/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.stderr
+++ b/tests/ui/transmutability/safety/should_reject_if_dst_has_safety_invariant.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src> // safety is NOT assumed
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.rs
index 126059dd7b7..16d163d5420 100644
--- a/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.rs
+++ b/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::BikeshedIntrinsicFrom;
+    use std::mem::TransmuteFrom;
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
+        Dst: TransmuteFrom<Src> // safety is NOT assumed
     {}
 }
 
diff --git a/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.stderr b/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.stderr
index 99feebe9211..38ef829f064 100644
--- a/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.stderr
+++ b/tests/ui/transmutability/safety/should_reject_if_ref_src_has_safety_invariant.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src> // safety is NOT assumed
+   |              ^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/structs/repr/should_handle_align.rs b/tests/ui/transmutability/structs/repr/should_handle_align.rs
index 0c207766045..03065298b50 100644
--- a/tests/ui/transmutability/structs/repr/should_handle_align.rs
+++ b/tests/ui/transmutability/structs/repr/should_handle_align.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/structs/repr/should_handle_all.rs b/tests/ui/transmutability/structs/repr/should_handle_all.rs
index 52c24eecf12..e5ca37e68ec 100644
--- a/tests/ui/transmutability/structs/repr/should_handle_all.rs
+++ b/tests/ui/transmutability/structs/repr/should_handle_all.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/structs/repr/should_handle_packed.rs b/tests/ui/transmutability/structs/repr/should_handle_packed.rs
index 4af32d6e84e..c9be32d7b2a 100644
--- a/tests/ui/transmutability/structs/repr/should_handle_packed.rs
+++ b/tests/ui/transmutability/structs/repr/should_handle_packed.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
index 64110753832..8d291054365 100644
--- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
+++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
@@ -7,11 +7,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src>,
+        Dst: TransmuteFrom<Src>,
     {
     }
 }
@@ -22,5 +22,4 @@ fn should_pad_explicitly_packed_field() {
     //~^ ERROR: recursive type
 
     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
-    //~^ ERROR: cannot be safely transmuted
 }
diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
index ebfb5361143..bdf2d3b6a58 100644
--- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
+++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
@@ -12,25 +12,10 @@ LL |     struct ExplicitlyPadded(Box<ExplicitlyPadded>);
 error[E0391]: cycle detected when computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded`
    |
    = note: ...which immediately requires computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` again
-   = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>`
+   = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::TransmuteFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
-  --> $DIR/transmute_infinitely_recursive_type.rs:24:55
-   |
-LL |     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
-   |                                                       ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/transmute_infinitely_recursive_type.rs:14:14
-   |
-LL |     pub fn is_maybe_transmutable<Src, Dst>()
-   |            --------------------- required by a bound in this function
-LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0072, E0277, E0391.
+Some errors have detailed explanations: E0072, E0391.
 For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/transmutability/structs/should_order_fields_correctly.rs b/tests/ui/transmutability/structs/should_order_fields_correctly.rs
index 3675e4330ec..aa9ca39eff2 100644
--- a/tests/ui/transmutability/structs/should_order_fields_correctly.rs
+++ b/tests/ui/transmutability/structs/should_order_fields_correctly.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/transmute-padding-ice.rs b/tests/ui/transmutability/transmute-padding-ice.rs
index f5935a0009e..133241c89cb 100644
--- a/tests/ui/transmutability/transmute-padding-ice.rs
+++ b/tests/ui/transmutability/transmute-padding-ice.rs
@@ -9,11 +9,11 @@
 use std::mem::size_of;
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<
+        Dst: TransmuteFrom<
             Src,
             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
         >,
diff --git a/tests/ui/transmutability/uninhabited.rs b/tests/ui/transmutability/uninhabited.rs
index 7524922c16a..74f7a1a2e89 100644
--- a/tests/ui/transmutability/uninhabited.rs
+++ b/tests/ui/transmutability/uninhabited.rs
@@ -3,11 +3,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr
index 88a98c798fc..3fa02f0867c 100644
--- a/tests/ui/transmutability/uninhabited.stderr
+++ b/tests/ui/transmutability/uninhabited.stderr
@@ -34,7 +34,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -56,7 +56,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -78,7 +78,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
@@ -100,7 +100,7 @@ note: required by a bound in `is_maybe_transmutable`
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
diff --git a/tests/ui/transmutability/unions/boolish.rs b/tests/ui/transmutability/unions/boolish.rs
index c829f83149e..838643defd5 100644
--- a/tests/ui/transmutability/unions/boolish.rs
+++ b/tests/ui/transmutability/unions/boolish.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/unions/repr/should_handle_align.rs b/tests/ui/transmutability/unions/repr/should_handle_align.rs
index ba4e904e161..0605651bd7b 100644
--- a/tests/ui/transmutability/unions/repr/should_handle_align.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_align.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/unions/repr/should_handle_all.rs b/tests/ui/transmutability/unions/repr/should_handle_all.rs
index 85d48dd9b7f..8505c7f9123 100644
--- a/tests/ui/transmutability/unions/repr/should_handle_all.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_all.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/unions/repr/should_handle_packed.rs b/tests/ui/transmutability/unions/repr/should_handle_packed.rs
index fc06eba4353..5e9851ab0c9 100644
--- a/tests/ui/transmutability/unions/repr/should_handle_packed.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_packed.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume {
                 alignment: true,
                 lifetimes: true,
diff --git a/tests/ui/transmutability/unions/should_pad_variants.rs b/tests/ui/transmutability/unions/should_pad_variants.rs
index 1e4d2db8f74..986c7fafb85 100644
--- a/tests/ui/transmutability/unions/should_pad_variants.rs
+++ b/tests/ui/transmutability/unions/should_pad_variants.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, {
+        Dst: TransmuteFrom<Src, {
             Assume::ALIGNMENT
                 .and(Assume::LIFETIMES)
                 .and(Assume::SAFETY)
diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr
index da4294bdbce..bb26281c2f0 100644
--- a/tests/ui/transmutability/unions/should_pad_variants.stderr
+++ b/tests/ui/transmutability/unions/should_pad_variants.stderr
@@ -10,7 +10,7 @@ note: required by a bound in `is_transmutable`
 LL |       pub fn is_transmutable<Src, Dst>()
    |              --------------- required by a bound in this function
 LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
+LL |           Dst: TransmuteFrom<Src, {
    |  ______________^
 LL | |             Assume::ALIGNMENT
 LL | |                 .and(Assume::LIFETIMES)
diff --git a/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs b/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
index 7efe9ac70f1..359ba515439 100644
--- a/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
+++ b/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs
@@ -7,11 +7,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
     {}
 }
 
diff --git a/tests/ui/transmutability/unions/should_reject_contraction.rs b/tests/ui/transmutability/unions/should_reject_contraction.rs
index 62a0ee92919..87398328fc7 100644
--- a/tests/ui/transmutability/unions/should_reject_contraction.rs
+++ b/tests/ui/transmutability/unions/should_reject_contraction.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
     {}
 }
 
diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr
index 20eaa3a6b09..ea68de14efc 100644
--- a/tests/ui/transmutability/unions/should_reject_contraction.stderr
+++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.rs b/tests/ui/transmutability/unions/should_reject_disjoint.rs
index 732f92e8160..0427e3c44a2 100644
--- a/tests/ui/transmutability/unions/should_reject_disjoint.rs
+++ b/tests/ui/transmutability/unions/should_reject_disjoint.rs
@@ -5,11 +5,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_maybe_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
     {}
 }
 
diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr
index ea47797c970..d55abbe0817 100644
--- a/tests/ui/transmutability/unions/should_reject_disjoint.stderr
+++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error[E0277]: `B` cannot be safely transmuted into `A`
   --> $DIR/should_reject_disjoint.rs:33:40
@@ -25,8 +25,8 @@ note: required by a bound in `is_maybe_transmutable`
 LL |     pub fn is_maybe_transmutable<Src, Dst>()
    |            --------------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.rs b/tests/ui/transmutability/unions/should_reject_intersecting.rs
index 752a606c861..9b3b18919f5 100644
--- a/tests/ui/transmutability/unions/should_reject_intersecting.rs
+++ b/tests/ui/transmutability/unions/should_reject_intersecting.rs
@@ -6,11 +6,11 @@
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
-    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    use std::mem::{Assume, TransmuteFrom};
 
     pub fn is_transmutable<Src, Dst>()
     where
-        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+        Dst: TransmuteFrom<Src, { Assume::SAFETY }>
         // validity is NOT assumed -----^^^^^^^^^^^^^^^^^^
     {}
 }
diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr
index 79dec659d9d..522681d7d15 100644
--- a/tests/ui/transmutability/unions/should_reject_intersecting.stderr
+++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr
@@ -10,8 +10,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error[E0277]: `B` cannot be safely transmuted into `A`
   --> $DIR/should_reject_intersecting.rs:36:34
@@ -25,8 +25,8 @@ note: required by a bound in `is_transmutable`
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
 LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+LL |         Dst: TransmuteFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr
index d22117165c1..311e8076ed4 100644
--- a/tests/ui/try-trait/try-operator-on-main.stderr
+++ b/tests/ui/try-trait/try-operator-on-main.stderr
@@ -14,9 +14,7 @@ LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
 LL |     // error for a `Try` type on a non-`Try` fn
 ...
 LL |     try_trait_generic::<()>();
-LL + 
 LL +     Ok(())
-LL + }
    |
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
index ba52eaa0359..113f6a4cc44 100644
--- a/tests/ui/type-alias-impl-trait/variance.rs
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -5,21 +5,21 @@
 trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
-type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
+type NotCapturedEarly<'a> = impl Sized; //~ ['a: *, 'a: o]
 //~^ ERROR: unconstrained opaque type
 
-type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
+type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ ['a: *, 'a: o]
 //~^ ERROR: unconstrained opaque type
 
-type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
+type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ ['a: *, 'b: o, 'a: o]
 //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
 //~| ERROR: unconstrained opaque type
 
-type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
+type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ ['a: *, 'b: o, 'a: o]
 //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
 //~| ERROR: unconstrained opaque type
 
-type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
+type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR ['a: *, 'b: *, T: o, 'a: o, 'b: o]
 //~^ ERROR: unconstrained opaque type
 
 trait Foo<'i> {
@@ -31,24 +31,24 @@ trait Foo<'i> {
 }
 
 impl<'i> Foo<'i> for &'i () {
-    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 }
 
 impl<'i> Foo<'i> for () {
-    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
     //~^ ERROR: unconstrained opaque type
 }
 
@@ -59,15 +59,15 @@ impl<'a> Nesting<'a> for &'a () {
     type Output = &'a ();
 }
 type NestedDeeply<'a> =
-    impl Nesting< //~ [*, o]
+    impl Nesting< //~ ['a: *, 'a: o]
         'a,
-        Output = impl Nesting< //~ [*, o]
+        Output = impl Nesting< //~ ['a: *, 'a: o]
             'a,
-            Output = impl Nesting< //~ [*, o]
+            Output = impl Nesting< //~ ['a: *, 'a: o]
                 'a,
-                Output = impl Nesting< //~ [*, o]
+                Output = impl Nesting< //~ ['a: *, 'a: o]
                     'a,
-                    Output = impl Nesting<'a> //~ [*, o]
+                    Output = impl Nesting<'a> //~ ['a: *, 'a: o]
                 >
             >,
         >,
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
index e5ced7a4981..489dfe03d44 100644
--- a/tests/ui/type-alias-impl-trait/variance.stderr
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -110,73 +110,73 @@ LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |
    = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:8:29
    |
 LL | type NotCapturedEarly<'a> = impl Sized;
    |                             ^^^^^^^^^^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:11:26
    |
 LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, o, o]
+error: ['a: *, 'b: o, 'a: o]
   --> $DIR/variance.rs:14:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
 
-error: [*, o, o]
+error: ['a: *, 'b: o, 'a: o]
   --> $DIR/variance.rs:18:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, *, o, o, o]
+error: ['a: *, 'b: *, T: o, 'a: o, 'b: o]
   --> $DIR/variance.rs:22:27
    |
 LL | type Bar<'a, 'b: 'b, T> = impl Sized;
    |                           ^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:34:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:37:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:40:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:45:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:48:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, *, o, o]
+error: ['i: *, 'a: *, 'a: o, 'i: o]
   --> $DIR/variance.rs:51:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:62:5
    |
 LL | /     impl Nesting<
@@ -188,7 +188,7 @@ LL | |         >,
 LL | |     >;
    | |_____^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:64:18
    |
 LL |           Output = impl Nesting<
@@ -201,7 +201,7 @@ LL | |             >,
 LL | |         >,
    | |_________^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:66:22
    |
 LL |               Output = impl Nesting<
@@ -214,7 +214,7 @@ LL | |                 >
 LL | |             >,
    | |_____________^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:68:26
    |
 LL |                   Output = impl Nesting<
@@ -224,7 +224,7 @@ LL | |                     Output = impl Nesting<'a>
 LL | |                 >
    | |_________________^
 
-error: [*, o]
+error: ['a: *, 'a: o]
   --> $DIR/variance.rs:70:30
    |
 LL |                     Output = impl Nesting<'a>
diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs
index 9fc249198d0..92c1999e154 100644
--- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs
+++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs
@@ -3,16 +3,18 @@
 // of an impl fn produces a type mismatch error instead of triggering
 // a const eval cycle
 
-
 trait Trait {
-    fn func<const N: u32>() -> [ (); N ]; //~ ERROR the constant `N` is not of type `usize`
+    fn func<const N: u32>() -> [(); N];
+    //~^ ERROR: the constant `N` is not of type `usize`
+    //~| ERROR: mismatched types
 }
 
 struct S {}
 
 #[allow(unused_braces)]
 impl Trait for S {
-    fn func<const N: u32>() -> [ (); { () }] { //~ ERROR mismatched types
+    fn func<const N: u32>() -> [(); { () }] {
+        //~^ ERROR mismatched types
         N
     }
 }
diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr
index bff926a2081..bb8025d47a1 100644
--- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr
+++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr
@@ -1,15 +1,21 @@
 error[E0308]: mismatched types
-  --> $DIR/const-in-impl-fn-return-type.rs:15:40
+  --> $DIR/const-in-impl-fn-return-type.rs:16:39
    |
-LL |     fn func<const N: u32>() -> [ (); { () }] {
-   |                                        ^^ expected `usize`, found `()`
+LL |     fn func<const N: u32>() -> [(); { () }] {
+   |                                       ^^ expected `usize`, found `()`
 
 error: the constant `N` is not of type `usize`
-  --> $DIR/const-in-impl-fn-return-type.rs:8:32
+  --> $DIR/const-in-impl-fn-return-type.rs:7:32
    |
-LL |     fn func<const N: u32>() -> [ (); N ];
-   |                                ^^^^^^^^^ expected `usize`, found `u32`
+LL |     fn func<const N: u32>() -> [(); N];
+   |                                ^^^^^^^ expected `usize`, found `u32`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/const-in-impl-fn-return-type.rs:7:37
+   |
+LL |     fn func<const N: u32>() -> [(); N];
+   |                                     ^ expected `usize`, found `u32`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unsized/unsized6.stderr b/tests/ui/unsized/unsized6.stderr
index 56e7f60f9ff..d406120efc5 100644
--- a/tests/ui/unsized/unsized6.stderr
+++ b/tests/ui/unsized/unsized6.stderr
@@ -123,6 +123,11 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized`
 LL - fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
 LL + fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
    |
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let y = *x2;
+LL +     let y = x2;
+   |
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:26:10
@@ -177,6 +182,11 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized`
 LL - fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
 LL + fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
    |
+help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
+   |
+LL -     let y = *x2;
+LL +     let y = x2;
+   |
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:34:10
diff --git a/tests/ui/variance/variance-associated-consts.rs b/tests/ui/variance/variance-associated-consts.rs
index 6a44a94df3f..97edb7e266a 100644
--- a/tests/ui/variance/variance-associated-consts.rs
+++ b/tests/ui/variance/variance-associated-consts.rs
@@ -10,7 +10,7 @@ trait Trait {
 }
 
 #[rustc_variance]
-struct Foo<T: Trait> { //~ ERROR [o]
+struct Foo<T: Trait> { //~ ERROR [T: o]
     field: [u8; <T as Trait>::Const]
     //~^ ERROR: unconstrained generic constant
 }
diff --git a/tests/ui/variance/variance-associated-consts.stderr b/tests/ui/variance/variance-associated-consts.stderr
index b955a7686c2..5c3ed93464a 100644
--- a/tests/ui/variance/variance-associated-consts.stderr
+++ b/tests/ui/variance/variance-associated-consts.stderr
@@ -9,7 +9,7 @@ help: try adding a `where` bound
 LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: {
    |                      ++++++++++++++++++++++++++++++++
 
-error: [o]
+error: [T: o]
   --> $DIR/variance-associated-consts.rs:13:1
    |
 LL | struct Foo<T: Trait> {
diff --git a/tests/ui/variance/variance-associated-types.rs b/tests/ui/variance/variance-associated-types.rs
index ecb0821827d..07ff41062e8 100644
--- a/tests/ui/variance/variance-associated-types.rs
+++ b/tests/ui/variance/variance-associated-types.rs
@@ -10,12 +10,12 @@ trait Trait<'a> {
 }
 
 #[rustc_variance]
-struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +]
+struct Foo<'a, T : Trait<'a>> { //~ ERROR ['a: +, T: +]
     field: (T, &'a ())
 }
 
 #[rustc_variance]
-struct Bar<'a, T : Trait<'a>> { //~ ERROR [o, o]
+struct Bar<'a, T : Trait<'a>> { //~ ERROR ['a: o, T: o]
     field: <T as Trait<'a>>::Type
 }
 
diff --git a/tests/ui/variance/variance-associated-types.stderr b/tests/ui/variance/variance-associated-types.stderr
index 70cb246f6e9..ca010b7e7ef 100644
--- a/tests/ui/variance/variance-associated-types.stderr
+++ b/tests/ui/variance/variance-associated-types.stderr
@@ -1,10 +1,10 @@
-error: [+, +]
+error: ['a: +, T: +]
   --> $DIR/variance-associated-types.rs:13:1
    |
 LL | struct Foo<'a, T : Trait<'a>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: ['a: o, T: o]
   --> $DIR/variance-associated-types.rs:18:1
    |
 LL | struct Bar<'a, T : Trait<'a>> {
diff --git a/tests/ui/variance/variance-object-types.rs b/tests/ui/variance/variance-object-types.rs
index 6ded24cd1e9..fd03dec9824 100644
--- a/tests/ui/variance/variance-object-types.rs
+++ b/tests/ui/variance/variance-object-types.rs
@@ -4,7 +4,7 @@
 // For better or worse, associated types are invariant, and hence we
 // get an invariant result for `'a`.
 #[rustc_variance]
-struct Foo<'a> { //~ ERROR [o]
+struct Foo<'a> { //~ ERROR ['a: o]
     x: Box<dyn Fn(i32) -> &'a i32 + 'static>
 }
 
diff --git a/tests/ui/variance/variance-object-types.stderr b/tests/ui/variance/variance-object-types.stderr
index 963f3454e1b..a6fb9b2403a 100644
--- a/tests/ui/variance/variance-object-types.stderr
+++ b/tests/ui/variance/variance-object-types.stderr
@@ -1,4 +1,4 @@
-error: [o]
+error: ['a: o]
   --> $DIR/variance-object-types.rs:7:1
    |
 LL | struct Foo<'a> {
diff --git a/tests/ui/variance/variance-regions-direct.rs b/tests/ui/variance/variance-regions-direct.rs
index f1763c403f1..2bcacec33ea 100644
--- a/tests/ui/variance/variance-regions-direct.rs
+++ b/tests/ui/variance/variance-regions-direct.rs
@@ -6,7 +6,7 @@
 // Regions that just appear in normal spots are contravariant:
 
 #[rustc_variance]
-struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
+struct Test2<'a, 'b, 'c> { //~ ERROR ['a: +, 'b: +, 'c: +]
     x: &'a isize,
     y: &'b [isize],
     c: &'c str
@@ -15,7 +15,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
 // Those same annotations in function arguments become covariant:
 
 #[rustc_variance]
-struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
+struct Test3<'a, 'b, 'c> { //~ ERROR ['a: -, 'b: -, 'c: -]
     x: extern "Rust" fn(&'a isize),
     y: extern "Rust" fn(&'b [isize]),
     c: extern "Rust" fn(&'c str),
@@ -24,7 +24,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
 // Mutability induces invariance:
 
 #[rustc_variance]
-struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
+struct Test4<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
     x: &'a mut &'b isize,
 }
 
@@ -32,7 +32,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
 // contravariant context:
 
 #[rustc_variance]
-struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
+struct Test5<'a, 'b:'a> { //~ ERROR ['a: -, 'b: o]
     x: extern "Rust" fn(&'a mut &'b isize),
 }
 
@@ -42,14 +42,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
 // argument list occurs in an invariant context.
 
 #[rustc_variance]
-struct Test6<'a, 'b:'a> { //~ ERROR [+, o]
+struct Test6<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
     x: &'a mut extern "Rust" fn(&'b isize),
 }
 
 // No uses at all is bivariant:
 
 #[rustc_variance]
-struct Test7<'a> { //~ ERROR [*]
+struct Test7<'a> { //~ ERROR ['a: *]
     //~^ ERROR: `'a` is never used
     x: isize
 }
@@ -57,7 +57,7 @@ struct Test7<'a> { //~ ERROR [*]
 // Try enums too.
 
 #[rustc_variance]
-enum Test8<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
+enum Test8<'a, 'b, 'c:'b> { //~ ERROR ['a: -, 'b: +, 'c: o]
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
diff --git a/tests/ui/variance/variance-regions-direct.stderr b/tests/ui/variance/variance-regions-direct.stderr
index edfc888f656..45ce0303fb2 100644
--- a/tests/ui/variance/variance-regions-direct.stderr
+++ b/tests/ui/variance/variance-regions-direct.stderr
@@ -6,43 +6,43 @@ LL | struct Test7<'a> {
    |
    = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: [+, +, +]
+error: ['a: +, 'b: +, 'c: +]
   --> $DIR/variance-regions-direct.rs:9:1
    |
 LL | struct Test2<'a, 'b, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [-, -, -]
+error: ['a: -, 'b: -, 'c: -]
   --> $DIR/variance-regions-direct.rs:18:1
    |
 LL | struct Test3<'a, 'b, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [+, o]
+error: ['a: +, 'b: o]
   --> $DIR/variance-regions-direct.rs:27:1
    |
 LL | struct Test4<'a, 'b:'a> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [-, o]
+error: ['a: -, 'b: o]
   --> $DIR/variance-regions-direct.rs:35:1
    |
 LL | struct Test5<'a, 'b:'a> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [+, o]
+error: ['a: +, 'b: o]
   --> $DIR/variance-regions-direct.rs:45:1
    |
 LL | struct Test6<'a, 'b:'a> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*]
+error: ['a: *]
   --> $DIR/variance-regions-direct.rs:52:1
    |
 LL | struct Test7<'a> {
    | ^^^^^^^^^^^^^^^^
 
-error: [-, +, o]
+error: ['a: -, 'b: +, 'c: o]
   --> $DIR/variance-regions-direct.rs:60:1
    |
 LL | enum Test8<'a, 'b, 'c:'b> {
diff --git a/tests/ui/variance/variance-regions-indirect.rs b/tests/ui/variance/variance-regions-indirect.rs
index 31e25641d8c..aaa4d3f8779 100644
--- a/tests/ui/variance/variance-regions-indirect.rs
+++ b/tests/ui/variance/variance-regions-indirect.rs
@@ -5,7 +5,7 @@
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
+enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR ['a: -, 'b: +, 'c: o, 'd: *]
     //~^ ERROR: `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
@@ -13,25 +13,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
 }
 
 #[rustc_variance]
-struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -]
+struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR ['w: *, 'x: o, 'y: +, 'z: -]
     //~^ ERROR: `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
-struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
+struct Derived2<'a, 'b:'a, 'c> { //~ ERROR ['a: o, 'b: o, 'c: *]
     //~^ ERROR: `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
-struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *]
+struct Derived3<'a:'b, 'b, 'c> { //~ ERROR ['a: o, 'b: +, 'c: *]
     //~^ ERROR: `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
 #[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
-struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [-, +, o]
+struct Derived4<'a, 'b, 'c:'b> { //~ ERROR ['a: -, 'b: +, 'c: o]
     f: Base<'a, 'b, 'c, 'a>
 }
 
diff --git a/tests/ui/variance/variance-regions-indirect.stderr b/tests/ui/variance/variance-regions-indirect.stderr
index 901ec0c6a76..ed839b32350 100644
--- a/tests/ui/variance/variance-regions-indirect.stderr
+++ b/tests/ui/variance/variance-regions-indirect.stderr
@@ -30,31 +30,31 @@ LL | struct Derived3<'a:'b, 'b, 'c> {
    |
    = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: [-, +, o, *]
+error: ['a: -, 'b: +, 'c: o, 'd: *]
   --> $DIR/variance-regions-indirect.rs:8:1
    |
 LL | enum Base<'a, 'b, 'c:'b, 'd> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, o, +, -]
+error: ['w: *, 'x: o, 'y: +, 'z: -]
   --> $DIR/variance-regions-indirect.rs:16:1
    |
 LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o, *]
+error: ['a: o, 'b: o, 'c: *]
   --> $DIR/variance-regions-indirect.rs:22:1
    |
 LL | struct Derived2<'a, 'b:'a, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, +, *]
+error: ['a: o, 'b: +, 'c: *]
   --> $DIR/variance-regions-indirect.rs:28:1
    |
 LL | struct Derived3<'a:'b, 'b, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [-, +, o]
+error: ['a: -, 'b: +, 'c: o]
   --> $DIR/variance-regions-indirect.rs:34:1
    |
 LL | struct Derived4<'a, 'b, 'c:'b> {
diff --git a/tests/ui/variance/variance-trait-bounds.rs b/tests/ui/variance/variance-trait-bounds.rs
index 25a01b160dd..f86fa2bbef7 100644
--- a/tests/ui/variance/variance-trait-bounds.rs
+++ b/tests/ui/variance/variance-trait-bounds.rs
@@ -13,24 +13,24 @@ trait Setter<T> {
 }
 
 #[rustc_variance]
-struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
+struct TestStruct<U,T:Setter<U>> { //~ ERROR [U: +, T: +]
     t: T, u: U
 }
 
 #[rustc_variance]
-enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +]
+enum TestEnum<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
     //~^ ERROR: `U` is never used
     Foo(T)
 }
 
 #[rustc_variance]
-struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
+struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
     //~^ ERROR: `U` is never used
     t: T
 }
 
 #[rustc_variance]
-struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +]
+struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [U: *, T: +]
     //~^ ERROR: `U` is never used
     t: T
 }
diff --git a/tests/ui/variance/variance-trait-bounds.stderr b/tests/ui/variance/variance-trait-bounds.stderr
index 95ed18c1ad2..49cee3cbeca 100644
--- a/tests/ui/variance/variance-trait-bounds.stderr
+++ b/tests/ui/variance/variance-trait-bounds.stderr
@@ -25,25 +25,25 @@ LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
    = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
 
-error: [+, +]
+error: [U: +, T: +]
   --> $DIR/variance-trait-bounds.rs:16:1
    |
 LL | struct TestStruct<U,T:Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, +]
+error: [U: *, T: +]
   --> $DIR/variance-trait-bounds.rs:21:1
    |
 LL | enum TestEnum<U,T:Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, +]
+error: [U: *, T: +]
   --> $DIR/variance-trait-bounds.rs:27:1
    |
 LL | struct TestContraStruct<U,T:Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [*, +]
+error: [U: *, T: +]
   --> $DIR/variance-trait-bounds.rs:33:1
    |
 LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
diff --git a/tests/ui/variance/variance-trait-object-bound.rs b/tests/ui/variance/variance-trait-object-bound.rs
index 11303c46520..ca80c6b6dce 100644
--- a/tests/ui/variance/variance-trait-object-bound.rs
+++ b/tests/ui/variance/variance-trait-object-bound.rs
@@ -11,7 +11,7 @@ use std::mem;
 trait T { fn foo(&self); }
 
 #[rustc_variance]
-struct TOption<'a> { //~ ERROR [+]
+struct TOption<'a> { //~ ERROR ['a: +]
     v: Option<Box<dyn T + 'a>>,
 }
 
diff --git a/tests/ui/variance/variance-trait-object-bound.stderr b/tests/ui/variance/variance-trait-object-bound.stderr
index f0471a34619..0af21ec12cc 100644
--- a/tests/ui/variance/variance-trait-object-bound.stderr
+++ b/tests/ui/variance/variance-trait-object-bound.stderr
@@ -1,4 +1,4 @@
-error: [+]
+error: ['a: +]
   --> $DIR/variance-trait-object-bound.rs:14:1
    |
 LL | struct TOption<'a> {
diff --git a/tests/ui/variance/variance-types-bounds.rs b/tests/ui/variance/variance-types-bounds.rs
index d1814dd97a0..f4738a2dae1 100644
--- a/tests/ui/variance/variance-types-bounds.rs
+++ b/tests/ui/variance/variance-types-bounds.rs
@@ -4,24 +4,24 @@
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-struct TestImm<A, B> { //~ ERROR [+, +]
+struct TestImm<A, B> { //~ ERROR [A: +, B: +]
     x: A,
     y: B,
 }
 
 #[rustc_variance]
-struct TestMut<A, B:'static> { //~ ERROR [+, o]
+struct TestMut<A, B:'static> { //~ ERROR [A: +, B: o]
     x: A,
     y: &'static mut B,
 }
 
 #[rustc_variance]
-struct TestIndirect<A:'static, B:'static> { //~ ERROR [+, o]
+struct TestIndirect<A:'static, B:'static> { //~ ERROR [A: +, B: o]
     m: TestMut<A, B>
 }
 
 #[rustc_variance]
-struct TestIndirect2<A:'static, B:'static> { //~ ERROR [o, o]
+struct TestIndirect2<A:'static, B:'static> { //~ ERROR [A: o, B: o]
     n: TestMut<A, B>,
     m: TestMut<B, A>
 }
@@ -35,7 +35,7 @@ trait Setter<A> {
 }
 
 #[rustc_variance]
-struct TestObject<A, R> { //~ ERROR [o, o]
+struct TestObject<A, R> { //~ ERROR [A: o, R: o]
     n: Box<dyn Setter<A>+Send>,
     m: Box<dyn Getter<R>+Send>,
 }
diff --git a/tests/ui/variance/variance-types-bounds.stderr b/tests/ui/variance/variance-types-bounds.stderr
index bb816443476..408c2ae8d36 100644
--- a/tests/ui/variance/variance-types-bounds.stderr
+++ b/tests/ui/variance/variance-types-bounds.stderr
@@ -1,28 +1,28 @@
-error: [+, +]
+error: [A: +, B: +]
   --> $DIR/variance-types-bounds.rs:7:1
    |
 LL | struct TestImm<A, B> {
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: [+, o]
+error: [A: +, B: o]
   --> $DIR/variance-types-bounds.rs:13:1
    |
 LL | struct TestMut<A, B:'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [+, o]
+error: [A: +, B: o]
   --> $DIR/variance-types-bounds.rs:19:1
    |
 LL | struct TestIndirect<A:'static, B:'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [A: o, B: o]
   --> $DIR/variance-types-bounds.rs:24:1
    |
 LL | struct TestIndirect2<A:'static, B:'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [A: o, R: o]
   --> $DIR/variance-types-bounds.rs:38:1
    |
 LL | struct TestObject<A, R> {
diff --git a/tests/ui/variance/variance-types.rs b/tests/ui/variance/variance-types.rs
index cfc03b75473..aa336d1b424 100644
--- a/tests/ui/variance/variance-types.rs
+++ b/tests/ui/variance/variance-types.rs
@@ -7,32 +7,32 @@ use std::cell::Cell;
 // not considered bivariant.
 
 #[rustc_variance]
-struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [+, o, o]
+struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR ['a: +, A: o, B: o]
     t: &'a mut (A,B)
 }
 
 #[rustc_variance]
-struct InvariantCell<A> { //~ ERROR [o]
+struct InvariantCell<A> { //~ ERROR [A: o]
     t: Cell<A>
 }
 
 #[rustc_variance]
-struct InvariantIndirect<A> { //~ ERROR [o]
+struct InvariantIndirect<A> { //~ ERROR [A: o]
     t: InvariantCell<A>
 }
 
 #[rustc_variance]
-struct Covariant<A> { //~ ERROR [+]
+struct Covariant<A> { //~ ERROR [A: +]
     t: A, u: fn() -> A
 }
 
 #[rustc_variance]
-struct Contravariant<A> { //~ ERROR [-]
+struct Contravariant<A> { //~ ERROR [A: -]
     t: fn(A)
 }
 
 #[rustc_variance]
-enum Enum<A,B,C> { //~ ERROR [+, -, o]
+enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o]
     Foo(Covariant<A>),
     Bar(Contravariant<B>),
     Zed(Covariant<C>,Contravariant<C>)
diff --git a/tests/ui/variance/variance-types.stderr b/tests/ui/variance/variance-types.stderr
index 0fda4b8036e..f2a67949425 100644
--- a/tests/ui/variance/variance-types.stderr
+++ b/tests/ui/variance/variance-types.stderr
@@ -1,34 +1,34 @@
-error: [+, o, o]
+error: ['a: +, A: o, B: o]
   --> $DIR/variance-types.rs:10:1
    |
 LL | struct InvariantMut<'a,A:'a,B:'a> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
+error: [A: o]
   --> $DIR/variance-types.rs:15:1
    |
 LL | struct InvariantCell<A> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
+error: [A: o]
   --> $DIR/variance-types.rs:20:1
    |
 LL | struct InvariantIndirect<A> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [+]
+error: [A: +]
   --> $DIR/variance-types.rs:25:1
    |
 LL | struct Covariant<A> {
    | ^^^^^^^^^^^^^^^^^^^
 
-error: [-]
+error: [A: -]
   --> $DIR/variance-types.rs:30:1
    |
 LL | struct Contravariant<A> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [+, -, o]
+error: [A: +, B: -, C: o]
   --> $DIR/variance-types.rs:35:1
    |
 LL | enum Enum<A,B,C> {
diff --git a/triagebot.toml b/triagebot.toml
index 161fe98fca9..d7bc60e6c6f 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -913,7 +913,7 @@ cc = ["@kobzol"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "jhpratt", "oli-obk"]
+users_on_vacation = ["jyn514", "jhpratt", "oli-obk", "kobzol"]
 
 [assign.adhoc_groups]
 compiler-team = [
@@ -951,6 +951,7 @@ libs = [
     "@joboet",
     "@jhpratt",
     "@tgross35",
+    "@thomcc",
 ]
 bootstrap = [
     "@Mark-Simulacrum",