about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-03 06:34:17 +0000
committerbors <bors@rust-lang.org>2024-05-03 06:34:17 +0000
commit5ce8532c2602822a8badfeb845b9631dcbf6d790 (patch)
treeababcae4e5dc33a589e3df9f37ce8a251aea922f
parent3c6d194186def9e8896e2206dbbbeac23fb11599 (diff)
parent4af1ba020405ce815cdc134335726edcd0d92cac (diff)
downloadrust-5ce8532c2602822a8badfeb845b9631dcbf6d790.tar.gz
rust-5ce8532c2602822a8badfeb845b9631dcbf6d790.zip
Auto merge of #3537 - rust-lang:rustup-2024-05-03, r=RalfJung
Automatic Rustup
-rw-r--r--.github/workflows/ci.yml233
-rw-r--r--Cargo.lock84
-rw-r--r--Cargo.toml4
-rw-r--r--RELEASES.md120
-rw-r--r--compiler/rustc_abi/src/layout.rs2
-rw-r--r--compiler/rustc_abi/src/lib.rs12
-rw-r--r--compiler/rustc_ast/src/ast.rs59
-rw-r--r--compiler/rustc_ast/src/expand/allocator.rs1
-rw-r--r--compiler/rustc_ast/src/expand/mod.rs1
-rw-r--r--compiler/rustc_ast/src/format.rs1
-rw-r--r--compiler/rustc_ast/src/lib.rs7
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs360
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs2
-rw-r--r--compiler/rustc_ast/src/util/literal.rs1
-rw-r--r--compiler/rustc_ast/src/visit.rs298
-rw-r--r--compiler/rustc_ast_ir/src/lib.rs3
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl1
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs1
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs17
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs2
-rw-r--r--compiler/rustc_ast_passes/src/node_count.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs17
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs21
-rw-r--r--compiler/rustc_attr/src/builtin.rs2
-rw-r--r--compiler/rustc_attr/src/lib.rs3
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs2
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs5
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs1
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs1
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs1
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/canonical.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs1
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs1
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl6
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/compile_error.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs23
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs32
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/edition_panic.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs25
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs13
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/log_syntax.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/pattern_type.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/trace_macros.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/util.rs192
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs31
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs1
-rw-r--r--compiler/rustc_data_structures/src/lib.rs7
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs1
-rw-r--r--compiler/rustc_data_structures/src/svh.rs4
-rw-r--r--compiler/rustc_data_structures/src/sync.rs6
-rw-r--r--compiler/rustc_data_structures/src/unord.rs7
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs7
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0637.md21
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs1
-rw-r--r--compiler/rustc_errors/src/emitter.rs21
-rw-r--r--compiler/rustc_errors/src/lib.rs8
-rw-r--r--compiler/rustc_errors/src/snippet.rs1
-rw-r--r--compiler/rustc_errors/src/translation.rs1
-rw-r--r--compiler/rustc_expand/messages.ftl9
-rw-r--r--compiler/rustc_expand/src/base.rs251
-rw-r--r--compiler/rustc_expand/src/build.rs27
-rw-r--r--compiler/rustc_expand/src/config.rs10
-rw-r--r--compiler/rustc_expand/src/errors.rs25
-rw-r--r--compiler/rustc_expand/src/expand.rs62
-rw-r--r--compiler/rustc_expand/src/lib.rs31
-rw-r--r--compiler/rustc_expand/src/mbe.rs12
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs5
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs12
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs100
-rw-r--r--compiler/rustc_expand/src/placeholders.rs8
-rw-r--r--compiler/rustc_feature/src/accepted.rs10
-rw-r--r--compiler/rustc_feature/src/unstable.rs18
-rw-r--r--compiler/rustc_hir/src/def.rs2
-rw-r--r--compiler/rustc_hir/src/definitions.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs6
-rw-r--r--compiler/rustc_hir/src/hir_id.rs1
-rw-r--r--compiler/rustc_hir/src/lang_items.rs4
-rw-r--r--compiler/rustc_hir/src/lib.rs9
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl14
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs44
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs313
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs45
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl11
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs245
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs103
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs140
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs14
-rw-r--r--compiler/rustc_incremental/src/assert_dep_graph.rs1
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs1
-rw-r--r--compiler/rustc_infer/src/infer/canonical/instantiate.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs7
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs1
-rw-r--r--compiler/rustc_infer/src/lib.rs6
-rw-r--r--compiler/rustc_infer/src/traits/engine.rs1
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs14
-rw-r--r--compiler/rustc_interface/src/tests.rs14
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs2
-rw-r--r--compiler/rustc_lint/src/async_fn_in_trait.rs1
-rw-r--r--compiler/rustc_lint/src/builtin.rs2
-rw-r--r--compiler/rustc_lint/src/context.rs19
-rw-r--r--compiler/rustc_lint/src/context/diagnostics/check_cfg.rs1
-rw-r--r--compiler/rustc_lint/src/deref_into_dyn_supertrait.rs1
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs1
-rw-r--r--compiler/rustc_lint/src/early.rs2
-rw-r--r--compiler/rustc_lint/src/enum_intrinsics_non_enums.rs1
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs1
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs1
-rw-r--r--compiler/rustc_lint/src/hidden_unicode_codepoints.rs1
-rw-r--r--compiler/rustc_lint/src/invalid_from_utf8.rs1
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs1
-rw-r--r--compiler/rustc_lint/src/levels.rs1
-rw-r--r--compiler/rustc_lint/src/lib.rs4
-rw-r--r--compiler/rustc_lint/src/lints.rs12
-rw-r--r--compiler/rustc_lint/src/map_unit_fn.rs1
-rw-r--r--compiler/rustc_lint/src/methods.rs1
-rw-r--r--compiler/rustc_lint/src/multiple_supertrait_upcastable.rs1
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs1
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs2
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs26
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs1
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs1
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs1
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs1
-rw-r--r--compiler/rustc_lint/src/redundant_semicolon.rs1
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs1
-rw-r--r--compiler/rustc_lint/src/traits.rs1
-rw-r--r--compiler/rustc_lint/src/types.rs2
-rw-r--r--compiler/rustc_lint/src/unit_bindings.rs6
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs146
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs13
-rw-r--r--compiler/rustc_metadata/src/errors.rs7
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/error.rs2
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs1
-rw-r--r--compiler/rustc_middle/src/hir/place.rs1
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/infer/mod.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs10
-rw-r--r--compiler/rustc_middle/src/lint.rs1
-rw-r--r--compiler/rustc_middle/src/metadata.rs2
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs3
-rw-r--r--compiler/rustc_middle/src/middle/debugger_visualizer.rs1
-rw-r--r--compiler/rustc_middle/src/middle/dependency_format.rs1
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs2
-rw-r--r--compiler/rustc_middle/src/middle/mod.rs1
-rw-r--r--compiler/rustc_middle/src/middle/region.rs4
-rw-r--r--compiler/rustc_middle/src/middle/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs1
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs1
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs3
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs25
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs13
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs10
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs1
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs17
-rw-r--r--compiler/rustc_middle/src/mir/query.rs1
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs2
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs1
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs1
-rw-r--r--compiler/rustc_middle/src/tests.rs16
-rw-r--r--compiler/rustc_middle/src/thir.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs7
-rw-r--r--compiler/rustc_middle/src/traits/query.rs2
-rw-r--r--compiler/rustc_middle/src/traits/select.rs1
-rw-r--r--compiler/rustc_middle/src/traits/solve.rs6
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect.rs20
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs7
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs1
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs1
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs6
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs1
-rw-r--r--compiler/rustc_middle/src/ty/cast.rs2
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs3
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs6
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs1
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs13
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs4
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs1
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs1
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs4
-rw-r--r--compiler/rustc_middle/src/ty/intrinsic.rs1
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs5
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs51
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_middle/src/ty/pattern.rs1
-rw-r--r--compiler/rustc_middle/src/ty/predicate.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs1
-rw-r--r--compiler/rustc_middle/src/ty/region.rs1
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs1
-rw-r--r--compiler/rustc_middle/src/ty/rvalue_scopes.rs1
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs7
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs2
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs1
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo.rs300
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs275
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs14
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs16
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs15
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs275
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs52
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs147
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs137
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs63
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs1
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs3
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs1
-rw-r--r--compiler/rustc_parse/src/parser/item.rs6
-rw-r--r--compiler/rustc_passes/src/abi_test.rs1
-rw-r--r--compiler/rustc_passes/src/check_attr.rs1
-rw-r--r--compiler/rustc_passes/src/check_const.rs1
-rw-r--r--compiler/rustc_passes/src/dead.rs1
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs2
-rw-r--r--compiler/rustc_passes/src/layout_test.rs1
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs1
-rw-r--r--compiler/rustc_passes/src/loops.rs1
-rw-r--r--compiler/rustc_passes/src/reachable.rs1
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs6
-rw-r--r--compiler/rustc_pattern_analysis/src/lints.rs6
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs1
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs11
-rw-r--r--compiler/rustc_privacy/src/lib.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs29
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs12
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs5
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs1
-rw-r--r--compiler/rustc_query_system/src/lib.rs7
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs1
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs13
-rw-r--r--compiler/rustc_resolve/src/late.rs8
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--compiler/rustc_resolve/src/macros.rs16
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs25
-rw-r--r--compiler/rustc_serialize/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/config.rs26
-rw-r--r--compiler/rustc_session/src/cstore.rs1
-rw-r--r--compiler/rustc_session/src/errors.rs2
-rw-r--r--compiler/rustc_session/src/filesearch.rs7
-rw-r--r--compiler/rustc_session/src/lib.rs5
-rw-r--r--compiler/rustc_session/src/options.rs14
-rw-r--r--compiler/rustc_session/src/search_paths.rs1
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--compiler/rustc_session/src/utils.rs1
-rw-r--r--compiler/rustc_session/src/version.rs1
-rw-r--r--compiler/rustc_span/src/def_id.rs2
-rw-r--r--compiler/rustc_span/src/edition.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs2
-rw-r--r--compiler/rustc_span/src/lib.rs5
-rw-r--r--compiler/rustc_span/src/source_map.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs7
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs1
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs3
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs1
-rw-r--r--compiler/rustc_target/src/asm/arm.rs1
-rw-r--r--compiler/rustc_target/src/asm/avr.rs1
-rw-r--r--compiler/rustc_target/src/asm/bpf.rs1
-rw-r--r--compiler/rustc_target/src/asm/csky.rs1
-rw-r--r--compiler/rustc_target/src/asm/hexagon.rs1
-rw-r--r--compiler/rustc_target/src/asm/loongarch.rs1
-rw-r--r--compiler/rustc_target/src/asm/m68k.rs1
-rw-r--r--compiler/rustc_target/src/asm/mips.rs1
-rw-r--r--compiler/rustc_target/src/asm/mod.rs6
-rw-r--r--compiler/rustc_target/src/asm/msp430.rs1
-rw-r--r--compiler/rustc_target/src/asm/nvptx.rs1
-rw-r--r--compiler/rustc_target/src/asm/powerpc.rs1
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs1
-rw-r--r--compiler/rustc_target/src/asm/s390x.rs1
-rw-r--r--compiler/rustc_target/src/asm/spirv.rs1
-rw-r--r--compiler/rustc_target/src/asm/wasm.rs1
-rw-r--r--compiler/rustc_target/src/asm/x86.rs1
-rw-r--r--compiler/rustc_target/src/lib.rs6
-rw-r--r--compiler/rustc_target/src/spec/abi/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs10
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs8
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs186
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs97
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs96
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs41
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs483
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs310
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/build.rs276
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs13
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs93
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs373
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs302
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs38
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs33
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs2
-rw-r--r--compiler/rustc_traits/src/codegen.rs15
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs2
-rw-r--r--compiler/rustc_traits/src/evaluate_obligation.rs1
-rw-r--r--compiler/rustc_traits/src/lib.rs5
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_projection_ty.rs1
-rw-r--r--compiler/rustc_transmute/src/layout/dfa.rs1
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs3
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/mod.rs2
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs32
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs2
-rw-r--r--compiler/rustc_type_ir/src/const_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/flags.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs8
-rw-r--r--compiler/rustc_type_ir/src/predicate_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/region_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs2
-rw-r--r--compiler/stable_mir/src/compiler_interface.rs2
-rw-r--r--compiler/stable_mir/src/lib.rs2
-rw-r--r--library/alloc/src/borrow.rs5
-rw-r--r--library/alloc/src/lib.rs6
-rw-r--r--library/alloc/src/rc.rs11
-rw-r--r--library/alloc/src/str.rs2
-rw-r--r--library/alloc/src/string.rs6
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/core/src/cell.rs8
-rw-r--r--library/core/src/cmp.rs38
-rw-r--r--library/core/src/default.rs2
-rw-r--r--library/core/src/ffi/c_str.rs2
-rw-r--r--library/core/src/ffi/mod.rs23
-rw-r--r--library/core/src/future/mod.rs2
-rw-r--r--library/core/src/intrinsics.rs147
-rw-r--r--library/core/src/intrinsics/simd.rs13
-rw-r--r--library/core/src/iter/sources/from_coroutine.rs2
-rw-r--r--library/core/src/iter/traits/collect.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs1
-rw-r--r--library/core/src/iter/traits/marker.rs2
-rw-r--r--library/core/src/lib.rs10
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/mem/manually_drop.rs5
-rw-r--r--library/core/src/mem/mod.rs4
-rw-r--r--library/core/src/num/int_macros.rs36
-rw-r--r--library/core/src/num/mod.rs2
-rw-r--r--library/core/src/num/nonzero.rs16
-rw-r--r--library/core/src/num/uint_macros.rs51
-rw-r--r--library/core/src/ops/coroutine.rs2
-rw-r--r--library/core/src/ops/deref.rs2
-rw-r--r--library/core/src/ops/drop.rs1
-rw-r--r--library/core/src/ops/mod.rs1
-rw-r--r--library/core/src/panic/location.rs8
-rw-r--r--library/core/src/panicking.rs1
-rw-r--r--library/core/src/pin.rs7
-rw-r--r--library/core/src/prelude/common.rs1
-rw-r--r--library/core/src/primitive_docs.rs47
-rw-r--r--library/core/src/ptr/const_ptr.rs10
-rw-r--r--library/core/src/ptr/metadata.rs25
-rw-r--r--library/core/src/ptr/mod.rs9
-rw-r--r--library/core/src/ptr/mut_ptr.rs10
-rw-r--r--library/core/src/ptr/non_null.rs149
-rw-r--r--library/core/src/slice/iter/macros.rs41
-rw-r--r--library/core/src/slice/mod.rs4
-rw-r--r--library/core/src/str/lossy.rs74
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/core/src/sync/atomic.rs9
-rw-r--r--library/core/src/ub_checks.rs8
-rw-r--r--library/core/tests/intrinsics.rs1
-rw-r--r--library/core/tests/lib.rs4
-rw-r--r--library/core/tests/str_lossy.rs6
-rw-r--r--library/proc_macro/src/lib.rs4
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/f32.rs145
-rw-r--r--library/std/src/f64.rs145
-rw-r--r--library/std/src/ffi/os_str.rs6
-rw-r--r--library/std/src/fs/tests.rs35
-rw-r--r--library/std/src/io/cursor.rs6
-rw-r--r--library/std/src/io/error.rs2
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/io/util.rs6
-rw-r--r--library/std/src/lib.rs5
-rw-r--r--library/std/src/num.rs2
-rw-r--r--library/std/src/os/fd/owned.rs7
-rw-r--r--library/std/src/os/unix/io/mod.rs31
-rw-r--r--library/std/src/os/unix/net/mod.rs12
-rw-r--r--library/std/src/os/unix/net/stream.rs16
-rw-r--r--library/std/src/os/unix/net/ucred.rs20
-rw-r--r--library/std/src/os/unix/net/ucred/tests.rs17
-rw-r--r--library/std/src/path.rs10
-rw-r--r--library/std/src/prelude/common.rs1
-rw-r--r--library/std/src/sys/os_str/bytes.rs12
-rw-r--r--library/std/src/sys/os_str/wtf8.rs6
-rw-r--r--library/std/src/sys/pal/unix/args.rs25
-rw-r--r--library/std/src/sys/pal/unix/fs.rs168
-rw-r--r--library/std/src/sys/pal/unix/mod.rs10
-rw-r--r--library/std/src/sys/pal/unix/os.rs30
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs21
-rw-r--r--library/std/src/sys/pal/unix/rand.rs6
-rw-r--r--library/std/src/sys/pal/unix/thread.rs18
-rw-r--r--library/std/src/sys/pal/unix/thread_local_dtor.rs8
-rw-r--r--library/std/src/sys/pal/unix/thread_parking/mod.rs11
-rw-r--r--library/std/src/sys/pal/unix/thread_parking/pthread.rs26
-rw-r--r--library/std/src/sys/pal/unix/time.rs24
-rw-r--r--library/std/src/sys/sync/condvar/pthread.rs24
-rw-r--r--library/std/src/sys/thread_local/fast_local.rs7
-rw-r--r--library/std/src/sys/thread_local/mod.rs14
-rw-r--r--library/std/src/sys_common/net.rs15
-rw-r--r--library/std/src/sys_common/wtf8.rs6
-rw-r--r--library/std/src/thread/tests.rs6
-rw-r--r--rustfmt.toml8
-rw-r--r--src/bootstrap/bootstrap.py8
-rw-r--r--src/bootstrap/mk/Makefile.in3
-rw-r--r--src/bootstrap/src/core/build_steps/clean.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs23
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/mod.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs31
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs13
-rw-r--r--src/bootstrap/src/core/build_steps/suggest.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs89
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/toolstate.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/vendor.rs61
-rw-r--r--src/bootstrap/src/core/builder.rs44
-rw-r--r--src/bootstrap/src/core/config/config.rs13
-rw-r--r--src/bootstrap/src/core/config/flags.rs106
-rw-r--r--src/bootstrap/src/core/sanity.rs48
-rw-r--r--src/bootstrap/src/lib.rs7
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile9
-rwxr-xr-xsrc/ci/github-actions/calculate-job-matrix.py41
-rw-r--r--src/ci/github-actions/ci.yml390
-rw-r--r--src/ci/github-actions/jobs.yml2
-rw-r--r--src/doc/rustc/src/SUMMARY.md6
-rw-r--r--src/doc/rustc/src/instrument-coverage.md6
-rw-r--r--src/doc/rustc/src/jobserver.md86
-rw-r--r--src/doc/rustc/src/platform-support.md98
-rw-r--r--src/doc/rustc/src/platform-support/arm-none-eabi.md178
-rw-r--r--src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md10
-rw-r--r--src/doc/rustc/src/platform-support/armv4t-none-eabi.md6
-rw-r--r--src/doc/rustc/src/platform-support/armv5te-none-eabi.md6
-rw-r--r--src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md6
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv7r-none-eabi.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv8r-none-eabihf.md2
-rw-r--r--src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md62
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md74
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md44
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md44
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md135
-rw-r--r--src/doc/unstable-book/src/compiler-flags/coverage-options.md11
-rw-r--r--src/etc/completions/x.py.fish37
-rw-r--r--src/etc/completions/x.py.ps144
-rw-r--r--src/etc/completions/x.py.sh119
-rw-r--r--src/etc/completions/x.py.zsh51
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/markdown.rs6
-rw-r--r--src/librustdoc/html/render/search_index/encode.rs23
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css31
-rw-r--r--src/librustdoc/html/static/images/clipboard.svg1
-rw-r--r--src/librustdoc/html/static/images/wheel.svg1
-rw-r--r--src/librustdoc/html/static_files.rs2
-rw-r--r--src/stage0.json848
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/CHANGELOG.md56
-rw-r--r--src/tools/clippy/Cargo.toml4
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md8
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md15
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs9
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/collection_is_never_read.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/dbg_macro.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_assert.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_for_each.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs46
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs99
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs4
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs13
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs16
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs124
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs13
-rw-r--r--src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs8
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr3
-rw-r--r--src/tools/clippy/tests/ui-toml/useless_vec/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.fixed26
-rw-r--r--src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.rs26
-rw-r--r--src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.stderr11
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs10
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr14
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macros.rs17
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.rs4
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr18
-rw-r--r--src/tools/clippy/tests/ui/box_default.fixed12
-rw-r--r--src/tools/clippy/tests/ui/box_default.rs12
-rw-r--r--src/tools/clippy/tests/ui/box_default.stderr8
-rw-r--r--src/tools/clippy/tests/ui/cast.rs21
-rw-r--r--src/tools/clippy/tests/ui/cast.stderr206
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.rs16
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr68
-rw-r--r--src/tools/clippy/tests/ui/collection_is_never_read.rs14
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5238.rs3
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs5
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr20
-rw-r--r--src/tools/clippy/tests/ui/disallowed_names.rs5
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr2
-rw-r--r--src/tools/clippy/tests/ui/large_stack_arrays.rs48
-rw-r--r--src/tools/clippy/tests/ui/large_stack_arrays.stderr60
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.fixed27
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.rs27
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.stderr42
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.stderr4
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed2
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_key.rs10
-rw-r--r--src/tools/clippy/tests/ui/mut_key.stderr32
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.fixed4
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs42
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr98
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.fixed24
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.rs24
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.stderr20
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed18
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs18
-rw-r--r--src/tools/clippy/tests/ui/readonly_write_lock.fixed4
-rw-r--r--src/tools/clippy/tests/ui/readonly_write_lock.rs4
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.fixed12
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr34
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.rs22
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.fixed14
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.rs8
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.stderr62
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.stderr2
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr48
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed33
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs33
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.rs2
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.stderr30
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs2
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/script.js2
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/common.rs12
-rw-r--r--src/tools/compiletest/src/errors.rs9
-rw-r--r--src/tools/compiletest/src/header.rs9
-rw-r--r--src/tools/compiletest/src/header/needs.rs70
-rw-r--r--src/tools/compiletest/src/lib.rs5
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs4
-rw-r--r--src/tools/compiletest/src/runtest.rs149
-rw-r--r--src/tools/expand-yaml-anchors/Cargo.toml8
-rw-r--r--src/tools/expand-yaml-anchors/src/main.rs198
-rw-r--r--src/tools/jsondocck/Cargo.toml1
-rw-r--r--src/tools/jsondocck/src/main.rs9
-rw-r--r--src/tools/linkchecker/Cargo.toml1
-rw-r--r--src/tools/linkchecker/main.rs12
-rw-r--r--src/tools/miri/Cargo.lock1
-rw-r--r--src/tools/miri/Cargo.toml1
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/lib.rs2
-rw-r--r--src/tools/miri/src/machine.rs2
-rw-r--r--src/tools/miri/tests/ui.rs22
-rw-r--r--src/tools/run-make-support/Cargo.toml1
-rw-r--r--src/tools/run-make-support/src/cc.rs10
-rw-r--r--src/tools/run-make-support/src/clang.rs5
-rw-r--r--src/tools/run-make-support/src/diff/mod.rs28
-rw-r--r--src/tools/run-make-support/src/diff/tests.rs22
-rw-r--r--src/tools/run-make-support/src/lib.rs19
-rw-r--r--src/tools/run-make-support/src/llvm_readobj.rs6
-rw-r--r--src/tools/run-make-support/src/rustc.rs38
-rw-r--r--src/tools/run-make-support/src/rustdoc.rs39
-rw-r--r--src/tools/rustfmt/src/items.rs6
-rw-r--r--src/tools/suggest-tests/Cargo.toml1
-rw-r--r--src/tools/suggest-tests/src/lib.rs4
-rw-r--r--src/tools/suggest-tests/src/static_suggestions.rs8
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt4
-rw-r--r--src/tools/tidy/src/features.rs19
-rw-r--r--src/tools/tidy/src/fluent_alphabetical.rs8
-rw-r--r--src/tools/tidy/src/fluent_used.rs7
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/lib.rs7
-rw-r--r--src/tools/tidy/src/style.rs22
-rw-r--r--src/tools/tidy/src/ui_tests.rs10
-rw-r--r--src/version2
-rw-r--r--tests/assembly/manual-eq-efficient.rs22
-rw-r--r--tests/assembly/simd-intrinsic-mask-reduce.rs2
-rw-r--r--tests/assembly/x86_64-floating-point-clamp.rs3
-rw-r--r--tests/codegen/enum/enum-match.rs6
-rw-r--r--tests/codegen/ptr-read-metadata.rs6
-rw-r--r--tests/codegen/target-feature-inline-closure.rs3
-rw-r--r--tests/coverage/mcdc_nested_if.cov-map201
-rw-r--r--tests/coverage/mcdc_nested_if.coverage235
-rw-r--r--tests/coverage/mcdc_nested_if.rs70
-rw-r--r--tests/crashes/109812.rs22
-rw-r--r--tests/crashes/123710.rs17
-rw-r--r--tests/crashes/123863.rs6
-rw-r--r--tests/crashes/124262.rs5
-rw-r--r--tests/crashes/124340.rs17
-rw-r--r--tests/crashes/124342.rs6
-rw-r--r--tests/crashes/124347.rs4
-rw-r--r--tests/crashes/124348.rs7
-rw-r--r--tests/crashes/124350.rs17
-rw-r--r--tests/crashes/124352.rs4
-rw-r--r--tests/crashes/124375.rs11
-rw-r--r--tests/crashes/92470.rs31
-rw-r--r--tests/incremental/slice-pattern-const-ice-83085.rs39
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff112
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff112
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff99
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff99
-rw-r--r--tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff64
-rw-r--r--tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff64
-rw-r--r--tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff58
-rw-r--r--tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff58
-rw-r--r--tests/mir-opt/dataflow-const-prop/offset_of.rs16
-rw-r--r--tests/pretty/postfix-match/precedence.pp34
-rw-r--r--tests/pretty/postfix-match/precedence.rs34
-rw-r--r--tests/pretty/postfix-match/simple-matches.rs (renamed from tests/pretty/postfix-match.rs)0
-rw-r--r--tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs10
-rw-r--r--tests/run-make/a-b-a-linker-guard/rmake.rs2
-rw-r--r--tests/run-make/arguments-non-c-like-enum/rmake.rs2
-rw-r--r--tests/run-make/artifact-incr-cache-no-obj/rmake.rs2
-rw-r--r--tests/run-make/artifact-incr-cache/rmake.rs2
-rw-r--r--tests/run-make/compiler-builtins/rmake.rs34
-rw-r--r--tests/run-make/core-no-fp-fmt-parse/rmake.rs2
-rw-r--r--tests/run-make/cross-lang-lto-riscv-abi/rmake.rs1
-rw-r--r--tests/run-make/exit-code/rmake.rs32
-rw-r--r--tests/run-make/issue-107495-archive-permissions/rmake.rs1
-rw-r--r--tests/run-make/no-input-file/rmake.rs2
-rw-r--r--tests/run-make/non-unicode-env/rmake.rs2
-rw-r--r--tests/run-make/non-unicode-in-incremental-dir/rmake.rs2
-rw-r--r--tests/run-make/print-cfg/Makefile37
-rw-r--r--tests/run-make/print-cfg/rmake.rs104
-rw-r--r--tests/run-make/print-native-static-libs/Makefile19
-rw-r--r--tests/run-make/print-native-static-libs/rmake.rs72
-rw-r--r--tests/run-make/print-to-output/rmake.rs62
-rw-r--r--tests/run-make/raw-dylib-cross-compilation/Makefile4
-rw-r--r--tests/run-make/repr128-dwarf/Makefile16
-rw-r--r--tests/run-make/repr128-dwarf/main.rs (renamed from tests/run-make/repr128-dwarf/lib.rs)5
-rw-r--r--tests/run-make/repr128-dwarf/rmake.rs73
-rw-r--r--tests/run-make/rust-lld-custom-target/rmake.rs2
-rw-r--r--tests/run-make/rust-lld/rmake.rs2
-rw-r--r--tests/run-make/rustdoc-test-args/rmake.rs2
-rw-r--r--tests/run-make/stdin-non-utf8/Makefile6
-rw-r--r--tests/run-make/stdin-non-utf8/non-utf81
-rw-r--r--tests/run-make/stdin-rustc/rmake.rs26
-rw-r--r--tests/run-make/wasm-abi/rmake.rs2
-rw-r--r--tests/run-make/wasm-custom-section/rmake.rs1
-rw-r--r--tests/run-make/wasm-custom-sections-opt/rmake.rs3
-rw-r--r--tests/run-make/wasm-export-all-symbols/rmake.rs4
-rw-r--r--tests/run-make/wasm-import-module/rmake.rs11
-rw-r--r--tests/run-make/wasm-panic-small/rmake.rs2
-rw-r--r--tests/run-make/wasm-spurious-import/rmake.rs2
-rw-r--r--tests/run-make/wasm-stringify-ints-small/rmake.rs2
-rw-r--r--tests/run-make/wasm-symbols-different-module/rmake.rs1
-rw-r--r--tests/run-make/wasm-symbols-not-exported/rmake.rs1
-rw-r--r--tests/run-make/wasm-symbols-not-imported/rmake.rs1
-rw-r--r--tests/rustdoc-ui/doctest/non_local_defs.rs10
-rw-r--r--tests/rustdoc-ui/doctest/non_local_defs.stderr14
-rw-r--r--tests/rustdoc-ui/doctest/non_local_defs.stdout6
-rw-r--r--tests/rustdoc/resolve-ice-124363.rs7
-rw-r--r--tests/ui/asm/x86_64/target-feature-attr.rs2
-rw-r--r--tests/ui/asm/x86_64/target-feature-attr.stderr8
-rw-r--r--tests/ui/async-await/inference_var_self_argument.rs2
-rw-r--r--tests/ui/async-await/inference_var_self_argument.stderr2
-rw-r--r--tests/ui/async-await/issue-66312.stderr2
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs2
-rw-r--r--tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs11
-rw-r--r--tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs9
-rw-r--r--tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs20
-rw-r--r--tests/ui/closures/deduce-signature/infer-signature-from-impl.rs (renamed from tests/ui/closures/infer-signature-from-impl.rs)3
-rw-r--r--tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr15
-rw-r--r--tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr (renamed from tests/ui/closures/infer-signature-from-impl.next.stderr)3
-rw-r--r--tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs23
-rw-r--r--tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs (renamed from tests/ui/closures/issue-23012-supertrait-signature-inference.rs)3
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.svg20
-rw-r--r--tests/ui/coherence/auxiliary/parametrized-trait.rs2
-rw-r--r--tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr19
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr18
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs42
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr19
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr19
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs44
-rw-r--r--tests/ui/coherence/orphan-check-projections-covering.rs25
-rw-r--r--tests/ui/coherence/orphan-check-projections-nested.rs23
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr15
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr15
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs29
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr26
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr26
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs24
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr37
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering.next.stderr37
-rw-r--r--tests/ui/coherence/orphan-check-projections-not-covering.rs42
-rw-r--r--tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr15
-rw-r--r--tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr15
-rw-r--r--tests/ui/coherence/orphan-check-projections-unsat-bounds.rs35
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-covering.rs20
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr12
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr12
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs19
-rw-r--r--tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs13
-rw-r--r--tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr16
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs32
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr39
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr68
-rw-r--r--tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs18
-rw-r--r--tests/ui/consts/const-eval/const_fn_target_feature.rs3
-rw-r--r--tests/ui/consts/const-eval/const_fn_target_feature.stderr2
-rw-r--r--tests/ui/consts/const-eval/ice-unhandled-type-122191.rs18
-rw-r--r--tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr58
-rw-r--r--tests/ui/consts/mono-reachable-invalid-const.rs23
-rw-r--r--tests/ui/consts/mono-reachable-invalid-const.stderr29
-rw-r--r--tests/ui/error-emitter/highlighting.svg10
-rw-r--r--tests/ui/error-emitter/highlighting.windows.svg10
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.svg10
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg10
-rw-r--r--tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.stderr20
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-stable.stderr12
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr12
-rw-r--r--tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs29
-rw-r--r--tests/ui/imports/issue-59764.stderr4
-rw-r--r--tests/ui/instrument-coverage/coverage-options.bad.stderr2
-rw-r--r--tests/ui/instrument-coverage/coverage-options.rs11
-rw-r--r--tests/ui/issues/issue-22644.stderr4
-rw-r--r--tests/ui/issues/issue-43250.stderr4
-rw-r--r--tests/ui/issues/issue-56806.stderr2
-rw-r--r--tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs22
-rw-r--r--tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr29
-rw-r--r--tests/ui/lint/non-local-defs/module_as_local.rs38
-rw-r--r--tests/ui/lint/use_suggestion_json.stderr2
-rw-r--r--tests/ui/lowering/expr-in-pat-issue-99380.rs11
-rw-r--r--tests/ui/lowering/expr-in-pat-issue-99380.stderr10
-rw-r--r--tests/ui/macros/issue-118048.stderr2
-rw-r--r--tests/ui/macros/vec-macro-in-pattern.stderr1
-rw-r--r--tests/ui/match/expr_before_ident_pat.stderr2
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr2
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs141
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr87
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr28
-rw-r--r--tests/ui/offset-of/offset-of-must-use.rs2
-rw-r--r--tests/ui/offset-of/offset-of-must-use.stderr4
-rw-r--r--tests/ui/offset-of/offset-of-temporaries.rs23
-rw-r--r--tests/ui/parser/issues/issue-32505.stderr2
-rw-r--r--tests/ui/pattern/issue-92074-macro-ice.stderr3
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs2
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr28
-rw-r--r--tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs2
-rw-r--r--tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs3
-rw-r--r--tests/ui/self/arbitrary-self-opaque.rs2
-rw-r--r--tests/ui/self/arbitrary-self-opaque.stderr2
-rw-r--r--tests/ui/span/issue-27522.stderr2
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.current.stderr (renamed from tests/ui/specialization/specialization-overlap-projection.stderr)2
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.next.stderr49
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.rs10
-rw-r--r--tests/ui/sse2.rs6
-rw-r--r--tests/ui/statics/nested_struct.rs4
-rw-r--r--tests/ui/stats/hir-stats.stderr20
-rw-r--r--tests/ui/str/str-escape.stderr4
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-2.stderr2
-rw-r--r--tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr4
-rw-r--r--tests/ui/suggestions/issue-99240-2.stderr2
-rw-r--r--tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr2
-rw-r--r--tests/ui/traits/dyn-any-prefer-vtable.rs9
-rw-r--r--tests/ui/traits/issue-78372.rs2
-rw-r--r--tests/ui/traits/issue-78372.stderr2
-rw-r--r--tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs11
-rw-r--r--tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.stderr2
-rw-r--r--tests/ui/typeck/ice-unexpected-region-123863.rs9
-rw-r--r--tests/ui/typeck/ice-unexpected-region-123863.stderr38
-rw-r--r--tests/ui/typeck/issue-100285.stderr2
-rw-r--r--tests/ui/typeck/issue-31173.stderr2
-rw-r--r--tests/ui/ufcs/ufcs-explicit-self-bad.stderr6
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr2
-rw-r--r--tests/ui/unpretty/staged-api-invalid-path-108697.rs9
-rw-r--r--tests/ui/unpretty/staged-api-invalid-path-108697.stderr8
-rw-r--r--tests/ui/variance/variance-regions-unused-indirect.stderr2
-rw-r--r--triagebot.toml4
973 files changed, 12459 insertions, 7789 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3651ef2c614..a2769a2c274 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,46 +1,53 @@
-#############################################################
-#   WARNING: automatically generated file, DO NOT CHANGE!   #
-#############################################################
-
-# This file was automatically generated by the expand-yaml-anchors tool. The
-# source file that generated this one is:
-#
-#   src/ci/github-actions/ci.yml
-#
-# Once you make changes to that file you need to run:
-#
-#   ./x.py run src/tools/expand-yaml-anchors/
+# This file defines our primary CI workflow that runs on pull requests
+# and also on pushes to special branches (auto, try).
 #
-# The CI build will fail if the tool is not run after changes to this file.
+# The actual definition of the executed jobs is calculated by a Python
+# script located at src/ci/github-actions/calculate-job-matrix.py, which
+# uses job definition data from src/ci/github-actions/jobs.yml.
+# You should primarily modify the `jobs.yml` file if you want to modify
+# what jobs are executed in CI.
 
----
 name: CI
-"on":
+on:
   push:
     branches:
       - auto
       - try
       - try-perf
       - automation/bors/try
-      - master
   pull_request:
     branches:
       - "**"
+
 permissions:
   contents: read
   packages: write
+
 defaults:
   run:
+    # On Linux, macOS, and Windows, use the system-provided bash as the default
+    # shell. (This should only make a difference on Windows, where the default
+    # shell is PowerShell.)
     shell: bash
+
 concurrency:
-  group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}"
+  # For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
+  # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
+  # are all triggered on the same branch, but which should be able to run concurrently.
+  group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
   cancel-in-progress: true
+env:
+  TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
 jobs:
+  # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml.
+  # It calculates which jobs should be executed, based on the data of the ${{ github }} context.
+  # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml.
   calculate_matrix:
     name: Calculate job matrix
     runs-on: ubuntu-latest
     outputs:
-      jobs: "${{ steps.jobs.outputs.jobs }}"
+      jobs: ${{ steps.jobs.outputs.jobs }}
+      run_type: ${{ steps.jobs.outputs.run_type }}
     steps:
       - name: Checkout the source code
         uses: actions/checkout@v4
@@ -48,171 +55,195 @@ jobs:
         run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT
         id: jobs
   job:
-    name: "${{ matrix.name }}"
-    needs:
-      - calculate_matrix
+    name: ${{ matrix.name }}
+    needs: [ calculate_matrix ]
+    runs-on: "${{ matrix.os }}"
+    defaults:
+      run:
+        shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}
+    timeout-minutes: 600
     env:
-      CI_JOB_NAME: "${{ matrix.image }}"
+      CI_JOB_NAME: ${{ matrix.image }}
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
-      HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
-      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+      # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
+      HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+      DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       SCCACHE_BUCKET: rust-lang-ci-sccache2
-      TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
       CACHE_DOMAIN: ci-caches.rust-lang.org
-    continue-on-error: "${{ matrix.continue_on_error || false }}"
+    continue-on-error: ${{ matrix.continue_on_error || false }}
     strategy:
       matrix:
-        include: "${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}"
-    if: "fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null"
-    defaults:
-      run:
-        shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
-    timeout-minutes: 600
-    runs-on: "${{ matrix.os }}"
+        # Check the `calculate_matrix` job to see how is the matrix defined.
+        include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}
+    # GitHub Actions fails the workflow if an empty list of jobs is provided to
+    # the workflow, so we need to skip this job if nothing was produced by
+    # the Python script.
+    #
+    # Unfortunately checking whether a list is empty is not possible in a nice
+    # way due to GitHub Actions expressions limits.
+    # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82
+    if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null
     steps:
-      - if: "contains(matrix.os, 'windows')"
+      - if: contains(matrix.os, 'windows')
         uses: msys2/setup-msys2@v2.22.0
         with:
-          msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
+          # i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64.
+          msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}
+          # don't try to download updates for already installed packages
           update: false
+          # don't try to use the msys that comes built-in to the github runner,
+          # so we can control what is installed (i.e. not python)
           release: true
+          # Inherit the full path from the Windows environment, with MSYS2's */bin/
+          # dirs placed in front. This lets us run Windows-native Python etc.
           path-type: inherit
-          install: "make dos2unix diffutils\n"
+          install: >
+            make
+            dos2unix
+            diffutils
+
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
+
       - name: checkout the source code
         uses: actions/checkout@v4
         with:
           fetch-depth: 2
+
+      # Rust Log Analyzer can't currently detect the PR number of a GitHub
+      # Actions build on its own, so a hint in the log message is needed to
+      # point it in the right direction.
       - name: configure the PR in which the error message will be posted
-        run: "echo \"[CI_PR_NUMBER=$num]\""
+        run: echo "[CI_PR_NUMBER=$num]"
         env:
-          num: "${{ github.event.number }}"
-        if: "success() && github.event_name == 'pull_request'"
+          num: ${{ github.event.number }}
+        if: needs.calculate_matrix.outputs.run_type == 'pr'
+
       - name: add extra environment variables
         run: src/ci/scripts/setup-environment.sh
         env:
-          EXTRA_VARIABLES: "${{ toJson(matrix.env) }}"
+          # Since it's not possible to merge `${{ matrix.env }}` with the other
+          # variables in `job.<name>.env`, the variables defined in the matrix
+          # are passed to the `setup-environment.sh` script encoded in JSON,
+          # which then uses log commands to actually set them.
+          EXTRA_VARIABLES: ${{ toJson(matrix.env) }}
+
       - name: ensure the channel matches the target branch
         run: src/ci/scripts/verify-channel.sh
+
       - name: collect CPU statistics
         run: src/ci/scripts/collect-cpu-stats.sh
+
       - name: show the current environment
         run: src/ci/scripts/dump-environment.sh
+
       - name: install awscli
         run: src/ci/scripts/install-awscli.sh
+
       - name: install sccache
         run: src/ci/scripts/install-sccache.sh
+
       - name: select Xcode
         run: src/ci/scripts/select-xcode.sh
+
       - name: install clang
         run: src/ci/scripts/install-clang.sh
+
       - name: install tidy
         run: src/ci/scripts/install-tidy.sh
+
       - name: install WIX
         run: src/ci/scripts/install-wix.sh
+
       - name: disable git crlf conversion
         run: src/ci/scripts/disable-git-crlf-conversion.sh
+
       - name: checkout submodules
         run: src/ci/scripts/checkout-submodules.sh
+
       - name: install MSYS2
         run: src/ci/scripts/install-msys2.sh
+
       - name: install MinGW
         run: src/ci/scripts/install-mingw.sh
+
       - name: install ninja
         run: src/ci/scripts/install-ninja.sh
+
       - name: enable ipv6 on Docker
         run: src/ci/scripts/enable-docker-ipv6.sh
+
+      # Disable automatic line ending conversion (again). On Windows, when we're
+      # installing dependencies, something switches the git configuration directory or
+      # re-enables autocrlf. We've not tracked down the exact cause -- and there may
+      # be multiple -- but this should ensure submodules are checked out with the
+      # appropriate line endings.
       - name: disable git crlf conversion
         run: src/ci/scripts/disable-git-crlf-conversion.sh
+
       - name: ensure line endings are correct
         run: src/ci/scripts/verify-line-endings.sh
+
       - name: ensure backported commits are in upstream branches
         run: src/ci/scripts/verify-backported-commits.sh
+
       - name: ensure the stable version number is correct
         run: src/ci/scripts/verify-stable-version-number.sh
+
       - name: run the build
+        # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
         run: src/ci/scripts/run-build-from-ci.sh 2>&1
         env:
-          AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}"
-          AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}"
-          TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
+          AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}
+          TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
+
       - name: create github artifacts
         run: src/ci/scripts/create-doc-artifacts.sh
+
       - name: upload artifacts to github
         uses: actions/upload-artifact@v4
         with:
-          name: "${{ env.DOC_ARTIFACT_NAME }}"
+          # name is set in previous step
+          name: ${{ env.DOC_ARTIFACT_NAME }}
           path: obj/artifacts/doc
           if-no-files-found: ignore
           retention-days: 5
+
       - name: upload artifacts to S3
         run: src/ci/scripts/upload-artifacts.sh
         env:
-          AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}"
-          AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}"
-        if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')"
-  master:
-    name: master
+          AWS_ACCESS_KEY_ID: ${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}
+          AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}
+        # Adding a condition on DEPLOY=1 or DEPLOY_ALT=1 is not needed as all deploy
+        # builders *should* have the AWS credentials available. Still, explicitly
+        # adding the condition is helpful as this way CI will not silently skip
+        # deploying artifacts from a dist builder if the variables are misconfigured,
+        # erroring about invalid credentials instead.
+        if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1'
+
+  # This job isused to tell bors the final status of the build, as there is no practical way to detect
+  # when a workflow is successful listening to webhooks only in our current bors implementation (homu).
+  outcome:
+    name: bors build finished
     runs-on: ubuntu-latest
-    env:
-      SCCACHE_BUCKET: rust-lang-ci-sccache2
-      DEPLOY_BUCKET: rust-lang-ci2
-      TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
-      TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues"
-      TOOLSTATE_PUBLISH: 1
-      CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
-      ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
-      AWS_REGION: us-west-1
-      CACHE_DOMAIN: ci-caches.rust-lang.org
-    if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'"
+    needs: [ calculate_matrix, job ]
+    # !cancelled() executes the job regardless of whether the previous jobs passed or failed
+    if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
     steps:
       - name: checkout the source code
         uses: actions/checkout@v4
         with:
           fetch-depth: 2
+      # Calculate the exit status of the whole CI workflow.
+      # If all dependent jobs were successful, this exits with 0 (and the outcome job continues successfully).
+      # If a some dependent job has failed, this exits with 1.
+      - name: calculate the correct exit status
+        run: jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}'
+      # Publish the toolstate if an auto build succeeds (just before push to master)
       - name: publish toolstate
         run: src/ci/publish_toolstate.sh
         shell: bash
+        if: needs.calculate_matrix.outputs.run_type == 'auto'
         env:
-          TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}"
-  try-success:
-    needs:
-      - job
-    if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
-    steps:
-      - name: mark the job as a success
-        run: exit 0
-        shell: bash
-    name: bors build finished
-    runs-on: ubuntu-latest
-  try-failure:
-    needs:
-      - job
-    if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
-    steps:
-      - name: mark the job as a failure
-        run: exit 1
-        shell: bash
-    name: bors build finished
-    runs-on: ubuntu-latest
-  auto-success:
-    needs:
-      - job
-    if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
-    steps:
-      - name: mark the job as a success
-        run: exit 0
-        shell: bash
-    name: bors build finished
-    runs-on: ubuntu-latest
-  auto-failure:
-    needs:
-      - job
-    if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
-    steps:
-      - name: mark the job as a failure
-        run: exit 1
-        shell: bash
-    name: bors build finished
-    runs-on: ubuntu-latest
+          TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
diff --git a/Cargo.lock b/Cargo.lock
index 6b2593ebbb1..7e4db4fdd53 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -121,6 +121,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "annotate-snippets"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5a59f105fb9635e9eebdc1e29d53e764fa5795b9cf899a638a53e61567ef61"
+dependencies = [
+ "anstyle",
+ "unicode-width",
+]
+
+[[package]]
 name = "ansi_term"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -574,7 +584,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
 
 [[package]]
 name = "clippy"
-version = "0.1.79"
+version = "0.1.80"
 dependencies = [
  "anstream",
  "clippy_config",
@@ -595,13 +605,13 @@ dependencies = [
  "termize",
  "tokio",
  "toml 0.7.8",
- "ui_test 0.22.3",
+ "ui_test 0.23.0",
  "walkdir",
 ]
 
 [[package]]
 name = "clippy_config"
-version = "0.1.79"
+version = "0.1.80"
 dependencies = [
  "rustc-semver",
  "serde",
@@ -624,7 +634,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_lints"
-version = "0.1.79"
+version = "0.1.80"
 dependencies = [
  "arrayvec",
  "cargo_metadata 0.18.1",
@@ -649,7 +659,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_utils"
-version = "0.1.79"
+version = "0.1.80"
 dependencies = [
  "arrayvec",
  "clippy_config",
@@ -760,11 +770,9 @@ dependencies = [
  "glob",
  "home",
  "indexmap",
- "lazycell",
  "libc",
  "miow",
  "miropt-test-tools",
- "once_cell",
  "regex",
  "rustfix 0.8.1",
  "serde",
@@ -970,7 +978,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
 
 [[package]]
 name = "declare_clippy_lint"
-version = "0.1.79"
+version = "0.1.80"
 dependencies = [
  "itertools 0.12.1",
  "quote",
@@ -1257,14 +1265,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "expand-yaml-anchors"
-version = "0.1.0"
-dependencies = [
- "yaml-merge-keys",
- "yaml-rust",
-]
-
-[[package]]
 name = "expect-test"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2115,7 +2115,6 @@ dependencies = [
  "fs-err",
  "getopts",
  "jsonpath_lib",
- "once_cell",
  "regex",
  "serde_json",
  "shlex",
@@ -2152,12 +2151,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
 name = "leb128"
 version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2240,17 +2233,10 @@ name = "linkchecker"
 version = "0.1.0"
 dependencies = [
  "html5ever",
- "once_cell",
  "regex",
 ]
 
 [[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
-[[package]]
 name = "lint-docs"
 version = "0.1.0"
 dependencies = [
@@ -2499,7 +2485,6 @@ dependencies = [
  "directories",
  "getrandom",
  "jemalloc-sys",
- "lazy_static",
  "libc",
  "libffi",
  "libloading",
@@ -3343,6 +3328,7 @@ dependencies = [
 name = "run_make_support"
 version = "0.0.0"
 dependencies = [
+ "gimli",
  "object 0.34.0",
  "regex",
  "similar",
@@ -4799,12 +4785,10 @@ dependencies = [
  "arrayvec",
  "askama",
  "base64",
- "byteorder",
  "expect-test",
  "indexmap",
  "itertools 0.12.1",
  "minifier",
- "once_cell",
  "regex",
  "rustdoc-json-types",
  "serde",
@@ -5186,9 +5170,9 @@ dependencies = [
 
 [[package]]
 name = "spanned"
-version = "0.1.6"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad48ded9f0734eca7058107cc170767b8758e41e4088fb0020e7ff7ec6b0d92d"
+checksum = "ccdf4f5590b7e6fbd4f2e80d442789079a6fff7c12ef921a9de358b7b353098e"
 dependencies = [
  "bstr",
  "color-eyre",
@@ -5359,7 +5343,6 @@ version = "0.1.0"
 dependencies = [
  "build_helper",
  "glob",
- "once_cell",
 ]
 
 [[package]]
@@ -5604,7 +5587,6 @@ version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.15.4",
  "ignore",
- "lazy_static",
  "miropt-test-tools",
  "regex",
  "rustc-hash",
@@ -5928,11 +5910,11 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.22.3"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa577a42db0e211a73c069d7dbcae54bc7473a7c5535a564842cbd8a13c0441e"
+checksum = "29e5f4ffcbab82453958fbf59990e981b8e8a177dcd60c2bd8f9b52c3036a6e1"
 dependencies = [
- "annotate-snippets 0.10.2",
+ "annotate-snippets 0.11.2",
  "anyhow",
  "bstr",
  "cargo-platform",
@@ -5947,7 +5929,7 @@ dependencies = [
  "prettydiff",
  "regex",
  "rustc_version",
- "rustfix 0.6.1",
+ "rustfix 0.8.1",
  "serde",
  "serde_json",
  "spanned",
@@ -6556,26 +6538,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "yaml-merge-keys"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd236a7dc9bb598f349fe4a8754f49181fee50284daa15cd1ba652d722280004"
-dependencies = [
- "lazy_static",
- "thiserror",
- "yaml-rust",
-]
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
-
-[[package]]
 name = "yansi-term"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index bbf4ecfe61d..a601ebf4369 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,6 @@ members = [
   "src/tools/miri/cargo-miri",
   "src/tools/rustdoc-themes",
   "src/tools/unicode-table-generator",
-  "src/tools/expand-yaml-anchors",
   "src/tools/jsondocck",
   "src/tools/jsondoclint",
   "src/tools/llvm-bitcode-linker",
@@ -112,6 +111,3 @@ strip = true
 rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
 rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' }
 rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }
-
-[patch."https://github.com/rust-lang/rust-clippy"]
-clippy_lints = { path = "src/tools/clippy/clippy_lints" }
diff --git a/RELEASES.md b/RELEASES.md
index 3bd638ff64c..104ea497ba4 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,123 @@
+Version 1.78.0 (2024-05-02)
+==========================
+
+<a id="1.78.0-Language"></a>
+
+Language
+--------
+- [Stabilize `#[cfg(target_abi = ...)]`](https://github.com/rust-lang/rust/pull/119590/)
+- [Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute](https://github.com/rust-lang/rust/pull/119888/)
+- [Make async-fn-in-trait implementable with concrete signatures](https://github.com/rust-lang/rust/pull/120103/)
+- [Make matching on NaN a hard error, and remove the rest of `illegal_floating_point_literal_pattern`](https://github.com/rust-lang/rust/pull/116284/)
+- [static mut: allow mutable reference to arbitrary types, not just slices and arrays](https://github.com/rust-lang/rust/pull/117614/)
+- [Extend `invalid_reference_casting` to include references casting to bigger memory layout](https://github.com/rust-lang/rust/pull/118983/)
+- [Add `non_contiguous_range_endpoints` lint for singleton gaps after exclusive ranges](https://github.com/rust-lang/rust/pull/118879/)
+- [Add `wasm_c_abi` lint for use of older wasm-bindgen versions](https://github.com/rust-lang/rust/pull/117918/)
+  This lint currently only works when using Cargo.
+- [Update `indirect_structural_match` and `pointer_structural_match` lints to match RFC](https://github.com/rust-lang/rust/pull/120423/)
+- [Make non-`PartialEq`-typed consts as patterns a hard error](https://github.com/rust-lang/rust/pull/120805/)
+- [Split `refining_impl_trait` lint into `_reachable`, `_internal` variants](https://github.com/rust-lang/rust/pull/121720/)
+- [Remove unnecessary type inference when using associated types inside of higher ranked `where`-bounds](https://github.com/rust-lang/rust/pull/119849)
+- [Weaken eager detection of cyclic types during type inference](https://github.com/rust-lang/rust/pull/119989)
+- [`trait Trait: Auto {}`: allow upcasting from `dyn Trait` to `dyn Auto`](https://github.com/rust-lang/rust/pull/119338)
+
+<a id="1.78.0-Compiler"></a>
+
+Compiler
+--------
+
+- [Made `INVALID_DOC_ATTRIBUTES` lint deny by default](https://github.com/rust-lang/rust/pull/111505/)
+- [Increase accuracy of redundant `use` checking](https://github.com/rust-lang/rust/pull/117772/)
+- [Suggest moving definition if non-found macro_rules! is defined later](https://github.com/rust-lang/rust/pull/121130/)
+- [Lower transmutes from int to pointer type as gep on null](https://github.com/rust-lang/rust/pull/121282/)
+
+Target changes:
+
+- [Windows tier 1 targets now require at least Windows 10](https://github.com/rust-lang/rust/pull/115141/)
+  - [Enable CMPXCHG16B, SSE3, SAHF/LAHF and 128-bit Atomics in tier 1 Windows](https://github.com/rust-lang/rust/pull/120820/)
+- [Add `wasm32-wasip1` tier 2 (without host tools) target](https://github.com/rust-lang/rust/pull/120468/)
+- [Add `wasm32-wasip2` tier 3 target](https://github.com/rust-lang/rust/pull/119616/)
+- [Rename `wasm32-wasi-preview1-threads` to `wasm32-wasip1-threads`](https://github.com/rust-lang/rust/pull/122170/)
+- [Add `arm64ec-pc-windows-msvc` tier 3 target](https://github.com/rust-lang/rust/pull/119199/)
+- [Add `armv8r-none-eabihf` tier 3 target for the Cortex-R52](https://github.com/rust-lang/rust/pull/110482/)
+- [Add `loongarch64-unknown-linux-musl` tier 3 target](https://github.com/rust-lang/rust/pull/121832/)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+<a id="1.78.0-Libraries"></a>
+
+Libraries
+---------
+
+- [Bump Unicode to version 15.1.0, regenerate tables](https://github.com/rust-lang/rust/pull/120777/)
+- [Make align_offset, align_to well-behaved in all cases](https://github.com/rust-lang/rust/pull/121201/)
+- [PartialEq, PartialOrd: document expectations for transitive chains](https://github.com/rust-lang/rust/pull/115386/)
+- [Optimize away poison guards when std is built with panic=abort](https://github.com/rust-lang/rust/pull/100603/)
+- [Replace pthread `RwLock` with custom implementation](https://github.com/rust-lang/rust/pull/110211/)
+- [Implement unwind safety for Condvar on all platforms](https://github.com/rust-lang/rust/pull/121768/)
+- [Add ASCII fast-path for `char::is_grapheme_extended`](https://github.com/rust-lang/rust/pull/121138/)
+
+<a id="1.78.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`impl Read for &Stdin`](https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#impl-Read-for-%26Stdin)
+- [Accept non `'static` lifetimes for several `std::error::Error` related implementations](https://github.com/rust-lang/rust/pull/113833/)
+- [Make `impl<Fd: AsFd>` impl take `?Sized`](https://github.com/rust-lang/rust/pull/114655/)
+- [`impl From<TryReserveError> for io::Error`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#impl-From%3CTryReserveError%3E-for-Error)
+
+These APIs are now stable in const contexts:
+
+- [`Barrier::new()`](https://doc.rust-lang.org/stable/std/sync/struct.Barrier.html#method.new)
+
+<a id="1.78.0-Cargo"></a>
+
+Cargo
+-----
+
+- [Stabilize lockfile v4](https://github.com/rust-lang/cargo/pull/12852/)
+- [Respect `rust-version` when generating lockfile](https://github.com/rust-lang/cargo/pull/12861/)
+- [Control `--charset` via auto-detecting config value](https://github.com/rust-lang/cargo/pull/13337/)
+- [Support `target.<triple>.rustdocflags` officially](https://github.com/rust-lang/cargo/pull/13197/)
+- [Stabilize global cache data tracking](https://github.com/rust-lang/cargo/pull/13492/)
+
+<a id="1.78.0-Misc"></a>
+
+Misc
+----
+
+- [rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests](https://github.com/rust-lang/rust/pull/114651/)
+
+<a id="1.78.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+
+- [Many unsafe precondition checks now run for user code with debug assertions enabled](https://github.com/rust-lang/rust/pull/120594/)
+  This change helps users catch undefined behavior in their code, though the details of how much is checked are generally not stable.
+- [riscv only supports split_debuginfo=off for now](https://github.com/rust-lang/rust/pull/120518/)
+- [Consistently check bounds on hidden types of `impl Trait`](https://github.com/rust-lang/rust/pull/121679)
+- [Change equality of higher ranked types to not rely on subtyping](https://github.com/rust-lang/rust/pull/118247)
+- [When called, additionally check bounds on normalized function return type](https://github.com/rust-lang/rust/pull/118882)
+- [Expand coverage for `arithmetic_overflow` lint](https://github.com/rust-lang/rust/pull/119432/)
+
+<a id="1.78.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Update to LLVM 18](https://github.com/rust-lang/rust/pull/120055/)
+- [Build `rustc` with 1CGU on `x86_64-pc-windows-msvc`](https://github.com/rust-lang/rust/pull/112267/)
+- [Build `rustc` with 1CGU on `x86_64-apple-darwin`](https://github.com/rust-lang/rust/pull/112268/)
+- [Introduce `run-make` V2 infrastructure, a `run_make_support` library and port over 2 tests as example](https://github.com/rust-lang/rust/pull/113026/)
+- [Windows: Implement condvar, mutex and rwlock using futex](https://github.com/rust-lang/rust/pull/121956/)
+
 Version 1.77.2 (2024-04-09)
 ===========================
 
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 3584eea0f14..a95ef4c460f 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -251,7 +251,7 @@ pub trait LayoutCalculator {
         // If all the non-ZST fields have the same ABI and union ABI optimizations aren't
         // disabled, we can use that common ABI for the union as a whole.
         struct AbiMismatch;
-        let mut common_non_zst_abi_and_align = if repr.inhibit_union_abi_opt() {
+        let mut common_non_zst_abi_and_align = if repr.inhibits_union_abi_opt() {
             // Can't optimize
             Err(AbiMismatch)
         } else {
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 7439af7aed3..6a2943da4a3 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -155,7 +155,7 @@ impl ReprOptions {
     }
 
     /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
-    pub fn inhibit_union_abi_opt(&self) -> bool {
+    pub fn inhibits_union_abi_opt(&self) -> bool {
         self.c()
     }
 }
@@ -743,10 +743,20 @@ impl Align {
     }
 
     #[inline]
+    pub fn bytes_usize(self) -> usize {
+        self.bytes().try_into().unwrap()
+    }
+
+    #[inline]
     pub fn bits(self) -> u64 {
         self.bytes() * 8
     }
 
+    #[inline]
+    pub fn bits_usize(self) -> usize {
+        self.bits().try_into().unwrap()
+    }
+
     /// Computes the best alignment possible for the given offset
     /// (the largest power of two that the offset is a multiple of).
     ///
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index af246e31371..fa378e19f71 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -32,7 +32,7 @@ use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lrc;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
@@ -1390,7 +1390,7 @@ pub struct StructExpr {
 // Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ExprKind {
-    /// An array (`[a, b, c, d]`)
+    /// An array (e.g, `[a, b, c, d]`).
     Array(ThinVec<P<Expr>>),
     /// Allow anonymous constants from an inline `const` block
     ConstBlock(AnonConst),
@@ -1401,7 +1401,7 @@ pub enum ExprKind {
     /// This also represents calling the constructor of
     /// tuple-like ADTs such as tuple structs and enum variants.
     Call(P<Expr>, ThinVec<P<Expr>>),
-    /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
+    /// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
     MethodCall(Box<MethodCall>),
     /// A tuple (e.g., `(a, b, c, d)`).
     Tup(ThinVec<P<Expr>>),
@@ -1413,7 +1413,10 @@ pub enum ExprKind {
     Lit(token::Lit),
     /// A cast (e.g., `foo as f64`).
     Cast(P<Expr>, P<Ty>),
-    /// A type ascription (e.g., `42: usize`).
+    /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
+    ///
+    /// Usually not written directly in user code but
+    /// indirectly via the macro `type_ascribe!(...)`.
     Type(P<Expr>, P<Ty>),
     /// A `let pat = expr` expression that is only semantically allowed in the condition
     /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
@@ -1488,7 +1491,10 @@ pub enum ExprKind {
     /// Output of the `asm!()` macro.
     InlineAsm(P<InlineAsm>),
 
-    /// Output of the `offset_of!()` macro.
+    /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
+    ///
+    /// Usually not written directly in user code but
+    /// indirectly via the macro `core::mem::offset_of!(...)`.
     OffsetOf(P<Ty>, P<[Ident]>),
 
     /// A macro invocation; pre-expansion.
@@ -3126,6 +3132,35 @@ pub struct StaticItem {
     pub expr: Option<P<Expr>>,
 }
 
+/// A static item in `extern` block.
+// This struct is identical to StaticItem for now but it's going to have a safety attribute.
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct StaticForeignItem {
+    pub ty: P<Ty>,
+    pub mutability: Mutability,
+    pub expr: Option<P<Expr>>,
+}
+
+impl From<StaticItem> for StaticForeignItem {
+    fn from(static_item: StaticItem) -> StaticForeignItem {
+        StaticForeignItem {
+            ty: static_item.ty,
+            mutability: static_item.mutability,
+            expr: static_item.expr,
+        }
+    }
+}
+
+impl From<StaticForeignItem> for StaticItem {
+    fn from(static_item: StaticForeignItem) -> StaticItem {
+        StaticItem {
+            ty: static_item.ty,
+            mutability: static_item.mutability,
+            expr: static_item.expr,
+        }
+    }
+}
+
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ConstItem {
     pub defaultness: Defaultness,
@@ -3329,7 +3364,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum ForeignItemKind {
     /// A foreign static item (`static FOO: u8`).
-    Static(P<Ty>, Mutability, Option<P<Expr>>),
+    Static(Box<StaticForeignItem>),
     /// An foreign function.
     Fn(Box<Fn>),
     /// An foreign type.
@@ -3341,8 +3376,8 @@ pub enum ForeignItemKind {
 impl From<ForeignItemKind> for ItemKind {
     fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
         match foreign_item_kind {
-            ForeignItemKind::Static(a, b, c) => {
-                ItemKind::Static(StaticItem { ty: a, mutability: b, expr: c }.into())
+            ForeignItemKind::Static(box static_foreign_item) => {
+                ItemKind::Static(Box::new(static_foreign_item.into()))
             }
             ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
             ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
@@ -3356,8 +3391,8 @@ impl TryFrom<ItemKind> for ForeignItemKind {
 
     fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
         Ok(match item_kind {
-            ItemKind::Static(box StaticItem { ty: a, mutability: b, expr: c }) => {
-                ForeignItemKind::Static(a, b, c)
+            ItemKind::Static(box static_item) => {
+                ForeignItemKind::Static(Box::new(static_item.into()))
             }
             ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
             ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
@@ -3382,8 +3417,8 @@ mod size_asserts {
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
     static_assert_size!(Fn, 160);
-    static_assert_size!(ForeignItem, 96);
-    static_assert_size!(ForeignItemKind, 24);
+    static_assert_size!(ForeignItem, 88);
+    static_assert_size!(ForeignItemKind, 16);
     static_assert_size!(GenericArg, 24);
     static_assert_size!(GenericBound, 88);
     static_assert_size!(Generics, 40);
diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs
index f825b10f489..1723501d0fe 100644
--- a/compiler/rustc_ast/src/expand/allocator.rs
+++ b/compiler/rustc_ast/src/expand/allocator.rs
@@ -1,3 +1,4 @@
+use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{sym, Symbol};
 
 #[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)]
diff --git a/compiler/rustc_ast/src/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs
index 942347383ce..37caadd0414 100644
--- a/compiler/rustc_ast/src/expand/mod.rs
+++ b/compiler/rustc_ast/src/expand/mod.rs
@@ -1,5 +1,6 @@
 //! Definitions shared by macros / syntax extensions and e.g. `rustc_middle`.
 
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::{def_id::DefId, symbol::Ident};
 
 use crate::MetaItem;
diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs
index 805596ff00a..49910e2283d 100644
--- a/compiler/rustc_ast/src/format.rs
+++ b/compiler/rustc_ast/src/format.rs
@@ -1,6 +1,7 @@
 use crate::ptr::P;
 use crate::Expr;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 4f21ff41529..63cde3c6809 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -11,7 +11,6 @@
 #![doc(rust_logo)]
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
@@ -20,12 +19,6 @@
 #![feature(negative_impls)]
 #![feature(stmt_expr_attributes)]
 
-#[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
-extern crate tracing;
-
 pub mod util {
     pub mod case;
     pub mod classify;
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 1cceca33c17..4d28ef56df1 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -34,6 +34,10 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
     }
 }
 
+pub trait NoopVisitItemKind {
+    fn noop_visit(&mut self, visitor: &mut impl MutVisitor);
+}
+
 pub trait MutVisitor: Sized {
     /// Mutable token visiting only exists for the `macro_rules` token marker and should not be
     /// used otherwise. Token visitor would be entirely separate from the regular visitor if
@@ -90,7 +94,7 @@ pub trait MutVisitor: Sized {
     }
 
     fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
-        noop_flat_map_foreign_item(ni, self)
+        noop_flat_map_item(ni, self)
     }
 
     fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
@@ -105,16 +109,12 @@ pub trait MutVisitor: Sized {
         noop_flat_map_field_def(fd, self)
     }
 
-    fn visit_item_kind(&mut self, i: &mut ItemKind) {
-        noop_visit_item_kind(i, self);
-    }
-
     fn flat_map_trait_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
-        noop_flat_map_assoc_item(i, self)
+        noop_flat_map_item(i, self)
     }
 
     fn flat_map_impl_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
-        noop_flat_map_assoc_item(i, self)
+        noop_flat_map_item(i, self)
     }
 
     fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
@@ -1068,149 +1068,151 @@ pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
     visit_lazy_tts(tokens, vis);
 }
 
-pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
-    match kind {
-        ItemKind::ExternCrate(_orig_name) => {}
-        ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
-        ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
-            vis.visit_ty(ty);
-            visit_opt(expr, |expr| vis.visit_expr(expr));
-        }
-        ItemKind::Const(item) => {
-            visit_const_item(item, vis);
-        }
-        ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
-            visit_defaultness(defaultness, vis);
-            visit_fn_sig(sig, vis);
-            vis.visit_generics(generics);
-            visit_opt(body, |body| vis.visit_block(body));
-        }
-        ItemKind::Mod(unsafety, mod_kind) => {
-            visit_unsafety(unsafety, vis);
-            match mod_kind {
-                ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
-                    vis.visit_span(inner_span);
-                    vis.visit_span(inject_use_span);
-                    items.flat_map_in_place(|item| vis.flat_map_item(item));
+pub fn noop_visit_item_kind(kind: &mut impl NoopVisitItemKind, vis: &mut impl MutVisitor) {
+    kind.noop_visit(vis)
+}
+
+impl NoopVisitItemKind for ItemKind {
+    fn noop_visit(&mut self, vis: &mut impl MutVisitor) {
+        match self {
+            ItemKind::ExternCrate(_orig_name) => {}
+            ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
+            ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
+                vis.visit_ty(ty);
+                visit_opt(expr, |expr| vis.visit_expr(expr));
+            }
+            ItemKind::Const(item) => {
+                visit_const_item(item, vis);
+            }
+            ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+                visit_defaultness(defaultness, vis);
+                visit_fn_sig(sig, vis);
+                vis.visit_generics(generics);
+                visit_opt(body, |body| vis.visit_block(body));
+            }
+            ItemKind::Mod(unsafety, mod_kind) => {
+                visit_unsafety(unsafety, vis);
+                match mod_kind {
+                    ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => {
+                        vis.visit_span(inner_span);
+                        vis.visit_span(inject_use_span);
+                        items.flat_map_in_place(|item| vis.flat_map_item(item));
+                    }
+                    ModKind::Unloaded => {}
                 }
-                ModKind::Unloaded => {}
             }
-        }
-        ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
-        ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
-        ItemKind::TyAlias(box TyAlias {
-            defaultness, generics, where_clauses, bounds, ty, ..
-        }) => {
-            visit_defaultness(defaultness, vis);
-            vis.visit_generics(generics);
-            vis.visit_span(&mut where_clauses.before.span);
-            vis.visit_span(&mut where_clauses.after.span);
-            visit_bounds(bounds, vis);
-            visit_opt(ty, |ty| vis.visit_ty(ty));
-        }
-        ItemKind::Enum(EnumDef { variants }, generics) => {
-            variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
-            vis.visit_generics(generics);
-        }
-        ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
-            vis.visit_variant_data(variant_data);
-            vis.visit_generics(generics);
-        }
-        ItemKind::Impl(box Impl {
-            defaultness,
-            unsafety,
-            generics,
-            constness,
-            polarity,
-            of_trait,
-            self_ty,
-            items,
-        }) => {
-            visit_defaultness(defaultness, vis);
-            visit_unsafety(unsafety, vis);
-            vis.visit_generics(generics);
-            visit_constness(constness, vis);
-            visit_polarity(polarity, vis);
-            visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
-            vis.visit_ty(self_ty);
-            items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
-        }
-        ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => {
-            visit_unsafety(unsafety, vis);
-            vis.visit_generics(generics);
-            visit_bounds(bounds, vis);
-            items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
-        }
-        ItemKind::TraitAlias(generics, bounds) => {
-            vis.visit_generics(generics);
-            visit_bounds(bounds, vis);
-        }
-        ItemKind::MacCall(m) => vis.visit_mac_call(m),
-        ItemKind::MacroDef(def) => vis.visit_macro_def(def),
-        ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
-            vis.visit_id(id);
-            vis.visit_qself(qself);
-            vis.visit_path(path);
-            if let Some(rename) = rename {
-                vis.visit_ident(rename);
+            ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
+            ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
+            ItemKind::TyAlias(box TyAlias {
+                defaultness,
+                generics,
+                where_clauses,
+                bounds,
+                ty,
+                ..
+            }) => {
+                visit_defaultness(defaultness, vis);
+                vis.visit_generics(generics);
+                vis.visit_span(&mut where_clauses.before.span);
+                vis.visit_span(&mut where_clauses.after.span);
+                visit_bounds(bounds, vis);
+                visit_opt(ty, |ty| vis.visit_ty(ty));
+            }
+            ItemKind::Enum(EnumDef { variants }, generics) => {
+                variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
+                vis.visit_generics(generics);
+            }
+            ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => {
+                vis.visit_variant_data(variant_data);
+                vis.visit_generics(generics);
+            }
+            ItemKind::Impl(box Impl {
+                defaultness,
+                unsafety,
+                generics,
+                constness,
+                polarity,
+                of_trait,
+                self_ty,
+                items,
+            }) => {
+                visit_defaultness(defaultness, vis);
+                visit_unsafety(unsafety, vis);
+                vis.visit_generics(generics);
+                visit_constness(constness, vis);
+                visit_polarity(polarity, vis);
+                visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
+                vis.visit_ty(self_ty);
+                items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
+            }
+            ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => {
+                visit_unsafety(unsafety, vis);
+                vis.visit_generics(generics);
+                visit_bounds(bounds, vis);
+                items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
+            }
+            ItemKind::TraitAlias(generics, bounds) => {
+                vis.visit_generics(generics);
+                visit_bounds(bounds, vis);
             }
-            if let Some(body) = body {
-                vis.visit_block(body);
+            ItemKind::MacCall(m) => vis.visit_mac_call(m),
+            ItemKind::MacroDef(def) => vis.visit_macro_def(def),
+            ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
+                vis.visit_id(id);
+                vis.visit_qself(qself);
+                vis.visit_path(path);
+                if let Some(rename) = rename {
+                    vis.visit_ident(rename);
+                }
+                if let Some(body) = body {
+                    vis.visit_block(body);
+                }
             }
         }
     }
 }
 
-pub fn noop_flat_map_assoc_item<T: MutVisitor>(
-    mut item: P<AssocItem>,
-    visitor: &mut T,
-) -> SmallVec<[P<AssocItem>; 1]> {
-    let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut();
-    visitor.visit_id(id);
-    visitor.visit_ident(ident);
-    visitor.visit_vis(vis);
-    visit_attrs(attrs, visitor);
-    match kind {
-        AssocItemKind::Const(item) => {
-            visit_const_item(item, visitor);
-        }
-        AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
-            visit_defaultness(defaultness, visitor);
-            visitor.visit_generics(generics);
-            visit_fn_sig(sig, visitor);
-            visit_opt(body, |body| visitor.visit_block(body));
-        }
-        AssocItemKind::Type(box TyAlias {
-            defaultness,
-            generics,
-            where_clauses,
-            bounds,
-            ty,
-            ..
-        }) => {
-            visit_defaultness(defaultness, visitor);
-            visitor.visit_generics(generics);
-            visitor.visit_span(&mut where_clauses.before.span);
-            visitor.visit_span(&mut where_clauses.after.span);
-            visit_bounds(bounds, visitor);
-            visit_opt(ty, |ty| visitor.visit_ty(ty));
-        }
-        AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
-        AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
-            visitor.visit_id(id);
-            visitor.visit_qself(qself);
-            visitor.visit_path(path);
-            if let Some(rename) = rename {
-                visitor.visit_ident(rename);
+impl NoopVisitItemKind for AssocItemKind {
+    fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
+        match self {
+            AssocItemKind::Const(item) => {
+                visit_const_item(item, visitor);
             }
-            if let Some(body) = body {
-                visitor.visit_block(body);
+            AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+                visit_defaultness(defaultness, visitor);
+                visitor.visit_generics(generics);
+                visit_fn_sig(sig, visitor);
+                visit_opt(body, |body| visitor.visit_block(body));
+            }
+            AssocItemKind::Type(box TyAlias {
+                defaultness,
+                generics,
+                where_clauses,
+                bounds,
+                ty,
+                ..
+            }) => {
+                visit_defaultness(defaultness, visitor);
+                visitor.visit_generics(generics);
+                visitor.visit_span(&mut where_clauses.before.span);
+                visitor.visit_span(&mut where_clauses.after.span);
+                visit_bounds(bounds, visitor);
+                visit_opt(ty, |ty| visitor.visit_ty(ty));
+            }
+            AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
+            AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
+                visitor.visit_id(id);
+                visitor.visit_qself(qself);
+                visitor.visit_path(path);
+                if let Some(rename) = rename {
+                    visitor.visit_ident(rename);
+                }
+                if let Some(body) = body {
+                    visitor.visit_block(body);
+                }
             }
         }
     }
-    visitor.visit_span(span);
-    visit_lazy_tts(tokens, visitor);
-    smallvec![item]
 }
 
 fn visit_const_item<T: MutVisitor>(
@@ -1241,62 +1243,52 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
 }
 
 // Mutates one item into possibly many items.
-pub fn noop_flat_map_item<T: MutVisitor>(
-    mut item: P<Item>,
-    visitor: &mut T,
-) -> SmallVec<[P<Item>; 1]> {
+pub fn noop_flat_map_item<K: NoopVisitItemKind>(
+    mut item: P<Item<K>>,
+    visitor: &mut impl MutVisitor,
+) -> SmallVec<[P<Item<K>>; 1]> {
     let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
-    visitor.visit_ident(ident);
-    visit_attrs(attrs, visitor);
     visitor.visit_id(id);
-    visitor.visit_item_kind(kind);
+    visit_attrs(attrs, visitor);
     visitor.visit_vis(vis);
+    visitor.visit_ident(ident);
+    kind.noop_visit(visitor);
     visitor.visit_span(span);
     visit_lazy_tts(tokens, visitor);
-
     smallvec![item]
 }
 
-pub fn noop_flat_map_foreign_item<T: MutVisitor>(
-    mut item: P<ForeignItem>,
-    visitor: &mut T,
-) -> SmallVec<[P<ForeignItem>; 1]> {
-    let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
-    visitor.visit_id(id);
-    visitor.visit_ident(ident);
-    visitor.visit_vis(vis);
-    visit_attrs(attrs, visitor);
-    match kind {
-        ForeignItemKind::Static(ty, _, expr) => {
-            visitor.visit_ty(ty);
-            visit_opt(expr, |expr| visitor.visit_expr(expr));
-        }
-        ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
-            visit_defaultness(defaultness, visitor);
-            visitor.visit_generics(generics);
-            visit_fn_sig(sig, visitor);
-            visit_opt(body, |body| visitor.visit_block(body));
-        }
-        ForeignItemKind::TyAlias(box TyAlias {
-            defaultness,
-            generics,
-            where_clauses,
-            bounds,
-            ty,
-            ..
-        }) => {
-            visit_defaultness(defaultness, visitor);
-            visitor.visit_generics(generics);
-            visitor.visit_span(&mut where_clauses.before.span);
-            visitor.visit_span(&mut where_clauses.after.span);
-            visit_bounds(bounds, visitor);
-            visit_opt(ty, |ty| visitor.visit_ty(ty));
+impl NoopVisitItemKind for ForeignItemKind {
+    fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
+        match self {
+            ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
+                visitor.visit_ty(ty);
+                visit_opt(expr, |expr| visitor.visit_expr(expr));
+            }
+            ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
+                visit_defaultness(defaultness, visitor);
+                visitor.visit_generics(generics);
+                visit_fn_sig(sig, visitor);
+                visit_opt(body, |body| visitor.visit_block(body));
+            }
+            ForeignItemKind::TyAlias(box TyAlias {
+                defaultness,
+                generics,
+                where_clauses,
+                bounds,
+                ty,
+                ..
+            }) => {
+                visit_defaultness(defaultness, visitor);
+                visitor.visit_generics(generics);
+                visitor.visit_span(&mut where_clauses.before.span);
+                visitor.visit_span(&mut where_clauses.after.span);
+                visit_bounds(bounds, visitor);
+                visit_opt(ty, |ty| visitor.visit_ty(ty));
+            }
+            ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
         }
-        ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
     }
-    visitor.visit_span(span);
-    visit_lazy_tts(tokens, visitor);
-    smallvec![item]
 }
 
 pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index dcdd44c6041..6e946530749 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -9,7 +9,7 @@ use crate::util::case::Case;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::symbol::{kw, sym};
 #[allow(clippy::useless_attribute)] // FIXME: following use of `hidden_glob_reexports` incorrectly triggers `useless_attribute` lint.
 #[allow(hidden_glob_reexports)]
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 08d65a5ffa5..aadcfa7fed5 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -20,7 +20,7 @@ use crate::AttrVec;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::{Decodable, Encodable};
 use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index a17c7708e4a..cb73b7908c2 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -8,6 +8,7 @@ use rustc_lexer::unescape::{
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 use std::{ascii, fmt, str};
+use tracing::debug;
 
 // Escapes a string, represented as a symbol. Reuses the original symbol,
 // avoiding interning, if no changes are required.
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index d9740928f8d..1d8fd63e459 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -102,6 +102,15 @@ pub enum LifetimeCtxt {
     GenericArg,
 }
 
+pub trait WalkItemKind: Sized {
+    fn walk<'a, V: Visitor<'a>>(
+        &'a self,
+        item: &'a Item<Self>,
+        ctxt: AssocCtxt,
+        visitor: &mut V,
+    ) -> V::Result;
+}
+
 /// Each method of the `Visitor` trait is a hook to be potentially
 /// overridden. Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
@@ -120,7 +129,7 @@ pub trait Visitor<'ast>: Sized {
         Self::Result::output()
     }
     fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result {
-        walk_foreign_item(self, i)
+        walk_item(self, i)
     }
     fn visit_item(&mut self, i: &'ast Item) -> Self::Result {
         walk_item(self, i)
@@ -312,87 +321,98 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
     visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
 }
 
-pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Result {
-    try_visit!(visitor.visit_vis(&item.vis));
-    try_visit!(visitor.visit_ident(item.ident));
-    match &item.kind {
-        ItemKind::ExternCrate(_) => {}
-        ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
-        ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
-            try_visit!(visitor.visit_ty(ty));
-            visit_opt!(visitor, visit_expr, expr);
-        }
-        ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
-            try_visit!(visitor.visit_generics(generics));
-            try_visit!(visitor.visit_ty(ty));
-            visit_opt!(visitor, visit_expr, expr);
-        }
-        ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-            let kind =
-                FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
-            try_visit!(visitor.visit_fn(kind, item.span, item.id));
-        }
-        ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
-            ModKind::Loaded(items, _inline, _inner_span) => {
-                walk_list!(visitor, visit_item, items);
+impl WalkItemKind for ItemKind {
+    fn walk<'a, V: Visitor<'a>>(
+        &'a self,
+        item: &'a Item<Self>,
+        _ctxt: AssocCtxt,
+        visitor: &mut V,
+    ) -> V::Result {
+        match self {
+            ItemKind::ExternCrate(_) => {}
+            ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
+            ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
+                try_visit!(visitor.visit_ty(ty));
+                visit_opt!(visitor, visit_expr, expr);
             }
-            ModKind::Unloaded => {}
-        },
-        ItemKind::ForeignMod(foreign_module) => {
-            walk_list!(visitor, visit_foreign_item, &foreign_module.items);
-        }
-        ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
-        ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
-            try_visit!(visitor.visit_generics(generics));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
-            visit_opt!(visitor, visit_ty, ty);
-        }
-        ItemKind::Enum(enum_definition, generics) => {
-            try_visit!(visitor.visit_generics(generics));
-            try_visit!(visitor.visit_enum_def(enum_definition));
-        }
-        ItemKind::Impl(box Impl {
-            defaultness: _,
-            unsafety: _,
-            generics,
-            constness: _,
-            polarity: _,
-            of_trait,
-            self_ty,
-            items,
-        }) => {
-            try_visit!(visitor.visit_generics(generics));
-            visit_opt!(visitor, visit_trait_ref, of_trait);
-            try_visit!(visitor.visit_ty(self_ty));
-            walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
-        }
-        ItemKind::Struct(struct_definition, generics)
-        | ItemKind::Union(struct_definition, generics) => {
-            try_visit!(visitor.visit_generics(generics));
-            try_visit!(visitor.visit_variant_data(struct_definition));
-        }
-        ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
-            try_visit!(visitor.visit_generics(generics));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
-            walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
-        }
-        ItemKind::TraitAlias(generics, bounds) => {
-            try_visit!(visitor.visit_generics(generics));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
-        }
-        ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
-        ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
-        ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
-            if let Some(qself) = qself {
-                try_visit!(visitor.visit_ty(&qself.ty));
+            ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
+                try_visit!(visitor.visit_generics(generics));
+                try_visit!(visitor.visit_ty(ty));
+                visit_opt!(visitor, visit_expr, expr);
+            }
+            ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
+                let kind =
+                    FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
+                try_visit!(visitor.visit_fn(kind, item.span, item.id));
+            }
+            ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
+                ModKind::Loaded(items, _inline, _inner_span) => {
+                    walk_list!(visitor, visit_item, items);
+                }
+                ModKind::Unloaded => {}
+            },
+            ItemKind::ForeignMod(foreign_module) => {
+                walk_list!(visitor, visit_foreign_item, &foreign_module.items);
+            }
+            ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
+            ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
+                try_visit!(visitor.visit_generics(generics));
+                walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+                visit_opt!(visitor, visit_ty, ty);
+            }
+            ItemKind::Enum(enum_definition, generics) => {
+                try_visit!(visitor.visit_generics(generics));
+                try_visit!(visitor.visit_enum_def(enum_definition));
+            }
+            ItemKind::Impl(box Impl {
+                defaultness: _,
+                unsafety: _,
+                generics,
+                constness: _,
+                polarity: _,
+                of_trait,
+                self_ty,
+                items,
+            }) => {
+                try_visit!(visitor.visit_generics(generics));
+                visit_opt!(visitor, visit_trait_ref, of_trait);
+                try_visit!(visitor.visit_ty(self_ty));
+                walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
+            }
+            ItemKind::Struct(struct_definition, generics)
+            | ItemKind::Union(struct_definition, generics) => {
+                try_visit!(visitor.visit_generics(generics));
+                try_visit!(visitor.visit_variant_data(struct_definition));
+            }
+            ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => {
+                try_visit!(visitor.visit_generics(generics));
+                walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
+                walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
+            }
+            ItemKind::TraitAlias(generics, bounds) => {
+                try_visit!(visitor.visit_generics(generics));
+                walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+            }
+            ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
+            ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
+            ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
+                if let Some(qself) = qself {
+                    try_visit!(visitor.visit_ty(&qself.ty));
+                }
+                try_visit!(visitor.visit_path(path, *id));
+                visit_opt!(visitor, visit_ident, *rename);
+                visit_opt!(visitor, visit_block, body);
             }
-            try_visit!(visitor.visit_path(path, *id));
-            visit_opt!(visitor, visit_ident, *rename);
-            visit_opt!(visitor, visit_block, body);
         }
+        V::Result::output()
     }
-    walk_list!(visitor, visit_attribute, &item.attrs);
-    V::Result::output()
+}
+
+pub fn walk_item<'a, V: Visitor<'a>>(
+    visitor: &mut V,
+    item: &'a Item<impl WalkItemKind>,
+) -> V::Result {
+    walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/)
 }
 
 pub fn walk_enum_def<'a, V: Visitor<'a>>(
@@ -613,30 +633,34 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
     V::Result::output()
 }
 
-pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) -> V::Result {
-    let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
-    try_visit!(visitor.visit_vis(vis));
-    try_visit!(visitor.visit_ident(ident));
-    walk_list!(visitor, visit_attribute, attrs);
-    match kind {
-        ForeignItemKind::Static(ty, _, expr) => {
-            try_visit!(visitor.visit_ty(ty));
-            visit_opt!(visitor, visit_expr, expr);
-        }
-        ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-            let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
-            try_visit!(visitor.visit_fn(kind, span, id));
-        }
-        ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
-            try_visit!(visitor.visit_generics(generics));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
-            visit_opt!(visitor, visit_ty, ty);
-        }
-        ForeignItemKind::MacCall(mac) => {
-            try_visit!(visitor.visit_mac_call(mac));
+impl WalkItemKind for ForeignItemKind {
+    fn walk<'a, V: Visitor<'a>>(
+        &'a self,
+        item: &'a Item<Self>,
+        _ctxt: AssocCtxt,
+        visitor: &mut V,
+    ) -> V::Result {
+        let &Item { id, span, ident, ref vis, .. } = item;
+        match self {
+            ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
+                try_visit!(visitor.visit_ty(ty));
+                visit_opt!(visitor, visit_expr, expr);
+            }
+            ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
+                let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
+                try_visit!(visitor.visit_fn(kind, span, id));
+            }
+            ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
+                try_visit!(visitor.visit_generics(generics));
+                walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+                visit_opt!(visitor, visit_ty, ty);
+            }
+            ForeignItemKind::MacCall(mac) => {
+                try_visit!(visitor.visit_mac_call(mac));
+            }
         }
+        V::Result::output()
     }
-    V::Result::output()
 }
 
 pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
@@ -756,42 +780,56 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
     V::Result::output()
 }
 
+impl WalkItemKind for AssocItemKind {
+    fn walk<'a, V: Visitor<'a>>(
+        &'a self,
+        item: &'a Item<Self>,
+        ctxt: AssocCtxt,
+        visitor: &mut V,
+    ) -> V::Result {
+        let &Item { id, span, ident, ref vis, .. } = item;
+        match self {
+            AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
+                try_visit!(visitor.visit_generics(generics));
+                try_visit!(visitor.visit_ty(ty));
+                visit_opt!(visitor, visit_expr, expr);
+            }
+            AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
+                let kind =
+                    FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
+                try_visit!(visitor.visit_fn(kind, span, id));
+            }
+            AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => {
+                try_visit!(visitor.visit_generics(generics));
+                walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
+                visit_opt!(visitor, visit_ty, ty);
+            }
+            AssocItemKind::MacCall(mac) => {
+                try_visit!(visitor.visit_mac_call(mac));
+            }
+            AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
+                if let Some(qself) = qself {
+                    try_visit!(visitor.visit_ty(&qself.ty));
+                }
+                try_visit!(visitor.visit_path(path, *id));
+                visit_opt!(visitor, visit_ident, *rename);
+                visit_opt!(visitor, visit_block, body);
+            }
+        }
+        V::Result::output()
+    }
+}
+
 pub fn walk_assoc_item<'a, V: Visitor<'a>>(
     visitor: &mut V,
-    item: &'a AssocItem,
+    item: &'a Item<impl WalkItemKind>,
     ctxt: AssocCtxt,
 ) -> V::Result {
-    let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
+    let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
+    walk_list!(visitor, visit_attribute, attrs);
     try_visit!(visitor.visit_vis(vis));
     try_visit!(visitor.visit_ident(ident));
-    walk_list!(visitor, visit_attribute, attrs);
-    match kind {
-        AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
-            try_visit!(visitor.visit_generics(generics));
-            try_visit!(visitor.visit_ty(ty));
-            visit_opt!(visitor, visit_expr, expr);
-        }
-        AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
-            let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
-            try_visit!(visitor.visit_fn(kind, span, id));
-        }
-        AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => {
-            try_visit!(visitor.visit_generics(generics));
-            walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
-            visit_opt!(visitor, visit_ty, ty);
-        }
-        AssocItemKind::MacCall(mac) => {
-            try_visit!(visitor.visit_mac_call(mac));
-        }
-        AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
-            if let Some(qself) = qself {
-                try_visit!(visitor.visit_ty(&qself.ty));
-            }
-            try_visit!(visitor.visit_path(path, *id));
-            visit_opt!(visitor, visit_ident, *rename);
-            visit_opt!(visitor, visit_block, body);
-        }
-    }
+    try_visit!(kind.walk(item, ctxt, visitor));
     V::Result::output()
 }
 
diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs
index 9ff2e32f06b..b1a77639b56 100644
--- a/compiler/rustc_ast_ir/src/lib.rs
+++ b/compiler/rustc_ast_ir/src/lib.rs
@@ -3,8 +3,7 @@
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 
 #[cfg(feature = "nightly")]
-#[macro_use]
-extern crate rustc_macros;
+use rustc_macros::{Decodable, Encodable, HashStable_NoContext};
 
 pub mod visit;
 
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index 73001c9990c..10efe6fba65 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -5,6 +5,7 @@ ast_lowering_abi_specified_multiple_times =
 
 ast_lowering_arbitrary_expression_in_pattern =
     arbitrary expressions aren't allowed in patterns
+    .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression
 
 ast_lowering_argument = argument
 
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 6f70e135c72..02744d16b42 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -368,6 +368,8 @@ pub struct NeverPatternWithGuard {
 pub struct ArbitraryExpressionInPattern {
     #[primary_span]
     pub span: Span,
+    #[note(ast_lowering_pattern_from_macro_note)]
+    pub pattern_from_macro_note: bool,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 93be9b9b8cf..be6c7da4108 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -7,6 +7,7 @@ use rustc_index::IndexVec;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{Span, DUMMY_SP};
+use tracing::{debug, instrument};
 
 /// A visitor that walks over the HIR and collects `Node`s into a HIR map.
 struct NodeCollector<'a, 'hir> {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index dcce54d66c2..dcd8f5d5f15 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -20,6 +20,7 @@ use rustc_span::{DesugaringKind, Span, Symbol};
 use rustc_target::spec::abi;
 use smallvec::{smallvec, SmallVec};
 use thin_vec::ThinVec;
+use tracing::instrument;
 
 pub(super) struct ItemLowerer<'a, 'hir> {
     pub(super) tcx: TyCtxt<'hir>,
@@ -662,10 +663,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
-                ForeignItemKind::Static(t, m, _) => {
-                    let ty =
-                        self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
-                    hir::ForeignItemKind::Static(ty, *m)
+                ForeignItemKind::Static(box StaticForeignItem { ty, mutability, expr: _ }) => {
+                    let ty = self
+                        .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
+                    hir::ForeignItemKind::Static(ty, *mutability)
                 }
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
                 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c5b5acf7f32..dd8c09ce485 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -37,11 +37,7 @@
 #![feature(box_patterns)]
 #![feature(let_chains)]
 
-#[macro_use]
-extern crate tracing;
-
 use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
-
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, *};
@@ -69,6 +65,7 @@ use rustc_span::{DesugaringKind, Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 use std::collections::hash_map::Entry;
 use thin_vec::ThinVec;
+use tracing::{debug, instrument, trace};
 
 macro_rules! arena_vec {
     ($this:expr; $($x:expr),*) => (
@@ -394,7 +391,7 @@ fn index_crate<'a>(
             let def_id = self.node_id_to_def_id[&item.id];
             *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
                 AstOwner::ForeignItem(item);
-            visit::walk_foreign_item(self, item);
+            visit::walk_item(self, item);
         }
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 118a7322fbd..32de07a0755 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -339,7 +339,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ExprKind::Path(..) if allow_paths => {}
             ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
             _ => {
-                let guar = self.dcx().emit_err(ArbitraryExpressionInPattern { span: expr.span });
+                let pattern_from_macro = expr.is_approximately_pattern();
+                let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
+                    span: expr.span,
+                    pattern_from_macro_note: pattern_from_macro,
+                });
                 return self.arena.alloc(self.expr_err(expr.span, guar));
             }
         }
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index aeeb4bf9e76..7679424dceb 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -18,6 +18,7 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP};
 
 use smallvec::{smallvec, SmallVec};
+use tracing::{debug, instrument};
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     #[instrument(level = "trace", skip(self))]
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 4e3d560ce89..172e97e7271 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -632,20 +632,19 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn emit_e0568(&self, span: Span, ident: Span) {
-        self.dcx().emit_err(errors::AutoTraitBounds { span, ident });
-    }
-
     fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) {
         if let [.., last] = &bounds[..] {
             let span = ident_span.shrink_to_hi().to(last.span());
-            self.emit_e0568(span, ident_span);
+            self.dcx().emit_err(errors::AutoTraitBounds { span, ident: ident_span });
         }
     }
 
     fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) {
         if !where_clause.predicates.is_empty() {
-            self.emit_e0568(where_clause.span, ident_span);
+            // FIXME: The current diagnostic is misleading since it only talks about
+            // super trait and lifetime bounds while we should just say “boundsâ€.
+            self.dcx()
+                .emit_err(errors::AutoTraitBounds { span: where_clause.span, ident: ident_span });
         }
     }
 
@@ -1185,14 +1184,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.check_foreign_ty_genericless(generics, where_clauses);
                 self.check_foreign_item_ascii_only(fi.ident);
             }
-            ForeignItemKind::Static(_, _, body) => {
-                self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span));
+            ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability: _, expr }) => {
+                self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
                 self.check_foreign_item_ascii_only(fi.ident);
             }
             ForeignItemKind::MacCall(..) => {}
         }
 
-        visit::walk_foreign_item(self, fi)
+        visit::walk_item(self, fi)
     }
 
     // Mirrors `visit::walk_generic_args`, but tracks relevant state.
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index d86196cbaa9..e0000e354ca 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ForeignItemKind::MacCall(..) => {}
         }
 
-        visit::walk_foreign_item(self, i)
+        visit::walk_item(self, i)
     }
 
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index fa42f87786d..2128acba0ba 100644
--- a/compiler/rustc_ast_passes/src/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
@@ -21,7 +21,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
     }
     fn visit_foreign_item(&mut self, i: &ForeignItem) {
         self.count += 1;
-        walk_foreign_item(self, i)
+        walk_item(self, i)
     }
     fn visit_item(&mut self, i: &Item) {
         self.count += 1;
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 4cbdc9f256d..93400c67949 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -422,7 +422,8 @@ impl<'a> State<'a> {
                 self.print_type(ty);
             }
             ast::ExprKind::Type(expr, ty) => {
-                self.word("type_ascribe!(");
+                self.word("builtin # type_ascribe");
+                self.popen();
                 self.ibox(0);
                 self.print_expr(expr, FixupContext::default());
 
@@ -431,7 +432,7 @@ impl<'a> State<'a> {
                 self.print_type(ty);
 
                 self.end();
-                self.word(")");
+                self.pclose();
             }
             ast::ExprKind::Let(pat, scrutinee, _, _) => {
                 self.print_let(pat, scrutinee, fixup);
@@ -488,7 +489,7 @@ impl<'a> State<'a> {
                         self.space();
                     }
                     MatchKind::Postfix => {
-                        self.print_expr_as_cond(expr);
+                        self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
                         self.word_nbsp(".match");
                     }
                 }
@@ -657,15 +658,15 @@ impl<'a> State<'a> {
                 );
             }
             ast::ExprKind::InlineAsm(a) => {
-                // FIXME: This should have its own syntax, distinct from a macro invocation.
+                // FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`.
                 self.word("asm!");
                 self.print_inline_asm(a);
             }
             ast::ExprKind::FormatArgs(fmt) => {
-                // FIXME: This should have its own syntax, distinct from a macro invocation.
+                // FIXME: Print `builtin # format_args` once macro `format_args` uses `builtin_syntax`.
                 self.word("format_args!");
                 self.popen();
-                self.rbox(0, Inconsistent);
+                self.ibox(0);
                 self.word(reconstruct_format_args_template_string(&fmt.template));
                 for arg in fmt.arguments.all_args() {
                     self.word_space(",");
@@ -677,7 +678,7 @@ impl<'a> State<'a> {
             ast::ExprKind::OffsetOf(container, fields) => {
                 self.word("builtin # offset_of");
                 self.popen();
-                self.rbox(0, Inconsistent);
+                self.ibox(0);
                 self.print_type(container);
                 self.word(",");
                 self.space();
@@ -690,8 +691,8 @@ impl<'a> State<'a> {
                         self.print_ident(field);
                     }
                 }
-                self.pclose();
                 self.end();
+                self.pclose();
             }
             ast::ExprKind::MacCall(m) => self.print_mac(m),
             ast::ExprKind::Paren(e) => {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 10886aace53..61398f7d605 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -30,15 +30,17 @@ impl<'a> State<'a> {
             ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
                 self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
             }
-            ast::ForeignItemKind::Static(ty, mutbl, body) => self.print_item_const(
-                ident,
-                Some(*mutbl),
-                &ast::Generics::default(),
-                ty,
-                body.as_deref(),
-                vis,
-                ast::Defaultness::Final,
-            ),
+            ast::ForeignItemKind::Static(box ast::StaticForeignItem { ty, mutability, expr }) => {
+                self.print_item_const(
+                    ident,
+                    Some(*mutability),
+                    &ast::Generics::default(),
+                    ty,
+                    expr.as_deref(),
+                    vis,
+                    ast::Defaultness::Final,
+                )
+            }
             ast::ForeignItemKind::TyAlias(box ast::TyAlias {
                 defaultness,
                 generics,
@@ -236,6 +238,7 @@ impl<'a> State<'a> {
                 self.bclose(item.span, empty);
             }
             ast::ItemKind::GlobalAsm(asm) => {
+                // FIXME: Print `builtin # global_asm` once macro `global_asm` uses `builtin_syntax`.
                 self.head(visibility_qualified(&item.vis, "global_asm!"));
                 self.print_inline_asm(asm);
                 self.word(";");
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 1c2077372e1..c08bf287733 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -6,7 +6,7 @@ use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedM
 use rustc_ast_pretty::pprust;
 use rustc_errors::ErrorGuaranteed;
 use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_session::config::ExpectedValues;
 use rustc_session::lint::builtin::UNEXPECTED_CFGS;
 use rustc_session::lint::BuiltinLintDiag;
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index dd87a5c4dc3..c61b7ea6d82 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -9,9 +9,6 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 
-#[macro_use]
-extern crate rustc_macros;
-
 mod builtin;
 mod session_diagnostics;
 
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 0ad7bd6e17e..303909de343 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -2,7 +2,7 @@ use std::num::IntErrorKind;
 
 use rustc_ast as ast;
 use rustc_errors::{codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
 
 use crate::fluent_generated as fluent;
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index af5f7571074..3e6d0311b27 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -6,6 +6,7 @@ use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::traversal;
 use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{self, Body, Local, Location};
+use rustc_middle::span_bug;
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::move_paths::MoveData;
 use std::fmt;
@@ -109,9 +110,7 @@ impl LocalsStateAtExit {
             has_storage_dead.visit_body(body);
             let mut has_storage_dead_or_moved = has_storage_dead.0;
             for move_out in &move_data.moves {
-                if let Some(index) = move_data.base_local(move_out.path) {
-                    has_storage_dead_or_moved.insert(index);
-                }
+                has_storage_dead_or_moved.insert(move_data.base_local(move_out.path));
             }
             LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved }
         }
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 6b576ba3c4c..622feb4e4c7 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -2,6 +2,7 @@
 #![allow(rustc::untranslatable_diagnostic)]
 
 use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxt};
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index 6fd80d005d9..1f0b0981c8f 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -1,3 +1,4 @@
+use rustc_middle::bug;
 use rustc_middle::mir::visit::{
     MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
 };
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index da58db57525..6c82dd1489c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -13,6 +13,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_block, walk_expr, Map, Visitor};
 use rustc_hir::{CoroutineDesugaring, PatField};
 use rustc_hir::{CoroutineKind, CoroutineSource, LangItem};
+use rustc_middle::bug;
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 6224cda1b16..0b4018a23ce 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -12,6 +12,7 @@ use rustc_hir::CoroutineKind;
 use rustc_index::IndexSlice;
 use rustc_infer::infer::BoundRegionConversionTime;
 use rustc_infer::traits::{FulfillmentErrorCode, SelectionError};
+use rustc_middle::bug;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
     AggregateKind, CallSource, ConstOperand, FakeReadCause, Local, LocalInfo, LocalKind, Location,
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 288b846daf5..1d844c3d6a2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -4,6 +4,7 @@
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{CaptureBy, ExprKind, HirId, Node};
+use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty};
 use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 8b314217190..5d74a01aa20 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -7,6 +7,7 @@ use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, BindingMode, ByRef, Node};
 use rustc_infer::traits;
+use rustc_middle::bug;
 use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
 use rustc_middle::ty::{self, InstanceDef, ToPredicate, Ty, TyCtxt};
 use rustc_middle::{
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 2fe75fe2a2b..d8d582b0ad1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -18,6 +18,7 @@ use rustc_infer::infer::{
     error_reporting::unexpected_hidden_region_diagnostic,
     NllRegionVariableOrigin, RelateParamBound,
 };
+use rustc_middle::bug;
 use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
 use rustc_middle::ty::GenericArgs;
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index cda61360404..28c5c505f79 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -11,6 +11,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_middle::ty::print::RegionHighlightMode;
 use rustc_middle::ty::{self, RegionVid, Ty};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 60037d28f62..47c83e0bb2b 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -4,7 +4,6 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(let_chains)]
@@ -15,8 +14,6 @@
 #![feature(try_blocks)]
 
 #[macro_use]
-extern crate rustc_middle;
-#[macro_use]
 extern crate tracing;
 
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -33,6 +30,7 @@ use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::UNUSED_MUT;
 use rustc_span::{Span, Symbol};
 use rustc_target::abi::FieldIdx;
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index c559f9d5748..ad3c3e6d079 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -54,6 +54,7 @@ use crate::ArtificialField;
 use crate::Overlap;
 use crate::{AccessDepth, Deep, Shallow};
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::mir::{
     Body, BorrowKind, FakeBorrowKind, MutBorrowKind, Place, PlaceElem, PlaceRef, ProjectionElem,
 };
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index de469080d14..a1e59977ede 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::graph::dominators::Dominators;
+use rustc_middle::bug;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{
     self, BasicBlock, Body, FakeBorrowKind, Location, NonDivergingIntrinsic, Place, Rvalue,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index dd75548a15d..78465ad7975 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -11,6 +11,7 @@ use rustc_index::{IndexSlice, IndexVec};
 use rustc_infer::infer::outlives::test_type_match;
 use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
 use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
+use rustc_middle::bug;
 use rustc_middle::mir::{
     BasicBlock, Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy,
     ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint,
diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs
index a950f10787b..49d3f7381d9 100644
--- a/compiler/rustc_borrowck/src/type_check/canonical.rs
+++ b/compiler/rustc_borrowck/src/type_check/canonical.rs
@@ -2,6 +2,7 @@ use std::fmt;
 
 use rustc_errors::ErrorGuaranteed;
 use rustc_infer::infer::canonical::Canonical;
+use rustc_middle::bug;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use rustc_span::def_id::DefId;
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index de75a9857f8..5aa8fe21381 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -4,6 +4,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
 use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
+use rustc_middle::bug;
 use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index 51ae7d14e43..38ec9f7678e 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -2,6 +2,7 @@ use itertools::{Either, Itertools};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::visit::{TyContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location, SourceInfo};
+use rustc_middle::span_bug;
 use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
 use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 61fa8466674..b67c5d85818 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -33,6 +33,7 @@ use rustc_middle::ty::{
     OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
 };
 use rustc_middle::ty::{GenericArgsRef, UserArgs};
+use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::points::DenseLocationMap;
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::source_map::Spanned;
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index d67ede57e78..5e4b3e532c4 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -5,6 +5,7 @@ use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases};
 use rustc_infer::traits::{Obligation, PredicateObligations};
 use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::span_bug;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::fold::FnMutDelegate;
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 9c65f64b03f..070238fc378 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -27,6 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{kw, sym};
 use rustc_span::Symbol;
 use std::iter;
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 2a5bc58af3b..0f158990319 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -118,6 +118,8 @@ builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Un
 
 builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
 
+builtin_macros_expected_comma_in_list = expected token: `,`
+
 builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
 
 builtin_macros_expected_register_class_or_explicit_register = expected register class or explicit register
@@ -219,12 +221,16 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive
 builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
     .help = consider a manual implementation of `Default`
 
+builtin_macros_only_one_argument = {$name} takes 1 argument
+
 builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
 
 builtin_macros_requires_cfg_pattern =
     macro requires a cfg-pattern as an argument
     .label = cfg-pattern required
 
+builtin_macros_takes_no_arguments = {$name} takes no arguments
+
 builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
     .label = `{$kind}` because of this
 
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index bc94e0b972b..064cf7d7f0f 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -9,7 +9,7 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand(
+pub(crate) fn expand(
     ecx: &mut ExtCtxt<'_>,
     _span: Span,
     meta_item: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 137ac441579..49b1b8cf992 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -1,3 +1,5 @@
+use crate::errors;
+use crate::util::expr_to_spanned_string;
 use ast::token::IdentIsRaw;
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
@@ -16,8 +18,6 @@ use rustc_span::{ErrorGuaranteed, InnerSpan, Span};
 use rustc_target::asm::InlineAsmArch;
 use smallvec::smallvec;
 
-use crate::errors;
-
 pub struct AsmArgs {
     pub templates: Vec<P<ast::Expr>>,
     pub operands: Vec<(ast::InlineAsmOperand, Span)>,
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index d200179f3a0..c75050f2701 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -15,7 +15,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use thin_vec::thin_vec;
 
-pub fn expand_assert<'cx>(
+pub(crate) fn expand_assert<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     span: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 5dc9bbacd06..827719d7944 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -11,7 +11,7 @@ use rustc_errors::PResult;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
 use rustc_span::Span;
 
-pub fn expand_cfg(
+pub(crate) fn expand_cfg(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 93f7d09546b..5f63a8ae0a8 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -18,6 +18,7 @@ use rustc_session::Session;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use smallvec::SmallVec;
+use tracing::instrument;
 
 pub(crate) fn expand(
     ecx: &mut ExtCtxt<'_>,
@@ -246,18 +247,18 @@ impl MutVisitor for CfgEval<'_, '_> {
     }
 
     fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
-        mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
+        mut_visit::noop_flat_map_item(configure!(self, item), self)
     }
 
     fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
-        mut_visit::noop_flat_map_assoc_item(configure!(self, item), self)
+        mut_visit::noop_flat_map_item(configure!(self, item), self)
     }
 
     fn flat_map_foreign_item(
         &mut self,
         foreign_item: P<ast::ForeignItem>,
     ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
-        mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self)
+        mut_visit::noop_flat_map_item(configure!(self, foreign_item), self)
     }
 
     fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index 2f2a87fc9aa..a08e8b2819b 100644
--- a/compiler/rustc_builtin_macros/src/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
@@ -1,11 +1,11 @@
 // The compiler code necessary to support the compile_error! extension.
 
+use crate::util::get_single_str_from_tts;
 use rustc_ast::tokenstream::TokenStream;
-use rustc_expand::base::get_single_str_from_tts;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
 use rustc_span::Span;
 
-pub fn expand_compile_error<'cx>(
+pub(crate) fn expand_compile_error<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 93a7ac05a9b..15af79ef67d 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -1,13 +1,12 @@
+use crate::errors;
+use crate::util::get_exprs_from_tts;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{ExprKind, LitKind, UnOp};
-use rustc_expand::base::get_exprs_from_tts;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
 use rustc_session::errors::report_lit_error;
 use rustc_span::symbol::Symbol;
 
-use crate::errors;
-
-pub fn expand_concat(
+pub(crate) fn expand_concat(
     cx: &mut ExtCtxt<'_>,
     sp: rustc_span::Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 45fec294578..3130870df41 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,11 +1,10 @@
+use crate::errors;
+use crate::util::get_exprs_from_tts;
 use rustc_ast::{ptr::P, token, tokenstream::TokenStream, ExprKind, LitIntType, LitKind, UintTy};
-use rustc_expand::base::get_exprs_from_tts;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
 use rustc_session::errors::report_lit_error;
 use rustc_span::{ErrorGuaranteed, Span};
 
-use crate::errors;
-
 /// Emits errors for literal expressions that are invalid inside and outside of an array.
 fn invalid_type_err(
     cx: &ExtCtxt<'_>,
@@ -108,7 +107,7 @@ fn handle_array_element(
     None
 }
 
-pub fn expand_concat_bytes(
+pub(crate) fn expand_concat_bytes(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 3ddb0ae45b5..13729a9d250 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -8,7 +8,7 @@ use rustc_span::Span;
 
 use crate::errors;
 
-pub fn expand_concat_idents<'cx>(
+pub(crate) fn expand_concat_idents<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 4f412cf79d9..d14858e5c1d 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -3,14 +3,18 @@ use crate::errors;
 
 use rustc_ast as ast;
 use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
-use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
+use rustc_expand::base::{
+    Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
+};
 use rustc_feature::AttributeTemplate;
 use rustc_parse::validate_attr;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{ErrorGuaranteed, Span};
 
-pub(crate) struct Expander(pub bool);
+pub(crate) struct Expander {
+    pub is_const: bool,
+}
 
 impl MultiItemModifier for Expander {
     fn expand(
@@ -58,7 +62,12 @@ impl MultiItemModifier for Expander {
                                 report_path_args(sess, meta);
                                 meta.path.clone()
                             })
-                            .map(|path| (path, dummy_annotatable(), None, self.0))
+                            .map(|path| DeriveResolution {
+                                path,
+                                item: dummy_annotatable(),
+                                exts: None,
+                                is_const: self.is_const,
+                            })
                             .collect()
                     }
                     _ => vec![],
@@ -67,15 +76,15 @@ impl MultiItemModifier for Expander {
                 // Do not configure or clone items unless necessary.
                 match &mut resolutions[..] {
                     [] => {}
-                    [(_, first_item, ..), others @ ..] => {
-                        *first_item = cfg_eval(
+                    [first, others @ ..] => {
+                        first.item = cfg_eval(
                             sess,
                             features,
                             item.clone(),
                             ecx.current_expansion.lint_node_id,
                         );
-                        for (_, item, _, _) in others {
-                            *item = first_item.clone();
+                        for other in others {
+                            other.item = first.item.clone();
                         }
                     }
                 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 26ef3da3a91..97e2344ff30 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -5,7 +5,7 @@ use rustc_ast::MetaItem;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::Span;
 
-pub fn expand_deriving_copy(
+pub(crate) fn expand_deriving_copy(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
@@ -28,7 +28,7 @@ pub fn expand_deriving_copy(
     trait_def.expand(cx, mitem, item, push);
 }
 
-pub fn expand_deriving_const_param_ty(
+pub(crate) fn expand_deriving_const_param_ty(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index cb1c9ef90bd..abcb402a46f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_clone(
+pub(crate) fn expand_deriving_clone(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 45c4467a109..53a15131605 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -9,7 +9,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_eq(
+pub(crate) fn expand_deriving_eq(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 1d7a69540ab..8470d466a23 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 use thin_vec::thin_vec;
 
-pub fn expand_deriving_ord(
+pub(crate) fn expand_deriving_ord(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
@@ -39,7 +39,7 @@ pub fn expand_deriving_ord(
     trait_def.expand(cx, mitem, item, push)
 }
 
-pub fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
     let test_id = Ident::new(sym::cmp, span);
     let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 234918ae429..dc73caa4ad5 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use thin_vec::thin_vec;
 
-pub fn expand_deriving_partial_eq(
+pub(crate) fn expand_deriving_partial_eq(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 63311c897ab..006e5a3d268 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 use thin_vec::thin_vec;
 
-pub fn expand_deriving_partial_ord(
+pub(crate) fn expand_deriving_partial_ord(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 8b681db9670..57ec0435e3e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_debug(
+pub(crate) fn expand_deriving_debug(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index 34798ab0a17..e9851c87aea 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -10,7 +10,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_rustc_decodable(
+pub(crate) fn expand_deriving_rustc_decodable(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 328770ce10d..bf92ddb3370 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -12,7 +12,7 @@ use rustc_span::{ErrorGuaranteed, Span};
 use smallvec::SmallVec;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_default(
+pub(crate) fn expand_deriving_default(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 2e5f1173825..3bd74d8d019 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -94,7 +94,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand_deriving_rustc_encodable(
+pub(crate) fn expand_deriving_rustc_encodable(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 85d54e9257d..52c1ba1757b 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -174,8 +174,8 @@
 //! )
 //! ```
 
-pub use StaticFields::*;
-pub use SubstructureFields::*;
+pub(crate) use StaticFields::*;
+pub(crate) use SubstructureFields::*;
 
 use crate::{deriving, errors};
 use rustc_ast::ptr::P;
@@ -195,9 +195,9 @@ use std::vec;
 use thin_vec::{thin_vec, ThinVec};
 use ty::{Bounds, Path, Ref, Self_, Ty};
 
-pub mod ty;
+pub(crate) mod ty;
 
-pub struct TraitDef<'a> {
+pub(crate) struct TraitDef<'a> {
     /// The span for the current #[derive(Foo)] header.
     pub span: Span,
 
@@ -224,7 +224,7 @@ pub struct TraitDef<'a> {
     pub is_const: bool,
 }
 
-pub struct MethodDef<'a> {
+pub(crate) struct MethodDef<'a> {
     /// name of the method
     pub name: Symbol,
     /// List of generics, e.g., `R: rand::Rng`
@@ -248,7 +248,7 @@ pub struct MethodDef<'a> {
 
 /// How to handle fieldless enum variants.
 #[derive(PartialEq)]
-pub enum FieldlessVariantsStrategy {
+pub(crate) enum FieldlessVariantsStrategy {
     /// Combine fieldless variants into a single match arm.
     /// This assumes that relevant information has been handled
     /// by looking at the enum's discriminant.
@@ -263,7 +263,7 @@ pub enum FieldlessVariantsStrategy {
 }
 
 /// All the data about the data structure/method being derived upon.
-pub struct Substructure<'a> {
+pub(crate) struct Substructure<'a> {
     /// ident of self
     pub type_ident: Ident,
     /// Verbatim access to any non-selflike arguments, i.e. arguments that
@@ -273,7 +273,7 @@ pub struct Substructure<'a> {
 }
 
 /// Summary of the relevant parts of a struct/enum field.
-pub struct FieldInfo {
+pub(crate) struct FieldInfo {
     pub span: Span,
     /// None for tuple structs/normal enum variants, Some for normal
     /// structs/struct enum variants.
@@ -287,13 +287,13 @@ pub struct FieldInfo {
 }
 
 #[derive(Copy, Clone)]
-pub enum IsTuple {
+pub(crate) enum IsTuple {
     No,
     Yes,
 }
 
 /// Fields for a static method
-pub enum StaticFields {
+pub(crate) enum StaticFields {
     /// Tuple and unit structs/enum variants like this.
     Unnamed(Vec<Span>, IsTuple),
     /// Normal structs/struct variants.
@@ -301,7 +301,7 @@ pub enum StaticFields {
 }
 
 /// A summary of the possible sets of fields.
-pub enum SubstructureFields<'a> {
+pub(crate) enum SubstructureFields<'a> {
     /// A non-static method where `Self` is a struct.
     Struct(&'a ast::VariantData, Vec<FieldInfo>),
 
@@ -329,10 +329,10 @@ pub enum SubstructureFields<'a> {
 
 /// Combine the values of all the fields together. The last argument is
 /// all the fields of all the structures.
-pub type CombineSubstructureFunc<'a> =
+pub(crate) type CombineSubstructureFunc<'a> =
     Box<dyn FnMut(&ExtCtxt<'_>, Span, &Substructure<'_>) -> BlockOrExpr + 'a>;
 
-pub fn combine_substructure(
+pub(crate) fn combine_substructure(
     f: CombineSubstructureFunc<'_>,
 ) -> RefCell<CombineSubstructureFunc<'_>> {
     RefCell::new(f)
@@ -349,7 +349,7 @@ struct TypeParameter {
 /// avoiding the insertion of any unnecessary blocks.
 ///
 /// The statements come before the expression.
-pub struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
+pub(crate) struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>);
 
 impl BlockOrExpr {
     pub fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr {
@@ -1647,7 +1647,7 @@ impl<'a> TraitDef<'a> {
 /// The function passed to `cs_fold` is called repeatedly with a value of this
 /// type. It describes one part of the code generation. The result is always an
 /// expression.
-pub enum CsFold<'a> {
+pub(crate) enum CsFold<'a> {
     /// The basic case: a field expression for one or more selflike args. E.g.
     /// for `PartialEq::eq` this is something like `self.x == other.x`.
     Single(&'a FieldInfo),
@@ -1662,7 +1662,7 @@ pub enum CsFold<'a> {
 
 /// Folds over fields, combining the expressions for each field in a sequence.
 /// Statics may not be folded over.
-pub fn cs_fold<F>(
+pub(crate) fn cs_fold<F>(
     use_foldl: bool,
     cx: &ExtCtxt<'_>,
     trait_span: Span,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 18883324683..f01d586033e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -1,7 +1,7 @@
 //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
 //! when specifying impls to be derived.
 
-pub use Ty::*;
+pub(crate) use Ty::*;
 
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind};
@@ -14,14 +14,14 @@ use thin_vec::ThinVec;
 /// A path, e.g., `::std::option::Option::<i32>` (global). Has support
 /// for type parameters.
 #[derive(Clone)]
-pub struct Path {
+pub(crate) struct Path {
     path: Vec<Symbol>,
     params: Vec<Box<Ty>>,
     kind: PathKind,
 }
 
 #[derive(Clone)]
-pub enum PathKind {
+pub(crate) enum PathKind {
     Local,
     Global,
     Std,
@@ -72,7 +72,7 @@ impl Path {
 
 /// A type. Supports pointers, Self, and literals.
 #[derive(Clone)]
-pub enum Ty {
+pub(crate) enum Ty {
     Self_,
     /// A reference.
     Ref(Box<Ty>, ast::Mutability),
@@ -83,7 +83,7 @@ pub enum Ty {
     Unit,
 }
 
-pub fn self_ref() -> Ty {
+pub(crate) fn self_ref() -> Ty {
     Ref(Box::new(Self_), ast::Mutability::Not)
 }
 
@@ -163,7 +163,7 @@ fn mk_ty_param(
 
 /// Bounds on type parameters.
 #[derive(Clone)]
-pub struct Bounds {
+pub(crate) struct Bounds {
     pub bounds: Vec<(Symbol, Vec<Path>)>,
 }
 
@@ -196,7 +196,7 @@ impl Bounds {
     }
 }
 
-pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
+pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
     // This constructs a fresh `self` path.
     let self_path = cx.expr_self(span);
     let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 41e27f65586..dcd92819865 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 use thin_vec::thin_vec;
 
-pub fn expand_deriving_hash(
+pub(crate) fn expand_deriving_hash(
     cx: &ExtCtxt<'_>,
     span: Span,
     mitem: &MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 9f786d22c93..d6e2d1d4d07 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -20,24 +20,24 @@ macro path_std($($x:tt)*) {
     generic::ty::Path::new( pathvec_std!( $($x)* ) )
 }
 
-pub mod bounds;
-pub mod clone;
-pub mod debug;
-pub mod decodable;
-pub mod default;
-pub mod encodable;
-pub mod hash;
+pub(crate) mod bounds;
+pub(crate) mod clone;
+pub(crate) mod debug;
+pub(crate) mod decodable;
+pub(crate) mod default;
+pub(crate) mod encodable;
+pub(crate) mod hash;
 
 #[path = "cmp/eq.rs"]
-pub mod eq;
+pub(crate) mod eq;
 #[path = "cmp/ord.rs"]
-pub mod ord;
+pub(crate) mod ord;
 #[path = "cmp/partial_eq.rs"]
-pub mod partial_eq;
+pub(crate) mod partial_eq;
 #[path = "cmp/partial_ord.rs"]
-pub mod partial_ord;
+pub(crate) mod partial_ord;
 
-pub mod generic;
+pub(crate) mod generic;
 
 pub(crate) type BuiltinDeriveFn =
     fn(&ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index bb3c83e8c0e..cc385bade47 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -16,7 +16,7 @@ use rustc_span::Span;
 ///
 /// `$crate` will refer to either the `std` or `core` crate depending on which
 /// one we're expanding from.
-pub fn expand_panic<'cx>(
+pub(crate) fn expand_panic<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -29,7 +29,7 @@ pub fn expand_panic<'cx>(
 /// - `$crate::panic::unreachable_2015!(...)` or
 /// - `$crate::panic::unreachable_2021!(...)`
 /// depending on the edition.
-pub fn expand_unreachable<'cx>(
+pub(crate) fn expand_unreachable<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -69,7 +69,7 @@ fn expand<'cx>(
     ))
 }
 
-pub fn use_panic_2021(mut span: Span) -> bool {
+pub(crate) fn use_panic_2021(mut span: Span) -> bool {
     // To determine the edition, we check the first span up the expansion
     // stack that does not have #[allow_internal_unstable(edition_panic)].
     // (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.)
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 93873045943..b03e14cf263 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -3,10 +3,11 @@
 // interface.
 //
 
+use crate::errors;
+use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts};
 use rustc_ast::token::{self, LitKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability};
-use rustc_expand::base::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts};
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
@@ -14,8 +15,6 @@ use std::env;
 use std::env::VarError;
 use thin_vec::thin_vec;
 
-use crate::errors;
-
 fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result<Symbol, VarError> {
     let var = var.as_str();
     if let Some(value) = cx.sess.opts.logical_env.get(var) {
@@ -26,7 +25,7 @@ fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result<Symbol, VarError
     Ok(Symbol::intern(&env::var(var)?))
 }
 
-pub fn expand_option_env<'cx>(
+pub(crate) fn expand_option_env<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -66,7 +65,7 @@ pub fn expand_option_env<'cx>(
     ExpandResult::Ready(MacEager::expr(e))
 }
 
-pub fn expand_env<'cx>(
+pub(crate) fn expand_env<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 9078dc07a31..d157703723b 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -579,7 +579,7 @@ pub(crate) struct FormatUnknownTrait<'a> {
     style = "tool-only",
     applicability = "maybe-incorrect"
 )]
-pub struct FormatUnknownTraitSugg {
+pub(crate) struct FormatUnknownTraitSugg {
     #[primary_span]
     pub span: Span,
     pub fmt: &'static str,
@@ -842,3 +842,26 @@ pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
     #[primary_span]
     pub(crate) span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_expected_comma_in_list)]
+pub(crate) struct ExpectedCommaInList {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_only_one_argument)]
+pub(crate) struct OnlyOneArgument<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_takes_no_arguments)]
+pub(crate) struct TakesNoArguments<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: &'a str,
+}
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 51d6058a744..2c717661a1c 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -1,3 +1,5 @@
+use crate::errors;
+use crate::util::expr_to_spanned_string;
 use parse::Position::ArgumentNamed;
 use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
@@ -10,14 +12,13 @@ use rustc_ast::{
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans};
 use rustc_expand::base::*;
+use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
+use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
 use rustc_parse::parser::Recovered;
 use rustc_parse_format as parse;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
 
-use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
-use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
-
 // The format_args!() macro is expanded in three steps:
 //  1. First, `parse_args` will parse the `(literal, arg, arg, name=arg, name=arg)` syntax,
 //     but doesn't parse the template (the literal) itself.
@@ -38,8 +39,6 @@ enum PositionUsedAs {
 }
 use PositionUsedAs::*;
 
-use crate::errors;
-
 #[derive(Debug)]
 struct MacroInput {
     fmtstr: P<Expr>,
@@ -1001,7 +1000,7 @@ fn expand_format_args_impl<'cx>(
     })
 }
 
-pub fn expand_format_args<'cx>(
+pub(crate) fn expand_format_args<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -1009,7 +1008,7 @@ pub fn expand_format_args<'cx>(
     expand_format_args_impl(ecx, sp, tts, false)
 }
 
-pub fn expand_format_args_nl<'cx>(
+pub(crate) fn expand_format_args_nl<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 099defd511b..a1630ad1379 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -12,7 +12,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use thin_vec::{thin_vec, ThinVec};
 
-pub fn expand(
+pub(crate) fn expand(
     ecx: &mut ExtCtxt<'_>,
     _span: Span,
     meta_item: &ast::MetaItem,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 1b4c6041294..744c7f9d090 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -19,11 +19,7 @@
 
 extern crate proc_macro;
 
-#[macro_use]
-extern crate tracing;
-
 use crate::deriving::*;
-
 use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
 use rustc_expand::proc_macro::BangProcMacro;
 use rustc_span::symbol::sym;
@@ -50,13 +46,13 @@ mod pattern_type;
 mod source_util;
 mod test;
 mod trace_macros;
-mod util;
 
 pub mod asm;
 pub mod cmdline_attrs;
 pub mod proc_macro_harness;
 pub mod standard_library_imports;
 pub mod test_harness;
+pub mod util;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
@@ -109,8 +105,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         bench: test::expand_bench,
         cfg_accessible: cfg_accessible::Expander,
         cfg_eval: cfg_eval::expand,
-        derive: derive::Expander(false),
-        derive_const: derive::Expander(true),
+        derive: derive::Expander { is_const: false },
+        derive_const: derive::Expander { is_const: true },
         global_allocator: global_allocator::expand,
         test: test::expand_test,
         test_case: test::expand_test_case,
diff --git a/compiler/rustc_builtin_macros/src/log_syntax.rs b/compiler/rustc_builtin_macros/src/log_syntax.rs
index 288a475ac24..205f21ae7c9 100644
--- a/compiler/rustc_builtin_macros/src/log_syntax.rs
+++ b/compiler/rustc_builtin_macros/src/log_syntax.rs
@@ -2,7 +2,7 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
 
-pub fn expand_log_syntax<'cx>(
+pub(crate) fn expand_log_syntax<'cx>(
     _cx: &'cx mut ExtCtxt<'_>,
     sp: rustc_span::Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs
index 54039c2c538..31f5656df13 100644
--- a/compiler/rustc_builtin_macros/src/pattern_type.rs
+++ b/compiler/rustc_builtin_macros/src/pattern_type.rs
@@ -3,7 +3,7 @@ use rustc_errors::PResult;
 use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
 use rustc_span::{sym, Span};
 
-pub fn expand<'cx>(
+pub(crate) fn expand<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index c79ae716806..47b2ee975ca 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -1,3 +1,6 @@
+use crate::util::{
+    check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
+};
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::token;
@@ -5,11 +8,8 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::sync::Lrc;
 use rustc_expand::base::{
-    check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
-    resolve_path,
+    resolve_path, DummyResult, ExpandResult, ExtCtxt, MacEager, MacResult, MacroExpanderResult,
 };
-use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt};
-use rustc_expand::base::{MacEager, MacResult, MacroExpanderResult};
 use rustc_expand::module::DirOwnership;
 use rustc_parse::new_parser_from_file;
 use rustc_parse::parser::{ForceCollect, Parser};
@@ -26,7 +26,7 @@ use std::rc::Rc;
 // a given file into the current one.
 
 /// line!(): expands to the current line number
-pub fn expand_line(
+pub(crate) fn expand_line(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -41,7 +41,7 @@ pub fn expand_line(
 }
 
 /* column!(): expands to the current column number */
-pub fn expand_column(
+pub(crate) fn expand_column(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -58,7 +58,7 @@ pub fn expand_column(
 /// file!(): expands to the current filename */
 /// The source_file (`loc.file`) contains a bunch more information we could spit
 /// out if we wanted.
-pub fn expand_file(
+pub(crate) fn expand_file(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -78,7 +78,7 @@ pub fn expand_file(
     )))
 }
 
-pub fn expand_stringify(
+pub(crate) fn expand_stringify(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -88,7 +88,7 @@ pub fn expand_stringify(
     ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
 }
 
-pub fn expand_mod(
+pub(crate) fn expand_mod(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -104,7 +104,7 @@ pub fn expand_mod(
 /// include! : parse the given file as an expr
 /// This is generally a bad idea because it's going to behave
 /// unhygienically.
-pub fn expand_include<'cx>(
+pub(crate) fn expand_include<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -181,7 +181,7 @@ pub fn expand_include<'cx>(
 }
 
 /// `include_str!`: read the given file, insert it as a literal string expr
-pub fn expand_include_str(
+pub(crate) fn expand_include_str(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
@@ -210,7 +210,7 @@ pub fn expand_include_str(
     })
 }
 
-pub fn expand_include_bytes(
+pub(crate) fn expand_include_bytes(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index c7568f1461c..1e4bf4611cf 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -12,6 +12,7 @@ use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span};
 use std::assert_matches::assert_matches;
 use std::iter;
 use thin_vec::{thin_vec, ThinVec};
+use tracing::debug;
 
 /// #[test_case] is used by custom test authors to mark tests
 /// When building for test, it needs to make the item public and gensym the name
@@ -20,7 +21,7 @@ use thin_vec::{thin_vec, ThinVec};
 ///
 /// We mark item with an inert attribute "rustc_test_marker" which the test generation
 /// logic will pick up on.
-pub fn expand_test_case(
+pub(crate) fn expand_test_case(
     ecx: &mut ExtCtxt<'_>,
     attr_sp: Span,
     meta_item: &ast::MetaItem,
@@ -73,7 +74,7 @@ pub fn expand_test_case(
     vec![ret]
 }
 
-pub fn expand_test(
+pub(crate) fn expand_test(
     cx: &mut ExtCtxt<'_>,
     attr_sp: Span,
     meta_item: &ast::MetaItem,
@@ -84,7 +85,7 @@ pub fn expand_test(
     expand_test_or_bench(cx, attr_sp, item, false)
 }
 
-pub fn expand_bench(
+pub(crate) fn expand_bench(
     cx: &mut ExtCtxt<'_>,
     attr_sp: Span,
     meta_item: &ast::MetaItem,
@@ -95,7 +96,7 @@ pub fn expand_bench(
     expand_test_or_bench(cx, attr_sp, item, true)
 }
 
-pub fn expand_test_or_bench(
+pub(crate) fn expand_test_or_bench(
     cx: &ExtCtxt<'_>,
     attr_sp: Span,
     item: Annotatable,
diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index 696d99004ba..4833ec32f76 100644
--- a/compiler/rustc_builtin_macros/src/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
@@ -4,7 +4,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult
 use rustc_span::symbol::kw;
 use rustc_span::Span;
 
-pub fn expand_trace_macros(
+pub(crate) fn expand_trace_macros(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tt: TokenStream,
diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs
index ad6b09ba574..8dc7bc14ec3 100644
--- a/compiler/rustc_builtin_macros/src/util.rs
+++ b/compiler/rustc_builtin_macros/src/util.rs
@@ -1,11 +1,16 @@
-use rustc_ast::{attr, AttrStyle, Attribute, MetaItem};
-use rustc_expand::base::{Annotatable, ExtCtxt};
+use crate::errors;
+use rustc_ast::tokenstream::TokenStream;
+use rustc_ast::{self as ast, attr, ptr::P, token, AttrStyle, Attribute, MetaItem};
+use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
+use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt};
+use rustc_expand::expand::AstFragment;
 use rustc_feature::AttributeTemplate;
 use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
-use rustc_parse::validate_attr;
-use rustc_span::Symbol;
+use rustc_parse::{parser, validate_attr};
+use rustc_session::errors::report_lit_error;
+use rustc_span::{BytePos, Span, Symbol};
 
-pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
+pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
     // All the built-in macro attributes are "words" at the moment.
     let template = AttributeTemplate { word: true, ..Default::default() };
     validate_attr::check_builtin_meta_item(
@@ -19,7 +24,7 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na
 
 /// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when
 /// an attribute may have been mistakenly duplicated.
-pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
+pub(crate) fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) {
     let attrs: Option<&[Attribute]> = match item {
         Annotatable::Item(item) => Some(&item.attrs),
         Annotatable::TraitItem(item) => Some(&item.attrs),
@@ -46,3 +51,178 @@ pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name:
         }
     }
 }
+
+/// `Ok` represents successfully retrieving the string literal at the correct
+/// position, e.g., `println("abc")`.
+type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>;
+
+/// - `Ok` is returned when the conversion to a string literal is unsuccessful,
+/// but another type of expression is obtained instead.
+/// - `Err` is returned when the conversion process fails.
+type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>;
+
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
+/// The returned bool indicates whether an applicable suggestion has already been
+/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))`
+/// indicates that an ast error was encountered.
+// FIXME(Nilstrieb) Make this function setup translatable
+#[allow(rustc::untranslatable_diagnostic)]
+pub(crate) fn expr_to_spanned_string<'a>(
+    cx: &'a mut ExtCtxt<'_>,
+    expr: P<ast::Expr>,
+    err_msg: &'static str,
+) -> ExpandResult<ExprToSpannedStringResult<'a>, ()> {
+    if !cx.force_mode
+        && let ast::ExprKind::MacCall(m) = &expr.kind
+        && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
+    {
+        return ExpandResult::Retry(());
+    }
+
+    // Perform eager expansion on the expression.
+    // We want to be able to handle e.g., `concat!("foo", "bar")`.
+    let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
+
+    ExpandResult::Ready(Err(match expr.kind {
+        ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
+            Ok(ast::LitKind::Str(s, style)) => {
+                return ExpandResult::Ready(Ok((s, style, expr.span)));
+            }
+            Ok(ast::LitKind::ByteStr(..)) => {
+                let mut err = cx.dcx().struct_span_err(expr.span, err_msg);
+                let span = expr.span.shrink_to_lo();
+                err.span_suggestion(
+                    span.with_hi(span.lo() + BytePos(1)),
+                    "consider removing the leading `b`",
+                    "",
+                    Applicability::MaybeIncorrect,
+                );
+                Ok((err, true))
+            }
+            Ok(ast::LitKind::Err(guar)) => Err(guar),
+            Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)),
+            _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+        },
+        ast::ExprKind::Err(guar) => Err(guar),
+        ast::ExprKind::Dummy => {
+            cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`")
+        }
+        _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+    }))
+}
+
+/// Extracts a string literal from the macro expanded version of `expr`,
+/// emitting `err_msg` if `expr` is not a string literal. This does not stop
+/// compilation on error, merely emits a non-fatal error and returns `Err`.
+pub(crate) fn expr_to_string(
+    cx: &mut ExtCtxt<'_>,
+    expr: P<ast::Expr>,
+    err_msg: &'static str,
+) -> ExpandResult<Result<(Symbol, ast::StrStyle), ErrorGuaranteed>, ()> {
+    expr_to_spanned_string(cx, expr, err_msg).map(|res| {
+        res.map_err(|err| match err {
+            Ok((err, _)) => err.emit(),
+            Err(guar) => guar,
+        })
+        .map(|(symbol, style, _)| (symbol, style))
+    })
+}
+
+/// Non-fatally assert that `tts` is empty. Note that this function
+/// returns even when `tts` is non-empty, macros that *need* to stop
+/// compilation should call `cx.diagnostic().abort_if_errors()`
+/// (this should be done as rarely as possible).
+pub(crate) fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) {
+    if !tts.is_empty() {
+        cx.dcx().emit_err(errors::TakesNoArguments { span, name });
+    }
+}
+
+/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
+pub(crate) fn parse_expr(p: &mut parser::Parser<'_>) -> Result<P<ast::Expr>, ErrorGuaranteed> {
+    let guar = match p.parse_expr() {
+        Ok(expr) => return Ok(expr),
+        Err(err) => err.emit(),
+    };
+    while p.token != token::Eof {
+        p.bump();
+    }
+    Err(guar)
+}
+
+/// Interpreting `tts` as a comma-separated sequence of expressions,
+/// expect exactly one string literal, or emit an error and return `Err`.
+pub(crate) fn get_single_str_from_tts(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    tts: TokenStream,
+    name: &str,
+) -> ExpandResult<Result<Symbol, ErrorGuaranteed>, ()> {
+    get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s))
+}
+
+pub(crate) fn get_single_str_spanned_from_tts(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    tts: TokenStream,
+    name: &str,
+) -> ExpandResult<Result<(Symbol, Span), ErrorGuaranteed>, ()> {
+    let mut p = cx.new_parser_from_tts(tts);
+    if p.token == token::Eof {
+        let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
+        return ExpandResult::Ready(Err(guar));
+    }
+    let ret = match parse_expr(&mut p) {
+        Ok(ret) => ret,
+        Err(guar) => return ExpandResult::Ready(Err(guar)),
+    };
+    let _ = p.eat(&token::Comma);
+
+    if p.token != token::Eof {
+        cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
+    }
+    expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
+        res.map_err(|err| match err {
+            Ok((err, _)) => err.emit(),
+            Err(guar) => guar,
+        })
+        .map(|(symbol, _style, span)| (symbol, span))
+    })
+}
+
+/// Extracts comma-separated expressions from `tts`.
+/// On error, emit it, and return `Err`.
+pub(crate) fn get_exprs_from_tts(
+    cx: &mut ExtCtxt<'_>,
+    tts: TokenStream,
+) -> ExpandResult<Result<Vec<P<ast::Expr>>, ErrorGuaranteed>, ()> {
+    let mut p = cx.new_parser_from_tts(tts);
+    let mut es = Vec::new();
+    while p.token != token::Eof {
+        let expr = match parse_expr(&mut p) {
+            Ok(expr) => expr,
+            Err(guar) => return ExpandResult::Ready(Err(guar)),
+        };
+        if !cx.force_mode
+            && let ast::ExprKind::MacCall(m) = &expr.kind
+            && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
+        {
+            return ExpandResult::Retry(());
+        }
+
+        // Perform eager expansion on the expression.
+        // We want to be able to handle e.g., `concat!("foo", "bar")`.
+        let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
+
+        es.push(expr);
+        if p.eat(&token::Comma) {
+            continue;
+        }
+        if p.token != token::Eof {
+            let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
+            return ExpandResult::Ready(Err(guar));
+        }
+    }
+    ExpandResult::Ready(Ok(es))
+}
diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs
index 8ffa66a4894..a48c0a4450c 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core.rs
@@ -420,7 +420,6 @@ pub fn panic(_msg: &'static str) -> ! {
 
 macro_rules! panic_const {
     ($($lang:ident = $message:expr,)+) => {
-        #[cfg(not(bootstrap))]
         pub mod panic_const {
             use super::*;
 
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index b7aec97ad8c..451e5258ebd 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -1223,7 +1223,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
         tcx,
         ty::Binder::dummy(tcx.mk_fn_sig(
             iter::once(i8p),
-            Ty::new_unit(tcx),
+            tcx.types.unit,
             false,
             rustc_hir::Unsafety::Unsafe,
             Abi::Rust,
@@ -1234,7 +1234,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
         tcx,
         ty::Binder::dummy(tcx.mk_fn_sig(
             [i8p, i8p].iter().cloned(),
-            Ty::new_unit(tcx),
+            tcx.types.unit,
             false,
             rustc_hir::Unsafety::Unsafe,
             Abi::Rust,
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 345c22394f2..3f2fadce9e4 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -23,7 +23,6 @@
     trusted_len,
     hash_raw_entry
 )]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![allow(broken_intra_doc_links)]
 #![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index f7546039540..5c8f358d03a 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -27,6 +27,7 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
 use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
 use smallvec::SmallVec;
 use std::borrow::Cow;
+use std::ffi::CString;
 use std::iter;
 use std::ops::Deref;
 use std::ptr;
@@ -1709,7 +1710,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         fn_name: &'ll Value,
         hash: &'ll Value,
         bitmap_bytes: &'ll Value,
-    ) -> &'ll Value {
+        max_decision_depth: u32,
+    ) -> Vec<&'ll Value> {
         debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
 
         assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
@@ -1722,6 +1724,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         let args = &[fn_name, hash, bitmap_bytes];
         let args = self.check_call("call", llty, llfn, args);
 
+        let mut cond_bitmaps = vec![];
+
         unsafe {
             let _ = llvm::LLVMRustBuildCall(
                 self.llbuilder,
@@ -1733,17 +1737,22 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 0 as c_uint,
             );
             // Create condition bitmap named `mcdc.addr`.
-            let mut bx = Builder::with_cx(self.cx);
-            bx.position_at_start(llvm::LLVMGetFirstBasicBlock(self.llfn()));
-            let cond_bitmap = {
-                let alloca =
-                    llvm::LLVMBuildAlloca(bx.llbuilder, bx.cx.type_i32(), c"mcdc.addr".as_ptr());
-                llvm::LLVMSetAlignment(alloca, 4);
-                alloca
-            };
-            bx.store(self.const_i32(0), cond_bitmap, self.tcx().data_layout.i32_align.abi);
-            cond_bitmap
+            for i in 0..=max_decision_depth {
+                let mut bx = Builder::with_cx(self.cx);
+                bx.position_at_start(llvm::LLVMGetFirstBasicBlock(self.llfn()));
+
+                let name = CString::new(format!("mcdc.addr.{i}")).unwrap();
+                let cond_bitmap = {
+                    let alloca =
+                        llvm::LLVMBuildAlloca(bx.llbuilder, bx.cx.type_i32(), name.as_ptr());
+                    llvm::LLVMSetAlignment(alloca, 4);
+                    alloca
+                };
+                bx.store(self.const_i32(0), cond_bitmap, self.tcx().data_layout.i32_align.abi);
+                cond_bitmaps.push(cond_bitmap);
+            }
         }
+        cond_bitmaps
     }
 
     pub(crate) fn mcdc_tvbitmap_update(
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 085ce15d81f..679c6e1a2ff 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -30,7 +30,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> {
     pub(crate) function_coverage_map:
         RefCell<FxIndexMap<Instance<'tcx>, FunctionCoverageCollector<'tcx>>>,
     pub(crate) pgo_func_name_var_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>,
-    pub(crate) mcdc_condition_bitmap_map: RefCell<FxHashMap<Instance<'tcx>, &'ll llvm::Value>>,
+    pub(crate) mcdc_condition_bitmap_map: RefCell<FxHashMap<Instance<'tcx>, Vec<&'ll llvm::Value>>>,
 }
 
 impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
@@ -49,9 +49,20 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
     }
 
     /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap.
-    /// This value is named `mcdc.addr` (same as clang) and is a 32-bit integer.
-    fn try_get_mcdc_condition_bitmap(&self, instance: &Instance<'tcx>) -> Option<&'ll llvm::Value> {
-        self.mcdc_condition_bitmap_map.borrow().get(instance).copied()
+    /// In order to handle nested decisions, several condition bitmaps can be
+    /// allocated for a function body.
+    /// These values are named `mcdc.addr.{i}` and are a 32-bit integers.
+    /// They respectively hold the condition bitmaps for decisions with a depth of `i`.
+    fn try_get_mcdc_condition_bitmap(
+        &self,
+        instance: &Instance<'tcx>,
+        decision_depth: u16,
+    ) -> Option<&'ll llvm::Value> {
+        self.mcdc_condition_bitmap_map
+            .borrow()
+            .get(instance)
+            .and_then(|bitmap_map| bitmap_map.get(decision_depth as usize))
+            .copied() // Dereference Option<&&Value> to Option<&Value>
     }
 }
 
@@ -143,7 +154,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             CoverageKind::ExpressionUsed { id } => {
                 func_coverage.mark_expression_id_seen(id);
             }
-            CoverageKind::CondBitmapUpdate { id, value, .. } => {
+            CoverageKind::CondBitmapUpdate { id, value, decision_depth } => {
                 drop(coverage_map);
                 assert_ne!(
                     id.as_u32(),
@@ -151,7 +162,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                     "ConditionId of evaluated conditions should never be zero"
                 );
                 let cond_bitmap = coverage_context
-                    .try_get_mcdc_condition_bitmap(&instance)
+                    .try_get_mcdc_condition_bitmap(&instance, decision_depth)
                     .expect("mcdc cond bitmap should have been allocated for updating");
                 let cond_loc = bx.const_i32(id.as_u32() as i32 - 1);
                 let bool_value = bx.const_bool(value);
@@ -159,10 +170,10 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                 let hash = bx.const_u64(function_coverage_info.function_source_hash);
                 bx.mcdc_condbitmap_update(fn_name, hash, cond_loc, cond_bitmap, bool_value);
             }
-            CoverageKind::TestVectorBitmapUpdate { bitmap_idx } => {
+            CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
                 drop(coverage_map);
                 let cond_bitmap = coverage_context
-                                    .try_get_mcdc_condition_bitmap(&instance)
+                                    .try_get_mcdc_condition_bitmap(&instance, decision_depth)
                                     .expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
                 let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes;
                 assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range");
@@ -195,7 +206,8 @@ fn ensure_mcdc_parameters<'ll, 'tcx>(
     let fn_name = bx.get_pgo_func_name_var(instance);
     let hash = bx.const_u64(function_coverage_info.function_source_hash);
     let bitmap_bytes = bx.const_u32(function_coverage_info.mcdc_bitmap_bytes);
-    let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes);
+    let max_decision_depth = function_coverage_info.mcdc_max_decision_depth;
+    let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes, max_decision_depth as u32);
     bx.coverage_context()
         .expect("already checked above")
         .mcdc_condition_bitmap_map
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 1aec65cf949..e521d5e259c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -5,6 +5,7 @@ use rustc_data_structures::{
     fx::FxHashMap,
     stable_hasher::{HashStable, StableHasher},
 };
+use rustc_macros::HashStable;
 use rustc_middle::{
     bug,
     ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt},
@@ -23,6 +24,8 @@ use crate::{
 use super::{unknown_file_metadata, SmallVec, UNKNOWN_LINE_NUMBER};
 
 mod private {
+    use rustc_macros::HashStable;
+
     // This type cannot be constructed outside of this module because
     // it has a private field. We make use of this in order to prevent
     // `UniqueTypeId` from being constructed directly, without asserting
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 41347333ea6..56550dbfa4b 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -984,7 +984,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
         tcx,
         ty::Binder::dummy(tcx.mk_fn_sig(
             [i8p],
-            Ty::new_unit(tcx),
+            tcx.types.unit,
             false,
             hir::Unsafety::Unsafe,
             Abi::Rust,
@@ -995,7 +995,7 @@ fn get_rust_try_fn<'ll, 'tcx>(
         tcx,
         ty::Binder::dummy(tcx.mk_fn_sig(
             [i8p, i8p],
-            Ty::new_unit(tcx),
+            tcx.types.unit,
             false,
             hir::Unsafety::Unsafe,
             Abi::Rust,
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index c84461e53eb..1cecf682e5d 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -16,8 +16,6 @@
 #![feature(impl_trait_in_assoc_type)]
 
 #[macro_use]
-extern crate rustc_macros;
-#[macro_use]
 extern crate tracing;
 
 use back::owned_target_machine::OwnedTargetMachine;
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index b458f325b73..1f691d14c53 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -8,6 +8,7 @@ use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::find_native_static_library;
 use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
+use rustc_middle::bug;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 85fcc4f4f40..f85056f8ad4 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -12,6 +12,7 @@ use std::{env, mem, str};
 
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::find_native_static_library;
+use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index ab1bc0b6cd2..264a98844ad 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -16,6 +16,7 @@ use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::fs::METADATA_FILENAME;
 use rustc_metadata::EncodedMetadata;
+use rustc_middle::bug;
 use rustc_session::Session;
 use rustc_span::sym;
 use rustc_target::abi::Endian;
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index cce3f0e6f2d..0e335bf00cf 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -6,6 +6,7 @@ use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE}
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::exported_symbols::{
     metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index c4f062405bb..53ba0da7d04 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -26,6 +26,7 @@ use rustc_incremental::{
 };
 use rustc_metadata::fs::copy_to_stdout;
 use rustc_metadata::EncodedMetadata;
+use rustc_middle::bug;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::middle::exported_symbols::SymbolExportInfo;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index ae7c0f24b40..358c24bfb82 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -24,6 +24,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
 use rustc_metadata::EncodedMetadata;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
 use rustc_middle::middle::exported_symbols;
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index b41739867c7..e4a36b3f591 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -4,6 +4,7 @@ use rustc_hir::LangItem;
 use rustc_middle::mir;
 use rustc_middle::ty::Instance;
 use rustc_middle::ty::{self, layout::TyAndLayout, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 
 use crate::traits::*;
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 5f0dcf9510f..e9c7606dc5a 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -16,6 +16,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
 use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability};
+use rustc_middle::bug;
 use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
 use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index b843d1bdf23..ed6a0c24410 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -431,7 +431,6 @@ pub struct ProcessingDymutilFailed {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unable_to_run_dsymutil)]
-#[note]
 pub struct UnableToRunDsymutil {
     pub error: Error,
 }
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 80fe7e0bb78..4eb24d71009 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -4,7 +4,6 @@
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
@@ -17,11 +16,7 @@
 //! have to be implemented by each backend.
 
 #[macro_use]
-extern crate rustc_macros;
-#[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashSet;
@@ -29,6 +24,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir::def_id::CrateNum;
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Dependencies;
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 4f7dc9968a1..23036e9bea0 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -1,5 +1,6 @@
 use crate::traits::*;
 
+use rustc_middle::bug;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::config::Lto;
 use rustc_symbol_mangling::typeid_for_trait_ref;
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index c1de9b76fe7..09ae7cf6410 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -10,6 +10,7 @@ use rustc_middle::mir::traversal;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{self, DefLocation, Location, TerminatorKind};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::{bug, span_bug};
 
 pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     fx: &FunctionCx<'a, 'tcx, Bx>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index d4d172c000f..be5458523d1 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -17,6 +17,7 @@ use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTermi
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty};
+use rustc_middle::{bug, span_bug};
 use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization;
 use rustc_session::config::OptLevel;
 use rustc_span::{source_map::Spanned, sym, Span};
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index c6260d35916..dba5fbefd8a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -5,6 +5,7 @@ use rustc_middle::mir;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{self, Ty};
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::Abi;
 
 use super::FunctionCx;
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index d0e2fc2de12..50bf1ef61f3 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,6 +1,7 @@
 use crate::traits::*;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index eb14a90412d..2e008460798 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -9,6 +9,7 @@ use crate::traits::*;
 use crate::MemFlags;
 
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::config::OptLevel;
 use rustc_span::{sym, Span};
 use rustc_target::abi::{
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index b98e90b5cde..0064c16f5d9 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -8,6 +8,7 @@ use rustc_middle::mir::traversal;
 use rustc_middle::mir::UnwindTerminateReason;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::call::{FnAbi, PassMode};
 
 use std::iter;
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index e5fd59657a4..38f77f2e646 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -5,6 +5,7 @@ use crate::size_of_val;
 use crate::traits::*;
 use crate::MemFlags;
 
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{alloc_range, Pointer, Scalar};
 use rustc_middle::mir::{self, ConstValue};
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index b23d0894da6..870a105c61d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -5,6 +5,7 @@ use crate::common::IntPredicate;
 use crate::size_of_val;
 use crate::traits::*;
 
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 7823d4c249a..4e7d251a2e9 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -8,11 +8,11 @@ use crate::traits::*;
 use crate::MemFlags;
 
 use rustc_hir as hir;
-use rustc_middle::mir;
-use rustc_middle::mir::{AggregateKind, Operand};
+use rustc_middle::mir::{self, AggregateKind, Operand};
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::config::OptLevel;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{self, FIRST_VARIANT};
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 2188eeae426..a0429022587 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,5 +1,5 @@
-use rustc_middle::mir;
-use rustc_middle::mir::NonDivergingIntrinsic;
+use rustc_middle::mir::{self, NonDivergingIntrinsic};
+use rustc_middle::span_bug;
 use rustc_session::config::OptLevel;
 
 use super::FunctionCx;
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index df564f705bc..40921c2932f 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -5,6 +5,7 @@ use rustc_hir as hir;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::span_bug;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_middle::ty::Instance;
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index c250cc26823..032699f1fa1 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -5,6 +5,7 @@ use crate::common::IntPredicate;
 use crate::meth;
 use crate::traits::*;
 use rustc_hir::LangItem;
+use rustc_middle::bug;
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Ty};
 use rustc_target::abi::WrappingRange;
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 241b0a15f78..bcddfe9fb9c 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -8,6 +8,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 34d9e75036f..ccb35629a82 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -3,6 +3,7 @@ use super::Backend;
 use super::HasCodegen;
 use crate::common::TypeKind;
 use crate::mir::place::PlaceRef;
+use rustc_middle::bug;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Ty};
 use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index 7ede90ad13f..7d7b421f869 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -18,6 +18,7 @@ mod util;
 mod validity;
 mod visitor;
 
+#[doc(no_inline)]
 pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
 
 pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup};
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 2b799d6f5d3..cf54e700e2b 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -25,6 +25,7 @@
 #![feature(lazy_cell)]
 #![feature(lint_reasons)]
 #![feature(macro_metavar_expr)]
+#![feature(map_try_insert)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
@@ -41,8 +42,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_macros;
 
 use std::fmt;
 
@@ -146,9 +145,9 @@ pub fn make_display(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl
     Printer { f }
 }
 
-// See comments in compiler/rustc_middle/src/tests.rs
+// See comment in compiler/rustc_middle/src/tests.rs and issue #27438.
 #[doc(hidden)]
-pub fn __noop_fix_for_27438() {}
+pub fn __noop_fix_for_windows_dllimport_issue() {}
 
 #[macro_export]
 macro_rules! external_bitflags_debug {
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 1436628139f..21d7c91ec48 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -1,4 +1,5 @@
 use crate::stable_hasher::{HashStable, StableHasher, StableOrd};
+use rustc_macros::{Decodable_Generic, Encodable_Generic};
 use std::borrow::Borrow;
 use std::fmt::Debug;
 use std::mem;
diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs
index 1cfc9fecd47..38629ea9801 100644
--- a/compiler/rustc_data_structures/src/svh.rs
+++ b/compiler/rustc_data_structures/src/svh.rs
@@ -6,9 +6,9 @@
 //! compiled from distinct sources.
 
 use crate::fingerprint::Fingerprint;
-use std::fmt;
-
 use crate::stable_hasher;
+use rustc_macros::{Decodable_Generic, Encodable_Generic};
+use std::fmt;
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable_Generic, Decodable_Generic, Hash)]
 pub struct Svh {
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index eab6d8168ca..ecb85db33f7 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -46,6 +46,7 @@ use std::collections::HashMap;
 use std::hash::{BuildHasher, Hash};
 
 mod lock;
+#[doc(no_inline)]
 pub use lock::{Lock, LockGuard, Mode};
 
 mod worker_local;
@@ -199,10 +200,15 @@ cfg_match! {
 
         pub use std::rc::Rc as Lrc;
         pub use std::rc::Weak as Weak;
+        #[doc(no_inline)]
         pub use std::cell::Ref as ReadGuard;
+        #[doc(no_inline)]
         pub use std::cell::Ref as MappedReadGuard;
+        #[doc(no_inline)]
         pub use std::cell::RefMut as WriteGuard;
+        #[doc(no_inline)]
         pub use std::cell::RefMut as MappedWriteGuard;
+        #[doc(no_inline)]
         pub use std::cell::RefMut as MappedLockGuard;
 
         pub use std::cell::OnceCell as OnceLock;
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs
index a99e2062039..1ccd22a56c9 100644
--- a/compiler/rustc_data_structures/src/unord.rs
+++ b/compiler/rustc_data_structures/src/unord.rs
@@ -3,6 +3,8 @@
 //! as required by the query system.
 
 use rustc_hash::{FxHashMap, FxHashSet};
+use rustc_macros::{Decodable_Generic, Encodable_Generic};
+use std::collections::hash_map::OccupiedError;
 use std::{
     borrow::{Borrow, BorrowMut},
     collections::hash_map::Entry,
@@ -469,6 +471,11 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
     }
 
     #[inline]
+    pub fn try_insert(&mut self, k: K, v: V) -> Result<&mut V, OccupiedError<'_, K, V>> {
+        self.inner.try_insert(k, v)
+    }
+
+    #[inline]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
     where
         K: Borrow<Q>,
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index b3cba4dbfc2..b2d38a00f0b 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -14,9 +14,6 @@
 #![feature(panic_update_hook)]
 #![feature(result_flattening)]
 
-#[macro_use]
-extern crate tracing;
-
 use rustc_ast as ast;
 use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
 use rustc_const_eval::CTRL_C_RECEIVED;
@@ -46,7 +43,6 @@ use rustc_span::symbol::sym;
 use rustc_span::FileName;
 use rustc_target::json::ToJson;
 use rustc_target::spec::{Target, TargetTriple};
-
 use std::cmp::max;
 use std::collections::BTreeMap;
 use std::env;
@@ -62,6 +58,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, OnceLock};
 use std::time::{Instant, SystemTime};
 use time::OffsetDateTime;
+use tracing::trace;
 
 #[allow(unused_macros)]
 macro do_not_use_print($($t:tt)*) {
@@ -971,7 +968,7 @@ Available lint options:
 
     let lint_store = unerased_lint_store(sess);
     let (loaded, builtin): (Vec<_>, _) =
-        lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_loaded);
+        lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_externally_loaded);
     let loaded = sort_lints(sess, loaded);
     let builtin = sort_lints(sess, builtin);
 
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 40f6f764993..fe426b8111c 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -13,9 +13,9 @@ use rustc_session::Session;
 use rustc_smir::rustc_internal::pretty::write_smir_pretty;
 use rustc_span::symbol::Ident;
 use rustc_span::FileName;
-
 use std::cell::Cell;
 use std::fmt::Write;
+use tracing::debug;
 
 pub use self::PpMode::*;
 pub use self::PpSourceMode::*;
diff --git a/compiler/rustc_error_codes/src/error_codes/E0637.md b/compiler/rustc_error_codes/src/error_codes/E0637.md
index 62d5565df27..9c2a53f51cf 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0637.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0637.md
@@ -1,5 +1,5 @@
 `'_` lifetime name or `&T` without an explicit lifetime name has been used
-on illegal place.
+in an illegal place.
 
 Erroneous code example:
 
@@ -13,7 +13,14 @@ fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
     }
 }
 
-fn and_without_explicit_lifetime<T>()
+fn without_explicit_lifetime<T>()
+where
+    T: Iterator<Item = &u32>,
+                     //^ `&` without an explicit lifetime name
+{
+}
+
+fn without_hrtb<T>()
 where
     T: Into<&u32>,
           //^ `&` without an explicit lifetime name
@@ -40,9 +47,15 @@ fn underscore_lifetime<'a>(str1: &'a str, str2: &'a str) -> &'a str {
     }
 }
 
-fn and_without_explicit_lifetime<'foo, T>()
+fn without_explicit_lifetime<'a, T>()
+where
+    T: Iterator<Item = &'a u32>,
+{
+}
+
+fn without_hrtb<T>()
 where
-    T: Into<&'foo u32>,
+    T: for<'foo> Into<&'foo u32>,
 {
 }
 ```
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 6c84eeaf888..1610135a0ef 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
 use rustc_error_messages::FluentValue;
 use rustc_lint_defs::{Applicability, LintExpectationId};
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
@@ -17,6 +18,7 @@ use std::marker::PhantomData;
 use std::ops::{Deref, DerefMut};
 use std::panic;
 use std::thread::panicking;
+use tracing::debug;
 
 /// Error type for `DiagInner`'s `suggestions` field, indicating that
 /// `.disable_suggestions()` was called on the `DiagInner`.
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 2b10fcd8d6a..b3a1e29f8e2 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -7,6 +7,7 @@ use crate::{
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_hir as hir;
+use rustc_macros::Subdiagnostic;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
 use rustc_span::Span;
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 6ce3fa3535d..5d4d2555100 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -35,6 +35,7 @@ use std::iter;
 use std::path::Path;
 use termcolor::{Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream};
 use termcolor::{Color, WriteColor};
+use tracing::{debug, instrument, trace, warn};
 
 /// Default column width, used in tests and when terminal dimensions cannot be determined.
 const DEFAULT_COLUMN_WIDTH: usize = 140;
@@ -984,7 +985,7 @@ impl HumanEmitter {
         // 4 |   }
         //   |
         for pos in 0..=line_len {
-            draw_col_separator(buffer, line_offset + pos + 1, width_offset - 2);
+            draw_col_separator_no_space(buffer, line_offset + pos + 1, width_offset - 2);
         }
 
         // Write the horizontal lines for multiline annotations
@@ -2019,7 +2020,7 @@ impl HumanEmitter {
                     let offset: isize = offsets
                         .iter()
                         .filter_map(
-                            |(start, v)| if span_start_pos <= *start { None } else { Some(v) },
+                            |(start, v)| if span_start_pos < *start { None } else { Some(v) },
                         )
                         .sum();
                     let underline_start = (span_start_pos + start) as isize + offset;
@@ -2028,7 +2029,7 @@ impl HumanEmitter {
                     let padding: usize = max_line_num_len + 3;
                     for p in underline_start..underline_end {
                         if let DisplaySuggestion::Underline = show_code_change {
-                            // If this is a replacement, underline with `^`, if this is an addition
+                            // If this is a replacement, underline with `~`, if this is an addition
                             // underline with `+`.
                             buffer.putc(
                                 row_num,
@@ -2260,13 +2261,23 @@ impl HumanEmitter {
                     buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
                 }
                 [] => {
-                    draw_col_separator(buffer, *row_num, max_line_num_len + 1);
+                    draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1);
                 }
                 _ => {
                     buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition);
                 }
             }
-            buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
+            //   LL | line_to_add
+            //   ++^^^
+            //    |  |
+            //    |  magic `3`
+            //    `max_line_num_len`
+            buffer.puts(
+                *row_num,
+                max_line_num_len + 3,
+                &normalize_whitespace(line_to_add),
+                Style::NoStyle,
+            );
         } else if let DisplaySuggestion::Add = show_code_change {
             buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
             buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index adbac80d7cc..3b884ff864a 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -25,12 +25,6 @@
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
 
-#[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
-extern crate tracing;
-
 extern crate self as rustc_errors;
 
 pub use codes::*;
@@ -64,6 +58,7 @@ use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_data_structures::AtomicRef;
 use rustc_lint_defs::LintExpectationId;
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::source_map::SourceMap;
 use rustc_span::{Loc, Span, DUMMY_SP};
 use std::backtrace::{Backtrace, BacktraceStatus};
@@ -76,6 +71,7 @@ use std::num::NonZero;
 use std::ops::DerefMut;
 use std::panic;
 use std::path::{Path, PathBuf};
+use tracing::debug;
 
 use Level::*;
 
diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs
index b55f7853885..d6119fb41d2 100644
--- a/compiler/rustc_errors/src/snippet.rs
+++ b/compiler/rustc_errors/src/snippet.rs
@@ -1,6 +1,7 @@
 // Code for annotating snippets.
 
 use crate::{Level, Loc};
+use rustc_macros::{Decodable, Encodable};
 
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
 pub struct Line {
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index bf0026568ce..445e9b4fd6e 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -6,6 +6,7 @@ pub use rustc_error_messages::FluentArgs;
 use std::borrow::Cow;
 use std::env;
 use std::error::Report;
+use tracing::{debug, trace};
 
 /// Convert diagnostic arguments (a rustc internal type that exists to implement
 /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index fdd1a87cae8..b7aae2af9ef 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -30,9 +30,6 @@ expand_duplicate_matcher_binding = duplicate matcher binding
     .label = duplicate binding
     .label2 = previous binding
 
-expand_expected_comma_in_list =
-    expected token: `,`
-
 expand_expected_paren_or_brace =
     expected `(` or `{"{"}`, found `{$token}`
 
@@ -116,9 +113,6 @@ expand_must_repeat_once =
 expand_not_a_meta_item =
     not a meta item
 
-expand_only_one_argument =
-    {$name} takes 1 argument
-
 expand_only_one_word =
     must only be one word
 
@@ -146,9 +140,6 @@ expand_remove_node_not_supported =
 expand_resolve_relative_path =
     cannot resolve relative path in non-file source `{$path}`
 
-expand_takes_no_arguments =
-    {$name} takes no arguments
-
 expand_trace_macro = trace_macro
 
 expand_unsupported_key_value =
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 3c465709ec7..12868a66605 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -5,27 +5,26 @@ use crate::module::DirOwnership;
 
 use rustc_ast::attr::MarkedAttrs;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Nonterminal};
+use rustc_ast::token::Nonterminal;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
 use rustc_attr::{self as attr, Deprecation, Stability};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, PResult};
+use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
 use rustc_feature::Features;
 use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools};
 use rustc_parse::{parser, MACRO_ARGUMENTS};
 use rustc_session::config::CollapseMacroDebuginfo;
-use rustc_session::errors::report_lit_error;
 use rustc_session::{parse::ParseSess, Limit, Session};
 use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_span::edition::Edition;
-use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
+use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
+use rustc_span::{FileName, Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 use std::default::Default;
 use std::iter;
@@ -33,8 +32,6 @@ use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use thin_vec::ThinVec;
 
-pub(crate) use rustc_span::hygiene::MacroKind;
-
 // When adding new variants, make sure to
 // adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
 // to use `assign_id!`
@@ -574,35 +571,6 @@ impl DummyResult {
             tokens: None,
         })
     }
-
-    /// A plain dummy pattern.
-    pub fn raw_pat(sp: Span) -> ast::Pat {
-        ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp, tokens: None }
-    }
-
-    /// A plain dummy type.
-    pub fn raw_ty(sp: Span) -> P<ast::Ty> {
-        // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
-        // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
-        // support, so we use an empty tuple instead.
-        P(ast::Ty {
-            id: ast::DUMMY_NODE_ID,
-            kind: ast::TyKind::Tup(ThinVec::new()),
-            span: sp,
-            tokens: None,
-        })
-    }
-
-    /// A plain dummy crate.
-    pub fn raw_crate() -> ast::Crate {
-        ast::Crate {
-            attrs: Default::default(),
-            items: Default::default(),
-            spans: Default::default(),
-            id: ast::DUMMY_NODE_ID,
-            is_placeholder: Default::default(),
-        }
-    }
 }
 
 impl MacResult for DummyResult {
@@ -611,7 +579,12 @@ impl MacResult for DummyResult {
     }
 
     fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
-        Some(P(DummyResult::raw_pat(self.span)))
+        Some(P(ast::Pat {
+            id: ast::DUMMY_NODE_ID,
+            kind: PatKind::Wild,
+            span: self.span,
+            tokens: None,
+        }))
     }
 
     fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
@@ -639,7 +612,15 @@ impl MacResult for DummyResult {
     }
 
     fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
-        Some(DummyResult::raw_ty(self.span))
+        // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
+        // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
+        // support, so we use an empty tuple instead.
+        Some(P(ast::Ty {
+            id: ast::DUMMY_NODE_ID,
+            kind: ast::TyKind::Tup(ThinVec::new()),
+            span: self.span,
+            tokens: None,
+        }))
     }
 
     fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
@@ -671,7 +652,13 @@ impl MacResult for DummyResult {
     }
 
     fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
-        Some(DummyResult::raw_crate())
+        Some(ast::Crate {
+            attrs: Default::default(),
+            items: Default::default(),
+            spans: Default::default(),
+            id: ast::DUMMY_NODE_ID,
+            is_placeholder: Default::default(),
+        })
     }
 }
 
@@ -963,7 +950,12 @@ impl SyntaxExtension {
 /// Error type that denotes indeterminacy.
 pub struct Indeterminate;
 
-pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>, bool)>;
+pub struct DeriveResolution {
+    pub path: ast::Path,
+    pub item: Annotatable,
+    pub exts: Option<Lrc<SyntaxExtension>>,
+    pub is_const: bool,
+}
 
 pub trait ResolverExpand {
     fn next_node_id(&mut self) -> NodeId;
@@ -1006,11 +998,11 @@ pub trait ResolverExpand {
         &mut self,
         expn_id: LocalExpnId,
         force: bool,
-        derive_paths: &dyn Fn() -> DeriveResolutions,
+        derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
     ) -> Result<(), Indeterminate>;
     /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
     /// back from resolver.
-    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<DeriveResolutions>;
+    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
     /// Path resolution logic for `#[cfg_accessible(path)]`.
     fn cfg_accessible(
         &mut self,
@@ -1264,181 +1256,6 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
     }
 }
 
-/// `Ok` represents successfully retrieving the string literal at the correct
-/// position, e.g., `println("abc")`.
-type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>;
-
-/// - `Ok` is returned when the conversion to a string literal is unsuccessful,
-/// but another type of expression is obtained instead.
-/// - `Err` is returned when the conversion process fails.
-type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>;
-
-/// Extracts a string literal from the macro expanded version of `expr`,
-/// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
-/// The returned bool indicates whether an applicable suggestion has already been
-/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))`
-/// indicates that an ast error was encountered.
-// FIXME(Nilstrieb) Make this function setup translatable
-#[allow(rustc::untranslatable_diagnostic)]
-pub fn expr_to_spanned_string<'a>(
-    cx: &'a mut ExtCtxt<'_>,
-    expr: P<ast::Expr>,
-    err_msg: &'static str,
-) -> ExpandResult<ExprToSpannedStringResult<'a>, ()> {
-    if !cx.force_mode
-        && let ast::ExprKind::MacCall(m) = &expr.kind
-        && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
-    {
-        return ExpandResult::Retry(());
-    }
-
-    // Perform eager expansion on the expression.
-    // We want to be able to handle e.g., `concat!("foo", "bar")`.
-    let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
-
-    ExpandResult::Ready(Err(match expr.kind {
-        ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
-            Ok(ast::LitKind::Str(s, style)) => {
-                return ExpandResult::Ready(Ok((s, style, expr.span)));
-            }
-            Ok(ast::LitKind::ByteStr(..)) => {
-                let mut err = cx.dcx().struct_span_err(expr.span, err_msg);
-                let span = expr.span.shrink_to_lo();
-                err.span_suggestion(
-                    span.with_hi(span.lo() + BytePos(1)),
-                    "consider removing the leading `b`",
-                    "",
-                    Applicability::MaybeIncorrect,
-                );
-                Ok((err, true))
-            }
-            Ok(ast::LitKind::Err(guar)) => Err(guar),
-            Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)),
-            _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
-        },
-        ast::ExprKind::Err(guar) => Err(guar),
-        ast::ExprKind::Dummy => {
-            cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`")
-        }
-        _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
-    }))
-}
-
-/// Extracts a string literal from the macro expanded version of `expr`,
-/// emitting `err_msg` if `expr` is not a string literal. This does not stop
-/// compilation on error, merely emits a non-fatal error and returns `Err`.
-pub fn expr_to_string(
-    cx: &mut ExtCtxt<'_>,
-    expr: P<ast::Expr>,
-    err_msg: &'static str,
-) -> ExpandResult<Result<(Symbol, ast::StrStyle), ErrorGuaranteed>, ()> {
-    expr_to_spanned_string(cx, expr, err_msg).map(|res| {
-        res.map_err(|err| match err {
-            Ok((err, _)) => err.emit(),
-            Err(guar) => guar,
-        })
-        .map(|(symbol, style, _)| (symbol, style))
-    })
-}
-
-/// Non-fatally assert that `tts` is empty. Note that this function
-/// returns even when `tts` is non-empty, macros that *need* to stop
-/// compilation should call `cx.diagnostic().abort_if_errors()`
-/// (this should be done as rarely as possible).
-pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) {
-    if !tts.is_empty() {
-        cx.dcx().emit_err(errors::TakesNoArguments { span, name });
-    }
-}
-
-/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
-pub fn parse_expr(p: &mut parser::Parser<'_>) -> Result<P<ast::Expr>, ErrorGuaranteed> {
-    let guar = match p.parse_expr() {
-        Ok(expr) => return Ok(expr),
-        Err(err) => err.emit(),
-    };
-    while p.token != token::Eof {
-        p.bump();
-    }
-    Err(guar)
-}
-
-/// Interpreting `tts` as a comma-separated sequence of expressions,
-/// expect exactly one string literal, or emit an error and return `Err`.
-pub fn get_single_str_from_tts(
-    cx: &mut ExtCtxt<'_>,
-    span: Span,
-    tts: TokenStream,
-    name: &str,
-) -> ExpandResult<Result<Symbol, ErrorGuaranteed>, ()> {
-    get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s))
-}
-
-pub fn get_single_str_spanned_from_tts(
-    cx: &mut ExtCtxt<'_>,
-    span: Span,
-    tts: TokenStream,
-    name: &str,
-) -> ExpandResult<Result<(Symbol, Span), ErrorGuaranteed>, ()> {
-    let mut p = cx.new_parser_from_tts(tts);
-    if p.token == token::Eof {
-        let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
-        return ExpandResult::Ready(Err(guar));
-    }
-    let ret = match parse_expr(&mut p) {
-        Ok(ret) => ret,
-        Err(guar) => return ExpandResult::Ready(Err(guar)),
-    };
-    let _ = p.eat(&token::Comma);
-
-    if p.token != token::Eof {
-        cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
-    }
-    expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| {
-        res.map_err(|err| match err {
-            Ok((err, _)) => err.emit(),
-            Err(guar) => guar,
-        })
-        .map(|(symbol, _style, span)| (symbol, span))
-    })
-}
-
-/// Extracts comma-separated expressions from `tts`.
-/// On error, emit it, and return `Err`.
-pub fn get_exprs_from_tts(
-    cx: &mut ExtCtxt<'_>,
-    tts: TokenStream,
-) -> ExpandResult<Result<Vec<P<ast::Expr>>, ErrorGuaranteed>, ()> {
-    let mut p = cx.new_parser_from_tts(tts);
-    let mut es = Vec::new();
-    while p.token != token::Eof {
-        let expr = match parse_expr(&mut p) {
-            Ok(expr) => expr,
-            Err(guar) => return ExpandResult::Ready(Err(guar)),
-        };
-        if !cx.force_mode
-            && let ast::ExprKind::MacCall(m) = &expr.kind
-            && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err()
-        {
-            return ExpandResult::Retry(());
-        }
-
-        // Perform eager expansion on the expression.
-        // We want to be able to handle e.g., `concat!("foo", "bar")`.
-        let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
-
-        es.push(expr);
-        if p.eat(&token::Comma) {
-            continue;
-        }
-        if p.token != token::Eof {
-            let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
-            return ExpandResult::Ready(Err(guar));
-        }
-    }
-    ExpandResult::Ready(Ok(es))
-}
-
 pub fn parse_macro_name_and_helper_attrs(
     dcx: &rustc_errors::DiagCtxt,
     attr: &Attribute,
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 83f120525bc..1b6e191c2eb 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -175,20 +175,6 @@ impl<'a> ExtCtxt<'a> {
         ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
     }
 
-    pub fn stmt_let_pat(&self, sp: Span, pat: P<ast::Pat>, ex: P<ast::Expr>) -> ast::Stmt {
-        let local = P(ast::Local {
-            pat,
-            ty: None,
-            id: ast::DUMMY_NODE_ID,
-            kind: LocalKind::Init(ex),
-            span: sp,
-            colon_sp: None,
-            attrs: AttrVec::new(),
-            tokens: None,
-        });
-        self.stmt_local(local, sp)
-    }
-
     pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
         self.stmt_let_ty(sp, mutbl, ident, None, ex)
     }
@@ -278,10 +264,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
     }
 
-    pub fn expr_field(&self, span: Span, expr: P<Expr>, field: Ident) -> P<ast::Expr> {
-        self.expr(span, ast::ExprKind::Field(expr, field))
-    }
-
     pub fn expr_macro_call(&self, span: Span, call: P<ast::MacCall>) -> P<ast::Expr> {
         self.expr(span, ast::ExprKind::MacCall(call))
     }
@@ -394,11 +376,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr(span, ast::ExprKind::Lit(lit))
     }
 
-    pub fn expr_char(&self, span: Span, ch: char) -> P<ast::Expr> {
-        let lit = token::Lit::new(token::Char, literal::escape_char_symbol(ch), None);
-        self.expr(span, ast::ExprKind::Lit(lit))
-    }
-
     pub fn expr_byte_str(&self, span: Span, bytes: Vec<u8>) -> P<ast::Expr> {
         let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None);
         self.expr(span, ast::ExprKind::Lit(lit))
@@ -414,10 +391,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr_addr_of(sp, self.expr_array(sp, exprs))
     }
 
-    pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Cast(expr, ty))
-    }
-
     pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
         self.expr_call_global(sp, some, thin_vec![expr])
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index c95d7cdeb73..897420a11cd 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -20,6 +20,7 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use thin_vec::ThinVec;
+use tracing::instrument;
 
 /// A folder that strips out items that do not belong in the current configuration.
 pub struct StripUnconfigured<'a> {
@@ -98,10 +99,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
             // If the declared feature is unstable, record it.
             if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
                 (f.set_enabled)(&mut features);
-                // When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance
-                // that the person hitting the ICE may be using -Zbuild-std or similar with an untested target.
-                // The bug is probably in the standard library and not the compiler in that case, but that doesn't
-                // really matter - we want a bug report.
+                // When the ICE comes from core, alloc or std (approximation of the standard
+                // library), there's a chance that the person hitting the ICE may be using
+                // -Zbuild-std or similar with an untested target. The bug is probably in the
+                // standard library and not the compiler in that case, but that doesn't really
+                // matter - we want a bug report.
                 if features.internal(name)
                     && ![sym::core, sym::alloc, sym::std].contains(&crate_name)
                 {
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 21ce5e1d81e..b0563bfdea7 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -1,6 +1,6 @@
 use rustc_ast::ast;
 use rustc_errors::codes::*;
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::Limit;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
 use rustc_span::{Span, Symbol};
@@ -153,29 +153,6 @@ pub(crate) struct HelperAttributeNameInvalid {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_expected_comma_in_list)]
-pub(crate) struct ExpectedCommaInList {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(expand_only_one_argument)]
-pub(crate) struct OnlyOneArgument<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub name: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(expand_takes_no_arguments)]
-pub(crate) struct TakesNoArguments<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub name: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(expand_feature_removed, code = E0557)]
 pub(crate) struct FeatureRemoved<'a> {
     #[primary_span]
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 6029caa965c..f61cebc0256 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -4,7 +4,6 @@ use crate::errors::{
     IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported,
     UnsupportedKeyValue, WrongFragmentKind,
 };
-use crate::hygiene::SyntaxContext;
 use crate::mbe::diagnostics::annotate_err_with_kind;
 use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
 use crate::placeholders::{placeholder, PlaceholderExpander};
@@ -32,6 +31,7 @@ use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::feature_err;
 use rustc_session::{Limit, Session};
+use rustc_span::hygiene::SyntaxContext;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span};
 
@@ -87,7 +87,7 @@ macro_rules! ast_fragments {
         }
 
         impl AstFragment {
-            pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
+            fn add_placeholders(&mut self, placeholders: &[NodeId]) {
                 if placeholders.is_empty() {
                     return;
                 }
@@ -100,14 +100,14 @@ macro_rules! ast_fragments {
                 }
             }
 
-            pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
+            pub(crate) fn make_opt_expr(self) -> Option<P<ast::Expr>> {
                 match self {
                     AstFragment::OptExpr(expr) => expr,
                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
                 }
             }
 
-            pub fn make_method_receiver_expr(self) -> P<ast::Expr> {
+            pub(crate) fn make_method_receiver_expr(self) -> P<ast::Expr> {
                 match self {
                     AstFragment::MethodReceiverExpr(expr) => expr,
                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
@@ -125,7 +125,7 @@ macro_rules! ast_fragments {
                 T::fragment_to_output(self)
             }
 
-            pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
+            pub(crate) fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
                 match self {
                     AstFragment::OptExpr(opt_expr) => {
                         visit_clobber(opt_expr, |opt_expr| {
@@ -372,6 +372,14 @@ impl Invocation {
             InvocationKind::Derive { path, .. } => path.span,
         }
     }
+
+    fn span_mut(&mut self) -> &mut Span {
+        match &mut self.kind {
+            InvocationKind::Bang { span, .. } => span,
+            InvocationKind::Attr { attr, .. } => &mut attr.span,
+            InvocationKind::Derive { path, .. } => &mut path.span,
+        }
+    }
 }
 
 pub struct MacroExpander<'a, 'b> {
@@ -432,7 +440,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     break;
                 }
                 invocations = mem::take(&mut undetermined_invocations);
-                force = !mem::replace(&mut progress, false);
+                force = !progress;
+                progress = false;
                 if force && self.monotonic {
                     self.cx.dcx().span_delayed_bug(
                         invocations.last().unwrap().0.span(),
@@ -471,7 +480,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             self.cx.force_mode = force;
 
             let fragment_kind = invoc.fragment_kind;
-            let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
+            match self.expand_invoc(invoc, &ext.kind) {
                 ExpandResult::Ready(fragment) => {
                     let mut derive_invocations = Vec::new();
                     let derive_placeholders = self
@@ -482,7 +491,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                             derive_invocations.reserve(derives.len());
                             derives
                                 .into_iter()
-                                .map(|(path, item, _exts, is_const)| {
+                                .map(|DeriveResolution { path, item, exts: _, is_const }| {
                                     // FIXME: Consider using the derive resolutions (`_exts`)
                                     // instead of enqueuing the derives to be resolved again later.
                                     let expn_id = LocalExpnId::fresh_empty();
@@ -503,12 +512,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         })
                         .unwrap_or_default();
 
-                    let (fragment, collected_invocations) =
+                    let (expanded_fragment, collected_invocations) =
                         self.collect_invocations(fragment, &derive_placeholders);
-                    // We choose to expand any derive invocations associated with this macro invocation
-                    // *before* any macro invocations collected from the output fragment
+                    // We choose to expand any derive invocations associated with this macro
+                    // invocation *before* any macro invocations collected from the output
+                    // fragment.
                     derive_invocations.extend(collected_invocations);
-                    (fragment, derive_invocations)
+
+                    progress = true;
+                    if expanded_fragments.len() < depth {
+                        expanded_fragments.push(Vec::new());
+                    }
+                    expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
+                    invocations.extend(derive_invocations.into_iter().rev());
                 }
                 ExpandResult::Retry(invoc) => {
                     if force {
@@ -519,17 +535,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     } else {
                         // Cannot expand, will retry this invocation later.
                         undetermined_invocations.push((invoc, Some(ext)));
-                        continue;
                     }
                 }
-            };
-
-            progress = true;
-            if expanded_fragments.len() < depth {
-                expanded_fragments.push(Vec::new());
             }
-            expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
-            invocations.extend(new_invocations.into_iter().rev());
         }
 
         self.cx.current_expansion = orig_expansion_data;
@@ -590,11 +598,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 for (invoc, _) in invocations.iter_mut() {
                     let expn_id = invoc.expansion_data.id;
                     let parent_def = self.cx.resolver.invocation_parent(expn_id);
-                    let span = match &mut invoc.kind {
-                        InvocationKind::Bang { span, .. } => span,
-                        InvocationKind::Attr { attr, .. } => &mut attr.span,
-                        InvocationKind::Derive { path, .. } => &mut path.span,
-                    };
+                    let span = invoc.span_mut();
                     *span = span.with_parent(Some(parent_def));
                 }
             }
@@ -957,7 +961,7 @@ pub fn parse_ast_fragment<'a>(
     })
 }
 
-pub fn ensure_complete_parse<'a>(
+pub(crate) fn ensure_complete_parse<'a>(
     parser: &Parser<'a>,
     macro_path: &ast::Path,
     kind_name: &str,
@@ -1218,7 +1222,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
         fragment.make_trait_items()
     }
     fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        noop_flat_map_assoc_item(self.wrapped, visitor)
+        noop_flat_map_item(self.wrapped, visitor)
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1243,7 +1247,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
         fragment.make_impl_items()
     }
     fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        noop_flat_map_assoc_item(self.wrapped, visitor)
+        noop_flat_map_item(self.wrapped, visitor)
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
@@ -1266,7 +1270,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
         fragment.make_foreign_items()
     }
     fn noop_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
-        noop_flat_map_foreign_item(self, visitor)
+        noop_flat_map_item(self, visitor)
     }
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ForeignItemKind::MacCall(..))
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index c9a3aeedd02..c2c3b777699 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,50 +1,39 @@
+// tidy-alphabetical-start
+#![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![doc(rust_logo)]
-#![feature(rustdoc_internals)]
 #![feature(array_windows)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(associated_type_defaults)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
-#![feature(lint_reasons)]
 #![feature(macro_metavar_expr)]
 #![feature(map_try_insert)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
-#![feature(proc_macro_span)]
+#![feature(rustdoc_internals)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
-#![allow(rustc::diagnostic_outside_of_impl)]
-#![allow(internal_features)]
-
-#[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
-extern crate tracing;
+// tidy-alphabetical-end
 
 extern crate proc_macro as pm;
 
+mod build;
+mod errors;
+// FIXME(Nilstrieb) Translate macro_rules diagnostics
+#[allow(rustc::untranslatable_diagnostic)]
+mod mbe;
 mod placeholders;
 mod proc_macro_server;
 
 pub use mbe::macro_rules::compile_declarative_macro;
-pub(crate) use rustc_span::hygiene;
 pub mod base;
-pub mod build;
-#[macro_use]
 pub mod config;
-pub mod errors;
 pub mod expand;
 pub mod module;
-
 // FIXME(Nilstrieb) Translate proc_macro diagnostics
 #[allow(rustc::untranslatable_diagnostic)]
 pub mod proc_macro;
 
-// FIXME(Nilstrieb) Translate macro_rules diagnostics
-#[allow(rustc::untranslatable_diagnostic)]
-pub(crate) mod mbe;
-
 // HACK(Centril, #64197): These shouldn't really be here.
 // Rather, they should be with their respective modules which are defined in other crates.
 // However, since for now constructing a `ParseSess` sorta requires `config` from this crate,
diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs
index ca4a1f327ad..a805c4fcf7b 100644
--- a/compiler/rustc_expand/src/mbe.rs
+++ b/compiler/rustc_expand/src/mbe.rs
@@ -4,16 +4,18 @@
 //! official terminology: "declarative macros".
 
 pub(crate) mod diagnostics;
-pub(crate) mod macro_check;
-pub(crate) mod macro_parser;
 pub(crate) mod macro_rules;
-pub(crate) mod metavar_expr;
-pub(crate) mod quoted;
-pub(crate) mod transcribe;
+
+mod macro_check;
+mod macro_parser;
+mod metavar_expr;
+mod quoted;
+mod transcribe;
 
 use metavar_expr::MetaVarExpr;
 use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan};
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 15193298cca..464361cb402 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -8,11 +8,13 @@ use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, Diag, DiagCtxt, DiagMessage};
+use rustc_macros::Subdiagnostic;
 use rustc_parse::parser::{Parser, Recovery};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Ident;
 use rustc_span::{ErrorGuaranteed, Span};
 use std::borrow::Cow;
+use tracing::debug;
 
 use super::macro_rules::{parser_from_cx, NoopTracker};
 
@@ -26,7 +28,8 @@ pub(super) fn failed_to_match_macro<'cx>(
 ) -> Box<dyn MacResult + 'cx> {
     let psess = &cx.sess.psess;
 
-    // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics.
+    // An error occurred, try the expansion again, tracking the expansion closely for better
+    // diagnostics.
     let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
 
     let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker);
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 7099f1b0d35..470bde232d7 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -29,6 +29,7 @@ use rustc_span::edition::Edition;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
 use rustc_span::Span;
+use tracing::{debug, instrument, trace, trace_span};
 
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
@@ -156,8 +157,8 @@ pub(super) trait Tracker<'matcher> {
     /// This is called before trying to match next MatcherLoc on the current token.
     fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {}
 
-    /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
-    /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
+    /// This is called after an arm has been parsed, either successfully or unsuccessfully. When
+    /// this is called, `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
     fn after_arm(&mut self, _result: &NamedParseResult<Self::Failure>) {}
 
     /// For tracing.
@@ -168,7 +169,8 @@ pub(super) trait Tracker<'matcher> {
     }
 }
 
-/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization.
+/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to
+/// monomorphization.
 pub(super) struct NoopTracker;
 
 impl<'matcher> Tracker<'matcher> for NoopTracker {
@@ -491,7 +493,7 @@ pub fn compile_declarative_macro(
                     .pop()
                     .unwrap();
                     // We don't handle errors here, the driver will abort
-                    // after parsing/expansion. we can report every error in every macro this way.
+                    // after parsing/expansion. We can report every error in every macro this way.
                     check_emission(check_lhs_nt_follows(sess, def, &tt));
                     return tt;
                 }
@@ -527,7 +529,7 @@ pub fn compile_declarative_macro(
         check_emission(check_rhs(sess, rhs));
     }
 
-    // don't abort iteration early, so that errors for multiple lhses can be reported
+    // Don't abort iteration early, so that errors for multiple lhses can be reported.
     for lhs in &lhses {
         check_emission(check_lhs_no_empty_seq(sess, slice::from_ref(lhs)));
     }
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index 81e1de5b095..8239cfd46cb 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree};
 use rustc_ast::{LitIntType, LitKind};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, PResult};
+use rustc_macros::{Decodable, Encodable};
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index dad83984c8b..011aa95c8a1 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -39,26 +39,32 @@ impl MutVisitor for Marker {
 }
 
 /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
-enum Frame<'a> {
-    Delimited {
-        tts: &'a [mbe::TokenTree],
-        idx: usize,
-        delim: Delimiter,
-        span: DelimSpan,
-        spacing: DelimSpacing,
-    },
-    Sequence {
-        tts: &'a [mbe::TokenTree],
-        idx: usize,
-        sep: Option<Token>,
-        kleene_op: KleeneOp,
-    },
+struct Frame<'a> {
+    tts: &'a [mbe::TokenTree],
+    idx: usize,
+    kind: FrameKind,
+}
+
+enum FrameKind {
+    Delimited { delim: Delimiter, span: DelimSpan, spacing: DelimSpacing },
+    Sequence { sep: Option<Token>, kleene_op: KleeneOp },
 }
 
 impl<'a> Frame<'a> {
-    /// Construct a new frame around the delimited set of tokens.
-    fn new(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
-        Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span, spacing }
+    fn new_delimited(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
+        Frame {
+            tts: &src.tts,
+            idx: 0,
+            kind: FrameKind::Delimited { delim: src.delim, span, spacing },
+        }
+    }
+
+    fn new_sequence(
+        src: &'a mbe::SequenceRepetition,
+        sep: Option<Token>,
+        kleene_op: KleeneOp,
+    ) -> Frame<'a> {
+        Frame { tts: &src.tts, idx: 0, kind: FrameKind::Sequence { sep, kleene_op } }
     }
 }
 
@@ -66,13 +72,9 @@ impl<'a> Iterator for Frame<'a> {
     type Item = &'a mbe::TokenTree;
 
     fn next(&mut self) -> Option<&'a mbe::TokenTree> {
-        match self {
-            Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => {
-                let res = tts.get(*idx);
-                *idx += 1;
-                res
-            }
-        }
+        let res = self.tts.get(self.idx);
+        self.idx += 1;
+        res
     }
 }
 
@@ -111,13 +113,16 @@ pub(super) fn transcribe<'a>(
     // We descend into the RHS (`src`), expanding things as we go. This stack contains the things
     // we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
     // choice of spacing values doesn't matter.
-    let mut stack: SmallVec<[Frame<'_>; 1]> =
-        smallvec![Frame::new(src, src_span, DelimSpacing::new(Spacing::Alone, Spacing::Alone))];
+    let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new_delimited(
+        src,
+        src_span,
+        DelimSpacing::new(Spacing::Alone, Spacing::Alone)
+    )];
 
     // As we descend in the RHS, we will need to be able to match nested sequences of matchers.
     // `repeats` keeps track of where we are in matching at each level, with the last element being
     // the most deeply nested sequence. This is used as a stack.
-    let mut repeats = Vec::new();
+    let mut repeats: Vec<(usize, usize)> = Vec::new();
 
     // `result` contains resulting token stream from the TokenTree we just finished processing. At
     // the end, this will contain the full result of transcription, but at arbitrary points during
@@ -142,11 +147,12 @@ pub(super) fn transcribe<'a>(
 
             // Otherwise, if we have just reached the end of a sequence and we can keep repeating,
             // go back to the beginning of the sequence.
-            if let Frame::Sequence { idx, sep, .. } = stack.last_mut().unwrap() {
+            let frame = stack.last_mut().unwrap();
+            if let FrameKind::Sequence { sep, .. } = &frame.kind {
                 let (repeat_idx, repeat_len) = repeats.last_mut().unwrap();
                 *repeat_idx += 1;
                 if repeat_idx < repeat_len {
-                    *idx = 0;
+                    frame.idx = 0;
                     if let Some(sep) = sep {
                         result.push(TokenTree::Token(sep.clone(), Spacing::Alone));
                     }
@@ -157,16 +163,16 @@ pub(super) fn transcribe<'a>(
             // We are done with the top of the stack. Pop it. Depending on what it was, we do
             // different things. Note that the outermost item must be the delimited, wrapped RHS
             // that was passed in originally to `transcribe`.
-            match stack.pop().unwrap() {
+            match stack.pop().unwrap().kind {
                 // Done with a sequence. Pop from repeats.
-                Frame::Sequence { .. } => {
+                FrameKind::Sequence { .. } => {
                     repeats.pop();
                 }
 
                 // We are done processing a Delimited. If this is the top-level delimited, we are
                 // done. Otherwise, we unwind the result_stack to append what we have produced to
                 // any previous results.
-                Frame::Delimited { delim, span, mut spacing, .. } => {
+                FrameKind::Delimited { delim, span, mut spacing, .. } => {
                     // Hack to force-insert a space after `]` in certain case.
                     // See discussion of the `hex-literal` crate in #114571.
                     if delim == Delimiter::Bracket {
@@ -192,7 +198,7 @@ pub(super) fn transcribe<'a>(
             // We are descending into a sequence. We first make sure that the matchers in the RHS
             // and the matches in `interp` have the same shape. Otherwise, either the caller or the
             // macro writer has made a mistake.
-            seq @ mbe::TokenTree::Sequence(_, delimited) => {
+            seq @ mbe::TokenTree::Sequence(_, seq_rep) => {
                 match lockstep_iter_size(seq, interp, &repeats) {
                     LockstepIterSize::Unconstrained => {
                         return Err(cx
@@ -233,12 +239,11 @@ pub(super) fn transcribe<'a>(
                             // The first time we encounter the sequence we push it to the stack. It
                             // then gets reused (see the beginning of the loop) until we are done
                             // repeating.
-                            stack.push(Frame::Sequence {
-                                idx: 0,
-                                sep: seq.separator.clone(),
-                                tts: &delimited.tts,
-                                kleene_op: seq.kleene.op,
-                            });
+                            stack.push(Frame::new_sequence(
+                                seq_rep,
+                                seq.separator.clone(),
+                                seq.kleene.op,
+                            ));
                         }
                     }
                 }
@@ -294,13 +299,7 @@ pub(super) fn transcribe<'a>(
             // the previous results (from outside the Delimited).
             mbe::TokenTree::Delimited(mut span, spacing, delimited) => {
                 mut_visit::visit_delim_span(&mut span, &mut marker);
-                stack.push(Frame::Delimited {
-                    tts: &delimited.tts,
-                    delim: delimited.delim,
-                    idx: 0,
-                    span,
-                    spacing: *spacing,
-                });
+                stack.push(Frame::new_delimited(delimited, span, *spacing));
                 result_stack.push(mem::take(&mut result));
             }
 
@@ -358,10 +357,13 @@ fn maybe_use_metavar_location(
 ) -> TokenTree {
     let undelimited_seq = matches!(
         stack.last(),
-        Some(Frame::Sequence {
+        Some(Frame {
             tts: [_],
-            sep: None,
-            kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
+            kind: FrameKind::Sequence {
+                sep: None,
+                kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
+                ..
+            },
             ..
         })
     );
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 2c4187031ca..7026425e167 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -9,7 +9,7 @@ use rustc_span::DUMMY_SP;
 use smallvec::{smallvec, SmallVec};
 use thin_vec::ThinVec;
 
-pub fn placeholder(
+pub(crate) fn placeholder(
     kind: AstFragmentKind,
     id: ast::NodeId,
     vis: Option<ast::Visibility>,
@@ -271,14 +271,14 @@ impl MutVisitor for PlaceholderExpander {
     fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
         match item.kind {
             ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_trait_items(),
-            _ => noop_flat_map_assoc_item(item, self),
+            _ => noop_flat_map_item(item, self),
         }
     }
 
     fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
         match item.kind {
             ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_impl_items(),
-            _ => noop_flat_map_assoc_item(item, self),
+            _ => noop_flat_map_item(item, self),
         }
     }
 
@@ -288,7 +288,7 @@ impl MutVisitor for PlaceholderExpander {
     ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
         match item.kind {
             ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
-            _ => noop_flat_map_foreign_item(item, self),
+            _ => noop_flat_map_item(item, self),
         }
     }
 
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index de2bd60ffad..943cc632857 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -60,7 +60,7 @@ declare_features! (
     /// Allows the definition of associated constants in `trait` or `impl` blocks.
     (accepted, associated_consts, "1.20.0", Some(29646)),
     /// Allows the user of associated type bounds.
-    (accepted, associated_type_bounds, "CURRENT_RUSTC_VERSION", Some(52662)),
+    (accepted, associated_type_bounds, "1.79.0", Some(52662)),
     /// Allows using associated `type`s in `trait`s.
     (accepted, associated_types, "1.0.0", None),
     /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
@@ -99,7 +99,7 @@ declare_features! (
     /// Allows using the CMPXCHG16B target feature.
     (accepted, cmpxchg16b_target_feature, "1.69.0", Some(44839)),
     /// Allows use of the `#[collapse_debuginfo]` attribute.
-    (accepted, collapse_debuginfo, "CURRENT_RUSTC_VERSION", Some(100758)),
+    (accepted, collapse_debuginfo, "1.79.0", Some(100758)),
     /// Allows usage of the `compile_error!` macro.
     (accepted, compile_error, "1.20.0", Some(40872)),
     /// Allows `impl Trait` in function return types.
@@ -208,13 +208,13 @@ declare_features! (
     /// Allows referencing `Self` and projections in impl-trait.
     (accepted, impl_trait_projections, "1.74.0", Some(103532)),
     /// Allows using imported `main` function
-    (accepted, imported_main, "CURRENT_RUSTC_VERSION", Some(28937)),
+    (accepted, imported_main, "1.79.0", Some(28937)),
     /// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237)),
     /// Allows inferring outlives requirements (RFC 2093).
     (accepted, infer_outlives_requirements, "1.30.0", Some(44493)),
     /// Allow anonymous constants from an inline `const` block
-    (accepted, inline_const, "CURRENT_RUSTC_VERSION", Some(76001)),
+    (accepted, inline_const, "1.79.0", Some(76001)),
     /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
     (accepted, irrefutable_let_patterns, "1.33.0", Some(44495)),
     /// Allows `#[instruction_set(_)]` attribute.
@@ -360,7 +360,7 @@ declare_features! (
     /// Allows macros to appear in the type position.
     (accepted, type_macros, "1.13.0", Some(27245)),
     /// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
-    (accepted, type_privacy_lints, "CURRENT_RUSTC_VERSION", Some(48054)),
+    (accepted, type_privacy_lints, "1.79.0", Some(48054)),
     /// Allows `const _: TYPE = VALUE`.
     (accepted, underscore_const_names, "1.37.0", Some(54912)),
     /// Allows `use path as _;` and `extern crate c as _;`.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 132e2ddee29..e7d7a9f380b 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -216,7 +216,7 @@ declare_features! (
     /// Set the maximum pattern complexity allowed (not limited by default).
     (internal, pattern_complexity, "1.78.0", None),
     /// Allows using pattern types.
-    (internal, pattern_types, "CURRENT_RUSTC_VERSION", Some(123646)),
+    (internal, pattern_types, "1.79.0", Some(123646)),
     /// Allows using `#[prelude_import]` on glob `use` items.
     (internal, prelude_import, "1.2.0", None),
     /// Used to identify crates that contain the profiler runtime.
@@ -384,7 +384,7 @@ declare_features! (
     /// Allows `cfg(target_thread_local)`.
     (unstable, cfg_target_thread_local, "1.7.0", Some(29594)),
     /// Allows the use of `#[cfg(ub_checks)` to check if UB checks are enabled.
-    (unstable, cfg_ub_checks, "CURRENT_RUSTC_VERSION", Some(123499)),
+    (unstable, cfg_ub_checks, "1.79.0", Some(123499)),
     /// Allow conditional compilation depending on rust version
     (unstable, cfg_version, "1.45.0", Some(64796)),
     /// Allows to use the `#[cfi_encoding = ""]` attribute.
@@ -439,7 +439,7 @@ declare_features! (
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (unstable, deprecated_suggestion, "1.61.0", Some(94785)),
     /// Allows deref patterns.
-    (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121)),
+    (incomplete, deref_patterns, "1.79.0", Some(87121)),
     /// Controls errors in trait implementations.
     (unstable, do_not_recommend, "1.67.0", Some(51992)),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
@@ -530,9 +530,9 @@ declare_features! (
     /// Allows the `#[must_not_suspend]` attribute.
     (unstable, must_not_suspend, "1.57.0", Some(83310)),
     /// Make `mut` not reset the binding mode on edition >= 2024.
-    (incomplete, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
+    (incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)),
     /// Allows `mut ref` and `mut ref mut` identifier patterns.
-    (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)),
+    (incomplete, mut_ref, "1.79.0", Some(123076)),
     /// Allows using `#[naked]` on functions.
     (unstable, naked_functions, "1.9.0", Some(90957)),
     /// Allows specifying the as-needed link modifier
@@ -564,17 +564,17 @@ declare_features! (
     /// Allows using `#[optimize(X)]`.
     (unstable, optimize_attribute, "1.34.0", Some(54882)),
     /// Allows postfix match `expr.match { ... }`
-    (unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)),
+    (unstable, postfix_match, "1.79.0", Some(121618)),
     /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.
-    (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)),
+    (incomplete, precise_capturing, "1.79.0", Some(123432)),
     /// Allows macro attributes on expressions, statements and non-inline modules.
     (unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
     /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
     (unstable, raw_ref_op, "1.41.0", Some(64490)),
     /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
-    (incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
+    (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
     /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
-    (incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
+    (incomplete, ref_pat_everywhere, "1.79.0", Some(123076)),
     /// Allows using the `#[register_tool]` attribute.
     (unstable, register_tool, "1.41.0", Some(66079)),
     /// Allows the `#[repr(i128)]` attribute for enums.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 37d9b2ffd6a..649a08b6972 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -5,7 +5,7 @@ use rustc_ast as ast;
 use rustc_ast::NodeId;
 use rustc_data_structures::stable_hasher::ToStableHashKey;
 use rustc_data_structures::unord::UnordMap;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::kw;
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index cd5da279a26..35833e258d5 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -7,14 +7,14 @@
 pub use crate::def_id::DefPathHash;
 use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::def_path_hash_map::DefPathHashMap;
-
 use rustc_data_structures::stable_hasher::{Hash64, StableHasher};
 use rustc_data_structures::unord::UnordMap;
 use rustc_index::IndexVec;
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::symbol::{kw, sym, Symbol};
-
 use std::fmt::{self, Write};
 use std::hash::Hash;
+use tracing::{debug, instrument};
 
 /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1646ea50fb0..fc8f7466694 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3,7 +3,6 @@ use crate::def_id::{DefId, LocalDefIdMap};
 pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
 use crate::intravisit::FnKind;
 use crate::LangItem;
-
 use rustc_ast as ast;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
@@ -13,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_index::IndexVec;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -21,9 +20,9 @@ use rustc_span::ErrorGuaranteed;
 use rustc_span::{def_id::LocalDefId, BytePos, Span, DUMMY_SP};
 use rustc_target::asm::InlineAsmRegOrRegClass;
 use rustc_target::spec::abi::Abi;
-
 use smallvec::SmallVec;
 use std::fmt;
+use tracing::debug;
 
 #[derive(Debug, Copy, Clone, HashStable_Generic)]
 pub struct Lifetime {
@@ -3863,6 +3862,7 @@ impl<'hir> Node<'hir> {
 #[cfg(target_pointer_width = "64")]
 mod size_asserts {
     use super::*;
+    use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
     static_assert_size!(Block<'_>, 48);
     static_assert_size!(Body<'_>, 24);
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 0341a482fa8..ac487469507 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -1,5 +1,6 @@
 use crate::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_ID};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::{def_id::DefPathHash, HashStableContext};
 use std::fmt::{self, Debug};
 
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 6aee1183a10..e870a04127a 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -12,7 +12,7 @@ use crate::{MethodKind, Target};
 
 use rustc_ast as ast;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
@@ -56,7 +56,7 @@ macro_rules! language_item_table {
         $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
     ) => {
 
-        enum_from_u32! {
+        rustc_data_structures::enum_from_u32! {
             /// A representation of all the valid lang items in Rust.
             #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
             pub enum LangItem {
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index c5c4075c6ba..600a0dce03b 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -10,15 +10,6 @@
 #![feature(variant_count)]
 #![allow(internal_features)]
 
-#[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
-extern crate tracing;
-
-#[macro_use]
-extern crate rustc_data_structures;
-
 extern crate self as rustc_hir;
 
 mod arena;
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 06b5ee299b8..3edea0191fa 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -201,6 +201,12 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
     .help = consider moving this inherent impl into the crate defining the type if possible
     .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
 
+hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}`
+    .note = type of `self` must be `Self` or a type that dereferences to it
+
+hir_analysis_invalid_receiver_ty_help =
+    consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
 hir_analysis_invalid_union_field =
     field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
     .note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
@@ -486,13 +492,13 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
 
 hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}`
 
-hir_analysis_ty_param_first_local = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
-    .label = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
+hir_analysis_ty_param_first_local = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
+    .label = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
     .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
     .case_note = in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
 
-hir_analysis_ty_param_some = type parameter `{$param_ty}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param_ty}>`)
-    .label = type parameter `{$param_ty}` must be used as the type parameter for some local type
+hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param}>`)
+    .label = type parameter `{$param}` must be used as the type parameter for some local type
     .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
     .only_note = only traits defined in the current crate can be implemented for a type parameter
 
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index f2ceb470264..f101c595bdf 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -1,6 +1,6 @@
 use crate::errors::AutoDerefReachedRecursionLimit;
+use crate::traits;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::{self, TraitEngine, TraitEngineExt};
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -8,7 +8,7 @@ use rustc_session::Limit;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::Span;
-use rustc_trait_selection::traits::StructurallyNormalizeExt;
+use rustc_trait_selection::traits::ObligationCtxt;
 
 #[derive(Copy, Clone, Debug)]
 pub enum AutoderefKind {
@@ -167,25 +167,19 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
         &self,
         ty: Ty<'tcx>,
     ) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> {
-        let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.infcx);
-
-        let cause = traits::ObligationCause::misc(self.span, self.body_id);
-        let normalized_ty = match self
-            .infcx
-            .at(&cause, self.param_env)
-            .structurally_normalize(ty, &mut *fulfill_cx)
-        {
-            Ok(normalized_ty) => normalized_ty,
-            Err(errors) => {
-                // This shouldn't happen, except for evaluate/fulfill mismatches,
-                // but that's not a reason for an ICE (`predicate_may_hold` is conservative
-                // by design).
-                debug!(?errors, "encountered errors while fulfilling");
-                return None;
-            }
+        let ocx = ObligationCtxt::new(self.infcx);
+        let Ok(normalized_ty) = ocx.structurally_normalize(
+            &traits::ObligationCause::misc(self.span, self.body_id),
+            self.param_env,
+            ty,
+        ) else {
+            // We shouldn't have errors here, except for evaluate/fulfill mismatches,
+            // but that's not a reason for an ICE (`predicate_may_hold` is conservative
+            // by design).
+            // FIXME(-Znext-solver): This *actually* shouldn't happen then.
+            return None;
         };
-
-        let errors = fulfill_cx.select_where_possible(self.infcx);
+        let errors = ocx.select_where_possible();
         if !errors.is_empty() {
             // This shouldn't happen, except for evaluate/fulfill mismatches,
             // but that's not a reason for an ICE (`predicate_may_hold` is conservative
@@ -194,7 +188,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        Some((normalized_ty, fulfill_cx.pending_obligations()))
+        Some((normalized_ty, ocx.into_pending_obligations()))
     }
 
     /// Returns the final type we ended up with, which may be an inference
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 74324c8695b..eb1fa1baecc 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -208,11 +208,11 @@ pub fn check_intrinsic_type(
                 Ty::new_tup(tcx, &[param(0), tcx.types.bool]),
             ),
             "load" => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
-            "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)),
+            "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit),
 
             "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax"
             | "umin" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
-            "fence" | "singlethreadfence" => (0, Vec::new(), Ty::new_unit(tcx)),
+            "fence" | "singlethreadfence" => (0, Vec::new(), tcx.types.unit),
             op => {
                 tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op });
                 return;
@@ -224,7 +224,7 @@ pub fn check_intrinsic_type(
         let (n_tps, n_cts, inputs, output) = match intrinsic_name {
             sym::abort => (0, 0, vec![], tcx.types.never),
             sym::unreachable => (0, 0, vec![], tcx.types.never),
-            sym::breakpoint => (0, 0, vec![], Ty::new_unit(tcx)),
+            sym::breakpoint => (0, 0, vec![], tcx.types.unit),
             sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
                 (1, 0, vec![], tcx.types.usize)
             }
@@ -235,14 +235,14 @@ pub fn check_intrinsic_type(
             sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
             sym::assert_inhabited
             | sym::assert_zero_valid
-            | sym::assert_mem_uninitialized_valid => (1, 0, vec![], Ty::new_unit(tcx)),
-            sym::forget => (1, 0, vec![param(0)], Ty::new_unit(tcx)),
+            | sym::assert_mem_uninitialized_valid => (1, 0, vec![], tcx.types.unit),
+            sym::forget => (1, 0, vec![param(0)], tcx.types.unit),
             sym::transmute | sym::transmute_unchecked => (2, 0, vec![param(0)], param(1)),
             sym::prefetch_read_data
             | sym::prefetch_write_data
             | sym::prefetch_read_instruction
             | sym::prefetch_write_instruction => {
-                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], tcx.types.unit)
             }
             sym::needs_drop => (1, 0, vec![], tcx.types.bool),
 
@@ -270,7 +270,7 @@ pub fn check_intrinsic_type(
                     Ty::new_mut_ptr(tcx, param(0)),
                     tcx.types.usize,
                 ],
-                Ty::new_unit(tcx),
+                tcx.types.unit,
             ),
             sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
                 1,
@@ -280,7 +280,7 @@ pub fn check_intrinsic_type(
                     Ty::new_imm_ptr(tcx, param(0)),
                     tcx.types.usize,
                 ],
-                Ty::new_unit(tcx),
+                tcx.types.unit,
             ),
             sym::compare_bytes => {
                 let byte_ptr = Ty::new_imm_ptr(tcx, tcx.types.u8);
@@ -290,7 +290,7 @@ pub fn check_intrinsic_type(
                 1,
                 0,
                 vec![Ty::new_mut_ptr(tcx, param(0)), tcx.types.u8, tcx.types.usize],
-                Ty::new_unit(tcx),
+                tcx.types.unit,
             ),
 
             sym::sqrtf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16),
@@ -409,7 +409,7 @@ pub fn check_intrinsic_type(
                 (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
             }
             sym::volatile_store | sym::unaligned_volatile_store => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
             }
 
             sym::ctpop | sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => {
@@ -440,7 +440,7 @@ pub fn check_intrinsic_type(
                 0,
                 1,
                 vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
-                Ty::new_unit(tcx),
+                tcx.types.unit,
             ),
 
             sym::ptr_offset_from => (
@@ -477,16 +477,16 @@ pub fn check_intrinsic_type(
             | sym::frem_algebraic => (1, 0, vec![param(0), param(0)], param(0)),
             sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
 
-            sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)),
+            sym::assume => (0, 1, vec![tcx.types.bool], tcx.types.unit),
             sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
             sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
 
             sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
             sym::write_via_move => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
             }
 
-            sym::typed_swap => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)); 2], Ty::new_unit(tcx)),
+            sym::typed_swap => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit),
 
             sym::discriminant_value => {
                 let assoc_items = tcx.associated_item_def_ids(
@@ -511,14 +511,14 @@ pub fn check_intrinsic_type(
                 let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
                 let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
                     [mut_u8],
-                    Ty::new_unit(tcx),
+                    tcx.types.unit,
                     false,
                     hir::Unsafety::Normal,
                     Abi::Rust,
                 ));
                 let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
                     [mut_u8, mut_u8],
-                    Ty::new_unit(tcx),
+                    tcx.types.unit,
                     false,
                     hir::Unsafety::Normal,
                     Abi::Rust,
@@ -532,14 +532,14 @@ pub fn check_intrinsic_type(
             }
 
             sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
-                Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], Ty::new_unit(tcx)),
+                Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], tcx.types.unit),
                 None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
             },
 
             sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
                 Some((va_list_ref_ty, va_list_ty)) => {
                     let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
-                    (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx))
+                    (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit)
                 }
                 None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
             },
@@ -550,7 +550,7 @@ pub fn check_intrinsic_type(
             },
 
             sym::nontemporal_store => {
-                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+                (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
             }
 
             sym::raw_eq => {
@@ -570,7 +570,7 @@ pub fn check_intrinsic_type(
             sym::const_eval_select => (4, 1, vec![param(0), param(1), param(2)], param(3)),
 
             sym::vtable_size | sym::vtable_align => {
-                (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
+                (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
             }
 
             // This type check is not particularly useful, but the `where` bounds
@@ -623,8 +623,8 @@ pub fn check_intrinsic_type(
             sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)),
             sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
             sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
-            sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
-            sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
+            sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
+            sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit),
             sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
             sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
             sym::simd_cast
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index c26f982fa47..5b127e0bf49 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -2,6 +2,7 @@ use crate::autoderef::Autoderef;
 use crate::collect::CollectItemTypesVisitor;
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 use crate::errors;
+use crate::fluent_generated as fluent;
 
 use hir::intravisit::Visitor;
 use rustc_ast as ast;
@@ -1636,10 +1637,6 @@ fn check_fn_or_method<'tcx>(
     }
 }
 
-const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
-     `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
-     of the previous types except `Self`)";
-
 #[instrument(level = "debug", skip(wfcx))]
 fn check_method_receiver<'tcx>(
     wfcx: &WfCheckingCtxt<'_, 'tcx>,
@@ -1675,7 +1672,7 @@ fn check_method_receiver<'tcx>(
     if tcx.features().arbitrary_self_types {
         if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
             // Report error; `arbitrary_self_types` was enabled.
-            return Err(e0307(tcx, span, receiver_ty));
+            return Err(tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }));
         }
     } else {
         if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
@@ -1690,24 +1687,17 @@ fn check_method_receiver<'tcx>(
                          the `arbitrary_self_types` feature",
                     ),
                 )
-                .with_help(HELP_FOR_SELF_TYPE)
+                .with_help(fluent::hir_analysis_invalid_receiver_ty_help)
                 .emit()
             } else {
                 // Report error; would not have worked with `arbitrary_self_types`.
-                e0307(tcx, span, receiver_ty)
+                tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
             });
         }
     }
     Ok(())
 }
 
-fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
-    struct_span_code_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}")
-        .with_note("type of `self` must be `Self` or a type that dereferences to it")
-        .with_help(HELP_FOR_SELF_TYPE)
-        .emit()
-}
-
 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 5585d2e069c..819e0925f68 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -2,14 +2,20 @@
 //! crate or pertains to a type defined in this crate.
 
 use crate::errors;
+
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir as hir;
-use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt};
-use rustc_span::def_id::LocalDefId;
-use rustc_span::Span;
-use rustc_trait_selection::traits::{self, IsFirstInputType};
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
+use rustc_span::def_id::{DefId, LocalDefId};
+use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams};
+use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode};
+use rustc_trait_selection::traits::{StructurallyNormalizeExt, TraitEngineExt};
 
-#[instrument(skip(tcx), level = "debug")]
+#[instrument(level = "debug", skip(tcx))]
 pub(crate) fn orphan_check_impl(
     tcx: TyCtxt<'_>,
     impl_def_id: LocalDefId,
@@ -17,31 +23,23 @@ pub(crate) fn orphan_check_impl(
     let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
     trait_ref.error_reported()?;
 
-    let trait_def_id = trait_ref.def_id;
-
-    match traits::orphan_check(tcx, impl_def_id.to_def_id()) {
+    match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) {
         Ok(()) => {}
-        Err(err) => {
-            let item = tcx.hir().expect_item(impl_def_id);
-            let hir::ItemKind::Impl(impl_) = item.kind else {
-                bug!("{:?} is not an impl: {:?}", impl_def_id, item);
-            };
-            let tr = impl_.of_trait.as_ref().unwrap();
-            let sp = tcx.def_span(impl_def_id);
-
-            emit_orphan_check_error(
-                tcx,
-                sp,
-                item.span,
-                tr.path.span,
-                trait_ref,
-                impl_.self_ty.span,
-                impl_.generics,
-                err,
-            )?
-        }
+        Err(err) => match orphan_check(tcx, impl_def_id, OrphanCheckMode::Compat) {
+            Ok(()) => match err {
+                OrphanCheckErr::UncoveredTyParams(uncovered_ty_params) => {
+                    lint_uncovered_ty_params(tcx, uncovered_ty_params, impl_def_id)
+                }
+                OrphanCheckErr::NonLocalInputType(_) => {
+                    bug!("orphanck: shouldn't've gotten non-local input tys in compat mode")
+                }
+            },
+            Err(err) => return Err(emit_orphan_check_error(tcx, trait_ref, impl_def_id, err)),
+        },
     }
 
+    let trait_def_id = trait_ref.def_id;
+
     // In addition to the above rules, we restrict impls of auto traits
     // so that they can only be implemented on nominal types, such as structs,
     // enums or foreign types. To see why this restriction exists, consider the
@@ -186,13 +184,13 @@ pub(crate) fn orphan_check_impl(
                     //     type This = T;
                     // }
                     // impl<T: ?Sized> AutoTrait for <T as Id>::This {}
-                    AliasKind::Projection => "associated type",
+                    ty::Projection => "associated type",
                     // type Foo = (impl Sized, bool)
                     // impl AutoTrait for Foo {}
-                    AliasKind::Weak => "type alias",
+                    ty::Weak => "type alias",
                     // type Opaque = impl Trait;
                     // impl AutoTrait for Opaque {}
-                    AliasKind::Opaque => "opaque type",
+                    ty::Opaque => "opaque type",
                     // ```
                     // struct S<T>(T);
                     // impl<T: ?Sized> S<T> {
@@ -201,7 +199,7 @@ pub(crate) fn orphan_check_impl(
                     // impl<T: ?Sized> AutoTrait for S<T>::This {}
                     // ```
                     // FIXME(inherent_associated_types): The example code above currently leads to a cycle
-                    AliasKind::Inherent => "associated type",
+                    ty::Inherent => "associated type",
                 };
                 (LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
             }
@@ -275,34 +273,126 @@ pub(crate) fn orphan_check_impl(
     Ok(())
 }
 
+/// Checks the coherence orphan rules.
+///
+/// `impl_def_id` should be the `DefId` of a trait impl.
+///
+/// To pass, either the trait must be local, or else two conditions must be satisfied:
+///
+/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
+/// 2. Some local type must appear in `Self`.
+#[instrument(level = "debug", skip(tcx), ret)]
+fn orphan_check<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    impl_def_id: LocalDefId,
+    mode: OrphanCheckMode,
+) -> Result<(), OrphanCheckErr<'tcx, FxIndexSet<DefId>>> {
+    // We only accept this routine to be invoked on implementations
+    // of a trait, not inherent implementations.
+    let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
+    debug!(trait_ref = ?trait_ref.skip_binder());
+
+    // If the *trait* is local to the crate, ok.
+    if let Some(def_id) = trait_ref.skip_binder().def_id.as_local() {
+        debug!("trait {def_id:?} is local to current crate");
+        return Ok(());
+    }
+
+    // (1)  Instantiate all generic params with fresh inference vars.
+    let infcx = tcx.infer_ctxt().intercrate(true).build();
+    let cause = traits::ObligationCause::dummy();
+    let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id());
+    let trait_ref = trait_ref.instantiate(tcx, args);
+
+    let lazily_normalize_ty = |user_ty: Ty<'tcx>| {
+        let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) };
+
+        let ocx = traits::ObligationCtxt::new(&infcx);
+        let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty);
+        let ty = infcx.resolve_vars_if_possible(ty);
+        let errors = ocx.select_where_possible();
+        if !errors.is_empty() {
+            return Ok(user_ty);
+        }
+
+        let ty = if infcx.next_trait_solver() {
+            let mut fulfill_cx = <dyn traits::TraitEngine<'_>>::new(&infcx);
+            infcx
+                .at(&cause, ty::ParamEnv::empty())
+                .structurally_normalize(ty, &mut *fulfill_cx)
+                .map(|ty| infcx.resolve_vars_if_possible(ty))
+                .unwrap_or(ty)
+        } else {
+            ty
+        };
+
+        Ok(ty)
+    };
+
+    let Ok(result) = traits::orphan_check_trait_ref::<!>(
+        &infcx,
+        trait_ref,
+        traits::InCrate::Local { mode },
+        lazily_normalize_ty,
+    ) else {
+        unreachable!()
+    };
+
+    // (2)  Try to map the remaining inference vars back to generic params.
+    result.map_err(|err| match err {
+        OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
+            let mut collector =
+                UncoveredTyParamCollector { infcx: &infcx, uncovered_params: Default::default() };
+            uncovered.visit_with(&mut collector);
+            // FIXME(fmease): This is very likely reachable.
+            debug_assert!(!collector.uncovered_params.is_empty());
+
+            OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
+                uncovered: collector.uncovered_params,
+                local_ty,
+            })
+        }
+        OrphanCheckErr::NonLocalInputType(tys) => {
+            let generics = tcx.generics_of(impl_def_id);
+            let tys = tys
+                .into_iter()
+                .map(|(ty, is_target_ty)| {
+                    (ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty)
+                })
+                .collect();
+            OrphanCheckErr::NonLocalInputType(tys)
+        }
+    })
+}
+
 fn emit_orphan_check_error<'tcx>(
     tcx: TyCtxt<'tcx>,
-    sp: Span,
-    full_impl_span: Span,
-    trait_span: Span,
     trait_ref: ty::TraitRef<'tcx>,
-    self_ty_span: Span,
-    generics: &hir::Generics<'tcx>,
-    err: traits::OrphanCheckErr<'tcx>,
-) -> Result<!, ErrorGuaranteed> {
-    let self_ty = trait_ref.self_ty();
-    Err(match err {
+    impl_def_id: LocalDefId,
+    err: traits::OrphanCheckErr<'tcx, FxIndexSet<DefId>>,
+) -> ErrorGuaranteed {
+    match err {
         traits::OrphanCheckErr::NonLocalInputType(tys) => {
-            let mut diag = tcx.dcx().create_err(match self_ty.kind() {
-                ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () },
-                _ if self_ty.is_primitive() => {
-                    errors::OnlyCurrentTraits::Primitive { span: sp, note: () }
+            let item = tcx.hir().expect_item(impl_def_id);
+            let impl_ = item.expect_impl();
+            let hir_trait_ref = impl_.of_trait.as_ref().unwrap();
+
+            let span = tcx.def_span(impl_def_id);
+            let mut diag = tcx.dcx().create_err(match trait_ref.self_ty().kind() {
+                ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span, note: () },
+                _ if trait_ref.self_ty().is_primitive() => {
+                    errors::OnlyCurrentTraits::Primitive { span, note: () }
                 }
-                _ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () },
+                _ => errors::OnlyCurrentTraits::Arbitrary { span, note: () },
             });
 
             for &(mut ty, is_target_ty) in &tys {
                 let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
                     // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
-                    self_ty_span
+                    impl_.self_ty.span
                 } else {
                     // Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
-                    trait_span
+                    hir_trait_ref.path.span
                 };
 
                 ty = tcx.erase_regions(ty);
@@ -354,12 +444,12 @@ fn emit_orphan_check_error<'tcx>(
                         diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
                     }
                     ty::RawPtr(ptr_ty, mutbl) => {
-                        if !self_ty.has_param() {
+                        if !trait_ref.self_ty().has_param() {
                             diag.subdiagnostic(
                                 tcx.dcx(),
                                 errors::OnlyCurrentTraitsPointerSugg {
-                                    wrapper_span: self_ty_span,
-                                    struct_span: full_impl_span.shrink_to_lo(),
+                                    wrapper_span: impl_.self_ty.span,
+                                    struct_span: item.span.shrink_to_lo(),
                                     mut_key: mutbl.prefix_str(),
                                     ptr_ty,
                                 },
@@ -387,23 +477,112 @@ fn emit_orphan_check_error<'tcx>(
 
             diag.emit()
         }
-        traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
-            let mut sp = sp;
-            for param in generics.params {
-                if param.name.ident().to_string() == param_ty.to_string() {
-                    sp = param.span;
-                }
-            }
+        traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => {
+            let mut reported = None;
+            for param_def_id in uncovered {
+                let span = tcx.def_ident_span(param_def_id).unwrap();
+                let name = tcx.item_name(param_def_id);
 
-            match local_type {
-                Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal {
-                    span: sp,
-                    note: (),
-                    param_ty,
-                    local_type,
-                }),
-                None => tcx.dcx().emit_err(errors::TyParamSome { span: sp, note: (), param_ty }),
+                reported.get_or_insert(match local_ty {
+                    Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal {
+                        span,
+                        note: (),
+                        param: name,
+                        local_type,
+                    }),
+                    None => tcx.dcx().emit_err(errors::TyParamSome { span, note: (), param: name }),
+                });
             }
+            reported.unwrap() // FIXME(fmease): This is very likely reachable.
         }
-    })
+    }
+}
+
+fn lint_uncovered_ty_params<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams<'tcx, FxIndexSet<DefId>>,
+    impl_def_id: LocalDefId,
+) {
+    let hir_id = tcx.local_def_id_to_hir_id(impl_def_id);
+
+    for param_def_id in uncovered {
+        let span = tcx.def_ident_span(param_def_id).unwrap();
+        let name = tcx.item_name(param_def_id);
+
+        match local_ty {
+            Some(local_type) => tcx.emit_node_span_lint(
+                UNCOVERED_PARAM_IN_PROJECTION,
+                hir_id,
+                span,
+                errors::TyParamFirstLocalLint { span, note: (), param: name, local_type },
+            ),
+            None => tcx.emit_node_span_lint(
+                UNCOVERED_PARAM_IN_PROJECTION,
+                hir_id,
+                span,
+                errors::TyParamSomeLint { span, note: (), param: name },
+            ),
+        };
+    }
+}
+
+struct UncoveredTyParamCollector<'cx, 'tcx> {
+    infcx: &'cx InferCtxt<'tcx>,
+    uncovered_params: FxIndexSet<DefId>,
+}
+
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
+        if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
+            return;
+        }
+        let Some(origin) = self.infcx.type_var_origin(ty) else {
+            return ty.super_visit_with(self);
+        };
+        if let Some(def_id) = origin.param_def_id {
+            self.uncovered_params.insert(def_id);
+        }
+    }
+
+    fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
+        if ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
+            ct.super_visit_with(self)
+        }
+    }
+}
+
+struct TyVarReplacer<'cx, 'tcx> {
+    infcx: &'cx InferCtxt<'tcx>,
+    generics: &'tcx ty::Generics,
+}
+
+impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> {
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
+            return ty;
+        }
+        let Some(origin) = self.infcx.type_var_origin(ty) else {
+            return ty.super_fold_with(self);
+        };
+        if let Some(def_id) = origin.param_def_id {
+            // The generics of an `impl` don't have a parent, we can index directly.
+            let index = self.generics.param_def_id_to_index[&def_id];
+            let name = self.generics.params[index as usize].name;
+
+            Ty::new_param(self.infcx.tcx, index, name)
+        } else {
+            ty
+        }
+    }
+
+    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+        if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
+            return ct;
+        }
+        ct.super_fold_with(self)
+    }
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 599f25147ce..0f0736f8756 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -386,6 +386,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
 
     fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
         let ty = self.tcx.fold_regions(ty, |r, _| match *r {
+            rustc_type_ir::RegionKind::ReStatic => r,
+
             // This is never reached in practice. If it ever is reached,
             // `ReErased` should be changed to `ReStatic`, and any other region
             // left alone.
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 867ee772a30..1c99713b3ae 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1355,29 +1355,54 @@ pub struct CrossCrateTraitsDefined {
     pub traits: String,
 }
 
+// FIXME(fmease): Deduplicate:
+
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ty_param_first_local, code = E0210)]
 #[note]
-pub struct TyParamFirstLocal<'a> {
+pub struct TyParamFirstLocal<'tcx> {
     #[primary_span]
     #[label]
     pub span: Span,
     #[note(hir_analysis_case_note)]
     pub note: (),
-    pub param_ty: Ty<'a>,
-    pub local_type: Ty<'a>,
+    pub param: Symbol,
+    pub local_type: Ty<'tcx>,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(hir_analysis_ty_param_first_local, code = E0210)]
+#[note]
+pub struct TyParamFirstLocalLint<'tcx> {
+    #[label]
+    pub span: Span,
+    #[note(hir_analysis_case_note)]
+    pub note: (),
+    pub param: Symbol,
+    pub local_type: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_ty_param_some, code = E0210)]
 #[note]
-pub struct TyParamSome<'a> {
+pub struct TyParamSome {
     #[primary_span]
     #[label]
     pub span: Span,
     #[note(hir_analysis_only_note)]
     pub note: (),
-    pub param_ty: Ty<'a>,
+    pub param: Symbol,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(hir_analysis_ty_param_some, code = E0210)]
+#[note]
+pub struct TyParamSomeLint {
+    #[label]
+    pub span: Span,
+    #[note(hir_analysis_only_note)]
+    pub note: (),
+    pub param: Symbol,
 }
 
 #[derive(Diagnostic)]
@@ -1641,3 +1666,13 @@ pub struct NonConstRange {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_invalid_receiver_ty, code = E0307)]
+#[note]
+#[help(hir_analysis_invalid_receiver_ty_help)]
+pub struct InvalidReceiverTy<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub receiver_ty: Ty<'tcx>,
+}
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 63da27246a2..f7213442ac2 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2370,7 +2370,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     self.lower_ty(output)
                 }
             }
-            hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx),
+            hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
         };
 
         debug!(?output_ty);
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 07b4948872d..0560d0d902a 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -99,6 +99,17 @@ hir_typeck_lossy_provenance_ptr2int =
 
 hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
 
+hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function
+    .help = specify the type explicitly
+hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference
+    .help = specify the type explicitly
+hir_typeck_never_type_fallback_flowing_into_unsafe_method = never type fallback affects this call to an `unsafe` method
+    .help = specify the type explicitly
+hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback affects this `unsafe` function
+    .help = specify the type explicitly
+hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access
+    .help = specify the type explicitly
+
 hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
     [true] {""}
     *[other] {" "}in the current scope
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 334a424d2e2..4ff6678fc91 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -66,7 +66,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // us to give better error messages (pointing to a usually better
                 // arm for inconsistent arms or to the whole match when a `()` type
                 // is required).
-                Expectation::ExpectHasType(ety) if ety != Ty::new_unit(self.tcx) => ety,
+                Expectation::ExpectHasType(ety) if ety != tcx.types.unit => ety,
                 _ => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }),
             };
             CoerceMany::with_coercion_sites(coerce_first, arms)
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index d6704d9e44f..4883c7aff8b 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -342,7 +342,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates(
                 Ty::new_var(self.tcx, self.root_var(vid)),
                 closure_kind,
-                self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)),
+                self.obligations_for_self_ty(vid)
+                    .into_iter()
+                    .map(|obl| (obl.predicate, obl.cause.span)),
             ),
             ty::FnPtr(sig) => match closure_kind {
                 hir::ClosureKind::Closure => {
@@ -889,7 +891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let output_ty = match *ret_ty.kind() {
             ty::Infer(ty::TyVar(ret_vid)) => {
-                self.obligations_for_self_ty(ret_vid).find_map(|obligation| {
+                self.obligations_for_self_ty(ret_vid).into_iter().find_map(|obligation| {
                     get_future_output(obligation.predicate, obligation.cause.span)
                 })?
             }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 4165fa7f07d..076c1936ded 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -45,8 +45,7 @@ use rustc_hir::Expr;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
 use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
-use rustc_infer::traits::TraitEngineExt as _;
-use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine};
+use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause};
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::traits::BuiltinImplSource;
@@ -65,7 +64,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc_trait_selection::traits::TraitEngineExt as _;
 use rustc_trait_selection::traits::{
     self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
@@ -164,11 +162,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             // Filter these cases out to make sure our coercion is more accurate.
             match res {
                 Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligations(self, obligations);
-                    let errs = fulfill_cx.select_where_possible(self);
-                    if errs.is_empty() {
-                        Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligations(obligations);
+                    if ocx.select_where_possible().is_empty() {
+                        Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
                     } else {
                         Err(TypeError::Mismatch)
                     }
@@ -631,13 +628,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 // but we need to constrain vars before processing goals mentioning
                 // them.
                 Some(ty::PredicateKind::AliasRelate(..)) => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligation(self, obligation);
-                    let errs = fulfill_cx.select_where_possible(self);
-                    if !errs.is_empty() {
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligation(obligation);
+                    if !ocx.select_where_possible().is_empty() {
                         return Err(TypeError::Mismatch);
                     }
-                    coercion.obligations.extend(fulfill_cx.pending_obligations());
+                    coercion.obligations.extend(ocx.into_pending_obligations());
                     continue;
                 }
                 _ => {
@@ -1462,7 +1458,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
             fcx,
             cause,
             None,
-            Ty::new_unit(fcx.tcx),
+            fcx.tcx.types.unit,
             augment_error,
             label_unit_as_expected,
         )
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 1c4d5657b17..ba8f246fd8d 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -164,6 +164,25 @@ pub struct MissingParenthesesInRange {
     pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
 }
 
+#[derive(LintDiagnostic)]
+pub enum NeverTypeFallbackFlowingIntoUnsafe {
+    #[help]
+    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
+    Call,
+    #[help]
+    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
+    Method,
+    #[help]
+    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
+    Path,
+    #[help]
+    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
+    UnionField,
+    #[help]
+    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
+    Deref,
+}
+
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(
     hir_typeck_add_missing_parentheses_in_range,
@@ -632,7 +651,6 @@ pub enum SuggestBoxingForReturnImplTrait {
         ends: Vec<Span>,
     },
 }
-
 #[derive(LintDiagnostic)]
 #[diag(hir_typeck_dereferencing_mut_binding)]
 pub struct DereferencingMutBinding {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 48b9142b014..8b1ea7c952c 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1,6 +1,6 @@
 //! Type checking expressions.
 //!
-//! See `mod.rs` for more context on type checking in general.
+//! See [`rustc_hir_analysis::check`] for more context on type checking in general.
 
 use crate::cast;
 use crate::coercion::CoerceMany;
@@ -654,7 +654,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 // Otherwise, this is a break *without* a value. That's
                 // always legal, and is equivalent to `break ()`.
-                e_ty = Ty::new_unit(tcx);
+                e_ty = tcx.types.unit;
                 cause = self.misc(expr.span);
             }
 
@@ -1133,7 +1133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // The expected type is `bool` but this will result in `()` so we can reasonably
             // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
             // The likely cause of this is `if foo = bar { .. }`.
-            let actual_ty = Ty::new_unit(self.tcx);
+            let actual_ty = self.tcx.types.unit;
             let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
             let lhs_ty = self.check_expr(lhs);
             let rhs_ty = self.check_expr(rhs);
@@ -1256,7 +1256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let Err(guar) = (lhs_ty, rhs_ty).error_reported() {
             Ty::new_error(self.tcx, guar)
         } else {
-            Ty::new_unit(self.tcx)
+            self.tcx.types.unit
         }
     }
 
@@ -1319,7 +1319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if ctxt.coerce.is_none() && !ctxt.may_break {
             self.dcx().span_bug(body.span, "no coercion, but loop may not break");
         }
-        ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| Ty::new_unit(self.tcx))
+        ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.types.unit)
     }
 
     /// Checks a method call.
@@ -3174,7 +3174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.dcx().emit_err(YieldExprOutsideOfCoroutine { span: expr.span });
                 // Avoid expressions without types during writeback (#78653).
                 self.check_expr(value);
-                Ty::new_unit(self.tcx)
+                self.tcx.types.unit
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index c0b3984e3e1..f240a53a679 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -1,11 +1,18 @@
-use crate::FnCtxt;
+use std::cell::OnceCell;
+
+use crate::{errors, FnCtxt, TypeckRootCtxt};
 use rustc_data_structures::{
     graph::{self, iterate::DepthFirstSearch, vec_graph::VecGraph},
     unord::{UnordBag, UnordMap, UnordSet},
 };
+use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
+use rustc_hir::HirId;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
+use rustc_session::lint;
 use rustc_span::DUMMY_SP;
+use rustc_span::{def_id::LocalDefId, Span};
 
 #[derive(Copy, Clone)]
 pub enum DivergingFallbackBehavior {
@@ -335,6 +342,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         // reach a member of N. If so, it falls back to `()`. Else
         // `!`.
         let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
+        let unsafe_infer_vars = OnceCell::new();
         for &diverging_vid in &diverging_vids {
             let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
             let root_vid = self.root_var(diverging_vid);
@@ -354,11 +362,51 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 output: infer_var_infos.items().any(|info| info.output),
             };
 
+            let mut fallback_to = |ty| {
+                let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| {
+                    let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id);
+                    debug!(?unsafe_infer_vars);
+                    unsafe_infer_vars
+                });
+
+                let affected_unsafe_infer_vars =
+                    graph::depth_first_search_as_undirected(&coercion_graph, root_vid)
+                        .filter_map(|x| unsafe_infer_vars.get(&x).copied())
+                        .collect::<Vec<_>>();
+
+                for (hir_id, span, reason) in affected_unsafe_infer_vars {
+                    self.tcx.emit_node_span_lint(
+                        lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
+                        hir_id,
+                        span,
+                        match reason {
+                            UnsafeUseReason::Call => {
+                                errors::NeverTypeFallbackFlowingIntoUnsafe::Call
+                            }
+                            UnsafeUseReason::Method => {
+                                errors::NeverTypeFallbackFlowingIntoUnsafe::Method
+                            }
+                            UnsafeUseReason::Path => {
+                                errors::NeverTypeFallbackFlowingIntoUnsafe::Path
+                            }
+                            UnsafeUseReason::UnionField => {
+                                errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
+                            }
+                            UnsafeUseReason::Deref => {
+                                errors::NeverTypeFallbackFlowingIntoUnsafe::Deref
+                            }
+                        },
+                    );
+                }
+
+                diverging_fallback.insert(diverging_ty, ty);
+            };
+
             use DivergingFallbackBehavior::*;
             match behavior {
                 FallbackToUnit => {
                     debug!("fallback to () - legacy: {:?}", diverging_vid);
-                    diverging_fallback.insert(diverging_ty, self.tcx.types.unit);
+                    fallback_to(self.tcx.types.unit);
                 }
                 FallbackToNiko => {
                     if found_infer_var_info.self_in_trait && found_infer_var_info.output {
@@ -387,13 +435,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                         // set, see the relationship finding module in
                         // compiler/rustc_trait_selection/src/traits/relationships.rs.
                         debug!("fallback to () - found trait and projection: {:?}", diverging_vid);
-                        diverging_fallback.insert(diverging_ty, self.tcx.types.unit);
+                        fallback_to(self.tcx.types.unit);
                     } else if can_reach_non_diverging {
                         debug!("fallback to () - reached non-diverging: {:?}", diverging_vid);
-                        diverging_fallback.insert(diverging_ty, self.tcx.types.unit);
+                        fallback_to(self.tcx.types.unit);
                     } else {
                         debug!("fallback to ! - all diverging: {:?}", diverging_vid);
-                        diverging_fallback.insert(diverging_ty, self.tcx.types.never);
+                        fallback_to(self.tcx.types.never);
                     }
                 }
                 FallbackToNever => {
@@ -401,7 +449,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                         "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}",
                         diverging_vid
                     );
-                    diverging_fallback.insert(diverging_ty, self.tcx.types.never);
+                    fallback_to(self.tcx.types.never);
                 }
                 NoFallback => {
                     debug!(
@@ -417,7 +465,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
 
     /// Returns a graph whose nodes are (unresolved) inference variables and where
     /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`.
-    fn create_coercion_graph(&self) -> VecGraph<ty::TyVid> {
+    fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> {
         let pending_obligations = self.fulfillment_cx.borrow_mut().pending_obligations();
         debug!("create_coercion_graph: pending_obligations={:?}", pending_obligations);
         let coercion_edges: Vec<(ty::TyVid, ty::TyVid)> = pending_obligations
@@ -436,17 +484,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 //
                 // In practice currently the two ways that this happens is
                 // coercion and subtyping.
-                let (a, b) = if let ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) = atom {
-                    (a, b)
-                } else if let ty::PredicateKind::Subtype(ty::SubtypePredicate {
-                    a_is_expected: _,
-                    a,
-                    b,
-                }) = atom
-                {
-                    (a, b)
-                } else {
-                    return None;
+                let (a, b) = match atom {
+                    ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => (a, b),
+                    ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => {
+                        (a, b)
+                    }
+                    _ => return None,
                 };
 
                 let a_vid = self.root_vid(a)?;
@@ -456,6 +499,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
             .collect();
         debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges);
         let num_ty_vars = self.num_ty_vars();
+
         VecGraph::new(num_ty_vars, coercion_edges)
     }
 
@@ -464,3 +508,166 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
     }
 }
+
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum UnsafeUseReason {
+    Call,
+    Method,
+    Path,
+    UnionField,
+    Deref,
+}
+
+/// Finds all type variables which are passed to an `unsafe` operation.
+///
+/// For example, for this function `f`:
+/// ```ignore (demonstrative)
+/// fn f() {
+///     unsafe {
+///         let x /* ?X */ = core::mem::zeroed();
+///         //               ^^^^^^^^^^^^^^^^^^^ -- hir_id, span, reason
+///
+///         let y = core::mem::zeroed::<Option<_ /* ?Y */>>();
+///         //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- hir_id, span, reason
+///     }
+/// }
+/// ```
+///
+/// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }`
+fn compute_unsafe_infer_vars<'a, 'tcx>(
+    root_ctxt: &'a TypeckRootCtxt<'tcx>,
+    body_id: LocalDefId,
+) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> {
+    let body_id =
+        root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner");
+    let body = root_ctxt.tcx.hir().body(body_id);
+    let mut res = UnordMap::default();
+
+    struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> {
+        root_ctxt: &'a TypeckRootCtxt<'tcx>,
+        res: &'r mut UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>,
+    }
+
+    impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_, '_> {
+        fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
+            let typeck_results = self.root_ctxt.typeck_results.borrow();
+
+            match ex.kind {
+                hir::ExprKind::MethodCall(..) => {
+                    if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
+                        && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity()
+                        && let sig = method_ty.fn_sig(self.root_ctxt.tcx)
+                        && let hir::Unsafety::Unsafe = sig.unsafety()
+                    {
+                        let mut collector = InferVarCollector {
+                            value: (ex.hir_id, ex.span, UnsafeUseReason::Method),
+                            res: self.res,
+                        };
+
+                        // Collect generic arguments (incl. `Self`) of the method
+                        typeck_results
+                            .node_args(ex.hir_id)
+                            .types()
+                            .for_each(|t| t.visit_with(&mut collector));
+                    }
+                }
+
+                hir::ExprKind::Call(func, ..) => {
+                    let func_ty = typeck_results.expr_ty(func);
+
+                    if func_ty.is_fn()
+                        && let sig = func_ty.fn_sig(self.root_ctxt.tcx)
+                        && let hir::Unsafety::Unsafe = sig.unsafety()
+                    {
+                        let mut collector = InferVarCollector {
+                            value: (ex.hir_id, ex.span, UnsafeUseReason::Call),
+                            res: self.res,
+                        };
+
+                        // Try collecting generic arguments of the function.
+                        // Note that we do this below for any paths (that don't have to be called),
+                        // but there we do it with a different span/reason.
+                        // This takes priority.
+                        typeck_results
+                            .node_args(func.hir_id)
+                            .types()
+                            .for_each(|t| t.visit_with(&mut collector));
+
+                        // Also check the return type, for cases like `returns_unsafe_fn_ptr()()`
+                        sig.output().visit_with(&mut collector);
+                    }
+                }
+
+                // Check paths which refer to functions.
+                // We do this, instead of only checking `Call` to make sure the lint can't be
+                // avoided by storing unsafe function in a variable.
+                hir::ExprKind::Path(_) => {
+                    let ty = typeck_results.expr_ty(ex);
+
+                    // If this path refers to an unsafe function, collect inference variables which may affect it.
+                    // `is_fn` excludes closures, but those can't be unsafe.
+                    if ty.is_fn()
+                        && let sig = ty.fn_sig(self.root_ctxt.tcx)
+                        && let hir::Unsafety::Unsafe = sig.unsafety()
+                    {
+                        let mut collector = InferVarCollector {
+                            value: (ex.hir_id, ex.span, UnsafeUseReason::Path),
+                            res: self.res,
+                        };
+
+                        // Collect generic arguments of the function
+                        typeck_results
+                            .node_args(ex.hir_id)
+                            .types()
+                            .for_each(|t| t.visit_with(&mut collector));
+                    }
+                }
+
+                hir::ExprKind::Unary(hir::UnOp::Deref, pointer) => {
+                    if let ty::RawPtr(pointee, _) = typeck_results.expr_ty(pointer).kind() {
+                        pointee.visit_with(&mut InferVarCollector {
+                            value: (ex.hir_id, ex.span, UnsafeUseReason::Deref),
+                            res: self.res,
+                        });
+                    }
+                }
+
+                hir::ExprKind::Field(base, _) => {
+                    let base_ty = typeck_results.expr_ty(base);
+
+                    if base_ty.is_union() {
+                        typeck_results.expr_ty(ex).visit_with(&mut InferVarCollector {
+                            value: (ex.hir_id, ex.span, UnsafeUseReason::UnionField),
+                            res: self.res,
+                        });
+                    }
+                }
+
+                _ => (),
+            };
+
+            hir::intravisit::walk_expr(self, ex);
+        }
+    }
+
+    struct InferVarCollector<'r, V> {
+        value: V,
+        res: &'r mut UnordMap<ty::TyVid, V>,
+    }
+
+    impl<'tcx, V: Copy> ty::TypeVisitor<TyCtxt<'tcx>> for InferVarCollector<'_, V> {
+        fn visit_ty(&mut self, t: Ty<'tcx>) {
+            if let Some(vid) = t.ty_vid() {
+                _ = self.res.try_insert(vid, self.value);
+            } else {
+                t.super_visit_with(self)
+            }
+        }
+    }
+
+    UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value);
+
+    debug!(?res, "collected the following unsafe vars for {body_id:?}");
+
+    res
+}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 0ba5d187864..2060e08aacf 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -3,7 +3,6 @@ use crate::errors::CtorIsPrivate;
 use crate::method::{self, MethodCallee, SelfSource};
 use crate::rvalue_scopes;
 use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey};
 use rustc_hir as hir;
@@ -47,7 +46,7 @@ use std::slice;
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Produces warning on the given node, if the current point in the
     /// function is unreachable, and there hasn't been another warning.
-    pub(in super::super) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) {
+    pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) {
         // FIXME: Combine these two 'if' expressions into one once
         // let chains are implemented
         if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
@@ -87,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // FIXME(-Znext-solver): A lot of the calls to this method should
     // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead.
     #[instrument(skip(self), level = "debug", ret)]
-    pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub(crate) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
         // No Infer()? Nothing needs doing.
         if !ty.has_non_region_infer() {
             debug!("no inference var, nothing needs doing");
@@ -109,7 +108,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.resolve_vars_if_possible(ty)
     }
 
-    pub(in super::super) fn record_deferred_call_resolution(
+    pub(crate) fn record_deferred_call_resolution(
         &self,
         closure_def_id: LocalDefId,
         r: DeferredCallResolution<'tcx>,
@@ -118,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
     }
 
-    pub(in super::super) fn remove_deferred_call_resolutions(
+    pub(crate) fn remove_deferred_call_resolutions(
         &self,
         closure_def_id: LocalDefId,
     ) -> Vec<DeferredCallResolution<'tcx>> {
@@ -172,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    pub(in super::super) fn write_resolution(
+    pub(crate) fn write_resolution(
         &self,
         hir_id: HirId,
         r: Result<(DefKind, DefId), ErrorGuaranteed>,
@@ -336,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Instantiates and normalizes the bounds for a given item
-    pub(in super::super) fn instantiate_bounds(
+    pub(crate) fn instantiate_bounds(
         &self,
         span: Span,
         def_id: DefId,
@@ -349,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         result
     }
 
-    pub(in super::super) fn normalize<T>(&self, span: Span, value: T) -> T
+    pub(crate) fn normalize<T>(&self, span: Span, value: T) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
@@ -537,7 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.normalize(span, field.ty(self.tcx, args))
     }
 
-    pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) {
+    pub(crate) fn resolve_rvalue_scopes(&self, def_id: DefId) {
         let scope_tree = self.tcx.region_scope_tree(def_id);
         let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) };
         let mut typeck_results = self.typeck_results.borrow_mut();
@@ -553,7 +552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// We must not attempt to select obligations after this method has run, or risk query cycle
     /// ICE.
     #[instrument(level = "debug", skip(self))]
-    pub(in super::super) fn resolve_coroutine_interiors(&self) {
+    pub(crate) fn resolve_coroutine_interiors(&self) {
         // Try selecting all obligations that are not blocked on inference variables.
         // Once we start unifying coroutine witnesses, trying to select obligations on them will
         // trigger query cycle ICEs, as doing so requires MIR.
@@ -594,7 +593,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    pub(in super::super) fn report_ambiguity_errors(&self) {
+    pub(crate) fn report_ambiguity_errors(&self) {
         let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors(self);
 
         if !errors.is_empty() {
@@ -609,7 +608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Select as many obligations as we can at present.
-    pub(in super::super) fn select_obligations_where_possible(
+    pub(crate) fn select_obligations_where_possible(
         &self,
         mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
     ) {
@@ -625,7 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// returns a type of `&T`, but the actual type we assign to the
     /// *expression* is `T`. So this function just peels off the return
     /// type by one layer to yield `T`.
-    pub(in super::super) fn make_overloaded_place_return_type(
+    pub(crate) fn make_overloaded_place_return_type(
         &self,
         method: MethodCallee<'tcx>,
     ) -> ty::TypeAndMut<'tcx> {
@@ -636,67 +635,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ret_ty.builtin_deref(true).unwrap()
     }
 
-    #[instrument(skip(self), level = "debug")]
-    fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
-        let self_ty = self.shallow_resolve(self_ty);
-        debug!(?self_ty);
-
-        match *self_ty.kind() {
-            ty::Infer(ty::TyVar(found_vid)) => {
-                let found_vid = self.root_var(found_vid);
-                debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
-                expected_vid == found_vid
-            }
-            _ => false,
-        }
-    }
-
-    #[instrument(skip(self), level = "debug")]
-    pub(in super::super) fn obligations_for_self_ty<'b>(
-        &'b self,
-        self_ty: ty::TyVid,
-    ) -> impl DoubleEndedIterator<Item = traits::PredicateObligation<'tcx>> + Captures<'tcx> + 'b
-    {
-        let ty_var_root = self.root_var(self_ty);
-        trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations());
-
-        self.fulfillment_cx.borrow().pending_obligations().into_iter().filter_map(
-            move |obligation| match &obligation.predicate.kind().skip_binder() {
-                ty::PredicateKind::Clause(ty::ClauseKind::Projection(data))
-                    if self.self_type_matches_expected_vid(
-                        data.projection_ty.self_ty(),
-                        ty_var_root,
-                    ) =>
-                {
-                    Some(obligation)
-                }
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(data))
-                    if self.self_type_matches_expected_vid(data.self_ty(), ty_var_root) =>
-                {
-                    Some(obligation)
-                }
-
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
-                | ty::PredicateKind::Subtype(..)
-                | ty::PredicateKind::Coerce(..)
-                | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
-                | ty::PredicateKind::ObjectSafe(..)
-                | ty::PredicateKind::NormalizesTo(..)
-                | ty::PredicateKind::AliasRelate(..)
-                | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
-                | ty::PredicateKind::ConstEquate(..)
-                | ty::PredicateKind::Ambiguous => None,
-            },
-        )
-    }
-
-    pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
+    pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
         let sized_did = self.tcx.lang_items().sized_trait();
-        self.obligations_for_self_ty(self_ty).any(|obligation| {
+        self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
             match obligation.predicate.kind().skip_binder() {
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
                     Some(data.def_id()) == sized_did
@@ -706,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         })
     }
 
-    pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
+    pub(crate) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
         let ty_error = Ty::new_misc_error(self.tcx);
         vec![ty_error; len]
     }
@@ -714,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Unifies the output type with the expected type early, for more coercions
     /// and forward type information on the input expressions.
     #[instrument(skip(self, call_span), level = "debug")]
-    pub(in super::super) fn expected_inputs_for_expected_output(
+    pub(crate) fn expected_inputs_for_expected_output(
         &self,
         call_span: Span,
         expected_ret: Expectation<'tcx>,
@@ -747,7 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expect_args
     }
 
-    pub(in super::super) fn resolve_lang_item_path(
+    pub(crate) fn resolve_lang_item_path(
         &self,
         lang_item: hir::LangItem,
         span: Span,
@@ -926,7 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// but we often want access to the parent function's signature.
     ///
     /// Otherwise, return false.
-    pub(in super::super) fn get_node_fn_decl(
+    pub(crate) fn get_node_fn_decl(
         &self,
         node: Node<'tcx>,
     ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
@@ -1004,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         })
     }
 
-    pub(in super::super) fn note_internal_mutation_in_method(
+    pub(crate) fn note_internal_mutation_in_method(
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'_>,
@@ -1549,7 +1490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(in super::super) fn with_breakable_ctxt<F: FnOnce() -> R, R>(
+    pub(crate) fn with_breakable_ctxt<F: FnOnce() -> R, R>(
         &self,
         id: HirId,
         ctxt: BreakableCtxt<'tcx>,
@@ -1575,7 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Instantiate a QueryResponse in a probe context, without a
     /// good ObligationCause.
-    pub(in super::super) fn probe_instantiate_query_response(
+    pub(crate) fn probe_instantiate_query_response(
         &self,
         span: Span,
         original_values: &OriginalQueryValues<'tcx>,
@@ -1590,7 +1531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
-    pub(in super::super) fn expr_in_place(&self, mut expr_id: HirId) -> bool {
+    pub(crate) fn expr_in_place(&self, mut expr_id: HirId) -> bool {
         let mut contained_in_place = false;
 
         while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index b729fbe844a..e45e0884aff 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1660,7 +1660,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir::StmtKind::Item(_) => {}
             hir::StmtKind::Expr(ref expr) => {
                 // Check with expected type of `()`.
-                self.check_expr_has_type_or_error(expr, Ty::new_unit(self.tcx), |err| {
+                self.check_expr_has_type_or_error(expr, self.tcx.types.unit, |err| {
                     if expr.can_have_side_effects() {
                         self.suggest_semicolon_at_end(expr.span, err);
                     }
@@ -1676,7 +1676,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
-        let unit = Ty::new_unit(self.tcx);
+        let unit = self.tcx.types.unit;
         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
 
         // if the block produces a `!` value, that can always be
@@ -1794,7 +1794,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         blk.span,
                                         blk.hir_id,
                                         expected_ty,
-                                        Ty::new_unit(self.tcx),
+                                        self.tcx.types.unit,
                                     );
                                 }
                                 if !self.err_ctxt().consider_removing_semicolon(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
new file mode 100644
index 00000000000..c2068d9f66b
--- /dev/null
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
@@ -0,0 +1,140 @@
+//! A utility module to inspect currently ambiguous obligations in the current context.
+use crate::rustc_middle::ty::TypeVisitableExt;
+use crate::FnCtxt;
+use rustc_infer::traits::solve::Goal;
+use rustc_infer::traits::{self, ObligationCause};
+use rustc_middle::ty::{self, Ty};
+use rustc_span::Span;
+use rustc_trait_selection::solve::inspect::ProofTreeInferCtxtExt;
+use rustc_trait_selection::solve::inspect::{InspectConfig, InspectGoal, ProofTreeVisitor};
+
+impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    /// Returns a list of all obligations whose self type has been unified
+    /// with the unconstrained type `self_ty`.
+    #[instrument(skip(self), level = "debug")]
+    pub(crate) fn obligations_for_self_ty(
+        &self,
+        self_ty: ty::TyVid,
+    ) -> Vec<traits::PredicateObligation<'tcx>> {
+        if self.next_trait_solver() {
+            self.obligations_for_self_ty_next(self_ty)
+        } else {
+            let ty_var_root = self.root_var(self_ty);
+            let mut obligations = self.fulfillment_cx.borrow().pending_obligations();
+            trace!("pending_obligations = {:#?}", obligations);
+            obligations
+                .retain(|obligation| self.predicate_has_self_ty(obligation.predicate, ty_var_root));
+            obligations
+        }
+    }
+
+    #[instrument(level = "debug", skip(self), ret)]
+    fn predicate_has_self_ty(
+        &self,
+        predicate: ty::Predicate<'tcx>,
+        expected_vid: ty::TyVid,
+    ) -> bool {
+        match predicate.kind().skip_binder() {
+            ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
+                self.type_matches_expected_vid(expected_vid, data.self_ty())
+            }
+            ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
+                self.type_matches_expected_vid(expected_vid, data.projection_ty.self_ty())
+            }
+            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
+            | ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Coerce(..)
+            | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
+            | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
+            | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
+            | ty::PredicateKind::ObjectSafe(..)
+            | ty::PredicateKind::NormalizesTo(..)
+            | ty::PredicateKind::AliasRelate(..)
+            | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
+            | ty::PredicateKind::ConstEquate(..)
+            | ty::PredicateKind::Ambiguous => false,
+        }
+    }
+
+    #[instrument(level = "debug", skip(self), ret)]
+    fn type_matches_expected_vid(&self, expected_vid: ty::TyVid, ty: Ty<'tcx>) -> bool {
+        let ty = self.shallow_resolve(ty);
+        debug!(?ty);
+
+        match *ty.kind() {
+            ty::Infer(ty::TyVar(found_vid)) => {
+                self.root_var(expected_vid) == self.root_var(found_vid)
+            }
+            _ => false,
+        }
+    }
+
+    pub(crate) fn obligations_for_self_ty_next(
+        &self,
+        self_ty: ty::TyVid,
+    ) -> Vec<traits::PredicateObligation<'tcx>> {
+        let obligations = self.fulfillment_cx.borrow().pending_obligations();
+        debug!(?obligations);
+        let mut obligations_for_self_ty = vec![];
+        for obligation in obligations {
+            let mut visitor = NestedObligationsForSelfTy {
+                fcx: self,
+                self_ty,
+                obligations_for_self_ty: &mut obligations_for_self_ty,
+                root_cause: &obligation.cause,
+            };
+
+            let goal = Goal::new(self.tcx, obligation.param_env, obligation.predicate);
+            self.visit_proof_tree(goal, &mut visitor);
+        }
+
+        obligations_for_self_ty.retain_mut(|obligation| {
+            obligation.predicate = self.resolve_vars_if_possible(obligation.predicate);
+            !obligation.predicate.has_placeholders()
+        });
+        obligations_for_self_ty
+    }
+}
+
+struct NestedObligationsForSelfTy<'a, 'tcx> {
+    fcx: &'a FnCtxt<'a, 'tcx>,
+    self_ty: ty::TyVid,
+    root_cause: &'a ObligationCause<'tcx>,
+    obligations_for_self_ty: &'a mut Vec<traits::PredicateObligation<'tcx>>,
+}
+
+impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
+    type Result = ();
+
+    fn span(&self) -> Span {
+        self.root_cause.span
+    }
+
+    fn config(&self) -> InspectConfig {
+        // Using an intentionally low depth to minimize the chance of future
+        // breaking changes in case we adapt the approach later on. This also
+        // avoids any hangs for exponentially growing proof trees.
+        InspectConfig { max_depth: 5 }
+    }
+
+    fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
+        let tcx = self.fcx.tcx;
+        let goal = inspect_goal.goal();
+        if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
+            self.obligations_for_self_ty.push(traits::Obligation::new(
+                tcx,
+                self.root_cause.clone(),
+                goal.param_env,
+                goal.predicate,
+            ));
+        }
+
+        // If there's a unique way to prove a given goal, recurse into
+        // that candidate. This means that for `impl<F: FnOnce(u32)> Trait<F> for () {}`
+        // and a `(): Trait<?0>` goal we recurse into the impl and look at
+        // the nested `?0: FnOnce(u32)` goal.
+        if let Some(candidate) = inspect_goal.unique_applicable_candidate() {
+            candidate.visit_nested_no_probe(self)
+        }
+    }
+}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 080571e1a70..794b854ca5f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -2,14 +2,17 @@ mod _impl;
 mod adjust_fulfillment_errors;
 mod arg_matrix;
 mod checks;
+mod inspect_obligations;
 mod suggestions;
 
+use rustc_errors::ErrorGuaranteed;
+
 use crate::coercion::DynamicCoerceMany;
 use crate::fallback::DivergingFallbackBehavior;
 use crate::fn_ctxt::checks::DivergingBlockBehavior;
 use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt};
 use hir::def_id::CRATE_DEF_ID;
-use rustc_errors::{DiagCtxt, ErrorGuaranteed};
+use rustc_errors::DiagCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 49d0c8bfcd1..a4f840d849d 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -39,7 +39,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty =
             if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && is_builtin_binop(lhs_ty, rhs_ty, op) {
                 self.enforce_builtin_binop_types(lhs.span, lhs_ty, rhs.span, rhs_ty, op);
-                Ty::new_unit(self.tcx)
+                self.tcx.types.unit
             } else {
                 return_ty
             };
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 6040b689f49..382dba5f95f 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1228,16 +1228,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
             }
         } else {
-            // Pattern has wrong number of fields.
-            let e =
-                self.e0023(pat.span, res, qpath, subpats, &variant.fields.raw, expected, had_err);
+            let e = self.emit_err_pat_wrong_number_of_fields(
+                pat.span,
+                res,
+                qpath,
+                subpats,
+                &variant.fields.raw,
+                expected,
+                had_err,
+            );
             on_error(e);
             return Ty::new_error(tcx, e);
         }
         pat_ty
     }
 
-    fn e0023(
+    fn emit_err_pat_wrong_number_of_fields(
         &self,
         pat_span: Span,
         res: Res,
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs
index aa6f184a2d7..8c66f239f8e 100644
--- a/compiler/rustc_incremental/src/assert_dep_graph.rs
+++ b/compiler/rustc_incremental/src/assert_dep_graph.rs
@@ -46,6 +46,7 @@ use rustc_middle::dep_graph::{
 };
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 0729986f32f..79402c88de4 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -7,8 +7,6 @@
 #![allow(internal_features)]
 
 #[macro_use]
-extern crate rustc_middle;
-#[macro_use]
 extern crate tracing;
 
 mod assert_dep_graph;
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index bf6ee044a0b..3d7c0cfc30a 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -110,6 +110,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_data_structures::{base_n, flock};
 use rustc_errors::ErrorGuaranteed;
 use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy};
+use rustc_middle::bug;
 use rustc_session::config::CrateType;
 use rustc_session::output::{collect_crate_types, find_crate_name};
 use rustc_session::{Session, StableCrateId};
diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
index c8adbf7f57a..f95cc13623c 100644
--- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs
+++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
@@ -7,6 +7,7 @@
 //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
 
 use crate::infer::canonical::{Canonical, CanonicalVarValues};
+use rustc_macros::extension;
 use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable};
 use rustc_middle::ty::GenericArgKind;
 use rustc_middle::ty::{self, TyCtxt};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 40a9db10956..635bbca37ec 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -68,6 +68,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
+use rustc_macros::extension;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
 use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 81130d69151..bb53aec0b4d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -4,6 +4,7 @@ pub use lexical_region_resolve::RegionResolutionError;
 pub use relate::combine::CombineFields;
 pub use relate::combine::ObligationEmittingRelation;
 pub use relate::StructurallyRelateAliases;
+pub use rustc_macros::{TypeFoldable, TypeVisitable};
 pub use rustc_middle::ty::IntVarValue;
 pub use BoundRegionConversionTime::*;
 pub use RegionVariableOrigin::*;
@@ -20,13 +21,13 @@ use opaque_types::OpaqueTypeStorage;
 use region_constraints::{GenericKind, VarInfos, VerifyBound};
 use region_constraints::{RegionConstraintCollector, RegionConstraintStorage};
 use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::Rollback;
 use rustc_data_structures::unify as ut;
 use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_macros::extension;
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::infer::unify_key::EffectVarValue;
@@ -478,7 +479,7 @@ pub enum SubregionOrigin<'tcx> {
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(SubregionOrigin<'_>, 32);
+rustc_data_structures::static_assert_size!(SubregionOrigin<'_>, 32);
 
 impl<'tcx> SubregionOrigin<'tcx> {
     pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 3d6b54721d0..223e6e3d344 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_data_structures::unify as ut;
 use rustc_index::IndexVec;
+use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::infer::unify_key::{RegionVariableValue, RegionVidKey};
 use rustc_middle::ty::ReStatic;
 use rustc_middle::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index a5f52420a84..0299af61d45 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -18,7 +18,6 @@
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(extend_one)]
@@ -31,11 +30,6 @@
 #![recursion_limit = "512"] // For rustdoc
 
 #[macro_use]
-extern crate rustc_macros;
-#[cfg(target_pointer_width = "64")]
-#[macro_use]
-extern crate rustc_data_structures;
-#[macro_use]
 extern crate tracing;
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index c495810858f..cb067c7a660 100644
--- a/compiler/rustc_infer/src/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
@@ -1,6 +1,7 @@
 use crate::infer::InferCtxt;
 use crate::traits::Obligation;
 use rustc_hir::def_id::DefId;
+use rustc_macros::extension;
 use rustc_middle::ty::{self, ToPredicate, Ty};
 
 use super::FulfillmentError;
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 7b4e085293c..f77a6115861 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -113,7 +113,7 @@ impl<'tcx> PolyTraitObligation<'tcx> {
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(PredicateObligation<'_>, 48);
+rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48);
 
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
 
@@ -206,6 +206,18 @@ impl<'tcx> FulfillmentError<'tcx> {
     ) -> FulfillmentError<'tcx> {
         FulfillmentError { obligation, code, root_obligation }
     }
+
+    pub fn is_true_error(&self) -> bool {
+        match self.code {
+            FulfillmentErrorCode::SelectionError(_)
+            | FulfillmentErrorCode::ProjectionError(_)
+            | FulfillmentErrorCode::SubtypeError(_, _)
+            | FulfillmentErrorCode::ConstEquateError(_, _) => true,
+            FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
+                false
+            }
+        }
+    }
 }
 
 impl<'tcx> PolyTraitObligation<'tcx> {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 68c7f187f52..db150cc1f87 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -4,12 +4,12 @@ use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
 use rustc_session::config::{
     build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
-    CollapseMacroDebuginfo, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType,
-    ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input,
-    InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli,
-    NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
-    Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion,
-    WasiExecModel,
+    CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat,
+    ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold,
+    Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail,
+    LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey,
+    PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
+    SymbolManglingVersion, WasiExecModel,
 };
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
@@ -761,7 +761,7 @@ fn test_unstable_options_tracking_hash() {
         })
     );
     tracked!(codegen_backend, Some("abc".to_string()));
-    tracked!(coverage_options, CoverageOptions { branch: true, mcdc: true });
+    tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc });
     tracked!(crate_attr, vec!["abc".to_string()]);
     tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
     tracked!(debug_info_for_profiling, true);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 82b90e1660a..676a7c21841 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -456,6 +456,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, th
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
+    .help_doctest =
+        remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
     .non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
     .exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module
 
diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index 3a5c585366a..8f4bae33957 100644
--- a/compiler/rustc_lint/src/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
@@ -3,9 +3,11 @@ use crate::{
     LateContext, LateLintPass, LintContext,
 };
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_session::lint::FutureIncompatibilityReason;
+use rustc_session::{declare_lint, impl_lint_pass};
 use rustc_span::edition::Edition;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs
index 5f7a3137d52..40778542c75 100644
--- a/compiler/rustc_lint/src/async_fn_in_trait.rs
+++ b/compiler/rustc_lint/src/async_fn_in_trait.rs
@@ -2,6 +2,7 @@ use crate::lints::AsyncFnInTraitDiag;
 use crate::LateContext;
 use crate::LateLintPass;
 use rustc_hir as hir;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_trait_selection::traits::error_reporting::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait;
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 0c89e186c47..ba316e5eeb0 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -51,6 +51,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::FnKind as HirFnKind;
 use rustc_hir::{Body, FnDecl, GenericParamKind, Node, PatKind, PredicateOrigin};
+use rustc_middle::bug;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -59,6 +60,7 @@ use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
 use rustc_session::lint::{BuiltinLintDiag, FutureIncompatibilityReason};
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::edition::Edition;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index d1dcfc524b5..0931bb29963 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -27,6 +27,7 @@ use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::bug;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError};
@@ -110,7 +111,7 @@ struct LintAlias {
 
 struct LintGroup {
     lint_ids: Vec<LintId>,
-    is_loaded: bool,
+    is_externally_loaded: bool,
     depr: Option<LintAlias>,
 }
 
@@ -159,7 +160,9 @@ impl LintStore {
                 // Don't display deprecated lint groups.
                 depr.is_none()
             })
-            .map(|(k, LintGroup { lint_ids, is_loaded, .. })| (*k, lint_ids.clone(), *is_loaded))
+            .map(|(k, LintGroup { lint_ids, is_externally_loaded, .. })| {
+                (*k, lint_ids.clone(), *is_externally_loaded)
+            })
     }
 
     pub fn register_early_pass(
@@ -218,7 +221,7 @@ impl LintStore {
                         .entry(edition.lint_name())
                         .or_insert(LintGroup {
                             lint_ids: vec![],
-                            is_loaded: lint.is_loaded,
+                            is_externally_loaded: lint.is_externally_loaded,
                             depr: None,
                         })
                         .lint_ids
@@ -231,7 +234,7 @@ impl LintStore {
                         .entry("future_incompatible")
                         .or_insert(LintGroup {
                             lint_ids: vec![],
-                            is_loaded: lint.is_loaded,
+                            is_externally_loaded: lint.is_externally_loaded,
                             depr: None,
                         })
                         .lint_ids
@@ -246,7 +249,7 @@ impl LintStore {
             alias,
             LintGroup {
                 lint_ids: vec![],
-                is_loaded: false,
+                is_externally_loaded: false,
                 depr: Some(LintAlias { name: lint_name, silent: true }),
             },
         );
@@ -254,21 +257,21 @@ impl LintStore {
 
     pub fn register_group(
         &mut self,
-        is_loaded: bool,
+        is_externally_loaded: bool,
         name: &'static str,
         deprecated_name: Option<&'static str>,
         to: Vec<LintId>,
     ) {
         let new = self
             .lint_groups
-            .insert(name, LintGroup { lint_ids: to, is_loaded, depr: None })
+            .insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None })
             .is_none();
         if let Some(deprecated) = deprecated_name {
             self.lint_groups.insert(
                 deprecated,
                 LintGroup {
                     lint_ids: vec![],
-                    is_loaded,
+                    is_externally_loaded,
                     depr: Some(LintAlias { name, silent: false }),
                 },
             );
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
index 0472525d49a..e9a6276192e 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
@@ -1,4 +1,5 @@
 use rustc_errors::{Applicability, Diag};
+use rustc_middle::bug;
 use rustc_session::{config::ExpectedValues, Session};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::{sym, Span, Symbol};
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
index 9bc81d2c46a..b671dfaa0d1 100644
--- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
+++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
@@ -6,6 +6,7 @@ use crate::{
 use rustc_hir as hir;
 use rustc_middle::ty;
 use rustc_session::lint::FutureIncompatibilityReason;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 use rustc_trait_selection::traits::supertraits;
 
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
index 78ac7f9b235..60b799f3c74 100644
--- a/compiler/rustc_lint/src/drop_forget_useless.rs
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -1,5 +1,6 @@
 use rustc_hir::{Arm, Expr, ExprKind, Node};
 use rustc_middle::ty;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
 use crate::{
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 9fae32a49c7..3f627baf770 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -99,7 +99,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
 
     fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) {
         self.with_lint_attrs(it.id, &it.attrs, |cx| {
-            ast_visit::walk_foreign_item(cx, it);
+            ast_visit::walk_item(cx, it);
         })
     }
 
diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
index a67f1b62fb0..958da177eda 100644
--- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
+++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
@@ -5,6 +5,7 @@ use crate::{
 };
 use rustc_hir as hir;
 use rustc_middle::ty::{visit::TypeVisitableExt, Ty};
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{symbol::sym, Span};
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index cb7feea16b5..ce3f45a17e9 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -10,6 +10,7 @@ use hir::{Expr, Pat};
 use rustc_hir as hir;
 use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause};
 use rustc_middle::ty::{self, List};
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{sym, Span};
 use rustc_trait_selection::traits::ObligationCtxt;
 
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index fae492f252e..48e5683fc0a 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -5,6 +5,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::LayoutError;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_session::declare_lint;
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::FIRST_VARIANT;
 
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
index 054cfe92a3a..aa8ca1776dc 100644
--- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
+++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
@@ -7,6 +7,7 @@ use crate::{
 };
 use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS};
 use rustc_ast as ast;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{BytePos, Span, Symbol};
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs
index 081e3e87530..0081374922e 100644
--- a/compiler/rustc_lint/src/invalid_from_utf8.rs
+++ b/compiler/rustc_lint/src/invalid_from_utf8.rs
@@ -2,6 +2,7 @@ use std::str::Utf8Error;
 
 use rustc_ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::source_map::Spanned;
 use rustc_span::sym;
 
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
index 9d4d75a646a..ea82fb9f262 100644
--- a/compiler/rustc_lint/src/let_underscore.rs
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -5,6 +5,7 @@ use crate::{
 use rustc_errors::MultiSpan;
 use rustc_hir as hir;
 use rustc_middle::ty;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{sym, Symbol};
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 5bb2942ad4b..12b3d1d2f9e 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -22,6 +22,7 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::{
     lint_level, reveal_actual_level, LevelAndSource, LintExpectation, LintLevelSource,
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index e00d8c1e6bd..a78b410f500 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -40,10 +40,6 @@
 #![allow(internal_features)]
 
 #[macro_use]
-extern crate rustc_middle;
-#[macro_use]
-extern crate rustc_session;
-#[macro_use]
 extern crate tracing;
 
 mod array_into_iter;
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 74a0a224dba..7efa5245baa 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1350,14 +1350,18 @@ pub enum NonLocalDefinitionsDiag {
         const_anon: Option<Span>,
     },
     #[diag(lint_non_local_definitions_macro_rules)]
-    #[help]
-    #[note(lint_non_local)]
-    #[note(lint_exception)]
-    #[note(lint_non_local_definitions_deprecation)]
     MacroRules {
         depth: u32,
         body_kind_descr: &'static str,
         body_name: String,
+        #[help]
+        help: Option<()>,
+        #[help(lint_help_doctest)]
+        doctest_help: Option<()>,
+        #[note(lint_non_local)]
+        #[note(lint_exception)]
+        #[note(lint_non_local_definitions_deprecation)]
+        notes: (),
         #[subdiagnostic]
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
     },
diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs
index 07980cfb6fa..e355604e206 100644
--- a/compiler/rustc_lint/src/map_unit_fn.rs
+++ b/compiler/rustc_lint/src/map_unit_fn.rs
@@ -6,6 +6,7 @@ use rustc_middle::{
     query::Key,
     ty::{self, Ty},
 };
+use rustc_session::{declare_lint, declare_lint_pass};
 
 declare_lint! {
     /// The `map_unit_fn` lint checks for `Iterator::map` receive
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs
index 9cfdaf0ce2f..b93245d58d9 100644
--- a/compiler/rustc_lint/src/methods.rs
+++ b/compiler/rustc_lint/src/methods.rs
@@ -4,6 +4,7 @@ use crate::LateLintPass;
 use crate::LintContext;
 use rustc_hir::{Expr, ExprKind};
 use rustc_middle::ty;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{symbol::sym, Span};
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
index 69d623b547b..48d140c6b7f 100644
--- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
+++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
@@ -1,6 +1,7 @@
 use crate::{LateContext, LateLintPass, LintContext};
 
 use rustc_hir as hir;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 79bc78ae55a..9f298a6071c 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -6,6 +6,7 @@ use crate::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::UnordMap;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::symbol::Symbol;
 use unicode_security::general_security_profile::IdentifierType;
 
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index e81790a7348..a6057afcbd6 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -4,10 +4,12 @@ use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::bug;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_parse_format::{ParseMode, Parser, Piece};
 use rustc_session::lint::FutureIncompatibilityReason;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
 use rustc_span::{hygiene, sym, symbol::kw, InnerSpan, Span, Symbol};
 use rustc_trait_selection::infer::InferCtxtExt;
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 004c2c2e4f4..7bdf5ef6af4 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -5,6 +5,7 @@ use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable};
+use rustc_session::{declare_lint, impl_lint_pass};
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::Span;
 use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
@@ -232,6 +233,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
             ItemKind::Macro(_macro, MacroKind::Bang)
                 if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
             {
+                // determining we if are in a doctest context can't currently be determined
+                // by the code it-self (no specific attrs), but fortunatly rustdoc sets a
+                // perma-unstable env for libtest so we just re-use that env for now
+                let is_at_toplevel_doctest =
+                    self.body_depth == 2 && std::env::var("UNSTABLE_RUSTDOC_TEST_PATH").is_ok();
+
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
                     item.span,
@@ -242,6 +249,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                             .map(|s| s.to_ident_string())
                             .unwrap_or_else(|| "<unnameable>".to_string()),
                         cargo_update: cargo_update(),
+                        help: (!is_at_toplevel_doctest).then_some(()),
+                        doctest_help: is_at_toplevel_doctest.then_some(()),
+                        notes: (),
                     },
                 )
             }
@@ -356,7 +366,7 @@ fn path_has_local_parent(
 }
 
 /// Given a def id and a parent impl def id, this checks if the parent
-/// def id correspond to the def id of the parent impl definition.
+/// def id (modulo modules) correspond to the def id of the parent impl definition.
 #[inline]
 fn did_has_local_parent(
     did: DefId,
@@ -364,8 +374,14 @@ fn did_has_local_parent(
     impl_parent: DefId,
     impl_parent_parent: Option<DefId>,
 ) -> bool {
-    did.is_local() && {
-        let res_parent = tcx.parent(did);
-        res_parent == impl_parent || Some(res_parent) == impl_parent_parent
-    }
+    did.is_local()
+        && if let Some(did_parent) = tcx.opt_parent(did) {
+            did_parent == impl_parent
+                || Some(did_parent) == impl_parent_parent
+                || !did_parent.is_crate_root()
+                    && tcx.def_kind(did_parent) == DefKind::Mod
+                    && did_has_local_parent(did_parent, tcx, impl_parent, impl_parent_parent)
+        } else {
+            false
+        }
 }
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index ee863672017..dbb0644cd63 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -11,6 +11,7 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{GenericParamKind, PatKind};
 use rustc_middle::ty;
 use rustc_session::config::CrateType;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{BytePos, Span};
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index 970d411fb06..91441248e70 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -8,6 +8,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::{Expr, ExprKind};
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::Adjust;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::symbol::sym;
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index ec7954536be..1ea1f496e50 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -4,6 +4,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{
     self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable,
 };
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::{symbol::kw, Span};
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index 160d42caa9e..1f0a8a0b567 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -4,6 +4,7 @@ use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::{GenericArg, PathSegment, QPath, TyKind};
 use rustc_middle::ty;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::sym;
 
 declare_tool_lint! {
diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs
index 1681ac2f1e5..ef08e79e24a 100644
--- a/compiler/rustc_lint/src/redundant_semicolon.rs
+++ b/compiler/rustc_lint/src/redundant_semicolon.rs
@@ -1,5 +1,6 @@
 use crate::{lints::RedundantSemicolonsDiag, EarlyContext, EarlyLintPass, LintContext};
 use rustc_ast::{Block, StmtKind};
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::Span;
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 9b938b34c00..9fed91f7262 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -2,6 +2,7 @@ use rustc_ast::Mutability;
 use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{self, layout::TyAndLayout};
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
 use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext};
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index 789f154eac5..4d1b1dc4fb7 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -3,6 +3,7 @@ use crate::LateContext;
 use crate::LateLintPass;
 use crate::LintContext;
 use rustc_hir as hir;
+use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::symbol::sym;
 
 declare_lint! {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index e982842f536..13b6054586c 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -17,11 +17,13 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagMessage;
 use rustc_hir as hir;
 use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
+use rustc_middle::bug;
 use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{
     self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
diff --git a/compiler/rustc_lint/src/unit_bindings.rs b/compiler/rustc_lint/src/unit_bindings.rs
index 6222adf58ae..8202bfa805a 100644
--- a/compiler/rustc_lint/src/unit_bindings.rs
+++ b/compiler/rustc_lint/src/unit_bindings.rs
@@ -1,7 +1,7 @@
 use crate::lints::UnitBindingsDiag;
 use crate::{LateLintPass, LintContext};
 use rustc_hir as hir;
-use rustc_middle::ty::Ty;
+use rustc_session::{declare_lint, declare_lint_pass};
 
 declare_lint! {
     /// The `unit_bindings` lint detects cases where bindings are useless because they have
@@ -56,8 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for UnitBindings {
             && let Some(init) = local.init
             && let init_ty = tyck_results.expr_ty(init)
             && let local_ty = tyck_results.node_type(local.hir_id)
-            && init_ty == Ty::new_unit(cx.tcx)
-            && local_ty == Ty::new_unit(cx.tcx)
+            && init_ty == cx.tcx.types.unit
+            && local_ty == cx.tcx.types.unit
             && local.ty.is_none()
             && !matches!(init.kind, hir::ExprKind::Tup([]))
             && !matches!(local.pat.kind, hir::PatKind::Tuple([], ..))
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 0b0949e4dd8..4d372d612e9 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId;
 use rustc_infer::traits::util::elaborate;
 use rustc_middle::ty::adjustment;
 use rustc_middle::ty::{self, Ty};
+use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::{BytePos, Span};
@@ -176,6 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                 | hir::BinOpKind::Shr => Some("bitwise operation"),
             },
             hir::ExprKind::AddrOf(..) => Some("borrow"),
+            hir::ExprKind::OffsetOf(..) => Some("`offset_of` call"),
             hir::ExprKind::Unary(..) => Some("unary operation"),
             _ => None,
         };
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index e74cc388cab..c7996c27c2f 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -69,6 +69,7 @@ declare_lint_pass! {
         MISSING_FRAGMENT_SPECIFIER,
         MUST_NOT_SUSPEND,
         NAMED_ARGUMENTS_USED_POSITIONALLY,
+        NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
         NON_CONTIGUOUS_RANGE_ENDPOINTS,
         NON_EXHAUSTIVE_OMITTED_PATTERNS,
         ORDER_DEPENDENT_TRAIT_OBJECTS,
@@ -101,6 +102,7 @@ declare_lint_pass! {
         TYVAR_BEHIND_RAW_POINTER,
         UNCONDITIONAL_PANIC,
         UNCONDITIONAL_RECURSION,
+        UNCOVERED_PARAM_IN_PROJECTION,
         UNDEFINED_NAKED_FUNCTION_ABI,
         UNEXPECTED_CFGS,
         UNFULFILLED_LINT_EXPECTATIONS,
@@ -4245,6 +4247,85 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `never_type_fallback_flowing_into_unsafe` lint detects cases where never type fallback
+    /// affects unsafe function calls.
+    ///
+    /// ### Never type fallback
+    ///
+    /// When the compiler sees a value of type [`!`] it implicitly inserts a coercion (if possible),
+    /// to allow type check to infer any type:
+    ///
+    /// ```ignore (illustrative-and-has-placeholders)
+    /// // this
+    /// let x: u8 = panic!();
+    ///
+    /// // is (essentially) turned by the compiler into
+    /// let x: u8 = absurd(panic!());
+    ///
+    /// // where absurd is a function with the following signature
+    /// // (it's sound, because `!` always marks unreachable code):
+    /// fn absurd<T>(_: !) -> T { ... }
+    // FIXME: use `core::convert::absurd` here instead, once it's merged
+    /// ```
+    ///
+    /// While it's convenient to be able to use non-diverging code in one of the branches (like
+    /// `if a { b } else { return }`) this could lead to compilation errors:
+    ///
+    /// ```compile_fail
+    /// // this
+    /// { panic!() };
+    ///
+    /// // gets turned into this
+    /// { absurd(panic!()) }; // error: can't infer the type of `absurd`
+    /// ```
+    ///
+    /// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it
+    /// can't infer their type, it sets the type to fallback. `{ absurd::<Fallback>(panic!()) };`.
+    /// This is what is known as "never type fallback".
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(never_type_fallback_flowing_into_unsafe)]
+    /// fn main() {
+    ///     if true {
+    ///         // return has type `!` which, is some cases, causes never type fallback
+    ///         return
+    ///     } else {
+    ///         // `zeroed` is an unsafe function, which returns an unbounded type
+    ///         unsafe { std::mem::zeroed() }
+    ///     };
+    ///     // depending on the fallback, `zeroed` may create `()` (which is completely sound),
+    ///     // or `!` (which is instant undefined behavior)
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Due to historic reasons never type fallback was `()`, meaning that `!` got spontaneously
+    /// coerced to `()`. There are plans to change that, but they may make the code such as above
+    /// unsound. Instead of depending on the fallback, you should specify the type explicitly:
+    /// ```
+    /// if true {
+    ///     return
+    /// } else {
+    ///     // type is explicitly specified, fallback can't hurt us no more
+    ///     unsafe { std::mem::zeroed::<()>() }
+    /// };
+    /// ```
+    ///
+    /// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748).
+    ///
+    /// [`!`]: https://doc.rust-lang.org/core/primitive.never.html
+    /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
+    pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
+    Warn,
+    "never type fallback affecting unsafe function calls"
+}
+
+declare_lint! {
     /// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
     /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
     /// more built-in traits.
@@ -4741,3 +4822,68 @@ declare_lint! {
     };
     crate_level_only
 }
+
+declare_lint! {
+    /// The `uncovered_param_in_projection` lint detects a violation of one of Rust's orphan rules for
+    /// foreign trait implementations that concerns the use of type parameters inside trait associated
+    /// type paths ("projections") whose output may not be a local type that is mistakenly considered
+    /// to "cover" said parameters which is **unsound** and which may be rejected by a future version
+    /// of the compiler.
+    ///
+    /// Originally reported in [#99554].
+    ///
+    /// [#99554]: https://github.com/rust-lang/rust/issues/99554
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (dependent)
+    /// // dependency.rs
+    /// #![crate_type = "lib"]
+    ///
+    /// pub trait Trait<T, U> {}
+    /// ```
+    ///
+    /// ```edition2021,ignore (needs dependency)
+    /// // dependent.rs
+    /// trait Identity {
+    ///     type Output;
+    /// }
+    ///
+    /// impl<T> Identity for T {
+    ///     type Output = T;
+    /// }
+    ///
+    /// struct Local;
+    ///
+    /// impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
+    ///
+    /// fn main() {}
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+    ///   --> dependent.rs:11:6
+    ///    |
+    /// 11 | impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
+    ///    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+    ///    |
+    ///    = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+    ///    = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+    ///    = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+    ///    = note: `#[warn(uncovered_param_in_projection)]` on by default
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// FIXME(fmease): Write explainer.
+    pub UNCOVERED_PARAM_IN_PROJECTION,
+    Warn,
+    "impl contains type parameters that are not covered",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reference: "issue #124559 <https://github.com/rust-lang/rust/issues/124559>",
+    };
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 7f200a7b623..ed165188787 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,6 +1,3 @@
-#[macro_use]
-extern crate rustc_macros;
-
 pub use self::Level::*;
 use rustc_ast::node_id::NodeId;
 use rustc_ast::{AttrId, Attribute};
@@ -11,6 +8,7 @@ use rustc_data_structures::stable_hasher::{
 use rustc_error_messages::{DiagMessage, MultiSpan};
 use rustc_hir::HashStableContext;
 use rustc_hir::HirId;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::edition::Edition;
 use rustc_span::{sym, symbol::Ident, Span, Symbol};
 use rustc_target::spec::abi::Abi;
@@ -323,7 +321,8 @@ pub struct Lint {
 
     pub future_incompatible: Option<FutureIncompatibleInfo>,
 
-    pub is_loaded: bool,
+    /// `true` if this lint is being loaded by another tool (e.g. Clippy).
+    pub is_externally_loaded: bool,
 
     /// `Some` if this lint is feature gated, otherwise `None`.
     pub feature_gate: Option<Symbol>,
@@ -468,7 +467,7 @@ impl Lint {
             default_level: Level::Forbid,
             desc: "",
             edition_lint_opts: None,
-            is_loaded: false,
+            is_externally_loaded: false,
             report_in_external_macro: false,
             future_incompatible: None,
             feature_gate: None,
@@ -817,7 +816,7 @@ macro_rules! declare_lint {
             name: stringify!($NAME),
             default_level: $crate::$Level,
             desc: $desc,
-            is_loaded: false,
+            is_externally_loaded: false,
             $($v: true,)*
             $(feature_gate: Some($gate),)?
             $(future_incompatible: Some($crate::FutureIncompatibleInfo {
@@ -859,7 +858,7 @@ macro_rules! declare_tool_lint {
             edition_lint_opts: None,
             report_in_external_macro: $external,
             future_incompatible: None,
-            is_loaded: true,
+            is_externally_loaded: true,
             $(feature_gate: Some($gate),)?
             crate_level_only: false,
             ..$crate::Lint::default_fields_for_macro()
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index b50ae057709..fb0010f2c5d 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -4,8 +4,7 @@ use std::{
 };
 
 use rustc_errors::{codes::*, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level};
-use rustc_macros::Diagnostic;
-use rustc_session::config;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 
@@ -640,9 +639,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
         diag.arg("locator_triple", self.locator_triple.triple());
         diag.code(E0463);
         diag.span(self.span);
-        if (self.crate_name == sym::std || self.crate_name == sym::core)
-            && self.locator_triple != TargetTriple::from_triple(config::host_triple())
-        {
+        if self.crate_name == sym::std || self.crate_name == sym::core {
             if self.missing_core {
                 diag.note(fluent::metadata_target_not_installed);
             } else {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 7dd03407bd7..c8162a1f0ee 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -20,8 +20,6 @@
 extern crate proc_macro;
 
 #[macro_use]
-extern crate rustc_macros;
-#[macro_use]
 extern crate rustc_middle;
 
 #[macro_use]
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index fd42c9c1faa..2a33088513b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1261,7 +1261,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         sess: &'a Session,
     ) -> impl Iterator<Item = ModChild> + 'a {
         iter::from_coroutine(
-            #[cfg_attr(not(bootstrap), coroutine)]
+            #[coroutine]
             move || {
                 if let Some(data) = &self.root.proc_macro_data {
                     // If we are loading as a proc macro, we want to return
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 5b0be8ac230..c9cb2f5a240 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -2,6 +2,7 @@ use crate::creader::CrateMetadataRef;
 use decoder::Metadata;
 use def_path_hash_map::DefPathHashMapRef;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_macros::{Decodable, Encodable, TyDecodable, TyEncodable};
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::lib_features::FeatureStability;
 use table::TableBuilder;
@@ -17,6 +18,7 @@ use rustc_hir::definitions::DefKey;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
+use rustc_macros::{MetadataDecodable, MetadataEncodable};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 0d3cffd2047..6e622b0405f 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -1,7 +1,7 @@
 use std::fmt;
 
 use rustc_errors::{codes::*, DiagArgName, DiagArgValue, DiagMessage};
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
 
 use crate::ty::Ty;
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 94d1039c763..34748afa863 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::*;
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_span::{ErrorGuaranteed, ExpnId};
 
 /// Gather the LocalDefId for each item-like within a module, including items contained within
diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs
index 32f3a177508..1ac35314ead 100644
--- a/compiler/rustc_middle/src/hir/place.rs
+++ b/compiler/rustc_middle/src/hir/place.rs
@@ -2,6 +2,7 @@ use crate::ty;
 use crate::ty::Ty;
 
 use rustc_hir::HirId;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_target::abi::{FieldIdx, VariantIdx};
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 62d7b7c28d1..aee97d77222 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -23,7 +23,7 @@
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lock;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_type_ir::Canonical as IrCanonical;
 use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
 pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs
index 1384611e146..f74f71b6b37 100644
--- a/compiler/rustc_middle/src/infer/mod.rs
+++ b/compiler/rustc_middle/src/infer/mod.rs
@@ -4,6 +4,7 @@ pub mod unify_key;
 use crate::ty::Region;
 use crate::ty::{OpaqueTypeKey, Ty};
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
 
 /// Requires that `region` must be equal to one of the regions in `choice_regions`.
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 501052b7411..04fd4c8d0f7 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -37,7 +37,6 @@
 #![feature(coroutines)]
 #![feature(stmt_expr_attributes)]
 #![feature(if_let_guard)]
-#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(iter_from_coroutine)]
 #![feature(negative_impls)]
 #![feature(never_type)]
@@ -48,7 +47,6 @@
 #![feature(trusted_len)]
 #![feature(type_alias_impl_trait)]
 #![feature(strict_provenance)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(rustc_attrs)]
 #![feature(control_flow_enum)]
 #![feature(trait_upcasting)]
@@ -66,15 +64,7 @@
 #![allow(rustc::untranslatable_diagnostic)]
 
 #[macro_use]
-extern crate bitflags;
-#[macro_use]
-extern crate rustc_macros;
-#[macro_use]
-extern crate rustc_data_structures;
-#[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate smallvec;
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 8d9e0dfd869..086582e60a3 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_errors::{Diag, DiagMessage, MultiSpan};
 use rustc_hir::{HirId, ItemLocalId};
+use rustc_macros::HashStable;
 use rustc_session::lint::{
     builtin::{self, FORBIDDEN_LINT_GROUPS},
     FutureIncompatibilityReason, Level, Lint, LintId,
diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs
index 674402cb4bf..589f274eb17 100644
--- a/compiler/rustc_middle/src/metadata.rs
+++ b/compiler/rustc_middle/src/metadata.rs
@@ -1,7 +1,7 @@
 use crate::ty;
 
 use rustc_hir::def::Res;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::Ident;
 use smallvec::SmallVec;
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index ec9697bbd35..3fa5054baed 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -1,5 +1,6 @@
 use crate::mir::mono::Linkage;
 use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::symbol::Symbol;
 use rustc_target::abi::Align;
 use rustc_target::spec::SanitizerSet;
@@ -48,7 +49,7 @@ pub struct CodegenFnAttrs {
 
 #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
 pub struct CodegenFnAttrFlags(u32);
-bitflags! {
+bitflags::bitflags! {
     impl CodegenFnAttrFlags: u32 {
         /// `#[cold]`: a hint to LLVM that this function, when called, is never on
         /// the hot path.
diff --git a/compiler/rustc_middle/src/middle/debugger_visualizer.rs b/compiler/rustc_middle/src/middle/debugger_visualizer.rs
index a0497d805da..74a5dfb0400 100644
--- a/compiler/rustc_middle/src/middle/debugger_visualizer.rs
+++ b/compiler/rustc_middle/src/middle/debugger_visualizer.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::sync::Lrc;
+use rustc_macros::{Decodable, Encodable, HashStable};
 use std::path::PathBuf;
 
 #[derive(HashStable)]
diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs
index e079843bfbc..e7d0cffc85c 100644
--- a/compiler/rustc_middle/src/middle/dependency_format.rs
+++ b/compiler/rustc_middle/src/middle/dependency_format.rs
@@ -4,6 +4,7 @@
 //! For all the gory details, see the provider of the `dependency_formats`
 //! query.
 
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_session::config::CrateType;
 
 /// A list of dependencies for a certain crate type.
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 123b32f4aea..3b6eecb7fa0 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -1,7 +1,7 @@
 use crate::ty::GenericArgsRef;
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_macros::HashStable;
+use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
 
 /// The SymbolExportLevel of a symbols specifies from which kinds of crates
 /// the symbol will be exported. `C` symbols will be exported from any
diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs
index bdb2270611a..5c395afadd7 100644
--- a/compiler/rustc_middle/src/middle/mod.rs
+++ b/compiler/rustc_middle/src/middle/mod.rs
@@ -5,6 +5,7 @@ pub mod exported_symbols;
 pub mod lang_items;
 pub mod lib_features {
     use rustc_data_structures::unord::UnordMap;
+    use rustc_macros::{HashStable, TyDecodable, TyEncodable};
     use rustc_span::{symbol::Symbol, Span};
 
     #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 5ae60e04277..de07ba9700a 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
 use rustc_hir::{HirId, HirIdMap, Node};
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::{Span, DUMMY_SP};
 
 use std::fmt;
@@ -153,7 +153,7 @@ rustc_index::newtype_index! {
 }
 
 // compilation error if size of `ScopeData` is not the same as a `u32`
-static_assert_size!(ScopeData, 4);
+rustc_data_structures::static_assert_size!(ScopeData, 4);
 
 impl Scope {
     /// Returns an item-local ID associated with this scope.
diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
index 610afd95f3c..d0103f62231 100644
--- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
+++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{ItemLocalId, OwnerId};
-use rustc_macros::HashStable;
+use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
 pub enum ResolvedArg {
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index c393287da95..67bd53f53da 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -14,6 +14,7 @@ use rustc_feature::GateIssue;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
 use rustc_hir::{self as hir, HirId};
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
 use rustc_session::lint::{BuiltinLintDiag, Level, Lint, LintBuffer};
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 1086d647721..f9398b254c7 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::graph::dominators::{dominators, Dominators};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::OnceLock;
 use rustc_index::{IndexSlice, IndexVec};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use smallvec::SmallVec;
 
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 6ff40c53c85..d025dc360a2 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -1,6 +1,7 @@
 use std::fmt::{self, Debug, Display, Formatter};
 
 use rustc_hir::def_id::DefId;
+use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{HasDataLayout, Size};
@@ -71,7 +72,7 @@ pub enum ConstValue<'tcx> {
 }
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(ConstValue<'_>, 24);
+rustc_data_structures::static_assert_size!(ConstValue<'_>, 24);
 
 impl<'tcx> ConstValue<'tcx> {
     #[inline]
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 04011fd4194..9d9ca22247a 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -1,7 +1,7 @@
 //! Metadata from source code coverage analysis and instrumentation.
 
 use rustc_index::IndexVec;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::{Span, Symbol};
 
 use std::fmt::{self, Debug, Formatter};
@@ -132,7 +132,7 @@ pub enum CoverageKind {
     ///
     /// If this statement does not survive MIR optimizations, the condition would never be
     /// taken as evaluated.
-    CondBitmapUpdate { id: ConditionId, value: bool },
+    CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 },
 
     /// Marks the point in MIR control flow represented by a evaluated decision.
     ///
@@ -140,7 +140,7 @@ pub enum CoverageKind {
     ///
     /// If this statement does not survive MIR optimizations, the decision would never be
     /// taken as evaluated.
-    TestVectorBitmapUpdate { bitmap_idx: u32 },
+    TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 },
 }
 
 impl Debug for CoverageKind {
@@ -151,11 +151,17 @@ impl Debug for CoverageKind {
             BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()),
             CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()),
             ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()),
-            CondBitmapUpdate { id, value } => {
-                write!(fmt, "CondBitmapUpdate({:?}, {:?})", id.index(), value)
+            CondBitmapUpdate { id, value, decision_depth } => {
+                write!(
+                    fmt,
+                    "CondBitmapUpdate({:?}, {:?}, depth={:?})",
+                    id.index(),
+                    value,
+                    decision_depth
+                )
             }
-            TestVectorBitmapUpdate { bitmap_idx } => {
-                write!(fmt, "TestVectorUpdate({:?})", bitmap_idx)
+            TestVectorBitmapUpdate { bitmap_idx, decision_depth } => {
+                write!(fmt, "TestVectorUpdate({:?}, depth={:?})", bitmap_idx, decision_depth)
             }
         }
     }
@@ -269,6 +275,9 @@ pub struct FunctionCoverageInfo {
     pub mcdc_bitmap_bytes: u32,
     pub expressions: IndexVec<ExpressionId, Expression>,
     pub mappings: Vec<Mapping>,
+    /// The depth of the deepest decision is used to know how many
+    /// temp condbitmaps should be allocated for the function.
+    pub mcdc_max_decision_depth: u16,
 }
 
 /// Branch information recorded during THIR-to-MIR lowering, and stored in MIR.
@@ -319,6 +328,7 @@ pub struct MCDCBranchSpan {
     pub condition_info: Option<ConditionInfo>,
     pub true_marker: BlockMarkerId,
     pub false_marker: BlockMarkerId,
+    pub decision_depth: u16,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -334,4 +344,5 @@ pub struct MCDCDecisionSpan {
     pub span: Span,
     pub conditions_num: usize,
     pub end_markers: Vec<BlockMarkerId>,
+    pub decision_depth: u16,
 }
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 00faa211853..791e87735f4 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -14,6 +14,7 @@ use either::{Left, Right};
 
 use rustc_ast::Mutability;
 use rustc_data_structures::intern::Interned;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_target::abi::{Align, HasDataLayout, Size};
 
 use super::{
@@ -28,9 +29,7 @@ use provenance_map::*;
 pub use init_mask::{InitChunk, InitChunkIter};
 
 /// Functionality required for the bytes of an `Allocation`.
-pub trait AllocBytes:
-    Clone + fmt::Debug + Eq + PartialEq + Hash + Deref<Target = [u8]> + DerefMut<Target = [u8]>
-{
+pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Target = [u8]> {
     /// Create an `AllocBytes` from a slice of `u8`.
     fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self;
 
@@ -345,10 +344,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
     }
 }
 
-impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
+impl Allocation {
     /// Adjust allocation from the ones in `tcx` to a custom Machine instance
-    /// with a different `Provenance` and `Extra` type.
-    pub fn adjust_from_tcx<Prov: Provenance, Extra, Err>(
+    /// with a different `Provenance`, `Extra` and `Byte` type.
+    pub fn adjust_from_tcx<Prov: Provenance, Extra, Bytes: AllocBytes, Err>(
         self,
         cx: &impl HasDataLayout,
         extra: Extra,
@@ -370,7 +369,7 @@ impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
         }
         // Create allocation.
         Ok(Allocation {
-            bytes,
+            bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align),
             provenance: ProvenanceMap::from_presorted_ptrs(new_provenance),
             init_mask: self.init_mask,
             align: self.align,
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
index 2c6bb908f39..d60db775ff0 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
@@ -5,6 +5,7 @@ use std::hash;
 use std::iter;
 use std::ops::Range;
 
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_serialize::{Decodable, Encodable};
 use rustc_target::abi::Size;
 use rustc_type_ir::{TyDecoder, TyEncoder};
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
index 9459af490e3..e974279f191 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
@@ -4,6 +4,7 @@
 use std::cmp;
 
 use rustc_data_structures::sorted_map::SortedMap;
+use rustc_macros::HashStable;
 use rustc_target::abi::{HasDataLayout, Size};
 
 use super::{alloc_range, AllocError, AllocRange, AllocResult, CtfeProvenance, Provenance};
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index a3d16d4f097..383241465c3 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -7,7 +7,7 @@ use crate::ty::{self, layout, tls, Ty, TyCtxt, ValTree};
 use rustc_ast_ir::Mutability;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg};
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_session::CtfeBacktrace;
 use rustc_span::{def_id::DefId, Span, DUMMY_SP};
 use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange};
@@ -89,7 +89,7 @@ pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
 pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(InterpErrorInfo<'_>, 8);
+rustc_data_structures::static_assert_size!(InterpErrorInfo<'_>, 8);
 
 /// Packages the kind of error we got from the const code interpreter
 /// up with a Rust-level backtrace of where the error occurred.
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 6275942bafe..ee3cdf36820 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -131,7 +131,7 @@ use rustc_data_structures::sync::{HashMapExt, Lock};
 use rustc_data_structures::tiny_list::TinyList;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_serialize::{Decodable, Encodable};
 use rustc_target::abi::{AddressSpace, Endian, HasDataLayout};
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index e2767ee2989..a0acacc844f 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -1,6 +1,7 @@
 use super::{AllocId, InterpResult};
 
-use rustc_macros::HashStable;
+use rustc_data_structures::static_assert_size;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_target::abi::{HasDataLayout, Size};
 
 use std::{fmt, num::NonZero};
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 9728967860a..c5c87c506b7 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -6,7 +6,7 @@ use rustc_apfloat::{
     ieee::{Double, Half, Quad, Single},
     Float,
 };
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_target::abi::{HasDataLayout, Size};
 
 use crate::ty::ScalarInt;
@@ -38,7 +38,7 @@ pub enum Scalar<Prov = CtfeProvenance> {
 }
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(Scalar, 24);
+rustc_data_structures::static_assert_size!(Scalar, 24);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
 // all the Miri types.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 43e4e8216e1..25cc9ac47c8 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -20,6 +20,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::{
     self as hir, BindingMode, ByRef, CoroutineDesugaring, CoroutineKind, HirId, ImplicitSelfKind,
 };
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_target::abi::{FieldIdx, VariantIdx};
@@ -701,10 +702,7 @@ impl<'tcx> Body<'tcx> {
                 env,
                 crate::ty::EarlyBinder::bind(constant.const_),
             );
-            let Some(bits) = mono_literal.try_eval_bits(tcx, env) else {
-                bug!("Couldn't evaluate constant {:?} in mono {:?}", constant, instance);
-            };
-            bits
+            mono_literal.try_eval_bits(tcx, env)
         };
 
         let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
@@ -714,7 +712,7 @@ impl<'tcx> Body<'tcx> {
         // If this is a SwitchInt(const _), then we can just evaluate the constant and return.
         let discr = match discr {
             Operand::Constant(constant) => {
-                let bits = eval_mono_const(constant);
+                let bits = eval_mono_const(constant)?;
                 return Some((bits, targets));
             }
             Operand::Move(place) | Operand::Copy(place) => place,
@@ -748,7 +746,7 @@ impl<'tcx> Body<'tcx> {
         match rvalue {
             Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)),
             Rvalue::Use(Operand::Constant(constant)) => {
-                let bits = eval_mono_const(constant);
+                let bits = eval_mono_const(constant)?;
                 Some((bits, targets))
             }
             _ => None,
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 9eed7019782..6d4585cfbc6 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -9,6 +9,7 @@ use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::ItemId;
 use rustc_index::Idx;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::config::OptLevel;
 use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a350eb05226..5aaa1c30cad 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -496,20 +496,27 @@ fn write_coverage_branch_info(
         )?;
     }
 
-    for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
-        mcdc_branch_spans
+    for coverage::MCDCBranchSpan {
+        span,
+        condition_info,
+        true_marker,
+        false_marker,
+        decision_depth,
+    } in mcdc_branch_spans
     {
         writeln!(
             w,
-            "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
+            "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
             condition_info.map(|info| info.condition_id)
         )?;
     }
 
-    for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in mcdc_decision_spans {
+    for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in
+        mcdc_decision_spans
+    {
         writeln!(
             w,
-            "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}"
+            "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
         )?;
     }
 
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index e3f58729fbd..9a7af6135e4 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -7,6 +7,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::{Idx, IndexVec};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use rustc_target::abi::{FieldIdx, VariantIdx};
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 5ddd71178ca..4278ce823d0 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -17,6 +17,7 @@ use rustc_data_structures::packed::Pu128;
 use rustc_hir::def_id::DefId;
 use rustc_hir::CoroutineKind;
 use rustc_index::IndexVec;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::source_map::Spanned;
 use rustc_target::abi::{FieldIdx, VariantIdx};
 
@@ -1522,6 +1523,7 @@ pub enum BinOp {
 #[cfg(target_pointer_width = "64")]
 mod size_asserts {
     use super::*;
+    use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
     static_assert_size!(AggregateKind<'_>, 32);
     static_assert_size!(Operand<'_>, 24);
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index ded2b93d6a1..3881723c5ec 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -15,7 +15,7 @@ pub struct PlaceTy<'tcx> {
 
 // At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(PlaceTy<'_>, 16);
+rustc_data_structures::static_assert_size!(PlaceTy<'_>, 16);
 
 impl<'tcx> PlaceTy<'tcx> {
     #[inline]
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 58a27c1f9ef..f95afb199f7 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -1,10 +1,10 @@
 /// Functionality for terminators and helper types that appear in terminators.
 use rustc_hir::LangItem;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
 use super::TerminatorKind;
 use rustc_data_structures::packed::Pu128;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use std::slice;
 
 use super::*;
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index a5d21c47e5b..c2f7a227f66 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -72,6 +72,7 @@ use rustc_hir::def_id::{
 use rustc_hir::lang_items::{LangItem, LanguageItems};
 use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate};
 use rustc_index::IndexVec;
+use rustc_macros::rustc_queries;
 use rustc_query_system::ich::StableHashingContext;
 use rustc_query_system::query::{try_get_cached, QueryCache, QueryMode, QueryState};
 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
@@ -846,8 +847,10 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query issue33140_self_ty(key: DefId) -> Option<ty::EarlyBinder<ty::Ty<'tcx>>> {
-        desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
+    query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
+        key: DefId
+    ) -> Option<ty::EarlyBinder<ty::Ty<'tcx>>> {
+        desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
     }
 
     /// Maps a `DefId` of a type to a list of its inherent impls.
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index db1b5a74f0a..2dcb58729ff 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -6,6 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathHash;
 use rustc_index::{Idx, IndexVec};
+use rustc_macros::{Decodable, Encodable};
 use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::mir::{self, interpret};
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 038d3fe93c4..8a4e3ab0e61 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -12,6 +12,7 @@ use rustc_data_structures::sync::AtomicU64;
 use rustc_data_structures::sync::WorkerLocal;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::hir_id::OwnerId;
+use rustc_macros::HashStable;
 use rustc_query_system::dep_graph::DepNodeIndex;
 use rustc_query_system::dep_graph::SerializedDepNodeIndex;
 pub(crate) use rustc_query_system::query::QueryJobId;
diff --git a/compiler/rustc_middle/src/tests.rs b/compiler/rustc_middle/src/tests.rs
index 49960cc0bb2..6c2e5f63418 100644
--- a/compiler/rustc_middle/src/tests.rs
+++ b/compiler/rustc_middle/src/tests.rs
@@ -1,13 +1,9 @@
-use super::*;
-
-// FIXME(#27438): right now the unit tests of rustc_middle don't refer to any actual
-//                functions generated in rustc_data_structures (all
-//                references are through generic functions), but statics are
-//                referenced from time to time. Due to this bug we won't
-//                actually correctly link in the statics unless we also
-//                reference a function, so be sure to reference a dummy
-//                function.
+// FIXME(#27438): Right now, the unit tests of `rustc_middle` don't refer to any actual functions
+//                generated in `rustc_data_structures` (all references are through generic functions),
+//                but statics are referenced from time to time. Due to this Windows `dllimport` bug
+//                we won't actually correctly link in the statics unless we also reference a function,
+//                so be sure to reference a dummy function.
 #[test]
 fn noop() {
-    rustc_data_structures::__noop_fix_for_27438();
+    rustc_data_structures::__noop_fix_for_windows_dllimport_issue();
 }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 99498fedcca..a7d8ead5677 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -15,6 +15,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
 use rustc_index::newtype_index;
 use rustc_index::IndexVec;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp};
@@ -1209,6 +1210,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
 #[cfg(target_pointer_width = "64")]
 mod size_asserts {
     use super::*;
+    use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
     static_assert_size!(Block, 48);
     static_assert_size!(Expr<'_>, 64);
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index b1e34dcd5f3..1ae037e09a7 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -20,10 +20,13 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::HirId;
+use rustc_macros::{
+    Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
+};
 use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
 use std::borrow::Cow;
 use std::hash::{Hash, Hasher};
@@ -557,7 +560,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(ObligationCauseCode<'_>, 48);
+rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum StatementAsExpression {
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 12e4f70ba57..70f3532e3ab 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -10,11 +10,13 @@ use crate::infer::canonical::{Canonical, QueryResponse};
 use crate::ty::error::TypeError;
 use crate::ty::GenericArg;
 use crate::ty::{self, Ty, TyCtxt};
+use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
 
 pub mod type_op {
     use crate::ty::fold::TypeFoldable;
     use crate::ty::{Predicate, Ty, TyCtxt, UserType};
+    use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
     use std::fmt;
 
     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index c35524373c7..c8caf228ffb 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -10,6 +10,7 @@ use rustc_errors::ErrorGuaranteed;
 use crate::ty;
 
 use rustc_hir::def_id::DefId;
+use rustc_macros::{HashStable, TypeVisitable};
 use rustc_query_system::cache::Cache;
 
 pub type SelectionCache<'tcx> = Cache<
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 13504c6ae93..4c34bf88c7f 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -1,5 +1,6 @@
 use rustc_ast_ir::try_visit;
 use rustc_data_structures::intern::Interned;
+use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_span::def_id::DefId;
 
 use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
@@ -332,4 +333,9 @@ pub enum CandidateSource {
     /// }
     /// ```
     AliasBound,
+    /// A candidate that is registered only during coherence to represent some
+    /// yet-unknown impl that could be produced downstream without violating orphan
+    /// rules.
+    // FIXME: Merge this with the forced ambiguity candidates, so those don't use `Misc`.
+    CoherenceUnknowable,
 }
diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs
index 52cdbae1e56..cddf9d5f874 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect.rs
@@ -24,6 +24,7 @@ use super::{
 };
 use crate::{infer::canonical::CanonicalVarValues, ty};
 use format::ProofTreeFormatter;
+use rustc_macros::{TypeFoldable, TypeVisitable};
 use std::fmt::{Debug, Write};
 
 mod format;
@@ -60,14 +61,14 @@ pub struct GoalEvaluation<'tcx> {
     pub evaluation: CanonicalGoalEvaluation<'tcx>,
 }
 
-#[derive(Eq, PartialEq)]
+#[derive(Eq, PartialEq, Debug)]
 pub struct CanonicalGoalEvaluation<'tcx> {
     pub goal: CanonicalInput<'tcx>,
     pub kind: CanonicalGoalEvaluationKind<'tcx>,
     pub result: QueryResult<'tcx>,
 }
 
-#[derive(Eq, PartialEq)]
+#[derive(Eq, PartialEq, Debug)]
 pub enum CanonicalGoalEvaluationKind<'tcx> {
     Overflow,
     CycleInStack,
@@ -86,7 +87,7 @@ pub struct AddedGoalsEvaluation<'tcx> {
     pub result: Result<Certainty, NoSolution>,
 }
 
-#[derive(Eq, PartialEq)]
+#[derive(Eq, PartialEq, Debug)]
 pub struct GoalEvaluationStep<'tcx> {
     pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
 
@@ -102,6 +103,7 @@ pub struct Probe<'tcx> {
     /// What happened inside of this probe in chronological order.
     pub steps: Vec<ProbeStep<'tcx>>,
     pub kind: ProbeKind<'tcx>,
+    pub final_state: CanonicalState<'tcx, ()>,
 }
 
 impl Debug for Probe<'_> {
@@ -121,6 +123,12 @@ pub enum ProbeStep<'tcx> {
     /// used whenever there are multiple candidates to prove the
     /// current goalby .
     NestedProbe(Probe<'tcx>),
+    /// A call to `EvalCtxt::evaluate_added_goals_make_canonical_response` with
+    /// `Certainty` was made. This is the certainty passed in, so it's not unified
+    /// with the certainty of the `try_evaluate_added_goals` that is done within;
+    /// if it's `Certainty::Yes`, then we can trust that the candidate is "finished"
+    /// and we didn't force ambiguity for some reason.
+    MakeCanonicalResponse { shallow_certainty: Certainty },
 }
 
 /// What kind of probe we're in. In case the probe represents a candidate, or
@@ -134,10 +142,6 @@ pub enum ProbeKind<'tcx> {
     TryNormalizeNonRigid { result: QueryResult<'tcx> },
     /// Probe entered when normalizing the self ty during candidate assembly
     NormalizedSelfTyAssembly,
-    /// Some candidate to prove the current goal.
-    ///
-    /// FIXME: Remove this in favor of always using more strongly typed variants.
-    MiscCandidate { name: &'static str, result: QueryResult<'tcx> },
     /// A candidate for proving a trait or alias-relate goal.
     TraitCandidate { source: CandidateSource, result: QueryResult<'tcx> },
     /// Used in the probe that wraps normalizing the non-self type for the unsize
@@ -147,4 +151,6 @@ pub enum ProbeKind<'tcx> {
     /// do a probe to find out what projection type(s) may be used to prove that
     /// the source type upholds all of the target type's object bounds.
     UpcastProjectionCompatibility,
+    /// Try to unify an opaque type with an existing key in the storage.
+    OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
 }
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 98f01fe8772..2d73be387fd 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             ProbeKind::UpcastProjectionCompatibility => {
                 write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
             }
-            ProbeKind::MiscCandidate { name, result } => {
-                write!(self.f, "CANDIDATE {name}: {result:?}")
+            ProbeKind::OpaqueTypeStorageLookup { result } => {
+                write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}")
             }
             ProbeKind::TraitCandidate { source, result } => {
                 write!(self.f, "CANDIDATE {source:?}: {result:?}")
@@ -132,6 +132,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
                     }
                     ProbeStep::EvaluateGoals(eval) => this.format_added_goals_evaluation(eval)?,
                     ProbeStep::NestedProbe(probe) => this.format_probe(probe)?,
+                    ProbeStep::MakeCanonicalResponse { shallow_certainty } => {
+                        writeln!(this.f, "EVALUATE GOALS AND MAKE RESPONSE: {shallow_certainty:?}")?
+                    }
                 }
             }
             Ok(())
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index ba29d4040a1..ff5d51bcb66 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -5,6 +5,7 @@ use crate::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::{DefId, DefIdMap};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::symbol::sym;
 
 /// A per-trait graph of impls in specialization order. At the moment, this
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 570f896ba29..dc46b470b6f 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -4,6 +4,7 @@ use crate::ty::{
     TypeVisitableExt,
 };
 use rustc_errors::ErrorGuaranteed;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
 
 #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)]
 #[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)]
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index c3e8991c63a..9badf65115e 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -1,7 +1,7 @@
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
 use rustc_target::abi::FieldIdx;
 
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index a7f1ba46b61..77da3fbe1d7 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -12,6 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_index::{IndexSlice, IndexVec};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::DataTypeKind;
 use rustc_span::symbol::sym;
@@ -26,7 +27,7 @@ use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, Var
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
 pub struct AdtFlags(u16);
-bitflags! {
+bitflags::bitflags! {
     impl AdtFlags: u16 {
         const NO_ADT_FLAGS        = 0;
         /// Indicates whether the ADT is an enum.
@@ -582,8 +583,7 @@ impl<'tcx> AdtDef<'tcx> {
     }
 }
 
-#[derive(Clone, Copy, Debug)]
-#[derive(HashStable)]
+#[derive(Clone, Copy, Debug, HashStable)]
 pub enum Representability {
     Representable,
     Infinite(ErrorGuaranteed),
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 94a5ff13158..1cdde3f057c 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -3,6 +3,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::def_id::DefId;
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_span::symbol::{Ident, Symbol};
 
 use super::{TyCtxt, Visibility};
diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs
index c9fd20bc112..26c5a865fdc 100644
--- a/compiler/rustc_middle/src/ty/cast.rs
+++ b/compiler/rustc_middle/src/ty/cast.rs
@@ -4,7 +4,7 @@
 use crate::ty::{self, Ty};
 use rustc_middle::mir;
 
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 
 /// Types that are represented as ints.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index b66c664e6ae..bade0d56415 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::HirId;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, Symbol};
@@ -423,7 +424,7 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>(
     mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T,
 ) -> impl Iterator<Item = T> + Captures<'a> + Captures<'tcx> {
     std::iter::from_coroutine(
-        #[cfg_attr(not(bootstrap), coroutine)]
+        #[coroutine]
         move || {
             let mut child_captures = child_captures.into_iter().enumerate().peekable();
 
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index fd4573c1603..a65b3a41ade 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -6,7 +6,7 @@ use rustc_error_messages::MultiSpan;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_type_ir::ConstKind as IrConstKind;
 use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo};
 
@@ -23,7 +23,7 @@ pub use valtree::*;
 pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(ConstKind<'_>, 32);
+rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
 
 /// Use this rather than `ConstData`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
@@ -63,7 +63,7 @@ pub struct ConstData<'tcx> {
 }
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(ConstData<'_>, 40);
+rustc_data_structures::static_assert_size!(ConstData<'_>, 40);
 
 impl<'tcx> Const<'tcx> {
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index a7e0a0402ce..7e49b0ac915 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -4,7 +4,7 @@ use crate::ty::abstract_const::CastKind;
 use crate::ty::GenericArgsRef;
 use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
 use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 
 /// An unevaluated (potentially generic) constant used in the type-system.
 #[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
@@ -72,4 +72,4 @@ pub enum Expr<'tcx> {
 }
 
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(Expr<'_>, 24);
+rustc_data_structures::static_assert_size!(Expr<'_>, 24);
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 45fa5e8f7ca..d2eacdf762f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -56,7 +56,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{HirId, Node, TraitCandidate};
 use rustc_index::IndexVec;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_query_system::dep_graph::DepNodeIndex;
 use rustc_query_system::ich::StableHashingContext;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
@@ -1285,7 +1285,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let definitions = &self.untracked.definitions;
         std::iter::from_coroutine(
-            #[cfg_attr(not(bootstrap), coroutine)]
+            #[coroutine]
             || {
                 let mut i = 0;
 
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index ce85c28ece8..71437ce1df9 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -4,6 +4,7 @@ use rustc_errors::pluralize;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind};
 use rustc_hir::def_id::DefId;
+use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::abi;
 use std::borrow::Cow;
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 10b0909209a..8d7489f5f7e 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -2,6 +2,7 @@ use crate::mir::Mutability;
 use crate::ty::GenericArgKind;
 use crate::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
 use rustc_hir::def_id::DefId;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use std::fmt::Debug;
 use std::hash::Hash;
 use std::iter;
@@ -329,20 +330,19 @@ impl DeepRejectCtxt {
     }
 
     pub fn consts_may_unify(self, obligation_ct: ty::Const<'_>, impl_ct: ty::Const<'_>) -> bool {
-        match impl_ct.kind() {
+        let impl_val = match impl_ct.kind() {
             ty::ConstKind::Expr(_)
             | ty::ConstKind::Param(_)
             | ty::ConstKind::Unevaluated(_)
             | ty::ConstKind::Error(_) => {
                 return true;
             }
-            ty::ConstKind::Value(_) => {}
+            ty::ConstKind::Value(impl_val) => impl_val,
             ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
                 bug!("unexpected impl arg: {:?}", impl_ct)
             }
-        }
+        };
 
-        let k = impl_ct.kind();
         match obligation_ct.kind() {
             ty::ConstKind::Param(_) => match self.treat_obligation_params {
                 TreatParams::ForLookup => false,
@@ -357,10 +357,7 @@ impl DeepRejectCtxt {
             ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
                 true
             }
-            ty::ConstKind::Value(obl) => match k {
-                ty::ConstKind::Value(imp) => obl == imp,
-                _ => true,
-            },
+            ty::ConstKind::Value(obl_val) => obl_val == impl_val,
 
             ty::ConstKind::Infer(_) => true,
 
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 19cef927faf..de2c01c3046 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -11,7 +11,9 @@ use rustc_ast_ir::walk_visitable_list;
 use rustc_data_structures::intern::Interned;
 use rustc_errors::{DiagArgValue, IntoDiagArg};
 use rustc_hir::def_id::DefId;
-use rustc_macros::HashStable;
+use rustc_macros::{
+    Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
+};
 use rustc_serialize::{Decodable, Encodable};
 use rustc_type_ir::WithCachedTypeInfo;
 use smallvec::SmallVec;
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index a99196cb363..6bf2051d67c 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -3,6 +3,7 @@ use crate::ty::{EarlyBinder, GenericArgsRef};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index c571ac50724..e3eea83ba49 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -1,3 +1,4 @@
+use rustc_macros::HashStable;
 use smallvec::SmallVec;
 
 use crate::ty::context::TyCtxt;
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 4002d0da790..a08fde976bc 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -8,7 +8,9 @@ use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::FiniteBitSet;
-use rustc_macros::HashStable;
+use rustc_macros::{
+    Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable, TypeVisitable,
+};
 use rustc_middle::ty::normalize_erasing_regions::NormalizationError;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::Symbol;
diff --git a/compiler/rustc_middle/src/ty/intrinsic.rs b/compiler/rustc_middle/src/ty/intrinsic.rs
index 18d08ed23a5..68c1d8c17ec 100644
--- a/compiler/rustc_middle/src/ty/intrinsic.rs
+++ b/compiler/rustc_middle/src/ty/intrinsic.rs
@@ -1,3 +1,4 @@
+use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_span::{def_id::DefId, Symbol};
 
 use super::TyCtxt;
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 897d6f5662f..f8490e5e15f 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -10,6 +10,7 @@ use rustc_errors::{
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_index::IndexVec;
+use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable};
 use rustc_session::config::OptLevel;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
@@ -124,7 +125,7 @@ impl Primitive {
             F64 => tcx.types.f64,
             F128 => tcx.types.f128,
             // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
-            Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)),
+            Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit),
         }
     }
 
@@ -774,7 +775,7 @@ where
                     // (which may have no non-DST form), and will work as long
                     // as the `Abi` or `FieldsShape` is checked by users.
                     if i == 0 {
-                        let nil = Ty::new_unit(tcx);
+                        let nil = tcx.types.unit;
                         let unit_ptr_ty = if this.ty.is_unsafe_ptr() {
                             Ty::new_mut_ptr(tcx, nil)
                         } else {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 094b68ce5ad..73b20f0485b 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -47,7 +47,9 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
 use rustc_index::IndexVec;
-use rustc_macros::HashStable;
+use rustc_macros::{
+    Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
+};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_serialize::{Decodable, Encodable};
 use rustc_session::lint::LintBuffer;
@@ -1083,7 +1085,7 @@ struct ParamTag {
     reveal: traits::Reveal,
 }
 
-impl_tag! {
+rustc_data_structures::impl_tag! {
     impl Tag for ParamTag;
     ParamTag { reveal: traits::Reveal::UserFacing },
     ParamTag { reveal: traits::Reveal::All },
@@ -1222,7 +1224,7 @@ pub struct Destructor {
 
 #[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
 pub struct VariantFlags(u8);
-bitflags! {
+bitflags::bitflags! {
     impl VariantFlags: u8 {
         const NO_VARIANT_FLAGS        = 0;
         /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
@@ -1501,14 +1503,14 @@ pub enum ImplOverlapKind {
         /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
         marker: bool,
     },
-    /// These impls are allowed to overlap, but that raises
-    /// an issue #33140 future-compatibility warning.
+    /// These impls are allowed to overlap, but that raises an
+    /// issue #33140 future-compatibility warning (tracked in #56484).
     ///
     /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
     /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
     ///
-    /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
-    /// that difference, making what reduces to the following set of impls:
+    /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied on
+    /// that difference, doing what reduces to the following set of impls:
     ///
     /// ```compile_fail,(E0119)
     /// trait Trait {}
@@ -1533,7 +1535,7 @@ pub enum ImplOverlapKind {
     /// 4. Neither of the impls can have any where-clauses.
     ///
     /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
-    Issue33140,
+    FutureCompatOrderDepTraitObjects,
 }
 
 /// Useful source information about where a desugared associated type for an
@@ -1728,27 +1730,26 @@ impl<'tcx> TyCtxt<'tcx> {
             | (ImplPolarity::Negative, ImplPolarity::Negative) => {}
         };
 
-        let is_marker_overlap = {
-            let is_marker_impl =
-                |trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker };
-            is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2)
-        };
+        let is_marker_impl = |trait_ref: TraitRef<'_>| self.trait_def(trait_ref.def_id).is_marker;
+        let is_marker_overlap = is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2);
 
         if is_marker_overlap {
-            Some(ImplOverlapKind::Permitted { marker: true })
-        } else {
-            if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
-                if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
-                    if self_ty1 == self_ty2 {
-                        return Some(ImplOverlapKind::Issue33140);
-                    } else {
-                        debug!("found {self_ty1:?} != {self_ty2:?}");
-                    }
-                }
-            }
+            return Some(ImplOverlapKind::Permitted { marker: true });
+        }
 
-            None
+        if let Some(self_ty1) =
+            self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id1)
+            && let Some(self_ty2) =
+                self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id2)
+        {
+            if self_ty1 == self_ty2 {
+                return Some(ImplOverlapKind::FutureCompatOrderDepTraitObjects);
+            } else {
+                debug!("found {self_ty1:?} != {self_ty2:?}");
+            }
         }
+
+        None
     }
 
     /// Returns `ty::VariantDef` if `res` refers to a struct,
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 58543674460..791f27a9789 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -10,6 +10,7 @@
 use crate::traits::query::NoSolution;
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
 use crate::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 
 #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)]
 pub enum NormalizationError<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs
index 8a41ba257ec..d1875fbaea3 100644
--- a/compiler/rustc_middle/src/ty/pattern.rs
+++ b/compiler/rustc_middle/src/ty/pattern.rs
@@ -2,6 +2,7 @@ use std::fmt;
 
 use crate::ty;
 use rustc_data_structures::intern::Interned;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
 #[rustc_pass_by_value]
diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs
index 05156dd5205..56dd52567fd 100644
--- a/compiler/rustc_middle/src/ty/predicate.rs
+++ b/compiler/rustc_middle/src/ty/predicate.rs
@@ -3,6 +3,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_errors::{DiagArgValue, IntoDiagArg};
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
+use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_span::Span;
 use rustc_type_ir::ClauseKind as IrClauseKind;
 use rustc_type_ir::PredicateKind as IrPredicateKind;
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index e5450182bf2..5f47aef0f32 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -16,6 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
 use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPathDataName};
 use rustc_hir::LangItem;
+use rustc_macros::Lift;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
 use rustc_session::Limit;
 use rustc_span::symbol::{kw, Ident, Symbol};
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs
index b92800a1728..3d9be15310f 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -3,6 +3,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_errors::MultiSpan;
 use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::symbol::sym;
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{ErrorGuaranteed, DUMMY_SP};
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 3c1dea1d9f2..7063ef07201 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -10,6 +10,7 @@ use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
+use rustc_macros::TypeVisitable;
 use rustc_target::spec::abi;
 use std::iter;
 
diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
index 17eabec257e..cb2f7284eaa 100644
--- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs
+++ b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
@@ -1,6 +1,7 @@
 use crate::middle::region::{Scope, ScopeData, ScopeTree};
 use rustc_hir as hir;
 use rustc_hir::ItemLocalMap;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 
 /// `RvalueScopes` is a mapping from sub-expressions to _extended_ lifetime as determined by
 /// rules laid out in `rustc_hir_analysis::check::rvalue_scopes`.
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 0184ff54979..de70c4f7b65 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -17,7 +17,7 @@ use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
@@ -1751,11 +1751,6 @@ impl<'tcx> Ty<'tcx> {
     // misc
 
     #[inline]
-    pub fn new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        tcx.types.unit
-    }
-
-    #[inline]
     pub fn new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_)
     }
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index e06e3465eb2..cf5decffea9 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -8,7 +8,7 @@ use std::iter;
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorGuaranteed;
-use rustc_macros::HashStable;
+use rustc_macros::{Decodable, Encodable, HashStable};
 
 /// A trait's definition with type information.
 #[derive(HashStable, Encodable, Decodable)]
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 0c4409197bb..41f417dfd4b 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -18,7 +18,7 @@ use rustc_hir::{
     BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
 };
 use rustc_index::IndexVec;
-use rustc_macros::HashStable;
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_middle::mir::FakeReadCause;
 use rustc_session::Session;
 use rustc_span::Span;
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 42e0565db83..f5e973f85da 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -17,12 +17,12 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_index::bit_set::GrowableBitSet;
-use rustc_macros::HashStable;
+use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable};
 use rustc_session::Limit;
 use rustc_span::sym;
 use rustc_target::abi::{Integer, IntegerType, Primitive, Size};
 use rustc_target::spec::abi::Abi;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 use std::{fmt, iter};
 
 #[derive(Copy, Clone, Debug)]
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index 62f41921d88..2ad19431310 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -3,6 +3,7 @@ use std::fmt;
 use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar};
 use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
 use rustc_ast::Mutability;
+use rustc_macros::HashStable;
 
 #[derive(Clone, Copy, PartialEq, HashStable)]
 pub enum VtblEntry<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 7069bdcbcb9..089e61749c3 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -4,7 +4,7 @@
 use crate::ty::{self, Ty};
 use crate::ty::{GenericArg, GenericArgKind};
 use rustc_data_structures::sso::SsoHashSet;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
 // The TypeWalker's stack is hot enough that it's worth going to some effort to
 // avoid heap allocations.
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs
index 9e9ccd3dc2d..e2a5f97a847 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs
@@ -1,31 +1,25 @@
+mod mcdc;
 use std::assert_matches::assert_matches;
 use std::collections::hash_map::Entry;
-use std::collections::VecDeque;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::mir::coverage::{
-    BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
-    MCDCDecisionSpan,
-};
+use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
 use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
-use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir};
+use rustc_middle::thir::{ExprId, ExprKind, Thir};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::Span;
 
+use crate::build::coverageinfo::mcdc::MCDCInfoBuilder;
 use crate::build::{Builder, CFG};
-use crate::errors::MCDCExceedsConditionNumLimit;
 
 pub(crate) struct BranchInfoBuilder {
     /// Maps condition expressions to their enclosing `!`, for better instrumentation.
     nots: FxHashMap<ExprId, NotInfo>,
 
-    num_block_markers: usize,
+    markers: BlockMarkerGen,
     branch_spans: Vec<BranchSpan>,
 
-    mcdc_branch_spans: Vec<MCDCBranchSpan>,
-    mcdc_decision_spans: Vec<MCDCDecisionSpan>,
-    mcdc_state: Option<MCDCState>,
+    mcdc_info: Option<MCDCInfoBuilder>,
 }
 
 #[derive(Clone, Copy)]
@@ -38,6 +32,35 @@ struct NotInfo {
     is_flipped: bool,
 }
 
+#[derive(Default)]
+struct BlockMarkerGen {
+    num_block_markers: usize,
+}
+
+impl BlockMarkerGen {
+    fn next_block_marker_id(&mut self) -> BlockMarkerId {
+        let id = BlockMarkerId::from_usize(self.num_block_markers);
+        self.num_block_markers += 1;
+        id
+    }
+
+    fn inject_block_marker(
+        &mut self,
+        cfg: &mut CFG<'_>,
+        source_info: SourceInfo,
+        block: BasicBlock,
+    ) -> BlockMarkerId {
+        let id = self.next_block_marker_id();
+        let marker_statement = mir::Statement {
+            source_info,
+            kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
+        };
+        cfg.push(block, marker_statement);
+
+        id
+    }
+}
+
 impl BranchInfoBuilder {
     /// Creates a new branch info builder, but only if branch coverage instrumentation
     /// is enabled and `def_id` represents a function that is eligible for coverage.
@@ -45,11 +68,9 @@ impl BranchInfoBuilder {
         if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) {
             Some(Self {
                 nots: FxHashMap::default(),
-                num_block_markers: 0,
+                markers: BlockMarkerGen::default(),
                 branch_spans: vec![],
-                mcdc_branch_spans: vec![],
-                mcdc_decision_spans: vec![],
-                mcdc_state: MCDCState::new_if_enabled(tcx),
+                mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new),
             })
         } else {
             None
@@ -96,44 +117,6 @@ impl BranchInfoBuilder {
         }
     }
 
-    fn fetch_mcdc_condition_info(
-        &mut self,
-        tcx: TyCtxt<'_>,
-        true_marker: BlockMarkerId,
-        false_marker: BlockMarkerId,
-    ) -> Option<ConditionInfo> {
-        let mcdc_state = self.mcdc_state.as_mut()?;
-        let (mut condition_info, decision_result) =
-            mcdc_state.take_condition(true_marker, false_marker);
-        if let Some(decision) = decision_result {
-            match decision.conditions_num {
-                0 => {
-                    unreachable!("Decision with no condition is not expected");
-                }
-                1..=MAX_CONDITIONS_NUM_IN_DECISION => {
-                    self.mcdc_decision_spans.push(decision);
-                }
-                _ => {
-                    // Do not generate mcdc mappings and statements for decisions with too many conditions.
-                    let rebase_idx = self.mcdc_branch_spans.len() - decision.conditions_num + 1;
-                    for branch in &mut self.mcdc_branch_spans[rebase_idx..] {
-                        branch.condition_info = None;
-                    }
-
-                    // ConditionInfo of this branch shall also be reset.
-                    condition_info = None;
-
-                    tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit {
-                        span: decision.span,
-                        conditions_num: decision.conditions_num,
-                        max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION,
-                    });
-                }
-            }
-        }
-        condition_info
-    }
-
     fn add_two_way_branch<'tcx>(
         &mut self,
         cfg: &mut CFG<'tcx>,
@@ -141,43 +124,18 @@ impl BranchInfoBuilder {
         true_block: BasicBlock,
         false_block: BasicBlock,
     ) {
-        let true_marker = self.inject_block_marker(cfg, source_info, true_block);
-        let false_marker = self.inject_block_marker(cfg, source_info, false_block);
+        let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
+        let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
 
         self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
     }
 
-    fn next_block_marker_id(&mut self) -> BlockMarkerId {
-        let id = BlockMarkerId::from_usize(self.num_block_markers);
-        self.num_block_markers += 1;
-        id
-    }
-
-    fn inject_block_marker(
-        &mut self,
-        cfg: &mut CFG<'_>,
-        source_info: SourceInfo,
-        block: BasicBlock,
-    ) -> BlockMarkerId {
-        let id = self.next_block_marker_id();
-
-        let marker_statement = mir::Statement {
-            source_info,
-            kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
-        };
-        cfg.push(block, marker_statement);
-
-        id
-    }
-
     pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
         let Self {
             nots: _,
-            num_block_markers,
+            markers: BlockMarkerGen { num_block_markers },
             branch_spans,
-            mcdc_branch_spans,
-            mcdc_decision_spans,
-            mcdc_state: _,
+            mcdc_info,
         } = self;
 
         if num_block_markers == 0 {
@@ -185,6 +143,9 @@ impl BranchInfoBuilder {
             return None;
         }
 
+        let (mcdc_decision_spans, mcdc_branch_spans) =
+            mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
+
         Some(Box::new(mir::coverage::BranchInfo {
             num_block_markers,
             branch_spans,
@@ -194,147 +155,6 @@ impl BranchInfoBuilder {
     }
 }
 
-/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen,
-/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge.
-/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged.
-const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
-
-struct MCDCState {
-    /// To construct condition evaluation tree.
-    decision_stack: VecDeque<ConditionInfo>,
-    processing_decision: Option<MCDCDecisionSpan>,
-}
-
-impl MCDCState {
-    fn new_if_enabled(tcx: TyCtxt<'_>) -> Option<Self> {
-        tcx.sess
-            .instrument_coverage_mcdc()
-            .then(|| Self { decision_stack: VecDeque::new(), processing_decision: None })
-    }
-
-    // At first we assign ConditionIds for each sub expression.
-    // If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS.
-    //
-    // Example: "x = (A && B) || (C && D) || (D && F)"
-    //
-    //      Visit Depth1:
-    //              (A && B) || (C && D) || (D && F)
-    //              ^-------LHS--------^    ^-RHS--^
-    //                      ID=1              ID=2
-    //
-    //      Visit LHS-Depth2:
-    //              (A && B) || (C && D)
-    //              ^-LHS--^    ^-RHS--^
-    //                ID=1        ID=3
-    //
-    //      Visit LHS-Depth3:
-    //               (A && B)
-    //               LHS   RHS
-    //               ID=1  ID=4
-    //
-    //      Visit RHS-Depth3:
-    //                         (C && D)
-    //                         LHS   RHS
-    //                         ID=3  ID=5
-    //
-    //      Visit RHS-Depth2:              (D && F)
-    //                                     LHS   RHS
-    //                                     ID=2  ID=6
-    //
-    //      Visit Depth1:
-    //              (A && B)  || (C && D)  || (D && F)
-    //              ID=1  ID=4   ID=3  ID=5   ID=2  ID=6
-    //
-    // A node ID of '0' always means MC/DC isn't being tracked.
-    //
-    // If a "next" node ID is '0', it means it's the end of the test vector.
-    //
-    // As the compiler tracks expression in pre-order, we can ensure that condition info of parents are always properly assigned when their children are visited.
-    // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next".
-    // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next".
-    fn record_conditions(&mut self, op: LogicalOp, span: Span) {
-        let decision = match self.processing_decision.as_mut() {
-            Some(decision) => {
-                decision.span = decision.span.to(span);
-                decision
-            }
-            None => self.processing_decision.insert(MCDCDecisionSpan {
-                span,
-                conditions_num: 0,
-                end_markers: vec![],
-            }),
-        };
-
-        let parent_condition = self.decision_stack.pop_back().unwrap_or_default();
-        let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
-            decision.conditions_num += 1;
-            ConditionId::from(decision.conditions_num)
-        } else {
-            parent_condition.condition_id
-        };
-
-        decision.conditions_num += 1;
-        let rhs_condition_id = ConditionId::from(decision.conditions_num);
-
-        let (lhs, rhs) = match op {
-            LogicalOp::And => {
-                let lhs = ConditionInfo {
-                    condition_id: lhs_id,
-                    true_next_id: rhs_condition_id,
-                    false_next_id: parent_condition.false_next_id,
-                };
-                let rhs = ConditionInfo {
-                    condition_id: rhs_condition_id,
-                    true_next_id: parent_condition.true_next_id,
-                    false_next_id: parent_condition.false_next_id,
-                };
-                (lhs, rhs)
-            }
-            LogicalOp::Or => {
-                let lhs = ConditionInfo {
-                    condition_id: lhs_id,
-                    true_next_id: parent_condition.true_next_id,
-                    false_next_id: rhs_condition_id,
-                };
-                let rhs = ConditionInfo {
-                    condition_id: rhs_condition_id,
-                    true_next_id: parent_condition.true_next_id,
-                    false_next_id: parent_condition.false_next_id,
-                };
-                (lhs, rhs)
-            }
-        };
-        // We visit expressions tree in pre-order, so place the left-hand side on the top.
-        self.decision_stack.push_back(rhs);
-        self.decision_stack.push_back(lhs);
-    }
-
-    fn take_condition(
-        &mut self,
-        true_marker: BlockMarkerId,
-        false_marker: BlockMarkerId,
-    ) -> (Option<ConditionInfo>, Option<MCDCDecisionSpan>) {
-        let Some(condition_info) = self.decision_stack.pop_back() else {
-            return (None, None);
-        };
-        let Some(decision) = self.processing_decision.as_mut() else {
-            bug!("Processing decision should have been created before any conditions are taken");
-        };
-        if condition_info.true_next_id == ConditionId::NONE {
-            decision.end_markers.push(true_marker);
-        }
-        if condition_info.false_next_id == ConditionId::NONE {
-            decision.end_markers.push(false_marker);
-        }
-
-        if self.decision_stack.is_empty() {
-            (Some(condition_info), self.processing_decision.take())
-        } else {
-            (Some(condition_info), None)
-        }
-    }
-}
-
 impl Builder<'_, '_> {
     /// If branch coverage is enabled, inject marker statements into `then_block`
     /// and `else_block`, and record their IDs in the table of branch spans.
@@ -359,30 +179,20 @@ impl Builder<'_, '_> {
         let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
 
         // Separate path for handling branches when MC/DC is enabled.
-        if branch_info.mcdc_state.is_some() {
-            let mut inject_block_marker =
-                |block| branch_info.inject_block_marker(&mut self.cfg, source_info, block);
-            let true_marker = inject_block_marker(then_block);
-            let false_marker = inject_block_marker(else_block);
-            let condition_info =
-                branch_info.fetch_mcdc_condition_info(self.tcx, true_marker, false_marker);
-            branch_info.mcdc_branch_spans.push(MCDCBranchSpan {
-                span: source_info.span,
-                condition_info,
-                true_marker,
-                false_marker,
-            });
+        if let Some(mcdc_info) = branch_info.mcdc_info.as_mut() {
+            let inject_block_marker = |source_info, block| {
+                branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block)
+            };
+            mcdc_info.visit_evaluated_condition(
+                self.tcx,
+                source_info,
+                then_block,
+                else_block,
+                inject_block_marker,
+            );
             return;
         }
 
         branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
     }
-
-    pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
-        if let Some(branch_info) = self.coverage_branch_info.as_mut()
-            && let Some(mcdc_state) = branch_info.mcdc_state.as_mut()
-        {
-            mcdc_state.record_conditions(logical_op, span);
-        }
-    }
 }
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
new file mode 100644
index 00000000000..566dba460d4
--- /dev/null
+++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
@@ -0,0 +1,275 @@
+use std::collections::VecDeque;
+
+use rustc_middle::mir::coverage::{
+    BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan,
+};
+use rustc_middle::mir::{BasicBlock, SourceInfo};
+use rustc_middle::thir::LogicalOp;
+use rustc_middle::ty::TyCtxt;
+use rustc_span::Span;
+
+use crate::build::Builder;
+use crate::errors::MCDCExceedsConditionNumLimit;
+
+/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen,
+/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge.
+/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged.
+const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
+
+#[derive(Default)]
+struct MCDCDecisionCtx {
+    /// To construct condition evaluation tree.
+    decision_stack: VecDeque<ConditionInfo>,
+    processing_decision: Option<MCDCDecisionSpan>,
+}
+
+struct MCDCState {
+    decision_ctx_stack: Vec<MCDCDecisionCtx>,
+}
+
+impl MCDCState {
+    fn new() -> Self {
+        Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] }
+    }
+
+    /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`,
+    /// as it is very unlikely that the depth ever reaches 2^16.
+    #[inline]
+    fn decision_depth(&self) -> u16 {
+        match u16::try_from(self.decision_ctx_stack.len())
+            .expect(
+                "decision depth did not fit in u16, this is likely to be an instrumentation error",
+            )
+            .checked_sub(1)
+        {
+            Some(d) => d,
+            None => bug!("Unexpected empty decision stack"),
+        }
+    }
+
+    // At first we assign ConditionIds for each sub expression.
+    // If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS.
+    //
+    // Example: "x = (A && B) || (C && D) || (D && F)"
+    //
+    //      Visit Depth1:
+    //              (A && B) || (C && D) || (D && F)
+    //              ^-------LHS--------^    ^-RHS--^
+    //                      ID=1              ID=2
+    //
+    //      Visit LHS-Depth2:
+    //              (A && B) || (C && D)
+    //              ^-LHS--^    ^-RHS--^
+    //                ID=1        ID=3
+    //
+    //      Visit LHS-Depth3:
+    //               (A && B)
+    //               LHS   RHS
+    //               ID=1  ID=4
+    //
+    //      Visit RHS-Depth3:
+    //                         (C && D)
+    //                         LHS   RHS
+    //                         ID=3  ID=5
+    //
+    //      Visit RHS-Depth2:              (D && F)
+    //                                     LHS   RHS
+    //                                     ID=2  ID=6
+    //
+    //      Visit Depth1:
+    //              (A && B)  || (C && D)  || (D && F)
+    //              ID=1  ID=4   ID=3  ID=5   ID=2  ID=6
+    //
+    // A node ID of '0' always means MC/DC isn't being tracked.
+    //
+    // If a "next" node ID is '0', it means it's the end of the test vector.
+    //
+    // As the compiler tracks expression in pre-order, we can ensure that condition info of parents are always properly assigned when their children are visited.
+    // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next".
+    // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next".
+    fn record_conditions(&mut self, op: LogicalOp, span: Span) {
+        let decision_depth = self.decision_depth();
+        let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else {
+            bug!("Unexpected empty decision_ctx_stack")
+        };
+        let decision = match decision_ctx.processing_decision.as_mut() {
+            Some(decision) => {
+                decision.span = decision.span.to(span);
+                decision
+            }
+            None => decision_ctx.processing_decision.insert(MCDCDecisionSpan {
+                span,
+                conditions_num: 0,
+                end_markers: vec![],
+                decision_depth,
+            }),
+        };
+
+        let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default();
+        let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
+            decision.conditions_num += 1;
+            ConditionId::from(decision.conditions_num)
+        } else {
+            parent_condition.condition_id
+        };
+
+        decision.conditions_num += 1;
+        let rhs_condition_id = ConditionId::from(decision.conditions_num);
+
+        let (lhs, rhs) = match op {
+            LogicalOp::And => {
+                let lhs = ConditionInfo {
+                    condition_id: lhs_id,
+                    true_next_id: rhs_condition_id,
+                    false_next_id: parent_condition.false_next_id,
+                };
+                let rhs = ConditionInfo {
+                    condition_id: rhs_condition_id,
+                    true_next_id: parent_condition.true_next_id,
+                    false_next_id: parent_condition.false_next_id,
+                };
+                (lhs, rhs)
+            }
+            LogicalOp::Or => {
+                let lhs = ConditionInfo {
+                    condition_id: lhs_id,
+                    true_next_id: parent_condition.true_next_id,
+                    false_next_id: rhs_condition_id,
+                };
+                let rhs = ConditionInfo {
+                    condition_id: rhs_condition_id,
+                    true_next_id: parent_condition.true_next_id,
+                    false_next_id: parent_condition.false_next_id,
+                };
+                (lhs, rhs)
+            }
+        };
+        // We visit expressions tree in pre-order, so place the left-hand side on the top.
+        decision_ctx.decision_stack.push_back(rhs);
+        decision_ctx.decision_stack.push_back(lhs);
+    }
+
+    fn take_condition(
+        &mut self,
+        true_marker: BlockMarkerId,
+        false_marker: BlockMarkerId,
+    ) -> (Option<ConditionInfo>, Option<MCDCDecisionSpan>) {
+        let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else {
+            bug!("Unexpected empty decision_ctx_stack")
+        };
+        let Some(condition_info) = decision_ctx.decision_stack.pop_back() else {
+            return (None, None);
+        };
+        let Some(decision) = decision_ctx.processing_decision.as_mut() else {
+            bug!("Processing decision should have been created before any conditions are taken");
+        };
+        if condition_info.true_next_id == ConditionId::NONE {
+            decision.end_markers.push(true_marker);
+        }
+        if condition_info.false_next_id == ConditionId::NONE {
+            decision.end_markers.push(false_marker);
+        }
+
+        if decision_ctx.decision_stack.is_empty() {
+            (Some(condition_info), decision_ctx.processing_decision.take())
+        } else {
+            (Some(condition_info), None)
+        }
+    }
+}
+
+pub struct MCDCInfoBuilder {
+    branch_spans: Vec<MCDCBranchSpan>,
+    decision_spans: Vec<MCDCDecisionSpan>,
+    state: MCDCState,
+}
+
+impl MCDCInfoBuilder {
+    pub fn new() -> Self {
+        Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() }
+    }
+
+    pub fn visit_evaluated_condition(
+        &mut self,
+        tcx: TyCtxt<'_>,
+        source_info: SourceInfo,
+        true_block: BasicBlock,
+        false_block: BasicBlock,
+        mut inject_block_marker: impl FnMut(SourceInfo, BasicBlock) -> BlockMarkerId,
+    ) {
+        let true_marker = inject_block_marker(source_info, true_block);
+        let false_marker = inject_block_marker(source_info, false_block);
+
+        let decision_depth = self.state.decision_depth();
+        let (mut condition_info, decision_result) =
+            self.state.take_condition(true_marker, false_marker);
+        // take_condition() returns Some for decision_result when the decision stack
+        // is empty, i.e. when all the conditions of the decision were instrumented,
+        // and the decision is "complete".
+        if let Some(decision) = decision_result {
+            match decision.conditions_num {
+                0 => {
+                    unreachable!("Decision with no condition is not expected");
+                }
+                1..=MAX_CONDITIONS_NUM_IN_DECISION => {
+                    self.decision_spans.push(decision);
+                }
+                _ => {
+                    // Do not generate mcdc mappings and statements for decisions with too many conditions.
+                    let rebase_idx = self.branch_spans.len() - decision.conditions_num + 1;
+                    for branch in &mut self.branch_spans[rebase_idx..] {
+                        branch.condition_info = None;
+                    }
+
+                    // ConditionInfo of this branch shall also be reset.
+                    condition_info = None;
+
+                    tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit {
+                        span: decision.span,
+                        conditions_num: decision.conditions_num,
+                        max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION,
+                    });
+                }
+            }
+        }
+        self.branch_spans.push(MCDCBranchSpan {
+            span: source_info.span,
+            condition_info,
+            true_marker,
+            false_marker,
+            decision_depth,
+        });
+    }
+
+    pub fn into_done(self) -> (Vec<MCDCDecisionSpan>, Vec<MCDCBranchSpan>) {
+        (self.decision_spans, self.branch_spans)
+    }
+}
+
+impl Builder<'_, '_> {
+    pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
+        if let Some(branch_info) = self.coverage_branch_info.as_mut()
+            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        {
+            mcdc_info.state.record_conditions(logical_op, span);
+        }
+    }
+
+    pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) {
+        if let Some(branch_info) = self.coverage_branch_info.as_mut()
+            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        {
+            mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default());
+        };
+    }
+
+    pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) {
+        if let Some(branch_info) = self.coverage_branch_info.as_mut()
+            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        {
+            if mcdc_info.state.decision_ctx_stack.pop().is_none() {
+                bug!("Unexpected empty decision stack");
+            }
+        };
+    }
+}
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index d36c51f4472..bce15267759 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -73,14 +73,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let expr_span = expr.span;
 
         match expr.kind {
-            ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => {
-                this.visit_coverage_branch_operation(LogicalOp::And, expr_span);
+            ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => {
+                this.visit_coverage_branch_operation(op, expr_span);
                 let lhs_then_block = unpack!(this.then_else_break_inner(block, lhs, args));
                 let rhs_then_block = unpack!(this.then_else_break_inner(lhs_then_block, rhs, args));
                 rhs_then_block.unit()
             }
-            ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => {
-                this.visit_coverage_branch_operation(LogicalOp::Or, expr_span);
+            ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => {
+                this.visit_coverage_branch_operation(op, expr_span);
                 let local_scope = this.local_scope();
                 let (lhs_success_block, failure_block) =
                     this.in_if_then_scope(local_scope, expr_span, |this| {
@@ -148,8 +148,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let mut block = block;
                 let temp_scope = args.temp_scope_override.unwrap_or_else(|| this.local_scope());
                 let mutability = Mutability::Mut;
+
+                // Increment the decision depth, in case we encounter boolean expressions
+                // further down.
+                this.mcdc_increment_depth_if_enabled();
                 let place =
                     unpack!(block = this.as_temp(block, Some(temp_scope), expr_id, mutability));
+                this.mcdc_decrement_depth_if_enabled();
+
                 let operand = Operand::Move(Place::from(place));
 
                 let then_block = this.cfg.start_new_block();
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 3c18afe1a78..d6e6cc957b4 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -997,7 +997,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         match self.unit_temp {
             Some(tmp) => tmp,
             None => {
-                let ty = Ty::new_unit(self.tcx);
+                let ty = self.tcx.types.unit;
                 let fn_span = self.fn_span;
                 let tmp = self.temp(ty, fn_span);
                 self.unit_temp = Some(tmp);
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 442f5fa7d17..e79e3b887fb 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -5,7 +5,6 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 #![feature(assert_matches)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index f4f591d15b9..79738b54035 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -15,7 +15,7 @@ use rustc_hir::HirId;
 use rustc_hir::Node;
 use rustc_middle::middle::region;
 use rustc_middle::thir::*;
-use rustc_middle::ty::{self, RvalueScopes, Ty, TyCtxt};
+use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
 
 pub(crate) fn thir_body(
     tcx: TyCtxt<'_>,
@@ -39,7 +39,7 @@ pub(crate) fn thir_body(
         // It will always be `()` in this case.
         if tcx.is_coroutine(owner_def.to_def_id()) && body.params.is_empty() {
             cx.thir.params.push(Param {
-                ty: Ty::new_unit(tcx),
+                ty: tcx.types.unit,
                 pat: None,
                 ty_span: None,
                 self_kind: None,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 241d38f90d2..25ab9046706 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -10,9 +10,7 @@ use rustc_arena::{DroplessArena, TypedArena};
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{
-    codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan,
-};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, ErrorGuaranteed, MultiSpan};
 use rustc_hir::def::*;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
@@ -24,7 +22,6 @@ use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
 use rustc_session::lint::builtin::{
     BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
 };
-use rustc_session::Session;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::{sym, Span};
 
@@ -64,10 +61,6 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
     visitor.error
 }
 
-fn create_e0004(sess: &Session, sp: Span, error_message: String) -> Diag<'_> {
-    struct_span_code_err!(sess.dcx(), sp, E0004, "{}", &error_message)
-}
-
 #[derive(Debug, Copy, Clone, PartialEq)]
 enum RefutableFlag {
     Irrefutable,
@@ -975,10 +968,11 @@ fn report_non_exhaustive_match<'p, 'tcx>(
 
     // FIXME: migration of this diagnostic will require list support
     let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
-    let mut err = create_e0004(
-        cx.tcx.sess,
+    let mut err = struct_span_code_err!(
+        cx.tcx.dcx(),
         sp,
-        format!("non-exhaustive patterns: {joined_patterns} not covered"),
+        E0004,
+        "non-exhaustive patterns: {joined_patterns} not covered"
     );
     err.span_label(
         sp,
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index d63db6ea8ed..185e87baed8 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -2,6 +2,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_index::Idx;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::traits::Reveal;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::GenericArgsRef;
@@ -630,7 +631,7 @@ where
 
         let ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
         let ref_place = self.new_temp(ref_ty);
-        let unit_temp = Place::from(self.new_temp(Ty::new_unit(tcx)));
+        let unit_temp = Place::from(self.new_temp(tcx.types.unit));
 
         let result = BasicBlockData {
             statements: vec![self.assign(
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 44a7dcc8277..ea9cf6565e7 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -13,6 +13,7 @@ use rustc_data_structures::work_queue::WorkQueue;
 use rustc_graphviz as dot;
 use rustc_hir::def_id::DefId;
 use rustc_index::{Idx, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::{self, traversal, BasicBlock};
 use rustc_middle::mir::{create_dump_file, dump_enabled};
 use rustc_middle::ty::print::with_no_trimmed_paths;
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 720515f262d..180168c7316 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -1,5 +1,6 @@
 use rustc_index::bit_set::{BitSet, ChunkedBitSet};
 use rustc_index::Idx;
+use rustc_middle::bug;
 use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges};
 use rustc_middle::ty::{self, TyCtxt};
 
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index c5adb81b614..5e96a73f6c5 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -6,8 +6,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 use rustc_middle::ty;
 
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index d7477309400..6ae7df79d30 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -2,6 +2,7 @@ use rustc_index::IndexVec;
 use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use smallvec::{smallvec, SmallVec};
 
 use std::mem;
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index 22cf3999239..830f44df5fb 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -358,20 +358,15 @@ impl<'tcx> MoveData<'tcx> {
         builder::gather_moves(body, tcx, param_env, filter)
     }
 
-    /// For the move path `mpi`, returns the root local variable (if any) that starts the path.
-    /// (e.g., for a path like `a.b.c` returns `Some(a)`)
-    pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
+    /// For the move path `mpi`, returns the root local variable that starts the path.
+    /// (e.g., for a path like `a.b.c` returns `a`)
+    pub fn base_local(&self, mut mpi: MovePathIndex) -> Local {
         loop {
             let path = &self.move_paths[mpi];
             if let Some(l) = path.place.as_local() {
-                return Some(l);
-            }
-            if let Some(parent) = path.parent {
-                mpi = parent;
-                continue;
-            } else {
-                return None;
+                return l;
             }
+            mpi = path.parent.expect("root move paths should be locals");
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 0e85f859ab2..807bef07411 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -40,6 +40,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_index::bit_set::BitSet;
 use rustc_index::{IndexSlice, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index b745d97567d..3008016863e 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -1260,7 +1260,7 @@ fn create_coroutine_drop_shim<'tcx>(
     }
 
     // Replace the return variable
-    body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(Ty::new_unit(tcx), source_info);
+    body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(tcx.types.unit, source_info);
 
     make_coroutine_state_argument_indirect(tcx, &mut body);
 
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
new file mode 100644
index 00000000000..d364658efb6
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -0,0 +1,275 @@
+use std::collections::BTreeSet;
+
+use rustc_data_structures::graph::DirectedGraph;
+use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::coverage::{
+    BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
+};
+use rustc_middle::mir::{self, BasicBlock, StatementKind};
+use rustc_span::Span;
+
+use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
+use crate::coverage::spans::{
+    extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
+};
+use crate::coverage::ExtractedHirInfo;
+use rustc_index::IndexVec;
+
+#[derive(Clone, Debug)]
+pub(super) enum BcbMappingKind {
+    /// Associates an ordinary executable code span with its corresponding BCB.
+    Code(BasicCoverageBlock),
+
+    // Ordinary branch mappings are stored separately, so they don't have a
+    // variant in this enum.
+    //
+    /// Associates a mcdc branch span with condition info besides fields for normal branch.
+    MCDCBranch {
+        true_bcb: BasicCoverageBlock,
+        false_bcb: BasicCoverageBlock,
+        /// If `None`, this actually represents a normal branch mapping inserted
+        /// for code that was too complex for MC/DC.
+        condition_info: Option<ConditionInfo>,
+        decision_depth: u16,
+    },
+    /// Associates a mcdc decision with its join BCB.
+    MCDCDecision {
+        end_bcbs: BTreeSet<BasicCoverageBlock>,
+        bitmap_idx: u32,
+        conditions_num: u16,
+        decision_depth: u16,
+    },
+}
+
+#[derive(Debug)]
+pub(super) struct BcbMapping {
+    pub(super) kind: BcbMappingKind,
+    pub(super) span: Span,
+}
+
+/// This is separate from [`BcbMappingKind`] to help prepare for larger changes
+/// that will be needed for improved branch coverage in the future.
+/// (See <https://github.com/rust-lang/rust/pull/124217>.)
+#[derive(Debug)]
+pub(super) struct BcbBranchPair {
+    pub(super) span: Span,
+    pub(super) true_bcb: BasicCoverageBlock,
+    pub(super) false_bcb: BasicCoverageBlock,
+}
+
+pub(super) struct CoverageSpans {
+    bcb_has_mappings: BitSet<BasicCoverageBlock>,
+    pub(super) mappings: Vec<BcbMapping>,
+    pub(super) branch_pairs: Vec<BcbBranchPair>,
+    test_vector_bitmap_bytes: u32,
+}
+
+impl CoverageSpans {
+    pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {
+        self.bcb_has_mappings.contains(bcb)
+    }
+
+    pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
+        self.test_vector_bitmap_bytes
+    }
+}
+
+/// Extracts coverage-relevant spans from MIR, and associates them with
+/// their corresponding BCBs.
+///
+/// Returns `None` if no coverage-relevant spans could be extracted.
+pub(super) fn generate_coverage_spans(
+    mir_body: &mir::Body<'_>,
+    hir_info: &ExtractedHirInfo,
+    basic_coverage_blocks: &CoverageGraph,
+) -> Option<CoverageSpans> {
+    let mut mappings = vec![];
+    let mut branch_pairs = vec![];
+
+    if hir_info.is_async_fn {
+        // An async function desugars into a function that returns a future,
+        // with the user code wrapped in a closure. Any spans in the desugared
+        // outer function will be unhelpful, so just keep the signature span
+        // and ignore all of the spans in the MIR body.
+        if let Some(span) = hir_info.fn_sig_span_extended {
+            mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span });
+        }
+    } else {
+        extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut mappings);
+
+        branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
+
+        mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks));
+    }
+
+    if mappings.is_empty() && branch_pairs.is_empty() {
+        return None;
+    }
+
+    // Identify which BCBs have one or more mappings.
+    let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
+    let mut insert = |bcb| {
+        bcb_has_mappings.insert(bcb);
+    };
+    let mut test_vector_bitmap_bytes = 0;
+    for BcbMapping { kind, span: _ } in &mappings {
+        match *kind {
+            BcbMappingKind::Code(bcb) => insert(bcb),
+            BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
+                insert(true_bcb);
+                insert(false_bcb);
+            }
+            BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
+                // `bcb_has_mappings` is used for inject coverage counters
+                // but they are not needed for decision BCBs.
+                // While the length of test vector bitmap should be calculated here.
+                test_vector_bitmap_bytes = test_vector_bitmap_bytes
+                    .max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
+            }
+        }
+    }
+    for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
+        insert(true_bcb);
+        insert(false_bcb);
+    }
+
+    Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
+}
+
+fn resolve_block_markers(
+    branch_info: &mir::coverage::BranchInfo,
+    mir_body: &mir::Body<'_>,
+) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
+    let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
+        None,
+        branch_info.num_block_markers,
+    );
+
+    // Fill out the mapping from block marker IDs to their enclosing blocks.
+    for (bb, data) in mir_body.basic_blocks.iter_enumerated() {
+        for statement in &data.statements {
+            if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind {
+                block_markers[id] = Some(bb);
+            }
+        }
+    }
+
+    block_markers
+}
+
+// FIXME: There is currently a lot of redundancy between
+// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so
+// that they can each be modified without interfering with the other, but in
+// the long term we should try to bring them together again when branch coverage
+// and MC/DC coverage support are more mature.
+
+pub(super) fn extract_branch_pairs(
+    mir_body: &mir::Body<'_>,
+    hir_info: &ExtractedHirInfo,
+    basic_coverage_blocks: &CoverageGraph,
+) -> Vec<BcbBranchPair> {
+    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] };
+
+    let block_markers = resolve_block_markers(branch_info, mir_body);
+
+    branch_info
+        .branch_spans
+        .iter()
+        .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
+            // For now, ignore any branch span that was introduced by
+            // expansion. This makes things like assert macros less noisy.
+            if !raw_span.ctxt().outer_expn_data().is_root() {
+                return None;
+            }
+            let (span, _) =
+                unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?;
+
+            let bcb_from_marker =
+                |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
+
+            let true_bcb = bcb_from_marker(true_marker)?;
+            let false_bcb = bcb_from_marker(false_marker)?;
+
+            Some(BcbBranchPair { span, true_bcb, false_bcb })
+        })
+        .collect::<Vec<_>>()
+}
+
+pub(super) fn extract_mcdc_mappings(
+    mir_body: &mir::Body<'_>,
+    body_span: Span,
+    basic_coverage_blocks: &CoverageGraph,
+) -> Vec<BcbMapping> {
+    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
+        return vec![];
+    };
+
+    let block_markers = resolve_block_markers(branch_info, mir_body);
+
+    let bcb_from_marker =
+        |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
+
+    let check_branch_bcb =
+        |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| {
+            // For now, ignore any branch span that was introduced by
+            // expansion. This makes things like assert macros less noisy.
+            if !raw_span.ctxt().outer_expn_data().is_root() {
+                return None;
+            }
+            let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?;
+
+            let true_bcb = bcb_from_marker(true_marker)?;
+            let false_bcb = bcb_from_marker(false_marker)?;
+            Some((span, true_bcb, false_bcb))
+        };
+
+    let mcdc_branch_filter_map = |&MCDCBranchSpan {
+                                      span: raw_span,
+                                      true_marker,
+                                      false_marker,
+                                      condition_info,
+                                      decision_depth,
+                                  }| {
+        check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| {
+            BcbMapping {
+                kind: BcbMappingKind::MCDCBranch {
+                    true_bcb,
+                    false_bcb,
+                    condition_info,
+                    decision_depth,
+                },
+                span,
+            }
+        })
+    };
+
+    let mut next_bitmap_idx = 0;
+
+    let decision_filter_map = |decision: &MCDCDecisionSpan| {
+        let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
+
+        let end_bcbs = decision
+            .end_markers
+            .iter()
+            .map(|&marker| bcb_from_marker(marker))
+            .collect::<Option<_>>()?;
+
+        let bitmap_idx = next_bitmap_idx;
+        next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
+
+        Some(BcbMapping {
+            kind: BcbMappingKind::MCDCDecision {
+                end_bcbs,
+                bitmap_idx,
+                conditions_num: decision.conditions_num as u16,
+                decision_depth: decision.decision_depth,
+            },
+            span,
+        })
+    };
+
+    std::iter::empty()
+        .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
+        .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
+        .collect::<Vec<_>>()
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 0b15c52c281..9edde666246 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -2,14 +2,14 @@ pub mod query;
 
 mod counters;
 mod graph;
+mod mappings;
 mod spans;
-
 #[cfg(test)]
 mod tests;
 
 use self::counters::{CounterIncrementSite, CoverageCounters};
 use self::graph::{BasicCoverageBlock, CoverageGraph};
-use self::spans::{BcbBranchPair, BcbMapping, BcbMappingKind, CoverageSpans};
+use self::mappings::{BcbBranchPair, BcbMapping, BcbMappingKind, CoverageSpans};
 
 use crate::MirPass;
 
@@ -71,7 +71,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     ////////////////////////////////////////////////////
     // Compute coverage spans from the `CoverageGraph`.
     let Some(coverage_spans) =
-        spans::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks)
+        mappings::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks)
     else {
         // No relevant spans were found in MIR, so skip instrumenting this function.
         return;
@@ -102,12 +102,23 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
 
     inject_mcdc_statements(mir_body, &basic_coverage_blocks, &coverage_spans);
 
+    let mcdc_max_decision_depth = coverage_spans
+        .mappings
+        .iter()
+        .filter_map(|bcb_mapping| match bcb_mapping.kind {
+            BcbMappingKind::MCDCDecision { decision_depth, .. } => Some(decision_depth),
+            _ => None,
+        })
+        .max()
+        .unwrap_or(0);
+
     mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo {
         function_source_hash: hir_info.function_source_hash,
         num_counters: coverage_counters.num_counters(),
         mcdc_bitmap_bytes: coverage_spans.test_vector_bitmap_bytes(),
         expressions: coverage_counters.into_expressions(),
         mappings,
+        mcdc_max_decision_depth,
     }));
 }
 
@@ -145,16 +156,17 @@ fn create_mappings<'tcx>(
         |BcbMapping { kind: bcb_mapping_kind, span }| {
             let kind = match *bcb_mapping_kind {
                 BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)),
-                BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: None } => {
-                    MappingKind::Branch {
-                        true_term: term_for_bcb(true_bcb),
-                        false_term: term_for_bcb(false_bcb),
-                    }
-                }
+                BcbMappingKind::MCDCBranch {
+                    true_bcb, false_bcb, condition_info: None, ..
+                } => MappingKind::Branch {
+                    true_term: term_for_bcb(true_bcb),
+                    false_term: term_for_bcb(false_bcb),
+                },
                 BcbMappingKind::MCDCBranch {
                     true_bcb,
                     false_bcb,
                     condition_info: Some(mcdc_params),
+                    ..
                 } => MappingKind::MCDCBranch {
                     true_term: term_for_bcb(true_bcb),
                     false_term: term_for_bcb(false_bcb),
@@ -246,24 +258,28 @@ fn inject_mcdc_statements<'tcx>(
     }
 
     // Inject test vector update first because `inject_statement` always insert new statement at head.
-    for (end_bcbs, bitmap_idx) in
+    for (end_bcbs, bitmap_idx, decision_depth) in
         coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind {
-            BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, .. } => {
-                Some((end_bcbs, *bitmap_idx))
+            BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => {
+                Some((end_bcbs, *bitmap_idx, *decision_depth))
             }
             _ => None,
         })
     {
         for end in end_bcbs {
             let end_bb = basic_coverage_blocks[*end].leader_bb();
-            inject_statement(mir_body, CoverageKind::TestVectorBitmapUpdate { bitmap_idx }, end_bb);
+            inject_statement(
+                mir_body,
+                CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth },
+                end_bb,
+            );
         }
     }
 
-    for (true_bcb, false_bcb, condition_id) in
+    for (true_bcb, false_bcb, condition_id, decision_depth) in
         coverage_spans.mappings.iter().filter_map(|mapping| match mapping.kind {
-            BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info } => {
-                Some((true_bcb, false_bcb, condition_info?.condition_id))
+            BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info, decision_depth } => {
+                Some((true_bcb, false_bcb, condition_info?.condition_id, decision_depth))
             }
             _ => None,
         })
@@ -271,13 +287,13 @@ fn inject_mcdc_statements<'tcx>(
         let true_bb = basic_coverage_blocks[true_bcb].leader_bb();
         inject_statement(
             mir_body,
-            CoverageKind::CondBitmapUpdate { id: condition_id, value: true },
+            CoverageKind::CondBitmapUpdate { id: condition_id, value: true, decision_depth },
             true_bb,
         );
         let false_bb = basic_coverage_blocks[false_bcb].leader_bb();
         inject_statement(
             mir_body,
-            CoverageKind::CondBitmapUpdate { id: condition_id, value: false },
+            CoverageKind::CondBitmapUpdate { id: condition_id, value: false, decision_depth },
             false_bb,
         );
     }
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 88f18b72085..d6432e2e9d4 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,146 +1,31 @@
-use rustc_data_structures::graph::DirectedGraph;
-use rustc_index::bit_set::BitSet;
 use rustc_middle::mir;
-use rustc_middle::mir::coverage::ConditionInfo;
 use rustc_span::{BytePos, Span};
-use std::collections::BTreeSet;
 
-use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
+use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
+use crate::coverage::mappings::{BcbMapping, BcbMappingKind};
 use crate::coverage::spans::from_mir::SpanFromMir;
 use crate::coverage::ExtractedHirInfo;
 
 mod from_mir;
 
-#[derive(Clone, Debug)]
-pub(super) enum BcbMappingKind {
-    /// Associates an ordinary executable code span with its corresponding BCB.
-    Code(BasicCoverageBlock),
-
-    // Ordinary branch mappings are stored separately, so they don't have a
-    // variant in this enum.
-    //
-    /// Associates a mcdc branch span with condition info besides fields for normal branch.
-    MCDCBranch {
-        true_bcb: BasicCoverageBlock,
-        false_bcb: BasicCoverageBlock,
-        /// If `None`, this actually represents a normal branch mapping inserted
-        /// for code that was too complex for MC/DC.
-        condition_info: Option<ConditionInfo>,
-    },
-    /// Associates a mcdc decision with its join BCB.
-    MCDCDecision { end_bcbs: BTreeSet<BasicCoverageBlock>, bitmap_idx: u32, conditions_num: u16 },
-}
-
-#[derive(Debug)]
-pub(super) struct BcbMapping {
-    pub(super) kind: BcbMappingKind,
-    pub(super) span: Span,
-}
-
-/// This is separate from [`BcbMappingKind`] to help prepare for larger changes
-/// that will be needed for improved branch coverage in the future.
-/// (See <https://github.com/rust-lang/rust/pull/124217>.)
-#[derive(Debug)]
-pub(super) struct BcbBranchPair {
-    pub(super) span: Span,
-    pub(super) true_bcb: BasicCoverageBlock,
-    pub(super) false_bcb: BasicCoverageBlock,
-}
-
-pub(super) struct CoverageSpans {
-    bcb_has_mappings: BitSet<BasicCoverageBlock>,
-    pub(super) mappings: Vec<BcbMapping>,
-    pub(super) branch_pairs: Vec<BcbBranchPair>,
-    test_vector_bitmap_bytes: u32,
-}
-
-impl CoverageSpans {
-    pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {
-        self.bcb_has_mappings.contains(bcb)
-    }
-
-    pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
-        self.test_vector_bitmap_bytes
-    }
-}
+// FIXME(#124545) It's awkward that we have to re-export this, because it's an
+// internal detail of `from_mir` that is also needed when handling branch and
+// MC/DC spans. Ideally we would find a more natural home for it.
+pub(super) use from_mir::unexpand_into_body_span_with_visible_macro;
 
-/// Extracts coverage-relevant spans from MIR, and associates them with
-/// their corresponding BCBs.
-///
-/// Returns `None` if no coverage-relevant spans could be extracted.
-pub(super) fn generate_coverage_spans(
+pub(super) fn extract_refined_covspans(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
     basic_coverage_blocks: &CoverageGraph,
-) -> Option<CoverageSpans> {
-    let mut mappings = vec![];
-    let mut branch_pairs = vec![];
-
-    if hir_info.is_async_fn {
-        // An async function desugars into a function that returns a future,
-        // with the user code wrapped in a closure. Any spans in the desugared
-        // outer function will be unhelpful, so just keep the signature span
-        // and ignore all of the spans in the MIR body.
-        if let Some(span) = hir_info.fn_sig_span_extended {
-            mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span });
-        }
-    } else {
-        let sorted_spans = from_mir::mir_to_initial_sorted_coverage_spans(
-            mir_body,
-            hir_info,
-            basic_coverage_blocks,
-        );
-        let coverage_spans = SpansRefiner::refine_sorted_spans(sorted_spans);
-        mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| {
-            // Each span produced by the generator represents an ordinary code region.
-            BcbMapping { kind: BcbMappingKind::Code(bcb), span }
-        }));
-
-        branch_pairs.extend(from_mir::extract_branch_pairs(
-            mir_body,
-            hir_info,
-            basic_coverage_blocks,
-        ));
-
-        mappings.extend(from_mir::extract_mcdc_mappings(
-            mir_body,
-            hir_info.body_span,
-            basic_coverage_blocks,
-        ));
-    }
-
-    if mappings.is_empty() && branch_pairs.is_empty() {
-        return None;
-    }
-
-    // Identify which BCBs have one or more mappings.
-    let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
-    let mut insert = |bcb| {
-        bcb_has_mappings.insert(bcb);
-    };
-    let mut test_vector_bitmap_bytes = 0;
-    for BcbMapping { kind, span: _ } in &mappings {
-        match *kind {
-            BcbMappingKind::Code(bcb) => insert(bcb),
-            BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
-                insert(true_bcb);
-                insert(false_bcb);
-            }
-            BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
-                // `bcb_has_mappings` is used for inject coverage counters
-                // but they are not needed for decision BCBs.
-                // While the length of test vector bitmap should be calculated here.
-                test_vector_bitmap_bytes = test_vector_bitmap_bytes
-                    .max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8));
-            }
-        }
-    }
-    for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
-        insert(true_bcb);
-        insert(false_bcb);
-    }
-
-    Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
+    mappings: &mut impl Extend<BcbMapping>,
+) {
+    let sorted_spans =
+        from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks);
+    let coverage_spans = SpansRefiner::refine_sorted_spans(sorted_spans);
+    mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| {
+        // Each span produced by the generator represents an ordinary code region.
+        BcbMapping { kind: BcbMappingKind::Code(bcb), span }
+    }));
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 64f21d74b1c..4ce37b5defc 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -1,11 +1,8 @@
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_index::IndexVec;
-use rustc_middle::mir::coverage::{
-    BlockMarkerId, BranchSpan, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan,
-};
+use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::{
-    self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
+    self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
     TerminatorKind,
 };
 use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
@@ -13,7 +10,6 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
 use crate::coverage::graph::{
     BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
 };
-use crate::coverage::spans::{BcbBranchPair, BcbMapping, BcbMappingKind};
 use crate::coverage::ExtractedHirInfo;
 
 /// Traverses the MIR body to produce an initial collection of coverage-relevant
@@ -287,7 +283,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
 ///
 /// [^1]Expansions result from Rust syntax including macros, syntactic sugar,
 /// etc.).
-fn unexpand_into_body_span_with_visible_macro(
+pub(crate) fn unexpand_into_body_span_with_visible_macro(
     original_span: Span,
     body_span: Span,
 ) -> Option<(Span, Option<Symbol>)> {
@@ -365,130 +361,3 @@ impl SpanFromMir {
         Self { span, visible_macro, bcb, is_hole }
     }
 }
-
-fn resolve_block_markers(
-    branch_info: &mir::coverage::BranchInfo,
-    mir_body: &mir::Body<'_>,
-) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
-    let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
-        None,
-        branch_info.num_block_markers,
-    );
-
-    // Fill out the mapping from block marker IDs to their enclosing blocks.
-    for (bb, data) in mir_body.basic_blocks.iter_enumerated() {
-        for statement in &data.statements {
-            if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind {
-                block_markers[id] = Some(bb);
-            }
-        }
-    }
-
-    block_markers
-}
-
-// FIXME: There is currently a lot of redundancy between
-// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so
-// that they can each be modified without interfering with the other, but in
-// the long term we should try to bring them together again when branch coverage
-// and MC/DC coverage support are more mature.
-
-pub(super) fn extract_branch_pairs(
-    mir_body: &mir::Body<'_>,
-    hir_info: &ExtractedHirInfo,
-    basic_coverage_blocks: &CoverageGraph,
-) -> Vec<BcbBranchPair> {
-    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] };
-
-    let block_markers = resolve_block_markers(branch_info, mir_body);
-
-    branch_info
-        .branch_spans
-        .iter()
-        .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
-            // For now, ignore any branch span that was introduced by
-            // expansion. This makes things like assert macros less noisy.
-            if !raw_span.ctxt().outer_expn_data().is_root() {
-                return None;
-            }
-            let (span, _) =
-                unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?;
-
-            let bcb_from_marker =
-                |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
-
-            let true_bcb = bcb_from_marker(true_marker)?;
-            let false_bcb = bcb_from_marker(false_marker)?;
-
-            Some(BcbBranchPair { span, true_bcb, false_bcb })
-        })
-        .collect::<Vec<_>>()
-}
-
-pub(super) fn extract_mcdc_mappings(
-    mir_body: &mir::Body<'_>,
-    body_span: Span,
-    basic_coverage_blocks: &CoverageGraph,
-) -> Vec<BcbMapping> {
-    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
-        return vec![];
-    };
-
-    let block_markers = resolve_block_markers(branch_info, mir_body);
-
-    let bcb_from_marker =
-        |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
-
-    let check_branch_bcb =
-        |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| {
-            // For now, ignore any branch span that was introduced by
-            // expansion. This makes things like assert macros less noisy.
-            if !raw_span.ctxt().outer_expn_data().is_root() {
-                return None;
-            }
-            let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?;
-
-            let true_bcb = bcb_from_marker(true_marker)?;
-            let false_bcb = bcb_from_marker(false_marker)?;
-            Some((span, true_bcb, false_bcb))
-        };
-
-    let mcdc_branch_filter_map =
-        |&MCDCBranchSpan { span: raw_span, true_marker, false_marker, condition_info }| {
-            check_branch_bcb(raw_span, true_marker, false_marker).map(
-                |(span, true_bcb, false_bcb)| BcbMapping {
-                    kind: BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info },
-                    span,
-                },
-            )
-        };
-
-    let mut next_bitmap_idx = 0;
-
-    let decision_filter_map = |decision: &MCDCDecisionSpan| {
-        let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?;
-
-        let end_bcbs = decision
-            .end_markers
-            .iter()
-            .map(|&marker| bcb_from_marker(marker))
-            .collect::<Option<_>>()?;
-
-        let bitmap_idx = next_bitmap_idx;
-        next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8);
-
-        Some(BcbMapping {
-            kind: BcbMappingKind::MCDCDecision {
-                end_bcbs,
-                bitmap_idx,
-                conditions_num: decision.conditions_num as u16,
-            },
-            span,
-        })
-    };
-
-    std::iter::empty()
-        .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
-        .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
-        .collect::<Vec<_>>()
-}
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index b8dbf8a759f..90c1c7ba63b 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -583,33 +583,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 val.into()
             }
 
-            Aggregate(ref kind, ref fields) => {
-                // Do not const prop union fields as they can be
-                // made to produce values that don't match their
-                // underlying layout's type (see ICE #121534).
-                // If the last element of the `Adt` tuple
-                // is `Some` it indicates the ADT is a union
-                if let AggregateKind::Adt(_, _, _, _, Some(_)) = **kind {
-                    return None;
-                };
-                Value::Aggregate {
-                    fields: fields
-                        .iter()
-                        .map(|field| {
-                            self.eval_operand(field).map_or(Value::Uninit, Value::Immediate)
-                        })
-                        .collect(),
-                    variant: match **kind {
-                        AggregateKind::Adt(_, variant, _, _, _) => variant,
-                        AggregateKind::Array(_)
-                        | AggregateKind::Tuple
-                        | AggregateKind::RawPtr(_, _)
-                        | AggregateKind::Closure(_, _)
-                        | AggregateKind::Coroutine(_, _)
-                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
-                    },
-                }
-            }
+            Aggregate(ref kind, ref fields) => Value::Aggregate {
+                fields: fields
+                    .iter()
+                    .map(|field| self.eval_operand(field).map_or(Value::Uninit, Value::Immediate))
+                    .collect(),
+                variant: match **kind {
+                    AggregateKind::Adt(_, variant, _, _, _) => variant,
+                    AggregateKind::Array(_)
+                    | AggregateKind::Tuple
+                    | AggregateKind::RawPtr(_, _)
+                    | AggregateKind::Closure(_, _)
+                    | AggregateKind::Coroutine(_, _)
+                    | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
+                },
+            },
 
             Repeat(ref op, n) => {
                 trace!(?op, ?n);
@@ -896,13 +884,20 @@ impl CanConstProp {
         };
         for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
             let ty = body.local_decls[local].ty;
-            match tcx.layout_of(param_env.and(ty)) {
-                Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
-                // Either the layout fails to compute, then we can't use this local anyway
-                // or the local is too large, then we don't want to.
-                _ => {
-                    *val = ConstPropMode::NoPropagation;
-                    continue;
+            if ty.is_union() {
+                // Unions are incompatible with the current implementation of
+                // const prop because Rust has no concept of an active
+                // variant of a union
+                *val = ConstPropMode::NoPropagation;
+            } else {
+                match tcx.layout_of(param_env.and(ty)) {
+                    Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
+                    // Either the layout fails to compute, then we can't use this local anyway
+                    // or the local is too large, then we don't want to.
+                    _ => {
+                        *val = ConstPropMode::NoPropagation;
+                        continue;
+                    }
                 }
             }
         }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index e42755ca7bf..e69c5da757e 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -4,7 +4,6 @@
 #![feature(cow_is_borrowed)]
 #![feature(decl_macro)]
 #![feature(impl_trait_in_assoc_type)]
-#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(is_sorted)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index a8fa6fe002d..dd1065590b3 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -228,6 +228,7 @@ use rustc_middle::ty::{
     TypeVisitableExt, VtblEntry,
 };
 use rustc_middle::ty::{GenericArgKind, GenericArgs};
+use rustc_middle::{bug, span_bug};
 use rustc_session::config::EntryFnType;
 use rustc_session::Limit;
 use rustc_span::source_map::{dummy_spanned, respan, Spanned};
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 2a91d69529a..cbab2006186 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -4,10 +4,9 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 use rustc_hir::lang_items::LangItem;
+use rustc_middle::bug;
 use rustc_middle::query::{Providers, TyCtxtAt};
 use rustc_middle::traits;
 use rustc_middle::ty::adjustment::CustomCoerceUnsized;
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 23e07890bb6..8f7b4c6472c 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -103,6 +103,7 @@ use rustc_data_structures::sync;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathDataName;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
 use rustc_middle::mir::mono::{
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index ed51710564a..848277c4611 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1191,7 +1191,11 @@ impl<'a> Parser<'a> {
                                 ident_span: ident.span,
                                 const_span,
                             });
-                            ForeignItemKind::Static(ty, Mutability::Not, expr)
+                            ForeignItemKind::Static(Box::new(StaticForeignItem {
+                                ty,
+                                mutability: Mutability::Not,
+                                expr,
+                            }))
                         }
                         _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
                     },
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 986ef69ad88..0c3dd649997 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -1,6 +1,7 @@
 use rustc_ast::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::span_bug;
 use rustc_middle::ty::layout::{FnAbiError, LayoutError};
 use rustc_middle::ty::{self, GenericArgs, Instance, Ty, TyCtxt};
 use rustc_span::source_map::Spanned;
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a2388b3bd52..c403e9196fa 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -19,6 +19,7 @@ use rustc_hir::{
 };
 use rustc_hir::{MethodKind, Target, Unsafety};
 use rustc_macros::LintDiagnostic;
+use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 4a1a2049083..eb29a65cb29 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -13,6 +13,7 @@ use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_span::{sym, Span, Symbol};
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 51f288b3c95..933412f677c 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -16,6 +16,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::privacy::Level;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_session::lint::builtin::DEAD_CODE;
 use rustc_span::symbol::{sym, Symbol};
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 49408c5618b..d7664d1c1ff 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -498,7 +498,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
             (self, i, i.kind, Id::None, ast, ForeignItem, ForeignItemKind),
             [Static, Fn, TyAlias, MacCall]
         );
-        ast_visit::walk_foreign_item(self, i)
+        ast_visit::walk_item(self, i)
     }
 
     fn visit_item(&mut self, i: &'v ast::Item) {
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index 8d223c23363..82d43f078ee 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -1,6 +1,7 @@
 use rustc_ast::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::span_bug;
 use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
 use rustc_span::source_map::Spanned;
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index bce29e2af09..d3608759eec 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -13,8 +13,6 @@
 #![feature(try_blocks)]
 
 #[macro_use]
-extern crate rustc_middle;
-#[macro_use]
 extern crate tracing;
 
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index c7729302783..b50cb158b1f 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -94,6 +94,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet};
 use rustc_index::IndexVec;
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
 use rustc_session::lint;
 use rustc_span::symbol::{kw, sym, Symbol};
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index e10a22cdf31..4b5c4dfe991 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -6,6 +6,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Destination, Node};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_span::hygiene::DesugaringKind;
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 869cbebbc0d..d5e1a70fd45 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -17,6 +17,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::Node;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::middle::privacy::{self, Level};
 use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc};
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index 6e8843d9049..4155540886a 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -14,12 +14,6 @@ pub mod pat_column;
 pub mod rustc;
 pub mod usefulness;
 
-#[macro_use]
-extern crate tracing;
-#[cfg(feature = "rustc")]
-#[macro_use]
-extern crate rustc_middle;
-
 #[cfg(feature = "rustc")]
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs
index 3ca5ebdb0dd..1d10c9df4ab 100644
--- a/compiler/rustc_pattern_analysis/src/lints.rs
+++ b/compiler/rustc_pattern_analysis/src/lints.rs
@@ -1,11 +1,11 @@
-use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
-use rustc_span::ErrorGuaranteed;
-
 use crate::constructor::Constructor;
 use crate::errors::{NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered};
 use crate::pat_column::PatternColumn;
 use crate::rustc::{RevealedTy, RustcPatCtxt, WitnessPat};
 use crate::MatchArm;
+use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
+use rustc_span::ErrorGuaranteed;
+use tracing::instrument;
 
 /// Traverse the patterns to collect any variants of a non_exhaustive enum that fail to be mentioned
 /// in a given column.
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 548a7b43005..ff68dd81bea 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -11,6 +11,7 @@ use rustc_middle::mir::{self, Const};
 use rustc_middle::thir::{self, FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, FieldDef, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT};
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 7246039174a..74af9154f85 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -709,16 +709,15 @@
 //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific
 //! reason not to, for example if they crucially depend on a particular feature like `or_patterns`.
 
+use self::PlaceValidity::*;
+use crate::constructor::{Constructor, ConstructorSet, IntRange};
+use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat};
+use crate::{Captures, MatchArm, PatCx, PrivateUninhabitedField};
 use rustc_hash::FxHashSet;
 use rustc_index::bit_set::BitSet;
 use smallvec::{smallvec, SmallVec};
 use std::fmt;
-
-use crate::constructor::{Constructor, ConstructorSet, IntRange};
-use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat};
-use crate::{Captures, MatchArm, PatCx, PrivateUninhabitedField};
-
-use self::PlaceValidity::*;
+use tracing::{debug, instrument};
 
 #[cfg(feature = "rustc")]
 use rustc_data_structures::stack::ensure_sufficient_stack;
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 2039e994aaa..a78f7e65981 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -6,9 +6,6 @@
 #![feature(try_blocks)]
 #![feature(let_chains)]
 
-#[macro_use]
-extern crate tracing;
-
 mod errors;
 
 use rustc_ast::visit::{try_visit, VisitorResult};
@@ -31,6 +28,7 @@ use rustc_session::lint;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
+use tracing::debug;
 
 use std::fmt;
 use std::marker::PhantomData;
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 17f96896a50..5f1a03502a7 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -49,6 +49,7 @@ use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey};
 use rustc_data_structures::AtomicRef;
 use rustc_hir::definitions::DefPathHash;
+use rustc_macros::{Decodable, Encodable};
 use std::fmt;
 use std::hash::Hash;
 
@@ -75,8 +76,6 @@ impl DepKind {
     }
 }
 
-static_assert_size!(DepKind, 2);
-
 pub fn default_dep_kind_debug(kind: DepKind, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     f.debug_struct("DepKind").field("variant", &kind.variant).finish()
 }
@@ -96,15 +95,6 @@ pub struct DepNode {
     pub hash: PackedFingerprint,
 }
 
-// We keep a lot of `DepNode`s in memory during compilation. It's not
-// required that their size stay the same, but we don't want to change
-// it inadvertently. This assert just ensures we're aware of any change.
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-static_assert_size!(DepNode, 18);
-
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-static_assert_size!(DepNode, 24);
-
 impl DepNode {
     /// Creates a new, parameterless DepNode. This method will assert
     /// that the DepNode corresponding to the given DepKind actually
@@ -285,8 +275,7 @@ pub struct DepKindStruct<Tcx: DepContext> {
 /// some independent path or string that persists between runs without
 /// the need to be mapped or unmapped. (This ensures we can serialize
 /// them even in the absence of a tcx.)
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(Encodable, Decodable)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
 pub struct WorkProductId {
     hash: Fingerprint,
 }
@@ -316,3 +305,17 @@ unsafe impl StableOrd for WorkProductId {
     // Fingerprint can use unstable (just a tuple of `u64`s), so WorkProductId can as well
     const CAN_USE_UNSTABLE_SORT: bool = true;
 }
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(target_pointer_width = "64")]
+mod size_asserts {
+    use super::*;
+    use rustc_data_structures::static_assert_size;
+    // tidy-alphabetical-start
+    static_assert_size!(DepKind, 2);
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    static_assert_size!(DepNode, 18);
+    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+    static_assert_size!(DepNode, 24);
+    // tidy-alphabetical-end
+}
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 2b3fa7f6cfa..76227a78c3d 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -6,6 +6,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc};
 use rustc_data_structures::unord::UnordMap;
 use rustc_index::IndexVec;
+use rustc_macros::{Decodable, Encodable};
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use std::assert_matches::assert_matches;
 use std::collections::hash_map::Entry;
@@ -14,6 +15,7 @@ use std::hash::Hash;
 use std::marker::PhantomData;
 use std::sync::atomic::Ordering;
 use std::sync::Arc;
+use tracing::{debug, instrument};
 
 use super::query::DepGraphQuery;
 use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
@@ -40,6 +42,11 @@ rustc_index::newtype_index! {
     pub struct DepNodeIndex {}
 }
 
+// We store a large collection of these in `prev_index_to_index` during
+// non-full incremental builds, and want to ensure that the element size
+// doesn't inadvertently increase.
+rustc_data_structures::static_assert_size!(Option<DepNodeIndex>, 4);
+
 impl DepNodeIndex {
     const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO;
     pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
@@ -1106,11 +1113,6 @@ impl<D: Deps> CurrentDepGraph<D> {
             Err(_) => None,
         };
 
-        // We store a large collection of these in `prev_index_to_index` during
-        // non-full incremental builds, and want to ensure that the element size
-        // doesn't inadvertently increase.
-        static_assert_size!(Option<DepNodeIndex>, 4);
-
         let new_node_count_estimate = 102 * prev_graph_node_count / 100 + 200;
 
         CurrentDepGraph {
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index feb69ecd078..cbd80295887 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -11,13 +11,12 @@ pub use graph::{hash_result, DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, W
 pub use query::DepGraphQuery;
 pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
 
+use self::graph::{print_markframe_trace, MarkFrame};
 use crate::ich::StableHashingContext;
 use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_session::Session;
-
 use std::panic;
-
-use self::graph::{print_markframe_trace, MarkFrame};
+use tracing::instrument;
 
 pub trait DepContext: Copy {
     type Deps: Deps;
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 6042aa6a2d2..b426bb888f4 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -51,6 +51,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::iter;
 use std::marker::PhantomData;
 use std::sync::Arc;
+use tracing::{debug, instrument};
 
 // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
 // unused so that we can store multiple index types in `CompressedHybridIndex`,
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 416f556f57d..fa07877ab9f 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -5,13 +5,6 @@
 #![feature(let_chains)]
 #![allow(rustc::potential_query_instability, internal_features)]
 
-#[macro_use]
-extern crate tracing;
-#[macro_use]
-extern crate rustc_data_structures;
-#[macro_use]
-extern crate rustc_macros;
-
 pub mod cache;
 pub mod dep_graph;
 mod error;
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 91a0026f281..ab4f48fcd32 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -20,6 +20,7 @@ use rustc_data_structures::stable_hasher::Hash64;
 use rustc_data_structures::sync::Lock;
 use rustc_errors::DiagInner;
 use rustc_hir::def::DefKind;
+use rustc_macros::{Decodable, Encodable};
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
 use thin_vec::ThinVec;
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 3d9848395a2..d37d5bce9cc 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -27,6 +27,7 @@ use std::fmt::Debug;
 use std::hash::Hash;
 use std::mem;
 use thin_vec::ThinVec;
+use tracing::instrument;
 
 use super::QueryConfig;
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 1b6387acf71..8068ea1a407 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1304,11 +1304,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 visit::walk_item(self, item);
                 macro_rules_scope
             }
-            ItemKind::MacCall(..) => {
-                let macro_rules_scope = self.visit_invoc_in_module(item.id);
-                visit::walk_item(self, item);
-                macro_rules_scope
-            }
+            ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id),
             _ => {
                 let orig_macro_rules_scope = self.parent_scope.macro_rules;
                 self.build_reduced_graph_for_item(item);
@@ -1339,7 +1335,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
 
         self.build_reduced_graph_for_foreign_item(foreign_item);
-        visit::walk_foreign_item(self, foreign_item);
+        visit::walk_item(self, foreign_item);
     }
 
     fn visit_block(&mut self, block: &'b Block) {
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index bef95aca0d1..a27a6bceda3 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -136,14 +136,9 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                 opt_macro_data = Some(macro_data);
                 DefKind::Macro(macro_kind)
             }
-            ItemKind::MacCall(..) => {
-                visit::walk_item(self, i);
-                return self.visit_macro_invoc(i.id);
-            }
             ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
-            ItemKind::Use(..) => {
-                return visit::walk_item(self, i);
-            }
+            ItemKind::Use(..) => return visit::walk_item(self, i),
+            ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
         };
         let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span);
 
@@ -214,7 +209,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         let def_kind = match fi.kind {
-            ForeignItemKind::Static(_, mutability, _) => {
+            ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability, expr: _ }) => {
                 DefKind::Static { mutability, nested: false }
             }
             ForeignItemKind::Fn(_) => DefKind::Fn,
@@ -224,7 +219,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
 
         let def = self.create_def(fi.id, fi.ident.name, def_kind, fi.span);
 
-        self.with_parent(def, |this| visit::walk_foreign_item(this, fi));
+        self.with_parent(def, |this| visit::walk_item(this, fi));
     }
 
     fn visit_variant(&mut self, v: &'a Variant) {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 292af43b602..6c870ddfd22 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -886,7 +886,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                         kind: LifetimeBinderKind::Item,
                         span: generics.span,
                     },
-                    |this| visit::walk_foreign_item(this, foreign_item),
+                    |this| visit::walk_item(this, foreign_item),
                 );
             }
             ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
@@ -898,13 +898,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                         kind: LifetimeBinderKind::Function,
                         span: generics.span,
                     },
-                    |this| visit::walk_foreign_item(this, foreign_item),
+                    |this| visit::walk_item(this, foreign_item),
                 );
             }
             ForeignItemKind::Static(..) => {
-                self.with_static_rib(def_kind, |this| {
-                    visit::walk_foreign_item(this, foreign_item);
-                });
+                self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item))
             }
             ForeignItemKind::MacCall(..) => {
                 panic!("unexpanded macro in resolve!")
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index e07c3247d07..af0b4792136 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -38,7 +38,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
 use rustc_errors::{Applicability, Diag, ErrCode};
-use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
+use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::NonMacroAttrKind;
@@ -959,7 +959,7 @@ enum BuiltinMacroState {
 }
 
 struct DeriveData {
-    resolutions: DeriveResolutions,
+    resolutions: Vec<DeriveResolution>,
     helper_attrs: Vec<(usize, Ident)>,
     has_derive_copy: bool,
 }
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 2a23ed71753..82e41b6c314 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -15,7 +15,7 @@ use rustc_attr::StabilityLevel;
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, StashKey};
-use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand};
+use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::compile_declarative_macro;
 use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
@@ -344,7 +344,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
         &mut self,
         expn_id: LocalExpnId,
         force: bool,
-        derive_paths: &dyn Fn() -> DeriveResolutions,
+        derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
     ) -> Result<(), Indeterminate> {
         // Block expansion of the container until we resolve all derives in it.
         // This is required for two reasons:
@@ -360,11 +360,11 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
             has_derive_copy: false,
         });
         let parent_scope = self.invocation_parent_scopes[&expn_id];
-        for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() {
-            if opt_ext.is_none() {
-                *opt_ext = Some(
+        for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
+            if resolution.exts.is_none() {
+                resolution.exts = Some(
                     match self.resolve_macro_path(
-                        path,
+                        &resolution.path,
                         Some(MacroKind::Derive),
                         &parent_scope,
                         true,
@@ -372,7 +372,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
                     ) {
                         Ok((Some(ext), _)) => {
                             if !ext.helper_attrs.is_empty() {
-                                let last_seg = path.segments.last().unwrap();
+                                let last_seg = resolution.path.segments.last().unwrap();
                                 let span = last_seg.ident.span.normalize_to_macros_2_0();
                                 entry.helper_attrs.extend(
                                     ext.helper_attrs
@@ -416,7 +416,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
         Ok(())
     }
 
-    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<DeriveResolutions> {
+    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>> {
         self.derive_data.remove(&expn_id).map(|data| data.resolutions)
     }
 
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 0bc7579918c..aace0f3fef9 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -6,8 +6,8 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{InnerSpan, Span, DUMMY_SP};
+use std::mem;
 use std::ops::Range;
-use std::{cmp, mem};
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub enum DocFragmentKind {
@@ -129,17 +129,20 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
     let Some(min_indent) = docs
         .iter()
         .map(|fragment| {
-            fragment.doc.as_str().lines().fold(usize::MAX, |min_indent, line| {
-                if line.chars().all(|c| c.is_whitespace()) {
-                    min_indent
-                } else {
+            fragment
+                .doc
+                .as_str()
+                .lines()
+                .filter(|line| line.chars().any(|c| !c.is_whitespace()))
+                .map(|line| {
                     // Compare against either space or tab, ignoring whether they are
                     // mixed or not.
                     let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count();
-                    cmp::min(min_indent, whitespace)
-                        + if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add }
-                }
-            })
+                    whitespace
+                        + (if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add })
+                })
+                .min()
+                .unwrap_or(usize::MAX)
         })
         .min()
     else {
@@ -151,13 +154,13 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
             continue;
         }
 
-        let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 {
+        let indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 {
             min_indent - add
         } else {
             min_indent
         };
 
-        fragment.indent = min_indent;
+        fragment.indent = indent;
     }
 }
 
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 19f4e6994ac..532b749f913 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -8,10 +8,8 @@
 #![doc(rust_logo)]
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(const_option)]
 #![feature(core_intrinsics)]
-#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(ptr_sub_ptr)]
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 4f259960ac3..ad66e5e1c2b 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -15,6 +15,7 @@ use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg};
 use rustc_feature::UnstableFeatures;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
@@ -32,6 +33,7 @@ use std::iter;
 use std::path::{Path, PathBuf};
 use std::str::{self, FromStr};
 use std::sync::LazyLock;
+use tracing::debug;
 
 mod cfg;
 pub mod sigpipe;
@@ -146,10 +148,26 @@ pub enum InstrumentCoverage {
 /// Individual flag values controlled by `-Z coverage-options`.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
 pub struct CoverageOptions {
-    /// Add branch coverage instrumentation.
-    pub branch: bool,
-    /// Add mcdc coverage instrumentation.
-    pub mcdc: bool,
+    pub level: CoverageLevel,
+    // Other boolean or enum-valued options might be added here.
+}
+
+/// Controls whether branch coverage or MC/DC coverage is enabled.
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum CoverageLevel {
+    /// Instrument for coverage at the MIR block level.
+    Block,
+    /// Also instrument branch points (includes block coverage).
+    Branch,
+    /// Instrument for MC/DC. Mostly a superset of branch coverage, but might
+    /// differ in some corner cases.
+    Mcdc,
+}
+
+impl Default for CoverageLevel {
+    fn default() -> Self {
+        Self::Block
+    }
 }
 
 /// Settings for `-Z instrument-xray` flag.
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 83377b66095..2c20c3f0e1a 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -10,6 +10,7 @@ use rustc_hir::def_id::{
     CrateNum, DefId, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE,
 };
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 2e4c7d14ecd..dce56382a53 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -6,7 +6,7 @@ use rustc_errors::{
     codes::*, Diag, DiagCtxt, DiagMessage, Diagnostic, EmissionGuarantee, ErrorGuaranteed, Level,
     MultiSpan,
 };
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
 
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index aecf5954c4c..f4e2436efb9 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -1,13 +1,12 @@
 //! A module for searching for libraries
 
-use rustc_fs_util::try_canonicalize;
+use crate::search_paths::{PathKind, SearchPath};
+use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use smallvec::{smallvec, SmallVec};
 use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
-
-use crate::search_paths::{PathKind, SearchPath};
-use rustc_fs_util::fix_windows_verbatim_for_gcc;
+use tracing::debug;
 
 #[derive(Clone)]
 pub struct FileSearch<'a> {
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 58e1394c090..ce866906e1e 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -6,13 +6,8 @@
 #![feature(iter_intersperse)]
 #![allow(internal_features)]
 
-#[macro_use]
-extern crate rustc_macros;
 pub mod errors;
 
-#[macro_use]
-extern crate tracing;
-
 pub mod utils;
 pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass};
 pub use rustc_lint_defs as lint;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index e1474ee365b..7355e5b6953 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -394,7 +394,7 @@ mod desc {
     pub const parse_optimization_fuel: &str = "crate=integer";
     pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
     pub const parse_instrument_coverage: &str = parse_bool;
-    pub const parse_coverage_options: &str = "either  `no-branch`, `branch` or `mcdc`";
+    pub const parse_coverage_options: &str = "`block` | `branch` | `mcdc`";
     pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
     pub const parse_unpretty: &str = "`string` or `string=string`";
     pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
@@ -946,15 +946,9 @@ mod parse {
 
         for option in v.split(',') {
             match option {
-                "no-branch" => {
-                    slot.branch = false;
-                    slot.mcdc = false;
-                }
-                "branch" => slot.branch = true,
-                "mcdc" => {
-                    slot.branch = true;
-                    slot.mcdc = true;
-                }
+                "block" => slot.level = CoverageLevel::Block,
+                "branch" => slot.level = CoverageLevel::Branch,
+                "mcdc" => slot.level = CoverageLevel::Mcdc,
                 _ => return false,
             }
         }
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index bc2f2a8af1f..5e8adffc249 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -1,5 +1,6 @@
 use crate::filesearch::make_target_lib_path;
 use crate::EarlyDiagCtxt;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_target::spec::TargetTriple;
 use std::path::{Path, PathBuf};
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 2bc14b43234..db01bb90d6f 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,8 +1,8 @@
 use crate::code_stats::CodeStats;
 pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use crate::config::{
-    self, CrateType, FunctionReturn, InstrumentCoverage, OptLevel, OutFileName, OutputType,
-    RemapPathScopeComponents, SwitchWithOptPath,
+    self, CoverageLevel, CrateType, FunctionReturn, InstrumentCoverage, OptLevel, OutFileName,
+    OutputType, RemapPathScopeComponents, SwitchWithOptPath,
 };
 use crate::config::{ErrorOutputType, Input};
 use crate::errors;
@@ -349,11 +349,13 @@ impl Session {
     }
 
     pub fn instrument_coverage_branch(&self) -> bool {
-        self.instrument_coverage() && self.opts.unstable_opts.coverage_options.branch
+        self.instrument_coverage()
+            && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Branch
     }
 
     pub fn instrument_coverage_mcdc(&self) -> bool {
-        self.instrument_coverage() && self.opts.unstable_opts.coverage_options.mcdc
+        self.instrument_coverage()
+            && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc
     }
 
     pub fn is_sanitizer_cfi_enabled(&self) -> bool {
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 58de5cb31a5..f70a53eeb41 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -1,6 +1,7 @@
 use crate::session::Session;
 use rustc_data_structures::profiling::VerboseTimingGuard;
 use rustc_fs_util::try_canonicalize;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use std::{
     path::{Path, PathBuf},
     sync::OnceLock,
diff --git a/compiler/rustc_session/src/version.rs b/compiler/rustc_session/src/version.rs
index c0c088bcef7..39e4541349e 100644
--- a/compiler/rustc_session/src/version.rs
+++ b/compiler/rustc_session/src/version.rs
@@ -1,3 +1,4 @@
+use rustc_macros::{current_rustc_version, Decodable, Encodable, HashStable_Generic};
 use std::fmt::{self, Display};
 
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 8925b7a42d4..1ac3a817bba 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::stable_hasher::{
 use rustc_data_structures::unhash::Unhasher;
 use rustc_data_structures::AtomicRef;
 use rustc_index::Idx;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::{Decodable, Encodable};
 use std::fmt;
 use std::hash::{BuildHasherDefault, Hash, Hasher};
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs
index 78ac61fa31d..fe09daf522c 100644
--- a/compiler/rustc_span/src/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
@@ -1,7 +1,7 @@
 use std::fmt;
 use std::str::FromStr;
 
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 
 /// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).)
 #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)]
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 6093df94179..aa4bcefab93 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -34,7 +34,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls,
 use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_index::IndexVec;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index f749d4eb833..f83bacdcebe 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -36,13 +36,10 @@
 extern crate self as rustc_span;
 
 #[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
 extern crate tracing;
 
 use rustc_data_structures::{outline, AtomicRef};
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::opaque::{FileEncoder, MemDecoder};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 33bd11cc807..2093dcf0e83 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -12,6 +12,7 @@
 use crate::*;
 use rustc_data_structures::sync::{IntoDynSyncSend, MappedReadGuard, ReadGuard, RwLock};
 use rustc_data_structures::unhash::UnhashMap;
+use rustc_macros::{Decodable, Encodable};
 use std::fs;
 use std::io::{self, BorrowedBuf, Read};
 use std::path;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 99591b5e144..7fe94c2e82b 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::stable_hasher::{
     HashStable, StableCompare, StableHasher, ToStableHashKey,
 };
 use rustc_data_structures::sync::Lock;
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{symbols, Decodable, Encodable, HashStable_Generic};
 
 use std::fmt;
 use std::hash::{Hash, Hasher};
@@ -754,6 +754,7 @@ symbols! {
         enable,
         encode,
         end,
+        enumerate_method,
         env,
         env_CFG_RELEASE: env!("CFG_RELEASE"),
         eprint_macro,
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index f1c3512315f..0ed1f67bb82 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -1,12 +1,13 @@
 use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::bug;
 use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
 use rustc_middle::ty::{self, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArg, GenericArgKind};
-
 use std::fmt::{self, Write};
 use std::mem::{self, discriminant};
+use tracing::debug;
 
 pub(super) fn mangle<'tcx>(
     tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index b9509478702..745ae41085b 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -93,12 +93,6 @@
 #![feature(let_chains)]
 #![allow(internal_features)]
 
-#[macro_use]
-extern crate rustc_middle;
-
-#[macro_use]
-extern crate tracing;
-
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -107,6 +101,7 @@ use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Instance, TyCtxt};
 use rustc_session::config::SymbolManglingVersion;
+use tracing::debug;
 
 mod hashed;
 mod legacy;
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 58b67c77a61..fc2c3dcb2d9 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -5,6 +5,7 @@ use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
+use rustc_middle::bug;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::print::{Print, PrintError, Printer};
 use rustc_middle::ty::{
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index cdd82aa9dbc..3ddea42f67b 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -1,6 +1,7 @@
 use crate::abi::{self, Abi, Align, FieldsShape, Size};
 use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
 use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt};
+use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 use std::str::FromStr;
@@ -100,6 +101,8 @@ pub use attr_impl::ArgAttribute;
 #[allow(non_upper_case_globals)]
 #[allow(unused)]
 mod attr_impl {
+    use rustc_macros::HashStable_Generic;
+
     // The subset of llvm::Attribute needed for arguments, packed into a bitfield.
     #[derive(Clone, Copy, Default, Hash, PartialEq, Eq, HashStable_Generic)]
     pub struct ArgAttribute(u8);
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index 5ae9a2e2058..1a3218da1af 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -1,7 +1,6 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index f56dbac708b..37184393a73 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -1,7 +1,6 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_macros::HashStable_Generic;
 use rustc_span::{sym, Symbol};
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs
index eab38a4a4f4..6943fd9b5d7 100644
--- a/compiler/rustc_target/src/asm/avr.rs
+++ b/compiler/rustc_target/src/asm/avr.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs
index 9bc94274675..faaeabb3c90 100644
--- a/compiler/rustc_target/src/asm/bpf.rs
+++ b/compiler/rustc_target/src/asm/bpf.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs
index 64607ee4b81..db6cdecfe19 100644
--- a/compiler/rustc_target/src/asm/csky.rs
+++ b/compiler/rustc_target/src/asm/csky.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs
index 19da7b80848..7a809efee6f 100644
--- a/compiler/rustc_target/src/asm/hexagon.rs
+++ b/compiler/rustc_target/src/asm/hexagon.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs
index 15d0f54ce3b..534b696f7ed 100644
--- a/compiler/rustc_target/src/asm/loongarch.rs
+++ b/compiler/rustc_target/src/asm/loongarch.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/m68k.rs b/compiler/rustc_target/src/asm/m68k.rs
index ac94dcc03dc..ea367e3d2f9 100644
--- a/compiler/rustc_target/src/asm/m68k.rs
+++ b/compiler/rustc_target/src/asm/m68k.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs
index 0ac1a43ae18..f0d659c9b97 100644
--- a/compiler/rustc_target/src/asm/mips.rs
+++ b/compiler/rustc_target/src/asm/mips.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 49de92b86cb..5f4ce5ed599 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -1,7 +1,7 @@
 use crate::spec::Target;
 use crate::{abi::Size, spec::RelocModel};
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::Symbol;
 use std::fmt;
 use std::str::FromStr;
@@ -24,7 +24,7 @@ macro_rules! def_reg_class {
             $class:ident,
         )*
     }) => {
-        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_regclass {
             $($class,)*
@@ -73,7 +73,7 @@ macro_rules! def_regs {
         )*
     }) => {
         #[allow(unreachable_code)]
-        #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
+        #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)]
         #[allow(non_camel_case_types)]
         pub enum $arch_reg {
             $($reg,)*
diff --git a/compiler/rustc_target/src/asm/msp430.rs b/compiler/rustc_target/src/asm/msp430.rs
index 439f3ba0b57..14013cd8a7b 100644
--- a/compiler/rustc_target/src/asm/msp430.rs
+++ b/compiler/rustc_target/src/asm/msp430.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs
index 57aa50fceb8..6c066ad7ac8 100644
--- a/compiler/rustc_target/src/asm/nvptx.rs
+++ b/compiler/rustc_target/src/asm/nvptx.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
 def_reg_class! {
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs
index 4e8cbe34de9..45e9ace0f29 100644
--- a/compiler/rustc_target/src/asm/powerpc.rs
+++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
index 2505d36f5b8..3845a0e14af 100644
--- a/compiler/rustc_target/src/asm/riscv.rs
+++ b/compiler/rustc_target/src/asm/riscv.rs
@@ -1,7 +1,6 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_macros::HashStable_Generic;
 use rustc_span::{sym, Symbol};
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 6bc668454b1..2bab41cd8a1 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/asm/spirv.rs b/compiler/rustc_target/src/asm/spirv.rs
index d13a6131f9a..f242faec026 100644
--- a/compiler/rustc_target/src/asm/spirv.rs
+++ b/compiler/rustc_target/src/asm/spirv.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
 def_reg_class! {
diff --git a/compiler/rustc_target/src/asm/wasm.rs b/compiler/rustc_target/src/asm/wasm.rs
index eb0b23ef43d..b5f4d10fb2b 100644
--- a/compiler/rustc_target/src/asm/wasm.rs
+++ b/compiler/rustc_target/src/asm/wasm.rs
@@ -1,5 +1,4 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
 def_reg_class! {
diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs
index 3b5da8806cc..28413a5bcbd 100644
--- a/compiler/rustc_target/src/asm/x86.rs
+++ b/compiler/rustc_target/src/asm/x86.rs
@@ -1,7 +1,6 @@
 use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
 use crate::spec::{RelocModel, Target};
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 use std::fmt;
 
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index ba359ac6de1..84d7930663a 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -20,12 +20,6 @@
 
 use std::path::{Path, PathBuf};
 
-#[macro_use]
-extern crate rustc_macros;
-
-#[macro_use]
-extern crate tracing;
-
 pub mod abi;
 pub mod asm;
 pub mod json;
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index 388e76d83e2..bf51bb4bf82 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -1,6 +1,6 @@
 use std::fmt;
 
-use rustc_macros::HashStable_Generic;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 291a761913b..bd347c1b4b3 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -40,6 +40,7 @@ use crate::json::{Json, ToJson};
 use crate::spec::abi::Abi;
 use crate::spec::crt_objects::CrtObjects;
 use rustc_fs_util::try_canonicalize;
+use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::symbol::{kw, sym, Symbol};
 use serde_json::Value;
@@ -50,8 +51,7 @@ use std::ops::{Deref, DerefMut};
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::{fmt, io};
-
-use rustc_macros::HashStable_Generic;
+use tracing::debug;
 
 pub mod abi;
 pub mod crt_objects;
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 9b08a86ef16..7228a9ba016 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -3,7 +3,7 @@ use rustc_errors::{
     codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level,
     SubdiagMessageOp, Subdiagnostic,
 };
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
 use rustc_span::{Span, Symbol};
 
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 0595e82b39e..3dc55509dad 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -1,10 +1,10 @@
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::{self, ObligationCtxt, SelectionContext};
 
-use crate::traits::TraitEngineExt as _;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
-use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt as _};
+use rustc_infer::traits::Obligation;
+use rustc_macros::extension;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
 use rustc_middle::traits::query::NoSolution;
@@ -94,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> {
                 ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
             )) {
                 Ok(Some(selection)) => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligations(self, selection.nested_obligations());
-                    Some(fulfill_cx.select_all_or_error(self))
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligations(selection.nested_obligations());
+                    Some(ocx.select_all_or_error())
                 }
                 Ok(None) | Err(_) => None,
             }
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index d54f714b22c..f1f03b810a9 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -17,7 +17,6 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 #![feature(assert_matches)]
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(associated_type_defaults)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
@@ -30,16 +29,9 @@
 #![recursion_limit = "512"] // For rustdoc
 
 #[macro_use]
-extern crate rustc_macros;
-#[cfg(target_pointer_width = "64")]
-#[macro_use]
-extern crate rustc_data_structures;
-#[macro_use]
 extern crate tracing;
 #[macro_use]
 extern crate rustc_middle;
-#[macro_use]
-extern crate smallvec;
 
 pub mod errors;
 pub mod infer;
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index 222d0b4d5e7..5e0d7da4f06 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -1,5 +1,6 @@
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, RegionResolutionError};
+use rustc_macros::extension;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
 
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 68b0db21141..280975f63bd 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -1,8 +1,7 @@
 //! Code shared by trait and projection goals for candidate assembly.
 
-use super::{EvalCtxt, SolverMode};
 use crate::solve::GoalSource;
-use crate::traits::coherence;
+use crate::solve::{inspect, EvalCtxt, SolverMode};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
 use rustc_middle::traits::solve::inspect::ProbeKind;
@@ -16,6 +15,7 @@ use rustc_middle::ty::{fast_reject, TypeFoldable};
 use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, DUMMY_SP};
 use std::fmt::Debug;
+use std::mem;
 
 pub(super) mod structural_traits;
 
@@ -47,21 +47,23 @@ pub(super) trait GoalKind<'tcx>:
     /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
+        source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// Consider a clause, which consists of a "assumption" and some "requirements",
     /// to satisfy a goal. If the requirements hold, then attempt to satisfy our
     /// goal by equating it with the assumption.
-    fn consider_implied_clause(
+    fn probe_and_consider_implied_clause(
         ecx: &mut EvalCtxt<'_, 'tcx>,
+        source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
         requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
-    ) -> QueryResult<'tcx> {
-        Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
+        Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
             // FIXME(-Znext-solver=coinductive): check whether this should be
             // `GoalSource::ImplWhereBound` for any caller.
             ecx.add_goals(GoalSource::Misc, requirements);
@@ -72,15 +74,16 @@ pub(super) trait GoalKind<'tcx>:
     /// Consider a clause specifically for a `dyn Trait` self type. This requires
     /// additionally checking all of the supertraits and object bounds to hold,
     /// since they're not implied by the well-formedness of the object type.
-    fn consider_object_bound_candidate(
+    fn probe_and_consider_object_bound_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
+        source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
-    ) -> QueryResult<'tcx> {
-        Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
+        Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
             let tcx = ecx.tcx();
             let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
-                bug!("expected object type in `consider_object_bound_candidate`");
+                bug!("expected object type in `probe_and_consider_object_bound_candidate`");
             };
             // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
             ecx.add_goals(
@@ -111,7 +114,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_error_guaranteed_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         guar: ErrorGuaranteed,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A type implements an `auto trait` if its components do as well.
     ///
@@ -120,13 +123,13 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_auto_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A trait alias holds if the RHS traits and `where` clauses hold.
     fn consider_trait_alias_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A type is `Sized` if its tail component is `Sized`.
     ///
@@ -135,7 +138,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_sized_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`.
     ///
@@ -144,20 +147,20 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_copy_clone_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A type is `PointerLike` if we can compute its layout, and that layout
     /// matches the layout of `usize`.
     fn consider_builtin_pointer_like_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A type is a `FnPtr` if it is of `FnPtr` type.
     fn consider_builtin_fn_ptr_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
     /// family of traits where `A` is given by the signature of the type.
@@ -165,7 +168,7 @@ pub(super) trait GoalKind<'tcx>:
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// An async closure is known to implement the `AsyncFn<A>` family of traits
     /// where `A` is given by the signature of the type.
@@ -173,7 +176,7 @@ pub(super) trait GoalKind<'tcx>:
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which
     /// is used internally to delay computation for async closures until after
@@ -181,13 +184,13 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_async_fn_kind_helper_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// `Tuple` is implemented if the `Self` type is a tuple.
     fn consider_builtin_tuple_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// `Pointee` is always implemented.
     ///
@@ -197,7 +200,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_pointee_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A coroutine (that comes from an `async` desugaring) is known to implement
     /// `Future<Output = O>`, where `O` is given by the coroutine's return type
@@ -205,7 +208,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_future_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A coroutine (that comes from a `gen` desugaring) is known to implement
     /// `Iterator<Item = O>`, where `O` is given by the generator's yield type
@@ -213,19 +216,19 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A coroutine (that comes from a `gen` desugaring) is known to implement
     /// `FusedIterator`
     fn consider_builtin_fused_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     fn consider_builtin_async_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to
     /// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
@@ -233,27 +236,27 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_builtin_coroutine_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     fn consider_builtin_discriminant_kind_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     fn consider_builtin_async_destruct_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     fn consider_builtin_destruct_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     fn consider_builtin_transmute_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// Consider (possibly several) candidates to upcast or unsize a type to another
     /// type, excluding the coercion of a sized type into a `dyn Trait`.
@@ -265,7 +268,7 @@ pub(super) trait GoalKind<'tcx>:
     fn consider_structural_builtin_unsize_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)>;
+    ) -> Vec<Candidate<'tcx>>;
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -281,7 +284,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         if normalized_self_ty.is_ty_var() {
             debug!("self type has been normalized to infer");
-            return self.forced_ambiguity(MaybeCause::Ambiguity);
+            return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
         }
 
         let goal =
@@ -314,21 +317,19 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates
     }
 
-    fn forced_ambiguity(&mut self, cause: MaybeCause) -> Vec<Candidate<'tcx>> {
-        let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
-        let certainty = Certainty::Maybe(cause);
+    pub(super) fn forced_ambiguity(
+        &mut self,
+        cause: MaybeCause,
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         // This may fail if `try_evaluate_added_goals` overflows because it
         // fails to reach a fixpoint but ends up getting an error after
         // running for some additional step.
         //
-        // FIXME: Add a test for this. It seems to be necessary for typenum but
-        // is incredibly hard to minimize as it may rely on being inside of a
-        // trait solver cycle.
-        let result = self.evaluate_added_goals_and_make_canonical_response(certainty);
-        let mut dummy_probe = self.inspect.new_probe();
-        dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result });
-        self.inspect.finish_probe(dummy_probe);
-        if let Ok(result) = result { vec![Candidate { source, result }] } else { vec![] }
+        // cc trait-system-refactor-initiative#105
+        let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
+        let certainty = Certainty::Maybe(cause);
+        self.probe_trait_candidate(source)
+            .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty))
     }
 
     #[instrument(level = "debug", skip_all)]
@@ -535,20 +536,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             Err(NoSolution)
         };
 
-        match result {
-            Ok(result) => candidates.push(Candidate {
-                source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                result,
-            }),
-            Err(NoSolution) => (),
-        }
+        candidates.extend(result);
 
         // There may be multiple unsize candidates for a trait with several supertraits:
         // `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
         if lang_items.unsize_trait() == Some(trait_def_id) {
-            for (result, source) in G::consider_structural_builtin_unsize_candidates(self, goal) {
-                candidates.push(Candidate { source: CandidateSource::BuiltinImpl(source), result });
-            }
+            candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal));
         }
     }
 
@@ -559,12 +552,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
         for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
-            match G::consider_implied_clause(self, goal, assumption, []) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
-                }
-                Err(NoSolution) => (),
-            }
+            candidates.extend(G::probe_and_consider_implied_clause(
+                self,
+                CandidateSource::ParamEnv(i),
+                goal,
+                assumption,
+                [],
+            ));
         }
     }
 
@@ -650,12 +644,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         for assumption in
             self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
         {
-            match G::consider_implied_clause(self, goal, assumption, []) {
-                Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
-                }
-                Err(NoSolution) => {}
-            }
+            candidates.extend(G::probe_and_consider_implied_clause(
+                self,
+                CandidateSource::AliasBound,
+                goal,
+                assumption,
+                [],
+            ));
         }
 
         if kind != ty::Projection {
@@ -730,17 +725,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 }
                 ty::ExistentialPredicate::Projection(_)
                 | ty::ExistentialPredicate::AutoTrait(_) => {
-                    match G::consider_object_bound_candidate(
+                    candidates.extend(G::probe_and_consider_object_bound_candidate(
                         self,
+                        CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
                         goal,
                         bound.with_self_ty(tcx, self_ty),
-                    ) {
-                        Ok(result) => candidates.push(Candidate {
-                            source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                            result,
-                        }),
-                        Err(NoSolution) => (),
-                    }
+                    ));
                 }
             }
         }
@@ -751,15 +741,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         if let Some(principal) = bounds.principal() {
             let principal_trait_ref = principal.with_self_ty(tcx, self_ty);
             self.walk_vtable(principal_trait_ref, |ecx, assumption, vtable_base, _| {
-                match G::consider_object_bound_candidate(ecx, goal, assumption.to_predicate(tcx)) {
-                    Ok(result) => candidates.push(Candidate {
-                        source: CandidateSource::BuiltinImpl(BuiltinImplSource::Object {
-                            vtable_base,
-                        }),
-                        result,
-                    }),
-                    Err(NoSolution) => (),
-                }
+                candidates.extend(G::probe_and_consider_object_bound_candidate(
+                    ecx,
+                    CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base }),
+                    goal,
+                    assumption.to_predicate(tcx),
+                ));
             });
         }
     }
@@ -777,25 +764,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
         let tcx = self.tcx();
-        let result = self.probe_misc_candidate("coherence unknowable").enter(|ecx| {
-            let trait_ref = goal.predicate.trait_ref(tcx);
-            let lazily_normalize_ty = |ty| ecx.structurally_normalize_ty(goal.param_env, ty);
 
-            match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty)? {
-                Ok(()) => Err(NoSolution),
-                Err(_) => {
+        candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
+            |ecx| {
+                let trait_ref = goal.predicate.trait_ref(tcx);
+                if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? {
+                    Err(NoSolution)
+                } else {
                     ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
                 }
-            }
-        });
-
-        match result {
-            Ok(result) => candidates.push(Candidate {
-                source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                result,
-            }),
-            Err(NoSolution) => {}
-        }
+            },
+        ))
     }
 
     /// If there's a where-bound for the current goal, do not use any impl candidates
@@ -813,6 +792,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, G>,
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
+        // HACK: We temporarily remove the `ProofTreeBuilder` to
+        // avoid adding `Trait` candidates to the candidates used
+        // to prove the current goal.
+        let inspect = mem::replace(&mut self.inspect, inspect::ProofTreeBuilder::new_noop());
+
         let tcx = self.tcx();
         let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
             goal.with(tcx, goal.predicate.trait_ref(tcx));
@@ -835,6 +819,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                             false
                         }
                         CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true,
+                        CandidateSource::CoherenceUnknowable => bug!("uh oh"),
                     });
                 }
                 // If it is still ambiguous we instead just force the whole goal
@@ -842,10 +827,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
                 Certainty::Maybe(cause) => {
                     debug!(?cause, "force ambiguity");
-                    *candidates = self.forced_ambiguity(cause);
+                    *candidates = self.forced_ambiguity(cause).into_iter().collect();
                 }
             }
         }
+        self.inspect = inspect;
     }
 
     /// If there are multiple ways to prove a trait or projection goal, we have
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index a778414d9d1..a8b1a182d3c 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::LangItem;
 use rustc_hir::{def_id::DefId, Movability, Mutability};
 use rustc_infer::traits::query::NoSolution;
+use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::{
     self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 0b37163d597..6722abd709c 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -19,9 +19,12 @@ use rustc_infer::infer::canonical::query_response::make_query_region_constraints
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
 use rustc_infer::infer::resolve::EagerResolver;
+use rustc_infer::infer::type_variable::TypeVariableOrigin;
+use rustc_infer::infer::RegionVariableOrigin;
 use rustc_infer::infer::{InferCtxt, InferOk};
 use rustc_infer::traits::solve::NestedNormalizationGoals;
 use rustc_middle::infer::canonical::Canonical;
+use rustc_middle::infer::unify_key::ConstVariableOrigin;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
     ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
@@ -29,7 +32,7 @@ use rustc_middle::traits::solve::{
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
 use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
-use rustc_span::DUMMY_SP;
+use rustc_span::{Span, DUMMY_SP};
 use std::assert_matches::assert_matches;
 use std::iter;
 use std::ops::Deref;
@@ -95,6 +98,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             previous call to `try_evaluate_added_goals!`"
         );
 
+        self.inspect.make_canonical_response(certainty);
+
         // When normalizing, we've replaced the expected term with an unconstrained
         // inference variable. This means that we dropped information which could
         // have been important. We handle this by instead returning the nested goals
@@ -374,36 +379,70 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     }
 }
 
-impl<'tcx> inspect::ProofTreeBuilder<'tcx> {
-    pub fn make_canonical_state<T: TypeFoldable<TyCtxt<'tcx>>>(
-        ecx: &EvalCtxt<'_, 'tcx>,
-        data: T,
-    ) -> inspect::CanonicalState<'tcx, T> {
-        let state = inspect::State { var_values: ecx.var_values, data };
-        let state = state.fold_with(&mut EagerResolver::new(ecx.infcx));
-        Canonicalizer::canonicalize(
-            ecx.infcx,
-            CanonicalizeMode::Response { max_input_universe: ecx.max_input_universe },
-            &mut vec![],
-            state,
-        )
+/// Used by proof trees to be able to recompute intermediate actions while
+/// evaluating a goal. The `var_values` not only include the bound variables
+/// of the query input, but also contain all unconstrained inference vars
+/// created while evaluating this goal.
+pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
+    infcx: &InferCtxt<'tcx>,
+    var_values: &[ty::GenericArg<'tcx>],
+    max_input_universe: ty::UniverseIndex,
+    data: T,
+) -> inspect::CanonicalState<'tcx, T> {
+    let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) };
+    let state = inspect::State { var_values, data };
+    let state = state.fold_with(&mut EagerResolver::new(infcx));
+    Canonicalizer::canonicalize(
+        infcx,
+        CanonicalizeMode::Response { max_input_universe },
+        &mut vec![],
+        state,
+    )
+}
+
+/// Instantiate a `CanonicalState`.
+///
+/// Unlike for query responses, `CanonicalState` also track fresh inference
+/// variables created while evaluating a goal. When creating two separate
+/// `CanonicalState` during a single evaluation both may reference this
+/// fresh inference variable. When instantiating them we now create separate
+/// inference variables for it and have to unify them somehow. We do this
+/// by extending the `var_values` while building the proof tree.
+///
+/// This currently assumes that unifying the var values trivially succeeds.
+/// Adding any inference constraints which weren't present when originally
+/// computing the canonical query can result in bugs.
+pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
+    infcx: &InferCtxt<'tcx>,
+    span: Span,
+    param_env: ty::ParamEnv<'tcx>,
+    orig_values: &mut Vec<ty::GenericArg<'tcx>>,
+    state: inspect::CanonicalState<'tcx, T>,
+) -> T {
+    // In case any fresh inference variables have been created between `state`
+    // and the previous instantiation, extend `orig_values` for it.
+    assert!(orig_values.len() <= state.value.var_values.len());
+    for i in orig_values.len()..state.value.var_values.len() {
+        let unconstrained = match state.value.var_values.var_values[i].unpack() {
+            ty::GenericArgKind::Lifetime(_) => {
+                infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)).into()
+            }
+            ty::GenericArgKind::Type(_) => {
+                infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }).into()
+            }
+            ty::GenericArgKind::Const(ct) => infcx
+                .next_const_var(ct.ty(), ConstVariableOrigin { param_def_id: None, span })
+                .into(),
+        };
+
+        orig_values.push(unconstrained);
     }
 
-    /// Instantiate a `CanonicalState`. This assumes that unifying the var values
-    /// trivially succeeds. Adding any inference constraints which weren't present when
-    /// originally computing the canonical query can result in bugs.
-    pub fn instantiate_canonical_state<T: TypeFoldable<TyCtxt<'tcx>>>(
-        infcx: &InferCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        original_values: &[ty::GenericArg<'tcx>],
-        state: inspect::CanonicalState<'tcx, T>,
-    ) -> T {
-        let instantiation =
-            EvalCtxt::compute_query_response_instantiation_values(infcx, original_values, &state);
+    let instantiation =
+        EvalCtxt::compute_query_response_instantiation_values(infcx, orig_values, &state);
 
-        let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation);
+    let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation);
 
-        EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values);
-        data
-    }
+    EvalCtxt::unify_query_var_values(infcx, param_env, orig_values, var_values);
+    data
 }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index f914e6b3f2e..1710746ae50 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -9,6 +9,7 @@ use rustc_infer::infer::{
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals};
 use rustc_infer::traits::ObligationCause;
+use rustc_macros::{extension, HashStable};
 use rustc_middle::infer::canonical::CanonicalVarInfos;
 use rustc_middle::infer::unify_key::ConstVariableOrigin;
 use rustc_middle::traits::solve::inspect;
@@ -26,6 +27,7 @@ use rustc_span::DUMMY_SP;
 use std::io::Write;
 use std::ops::ControlFlow;
 
+use crate::traits::coherence;
 use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
 
 use super::inspect::ProofTreeBuilder;
@@ -34,7 +36,7 @@ use super::{search_graph::SearchGraph, Goal};
 use super::{GoalSource, SolverMode};
 pub use select::InferCtxtSelectExt;
 
-mod canonical;
+pub(super) mod canonical;
 mod probe;
 mod select;
 
@@ -84,7 +86,7 @@ pub struct EvalCtxt<'a, 'tcx> {
 
     pub(super) search_graph: &'a mut SearchGraph<'tcx>,
 
-    pub(super) nested_goals: NestedGoals<'tcx>,
+    nested_goals: NestedGoals<'tcx>,
 
     // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
     //
@@ -161,7 +163,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
     /// Creates a root evaluation context and search graph. This should only be
     /// used from outside of any evaluation, and other methods should be preferred
     /// over using this manually (such as [`InferCtxtEvalExt::evaluate_root_goal`]).
-    fn enter_root<R>(
+    pub(super) fn enter_root<R>(
         infcx: &InferCtxt<'tcx>,
         generate_proof_tree: GenerateProofTree,
         f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R,
@@ -242,7 +244,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             search_graph,
             nested_goals: NestedGoals::new(),
             tainted: Ok(()),
-            inspect: canonical_goal_evaluation.new_goal_evaluation_step(input),
+            inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values, input),
         };
 
         for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
@@ -255,7 +257,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
 
         let result = f(&mut ecx, input.goal);
-
+        ecx.inspect.probe_final_state(ecx.infcx, ecx.max_input_universe);
         canonical_goal_evaluation.goal_evaluation_step(ecx.inspect);
 
         // When creating a query response we clone the opaque type constraints
@@ -338,7 +340,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
     /// storage.
     // FIXME(-Znext-solver=coinduction): `_source` is currently unused but will
     // be necessary once we implement the new coinduction approach.
-    fn evaluate_goal_raw(
+    pub(super) fn evaluate_goal_raw(
         &mut self,
         goal_evaluation_kind: GoalEvaluationKind,
         _source: GoalSource,
@@ -458,13 +460,23 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
+    pub(super) fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) {
+        self.inspect.add_normalizes_to_goal(self.infcx, self.max_input_universe, goal);
+        self.nested_goals.normalizes_to_goals.push(goal);
+    }
+
+    #[instrument(level = "debug", skip(self))]
+    pub(super) fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) {
+        self.inspect.add_goal(self.infcx, self.max_input_universe, source, goal);
+        self.nested_goals.goals.push((source, goal));
+    }
+
     // Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning
     // the certainty of all the goals.
     #[instrument(level = "debug", skip(self))]
     pub(super) fn try_evaluate_added_goals(&mut self) -> Result<Certainty, NoSolution> {
-        let inspect = self.inspect.new_evaluate_added_goals();
-        let inspect = core::mem::replace(&mut self.inspect, inspect);
-
+        self.inspect.start_evaluate_added_goals();
         let mut response = Ok(Certainty::overflow(false));
         for _ in 0..FIXPOINT_STEP_LIMIT {
             // FIXME: This match is a bit ugly, it might be nice to change the inspect
@@ -482,15 +494,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             }
         }
 
-        self.inspect.eval_added_goals_result(response);
+        self.inspect.evaluate_added_goals_result(response);
 
         if response.is_err() {
             self.tainted = Err(NoSolution);
         }
 
-        let goal_evaluations = std::mem::replace(&mut self.inspect, inspect);
-        self.inspect.added_goals_evaluation(goal_evaluations);
-
         response
     }
 
@@ -499,10 +508,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
     /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
     fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
         let tcx = self.tcx();
+        self.inspect.start_evaluate_added_goals_step();
         let mut goals = core::mem::take(&mut self.nested_goals);
 
-        self.inspect.evaluate_added_goals_loop_start();
-
         // If this loop did not result in any progress, what's our final certainty.
         let mut unchanged_certainty = Some(Certainty::Yes);
         for goal in goals.normalizes_to_goals {
@@ -586,17 +594,23 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         self.infcx.tcx
     }
 
-    pub(super) fn next_ty_infer(&self) -> Ty<'tcx> {
-        self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP })
+    pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> {
+        let ty = self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP });
+        self.inspect.add_var_value(ty);
+        ty
     }
 
-    pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
-        self.infcx.next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP })
+    pub(super) fn next_const_infer(&mut self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+        let ct = self
+            .infcx
+            .next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP });
+        self.inspect.add_var_value(ct);
+        ct
     }
 
     /// Returns a ty infer or a const infer depending on whether `kind` is a `Ty` or `Const`.
     /// If `kind` is an integer inference variable this will still return a ty infer var.
-    pub(super) fn next_term_infer_of_kind(&self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> {
+    pub(super) fn next_term_infer_of_kind(&mut self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> {
         match kind.unpack() {
             ty::TermKind::Ty(_) => self.next_ty_infer().into(),
             ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
@@ -929,6 +943,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    pub(super) fn trait_ref_is_knowable(
+        &mut self,
+        param_env: ty::ParamEnv<'tcx>,
+        trait_ref: ty::TraitRef<'tcx>,
+    ) -> Result<bool, NoSolution> {
+        let infcx = self.infcx;
+        let lazily_normalize_ty = |ty| self.structurally_normalize_ty(param_env, ty);
+        coherence::trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty)
+            .map(|is_knowable| is_knowable.is_ok())
+    }
+
     pub(super) fn can_define_opaque_ty(&self, def_id: impl Into<DefId>) -> bool {
         self.infcx.can_define_opaque_ty(def_id)
     }
@@ -986,19 +1011,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             if candidate_key.def_id != key.def_id {
                 continue;
             }
-            values.extend(self.probe_misc_candidate("opaque type storage").enter(|ecx| {
-                for (a, b) in std::iter::zip(candidate_key.args, key.args) {
-                    ecx.eq(param_env, a, b)?;
-                }
-                ecx.eq(param_env, candidate_ty, ty)?;
-                ecx.add_item_bounds_for_hidden_type(
-                    candidate_key.def_id.to_def_id(),
-                    candidate_key.args,
-                    param_env,
-                    candidate_ty,
-                );
-                ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-            }));
+            values.extend(
+                self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
+                    result: *result,
+                })
+                .enter(|ecx| {
+                    for (a, b) in std::iter::zip(candidate_key.args, key.args) {
+                        ecx.eq(param_env, a, b)?;
+                    }
+                    ecx.eq(param_env, candidate_ty, ty)?;
+                    ecx.add_item_bounds_for_hidden_type(
+                        candidate_key.def_id.to_def_id(),
+                        candidate_key.args,
+                        param_env,
+                        candidate_ty,
+                    );
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                }),
+            );
         }
         values
     }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
index 5b1124e8b9f..ee23f49939b 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
@@ -1,6 +1,7 @@
 use crate::solve::assembly::Candidate;
 
 use super::EvalCtxt;
+use rustc_infer::traits::BuiltinImplSource;
 use rustc_middle::traits::{
     query::NoSolution,
     solve::{inspect, CandidateSource, QueryResult},
@@ -20,23 +21,29 @@ where
     pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T {
         let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
 
+        let infcx = outer_ecx.infcx;
+        let max_input_universe = outer_ecx.max_input_universe;
         let mut nested_ecx = EvalCtxt {
-            infcx: outer_ecx.infcx,
+            infcx,
             variables: outer_ecx.variables,
             var_values: outer_ecx.var_values,
             is_normalizes_to_goal: outer_ecx.is_normalizes_to_goal,
             predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body,
-            max_input_universe: outer_ecx.max_input_universe,
+            max_input_universe,
             search_graph: outer_ecx.search_graph,
             nested_goals: outer_ecx.nested_goals.clone(),
             tainted: outer_ecx.tainted,
-            inspect: outer_ecx.inspect.new_probe(),
+            inspect: outer_ecx.inspect.take_and_enter_probe(),
         };
-        let r = nested_ecx.infcx.probe(|_| f(&mut nested_ecx));
-        if !outer_ecx.inspect.is_noop() {
+        let r = nested_ecx.infcx.probe(|_| {
+            let r = f(&mut nested_ecx);
+            nested_ecx.inspect.probe_final_state(infcx, max_input_universe);
+            r
+        });
+        if !nested_ecx.inspect.is_noop() {
             let probe_kind = probe_kind(&r);
             nested_ecx.inspect.probe_kind(probe_kind);
-            outer_ecx.inspect.finish_probe(nested_ecx.inspect);
+            outer_ecx.inspect = nested_ecx.inspect.finish_probe();
         }
         r
     }
@@ -69,24 +76,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         ProbeCtxt { ecx: self, probe_kind, _result: PhantomData }
     }
 
-    pub(in crate::solve) fn probe_misc_candidate(
+    pub(in crate::solve) fn probe_builtin_trait_candidate(
         &mut self,
-        name: &'static str,
-    ) -> ProbeCtxt<
-        '_,
-        'a,
-        'tcx,
-        impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>,
-        QueryResult<'tcx>,
-    > {
-        ProbeCtxt {
-            ecx: self,
-            probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::MiscCandidate {
-                name,
-                result: *result,
-            },
-            _result: PhantomData,
-        }
+        source: BuiltinImplSource,
+    ) -> TraitProbeCtxt<'_, 'a, 'tcx, impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>>
+    {
+        self.probe_trait_candidate(CandidateSource::BuiltinImpl(source))
     }
 
     pub(in crate::solve) fn probe_trait_candidate(
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 6644d3c77af..16fe045b82d 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -1,21 +1,17 @@
-use rustc_hir as hir;
+use std::ops::ControlFlow;
+
 use rustc_hir::def_id::DefId;
-use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt};
+use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
+use rustc_infer::traits::solve::inspect::ProbeKind;
+use rustc_infer::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_infer::traits::{
-    Obligation, PolyTraitObligation, PredicateObligation, Selection, SelectionResult, TraitEngine,
-};
-use rustc_middle::traits::solve::{CandidateSource, CanonicalInput, Certainty, Goal};
-use rustc_middle::traits::{
-    BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, ObligationCause, SelectionError,
+    BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, Obligation, ObligationCause,
+    PolyTraitObligation, PredicateObligation, Selection, SelectionError, SelectionResult,
 };
-use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::DUMMY_SP;
+use rustc_macros::extension;
+use rustc_span::Span;
 
-use crate::solve::assembly::Candidate;
-use crate::solve::eval_ctxt::{EvalCtxt, GenerateProofTree};
-use crate::solve::inspect::ProofTreeBuilder;
-use crate::traits::StructurallyNormalizeExt;
-use crate::traits::TraitEngineExt;
+use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
 
 #[extension(pub trait InferCtxtSelectExt<'tcx>)]
 impl<'tcx> InferCtxt<'tcx> {
@@ -25,357 +21,192 @@ impl<'tcx> InferCtxt<'tcx> {
     ) -> SelectionResult<'tcx, Selection<'tcx>> {
         assert!(self.next_trait_solver());
 
-        self.enter_forall(obligation.predicate, |pred| {
-            let trait_goal = Goal::new(self.tcx, obligation.param_env, pred);
-
-            let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::Never, |ecx| {
-                let goal = Goal::new(ecx.tcx(), trait_goal.param_env, trait_goal.predicate);
-                let (orig_values, canonical_goal) = ecx.canonicalize_goal(goal);
-                let mut candidates = ecx.compute_canonical_trait_candidates(canonical_goal);
+        self.visit_proof_tree(
+            Goal::new(self.tcx, obligation.param_env, obligation.predicate),
+            &mut Select { span: obligation.cause.span },
+        )
+        .break_value()
+        .unwrap()
+    }
+}
 
-                // pseudo-winnow
-                if candidates.len() == 0 {
-                    return Err(SelectionError::Unimplemented);
-                } else if candidates.len() > 1 {
-                    let mut i = 0;
-                    while i < candidates.len() {
-                        let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
-                            candidate_should_be_dropped_in_favor_of(
-                                ecx.tcx(),
-                                &candidates[i],
-                                &candidates[j],
-                            )
-                        });
-                        if should_drop_i {
-                            candidates.swap_remove(i);
-                        } else {
-                            i += 1;
-                            if i > 1 {
-                                return Ok(None);
-                            }
-                        }
-                    }
-                }
+struct Select {
+    span: Span,
+}
 
-                let candidate = candidates.pop().unwrap();
-                let (normalization_nested_goals, certainty) = ecx
-                    .instantiate_and_apply_query_response(
-                        trait_goal.param_env,
-                        orig_values,
-                        candidate.result,
-                    );
-                assert!(normalization_nested_goals.is_empty());
-                Ok(Some((candidate, certainty)))
-            });
+impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select {
+    type Result = ControlFlow<SelectionResult<'tcx, Selection<'tcx>>>;
 
-            let (candidate, certainty) = match result {
-                Ok(Some(result)) => result,
-                Ok(None) => return Ok(None),
-                Err(e) => return Err(e),
-            };
+    fn span(&self) -> Span {
+        self.span
+    }
 
-            let goal = self.resolve_vars_if_possible(trait_goal);
-            match (certainty, candidate.source) {
-                // Rematching the implementation will instantiate the same nested goals that
-                // would have caused the ambiguity, so we can still make progress here regardless.
-                (_, CandidateSource::Impl(def_id)) => rematch_impl(self, goal, def_id),
+    fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
+        let mut candidates = goal.candidates();
+        candidates.retain(|cand| cand.result().is_ok());
 
-                // If an unsize goal is ambiguous, then we can manually rematch it to make
-                // selection progress for coercion during HIR typeck. If it is *not* ambiguous,
-                // but is `BuiltinImplSource::Misc`, it may have nested `Unsize` goals,
-                // and we need to rematch those to detect tuple unsizing and trait upcasting.
-                // FIXME: This will be wrong if we have param-env or where-clause bounds
-                // with the unsize goal -- we may need to mark those with different impl
-                // sources.
-                (Certainty::Maybe(_), CandidateSource::BuiltinImpl(src))
-                | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
-                    if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
-                {
-                    rematch_unsize(self, goal, src, certainty)
-                }
+        // No candidates -- not implemented.
+        if candidates.is_empty() {
+            return ControlFlow::Break(Err(SelectionError::Unimplemented));
+        }
 
-                // Technically some builtin impls have nested obligations, but if
-                // `Certainty::Yes`, then they should've all been verified and don't
-                // need re-checking.
-                (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => {
-                    Ok(Some(ImplSource::Builtin(src, vec![])))
-                }
+        // One candidate, no need to winnow.
+        if candidates.len() == 1 {
+            return ControlFlow::Break(Ok(to_selection(
+                self.span,
+                candidates.into_iter().next().unwrap(),
+            )));
+        }
 
-                // It's fine not to do anything to rematch these, since there are no
-                // nested obligations.
-                (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
-                    Ok(Some(ImplSource::Param(vec![])))
+        // We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`.
+        let mut i = 0;
+        while i < candidates.len() {
+            let should_drop_i = (0..candidates.len())
+                .filter(|&j| i != j)
+                .any(|j| candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j]));
+            if should_drop_i {
+                candidates.swap_remove(i);
+            } else {
+                i += 1;
+                if i > 1 {
+                    return ControlFlow::Break(Ok(None));
                 }
-
-                (Certainty::Maybe(_), _) => Ok(None),
             }
-        })
-    }
-}
+        }
 
-impl<'tcx> EvalCtxt<'_, 'tcx> {
-    fn compute_canonical_trait_candidates(
-        &mut self,
-        canonical_input: CanonicalInput<'tcx>,
-    ) -> Vec<Candidate<'tcx>> {
-        // This doesn't record the canonical goal on the stack during the
-        // candidate assembly step, but that's fine. Selection is conceptually
-        // outside of the solver, and if there were any cycles, we'd encounter
-        // the cycle anyways one step later.
-        EvalCtxt::enter_canonical(
-            self.tcx(),
-            self.search_graph,
-            canonical_input,
-            // FIXME: This is wrong, idk if we even want to track stuff here.
-            &mut ProofTreeBuilder::new_noop(),
-            |ecx, goal| {
-                let trait_goal = Goal {
-                    param_env: goal.param_env,
-                    predicate: goal
-                        .predicate
-                        .to_opt_poly_trait_pred()
-                        .expect("we canonicalized a trait goal")
-                        .no_bound_vars()
-                        .expect("we instantiated all bound vars"),
-                };
-                ecx.assemble_and_evaluate_candidates(trait_goal)
-            },
-        )
+        ControlFlow::Break(Ok(to_selection(self.span, candidates.into_iter().next().unwrap())))
     }
 }
 
+/// This is a lot more limited than the old solver's equivalent method. This may lead to more `Ok(None)`
+/// results when selecting traits in polymorphic contexts, but we should never rely on the lack of ambiguity,
+/// and should always just gracefully fail here. We shouldn't rely on this incompleteness.
 fn candidate_should_be_dropped_in_favor_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    victim: &Candidate<'tcx>,
-    other: &Candidate<'tcx>,
+    victim: &inspect::InspectCandidate<'_, 'tcx>,
+    other: &inspect::InspectCandidate<'_, 'tcx>,
 ) -> bool {
-    match (victim.source, other.source) {
-        (CandidateSource::ParamEnv(victim_idx), CandidateSource::ParamEnv(other_idx)) => {
-            victim_idx >= other_idx
+    // Don't winnow until `Certainty::Yes` -- we don't need to winnow until
+    // codegen, technically.
+    if matches!(other.result().unwrap(), Certainty::Maybe(..)) {
+        return false;
+    }
+
+    let inspect::ProbeKind::TraitCandidate { source: victim_source, result: _ } = victim.kind()
+    else {
+        return false;
+    };
+    let inspect::ProbeKind::TraitCandidate { source: other_source, result: _ } = other.kind()
+    else {
+        return false;
+    };
+
+    match (victim_source, other_source) {
+        (_, CandidateSource::CoherenceUnknowable) | (CandidateSource::CoherenceUnknowable, _) => {
+            bug!("should not have assembled a CoherenceUnknowable candidate")
         }
-        (_, CandidateSource::ParamEnv(_)) => true,
 
-        // FIXME: we could prefer earlier vtable bases perhaps...
+        // Prefer dyn candidates over non-dyn candidates. This is necessary to
+        // handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.
         (
             CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
             CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
         ) => false,
-        (_, CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. })) => true,
+        (
+            CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
+        ) => true,
 
+        // Prefer specializing candidates over specialized candidates.
         (CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => {
-            tcx.specializes((other_def_id, victim_def_id))
-                && other.result.value.certainty == Certainty::Yes
+            victim.goal().infcx().tcx.specializes((other_def_id, victim_def_id))
         }
 
         _ => false,
     }
 }
 
+fn to_selection<'tcx>(
+    span: Span,
+    cand: inspect::InspectCandidate<'_, 'tcx>,
+) -> Option<Selection<'tcx>> {
+    if let Certainty::Maybe(..) = cand.shallow_certainty() {
+        return None;
+    }
+
+    let make_nested = || {
+        cand.instantiate_nested_goals(span)
+            .into_iter()
+            .map(|nested| {
+                Obligation::new(
+                    nested.infcx().tcx,
+                    ObligationCause::dummy_with_span(span),
+                    nested.goal().param_env,
+                    nested.goal().predicate,
+                )
+            })
+            .collect()
+    };
+
+    Some(match cand.kind() {
+        ProbeKind::TraitCandidate { source, result: _ } => match source {
+            CandidateSource::Impl(impl_def_id) => {
+                // FIXME: Remove this in favor of storing this in the tree
+                // For impl candidates, we do the rematch manually to compute the args.
+                ImplSource::UserDefined(rematch_impl(cand.goal(), impl_def_id, span))
+            }
+            CandidateSource::BuiltinImpl(builtin) => ImplSource::Builtin(builtin, make_nested()),
+            CandidateSource::ParamEnv(_) => ImplSource::Param(make_nested()),
+            CandidateSource::AliasBound => {
+                ImplSource::Builtin(BuiltinImplSource::Misc, make_nested())
+            }
+            CandidateSource::CoherenceUnknowable => {
+                span_bug!(span, "didn't expect to select an unknowable candidate")
+            }
+        },
+        ProbeKind::TryNormalizeNonRigid { result: _ }
+        | ProbeKind::NormalizedSelfTyAssembly
+        | ProbeKind::UnsizeAssembly
+        | ProbeKind::UpcastProjectionCompatibility
+        | ProbeKind::OpaqueTypeStorageLookup { result: _ }
+        | ProbeKind::Root { result: _ } => {
+            span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
+        }
+    })
+}
+
 fn rematch_impl<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
+    goal: &inspect::InspectGoal<'_, 'tcx>,
     impl_def_id: DefId,
-) -> SelectionResult<'tcx, Selection<'tcx>> {
-    let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
+    span: Span,
+) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
+    let infcx = goal.infcx();
+    let goal_trait_ref = infcx
+        .enter_forall_and_leak_universe(goal.goal().predicate.to_opt_poly_trait_pred().unwrap())
+        .trait_ref;
+
+    let args = infcx.fresh_args_for_item(span, impl_def_id);
     let impl_trait_ref =
         infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args);
 
-    let mut nested = infcx
-        .at(&ObligationCause::dummy(), goal.param_env)
-        // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
-        .eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref)
-        .map_err(|_| SelectionError::Unimplemented)?
-        .into_obligations();
+    let InferOk { value: (), obligations: mut nested } = infcx
+        .at(&ObligationCause::dummy_with_span(span), goal.goal().param_env)
+        .eq(DefineOpaqueTypes::Yes, goal_trait_ref, impl_trait_ref)
+        .expect("rematching impl failed");
+
+    // FIXME(-Znext-solver=coinductive): We need to add supertraits here eventually.
 
     nested.extend(
         infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map(
-            |(pred, _)| Obligation::new(infcx.tcx, ObligationCause::dummy(), goal.param_env, pred),
-        ),
-    );
-
-    Ok(Some(ImplSource::UserDefined(ImplSourceUserDefinedData { impl_def_id, args, nested })))
-}
-
-/// The `Unsize` trait is particularly important to coercion, so we try rematch it.
-/// NOTE: This must stay in sync with `consider_builtin_unsize_candidate` in trait
-/// goal assembly in the solver, both for soundness and in order to avoid ICEs.
-fn rematch_unsize<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
-    source: BuiltinImplSource,
-    certainty: Certainty,
-) -> SelectionResult<'tcx, Selection<'tcx>> {
-    let tcx = infcx.tcx;
-    let mut nested = vec![];
-    let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested);
-    let b_ty = structurally_normalize(
-        goal.predicate.trait_ref.args.type_at(1),
-        infcx,
-        goal.param_env,
-        &mut nested,
-    );
-
-    match (a_ty.kind(), b_ty.kind()) {
-        // Don't try to coerce `?0` to `dyn Trait`
-        (ty::Infer(ty::TyVar(_)), _) | (_, ty::Infer(ty::TyVar(_))) => Ok(None),
-        // Stall any ambiguous upcasting goals, since we can't rematch those
-        (ty::Dynamic(_, _, ty::Dyn), ty::Dynamic(_, _, ty::Dyn)) => match certainty {
-            Certainty::Yes => Ok(Some(ImplSource::Builtin(source, nested))),
-            _ => Ok(None),
-        },
-        // `T` -> `dyn Trait` upcasting
-        (_, &ty::Dynamic(data, region, ty::Dyn)) => {
-            // Check that the type implements all of the predicates of the def-id.
-            // (i.e. the principal, all of the associated types match, and any auto traits)
-            nested.extend(data.iter().map(|pred| {
+            |(clause, _)| {
                 Obligation::new(
                     infcx.tcx,
-                    ObligationCause::dummy(),
-                    goal.param_env,
-                    pred.with_self_ty(tcx, a_ty),
+                    ObligationCause::dummy_with_span(span),
+                    goal.goal().param_env,
+                    clause,
                 )
-            }));
-            // The type must be Sized to be unsized.
-            let sized_def_id = tcx.require_lang_item(hir::LangItem::Sized, None);
-            nested.push(Obligation::new(
-                infcx.tcx,
-                ObligationCause::dummy(),
-                goal.param_env,
-                ty::TraitRef::new(tcx, sized_def_id, [a_ty]),
-            ));
-            // The type must outlive the lifetime of the `dyn` we're unsizing into.
-            nested.push(Obligation::new(
-                infcx.tcx,
-                ObligationCause::dummy(),
-                goal.param_env,
-                ty::OutlivesPredicate(a_ty, region),
-            ));
-
-            Ok(Some(ImplSource::Builtin(source, nested)))
-        }
-        // `[T; n]` -> `[T]` unsizing
-        (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => {
-            nested.extend(
-                infcx
-                    .at(&ObligationCause::dummy(), goal.param_env)
-                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
-                    .eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty)
-                    .expect("expected rematch to succeed")
-                    .into_obligations(),
-            );
-
-            Ok(Some(ImplSource::Builtin(source, nested)))
-        }
-        // Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
-        (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
-            if a_def.is_struct() && a_def.did() == b_def.did() =>
-        {
-            let unsizing_params = tcx.unsizing_params_for_adt(a_def.did());
-            // We must be unsizing some type parameters. This also implies
-            // that the struct has a tail field.
-            if unsizing_params.is_empty() {
-                bug!("expected rematch to succeed")
-            }
-
-            let tail_field = a_def
-                .non_enum_variant()
-                .fields
-                .raw
-                .last()
-                .expect("expected unsized ADT to have a tail field");
-            let tail_field_ty = tcx.type_of(tail_field.did);
-
-            let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
-            let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
-
-            // Instantiate just the unsizing params from B into A. The type after
-            // this instantiation must be equal to B. This is so we don't unsize
-            // unrelated type parameters.
-            let new_a_args = tcx.mk_args_from_iter(
-                a_args
-                    .iter()
-                    .enumerate()
-                    .map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { a }),
-            );
-            let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_args);
-
-            nested.extend(
-                infcx
-                    .at(&ObligationCause::dummy(), goal.param_env)
-                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
-                    .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
-                    .expect("expected rematch to succeed")
-                    .into_obligations(),
-            );
-
-            // Finally, we require that `TailA: Unsize<TailB>` for the tail field
-            // types.
-            nested.push(Obligation::new(
-                tcx,
-                ObligationCause::dummy(),
-                goal.param_env,
-                ty::TraitRef::new(tcx, goal.predicate.def_id(), [a_tail_ty, b_tail_ty]),
-            ));
-
-            Ok(Some(ImplSource::Builtin(source, nested)))
-        }
-        // Tuple unsizing `(.., T)` -> `(.., U)` where `T: Unsize<U>`
-        (&ty::Tuple(a_tys), &ty::Tuple(b_tys))
-            if a_tys.len() == b_tys.len() && !a_tys.is_empty() =>
-        {
-            let (a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
-            let b_last_ty = b_tys.last().unwrap();
-
-            // Instantiate just the tail field of B., and require that they're equal.
-            let unsized_a_ty =
-                Ty::new_tup_from_iter(tcx, a_rest_tys.iter().chain([b_last_ty]).copied());
-            nested.extend(
-                infcx
-                    .at(&ObligationCause::dummy(), goal.param_env)
-                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
-                    .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
-                    .expect("expected rematch to succeed")
-                    .into_obligations(),
-            );
-
-            // Similar to ADTs, require that we can unsize the tail.
-            nested.push(Obligation::new(
-                tcx,
-                ObligationCause::dummy(),
-                goal.param_env,
-                ty::TraitRef::new(tcx, goal.predicate.def_id(), [*a_last_ty, *b_last_ty]),
-            ));
-
-            // We need to be able to detect tuple unsizing to require its feature gate.
-            assert_eq!(
-                source,
-                BuiltinImplSource::TupleUnsizing,
-                "compiler-errors wants to know if this can ever be triggered..."
-            );
-            Ok(Some(ImplSource::Builtin(source, nested)))
-        }
-        _ => {
-            assert_ne!(certainty, Certainty::Yes);
-            Ok(None)
-        }
-    }
-}
+            },
+        ),
+    );
 
-fn structurally_normalize<'tcx>(
-    ty: Ty<'tcx>,
-    infcx: &InferCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    nested: &mut Vec<PredicateObligation<'tcx>>,
-) -> Ty<'tcx> {
-    if matches!(ty.kind(), ty::Alias(..)) {
-        let mut engine = <dyn TraitEngine<'tcx>>::new(infcx);
-        let normalized_ty = infcx
-            .at(&ObligationCause::dummy(), param_env)
-            .structurally_normalize(ty, &mut *engine)
-            .expect("normalization shouldn't fail if we got to here");
-        nested.extend(engine.pending_obligations());
-        normalized_ty
-    } else {
-        ty
-    }
+    ImplSourceUserDefinedData { impl_def_id, nested, args }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 56c32d3d539..97de25295b8 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -11,35 +11,92 @@
 
 use rustc_ast_ir::try_visit;
 use rustc_ast_ir::visit::VisitorResult;
-use rustc_infer::infer::InferCtxt;
+use rustc_infer::infer::resolve::EagerResolver;
+use rustc_infer::infer::type_variable::TypeVariableOrigin;
+use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
+use rustc_macros::extension;
+use rustc_middle::infer::unify_key::ConstVariableOrigin;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{inspect, QueryResult};
 use rustc_middle::traits::solve::{Certainty, Goal};
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty;
+use rustc_middle::ty::TypeFoldable;
+use rustc_span::{Span, DUMMY_SP};
 
-use crate::solve::inspect::ProofTreeBuilder;
+use crate::solve::eval_ctxt::canonical;
+use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource};
 use crate::solve::{GenerateProofTree, InferCtxtEvalExt};
+use crate::traits::ObligationCtxt;
+
+pub struct InspectConfig {
+    pub max_depth: usize,
+}
 
 pub struct InspectGoal<'a, 'tcx> {
     infcx: &'a InferCtxt<'tcx>,
     depth: usize,
-    orig_values: &'a [ty::GenericArg<'tcx>],
+    orig_values: Vec<ty::GenericArg<'tcx>>,
     goal: Goal<'tcx, ty::Predicate<'tcx>>,
-    evaluation: &'a inspect::GoalEvaluation<'tcx>,
+    result: Result<Certainty, NoSolution>,
+    evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>,
+    normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
+}
+
+/// The expected term of a `NormalizesTo` goal gets replaced
+/// with an unconstrained inference variable when computing
+/// `NormalizesTo` goals and we return the nested goals to the
+/// caller, who also equates the actual term with the expected.
+///
+/// This is an implementation detail of the trait solver and
+/// not something we want to leak to users. We therefore
+/// treat `NormalizesTo` goals as if they apply the expected
+/// type at the end of each candidate.
+#[derive(Copy, Clone)]
+struct NormalizesToTermHack<'tcx> {
+    term: ty::Term<'tcx>,
+    unconstrained_term: ty::Term<'tcx>,
+}
+
+impl<'tcx> NormalizesToTermHack<'tcx> {
+    /// Relate the `term` with the new `unconstrained_term` created
+    /// when computing the proof tree for this `NormalizesTo` goals.
+    /// This handles nested obligations.
+    fn constrain(
+        self,
+        infcx: &InferCtxt<'tcx>,
+        span: Span,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> Result<Certainty, NoSolution> {
+        infcx
+            .at(&ObligationCause::dummy_with_span(span), param_env)
+            .eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term)
+            .map_err(|_| NoSolution)
+            .and_then(|InferOk { value: (), obligations }| {
+                let ocx = ObligationCtxt::new(infcx);
+                ocx.register_obligations(obligations);
+                let errors = ocx.select_all_or_error();
+                if errors.is_empty() {
+                    Ok(Certainty::Yes)
+                } else if errors.iter().all(|e| !e.is_true_error()) {
+                    Ok(Certainty::AMBIGUOUS)
+                } else {
+                    Err(NoSolution)
+                }
+            })
+    }
 }
 
 pub struct InspectCandidate<'a, 'tcx> {
     goal: &'a InspectGoal<'a, 'tcx>,
     kind: inspect::ProbeKind<'tcx>,
     nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
+    final_state: inspect::CanonicalState<'tcx, ()>,
     result: QueryResult<'tcx>,
+    shallow_certainty: Certainty,
 }
 
 impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
-    pub fn infcx(&self) -> &'a InferCtxt<'tcx> {
-        self.goal.infcx
-    }
-
     pub fn kind(&self) -> inspect::ProbeKind<'tcx> {
         self.kind
     }
@@ -48,55 +105,112 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
         self.result.map(|c| c.value.certainty)
     }
 
-    /// Visit the nested goals of this candidate.
+    pub fn goal(&self) -> &'a InspectGoal<'a, 'tcx> {
+        self.goal
+    }
+
+    /// Certainty passed into `evaluate_added_goals_and_make_canonical_response`.
     ///
-    /// FIXME(@lcnr): we have to slightly adapt this API
-    /// to also use it to compute the most relevant goal
-    /// for fulfillment errors. Will do that once we actually
-    /// need it.
-    pub fn visit_nested<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
-        // HACK: An arbitrary cutoff to avoid dealing with overflow and cycles.
-        if self.goal.depth <= 10 {
-            let infcx = self.goal.infcx;
-            infcx.probe(|_| {
-                let mut instantiated_goals = vec![];
-                for goal in &self.nested_goals {
-                    let goal = ProofTreeBuilder::instantiate_canonical_state(
-                        infcx,
-                        self.goal.goal.param_env,
-                        self.goal.orig_values,
-                        *goal,
-                    );
-                    instantiated_goals.push(goal);
-                }
+    /// If this certainty is `Yes`, then we must be confident that the candidate
+    /// must hold iff it's nested goals hold. This is not true if the certainty is
+    /// `Maybe(..)`, which suggests we forced ambiguity instead.
+    ///
+    /// This is *not* the certainty of the candidate's full nested evaluation, which
+    /// can be accessed with [`Self::result`] instead.
+    pub fn shallow_certainty(&self) -> Certainty {
+        self.shallow_certainty
+    }
+
+    /// Visit all nested goals of this candidate without rolling
+    /// back their inference constraints. This function modifies
+    /// the state of the `infcx`.
+    pub fn visit_nested_no_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
+        if self.goal.depth < visitor.config().max_depth {
+            for goal in self.instantiate_nested_goals(visitor.span()) {
+                try_visit!(visitor.visit_goal(&goal));
+            }
+        }
 
-                for goal in instantiated_goals.iter().copied() {
-                    // We need to be careful with `NormalizesTo` goals as the
-                    // expected term has to be replaced with an unconstrained
-                    // inference variable.
-                    if let Some(kind) = goal.predicate.kind().no_bound_vars()
-                        && let ty::PredicateKind::NormalizesTo(predicate) = kind
-                        && !predicate.alias.is_opaque(infcx.tcx)
-                    {
-                        // FIXME: We currently skip these goals as
-                        // `fn evaluate_root_goal` ICEs if there are any
-                        // `NestedNormalizationGoals`.
-                        continue;
+        V::Result::output()
+    }
+
+    /// Instantiate the nested goals for the candidate without rolling back their
+    /// inference constraints. This function modifies the state of the `infcx`.
+    pub fn instantiate_nested_goals(&self, span: Span) -> Vec<InspectGoal<'a, 'tcx>> {
+        let infcx = self.goal.infcx;
+        let param_env = self.goal.goal.param_env;
+        let mut orig_values = self.goal.orig_values.to_vec();
+        let instantiated_goals: Vec<_> = self
+            .nested_goals
+            .iter()
+            .map(|goal| {
+                canonical::instantiate_canonical_state(
+                    infcx,
+                    span,
+                    param_env,
+                    &mut orig_values,
+                    *goal,
+                )
+            })
+            .collect();
+
+        let () = canonical::instantiate_canonical_state(
+            infcx,
+            span,
+            param_env,
+            &mut orig_values,
+            self.final_state,
+        );
+
+        if let Some(term_hack) = self.goal.normalizes_to_term_hack {
+            // FIXME: We ignore the expected term of `NormalizesTo` goals
+            // when computing the result of its candidates. This is
+            // scuffed.
+            let _ = term_hack.constrain(infcx, span, param_env);
+        }
+
+        instantiated_goals
+            .into_iter()
+            .map(|goal| match goal.predicate.kind().no_bound_vars() {
+                Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
+                    let unconstrained_term = match term.unpack() {
+                        ty::TermKind::Ty(_) => infcx
+                            .next_ty_var(TypeVariableOrigin { param_def_id: None, span })
+                            .into(),
+                        ty::TermKind::Const(ct) => infcx
+                            .next_const_var(
+                                ct.ty(),
+                                ConstVariableOrigin { param_def_id: None, span },
+                            )
+                            .into(),
                     };
-                    let (_, proof_tree) = infcx.evaluate_root_goal(goal, GenerateProofTree::Yes);
-                    let proof_tree = proof_tree.unwrap();
-                    try_visit!(visitor.visit_goal(&InspectGoal::new(
+                    let goal =
+                        goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
+                    let proof_tree = EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| {
+                        ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal)
+                    })
+                    .1;
+                    InspectGoal::new(
                         infcx,
                         self.goal.depth + 1,
-                        &proof_tree,
-                    )));
+                        proof_tree.unwrap(),
+                        Some(NormalizesToTermHack { term, unconstrained_term }),
+                    )
                 }
-
-                V::Result::output()
+                _ => InspectGoal::new(
+                    infcx,
+                    self.goal.depth + 1,
+                    infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(),
+                    None,
+                ),
             })
-        } else {
-            V::Result::output()
-        }
+            .collect()
+    }
+
+    /// Visit all nested goals of this candidate, rolling back
+    /// all inference constraints.
+    pub fn visit_nested_in_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
+        self.goal.infcx.probe(|_| self.visit_nested_no_probe(visitor))
     }
 }
 
@@ -110,7 +224,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
     }
 
     pub fn result(&self) -> Result<Certainty, NoSolution> {
-        self.evaluation.evaluation.result.map(|c| c.value.certainty)
+        self.result
     }
 
     fn candidates_recur(
@@ -119,6 +233,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
         nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
         probe: &inspect::Probe<'tcx>,
     ) {
+        let mut shallow_certainty = None;
         for step in &probe.steps {
             match step {
                 &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
@@ -130,6 +245,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                     self.candidates_recur(candidates, nested_goals, probe);
                     nested_goals.truncate(num_goals);
                 }
+                inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
+                    assert_eq!(shallow_certainty.replace(*c), None);
+                }
                 inspect::ProbeStep::EvaluateGoals(_) => (),
             }
         }
@@ -138,42 +256,36 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
             inspect::ProbeKind::NormalizedSelfTyAssembly
             | inspect::ProbeKind::UnsizeAssembly
             | inspect::ProbeKind::UpcastProjectionCompatibility => (),
-            // We add a candidate for the root evaluation if there
+
+            // We add a candidate even for the root evaluation if there
             // is only one way to prove a given goal, e.g. for `WellFormed`.
-            //
-            // FIXME: This is currently wrong if we don't even try any
-            // candidates, e.g. for a trait goal, as in this case `candidates` is
-            // actually supposed to be empty.
-            inspect::ProbeKind::Root { result } => {
-                if candidates.is_empty() {
+            inspect::ProbeKind::Root { result }
+            | inspect::ProbeKind::TryNormalizeNonRigid { result }
+            | inspect::ProbeKind::TraitCandidate { source: _, result }
+            | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
+                // We only add a candidate if `shallow_certainty` was set, which means
+                // that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
+                if let Some(shallow_certainty) = shallow_certainty {
                     candidates.push(InspectCandidate {
                         goal: self,
                         kind: probe.kind,
                         nested_goals: nested_goals.clone(),
+                        final_state: probe.final_state,
                         result,
+                        shallow_certainty,
                     });
                 }
             }
-            inspect::ProbeKind::TryNormalizeNonRigid { result }
-            | inspect::ProbeKind::MiscCandidate { name: _, result }
-            | inspect::ProbeKind::TraitCandidate { source: _, result } => {
-                candidates.push(InspectCandidate {
-                    goal: self,
-                    kind: probe.kind,
-                    nested_goals: nested_goals.clone(),
-                    result,
-                });
-            }
         }
     }
 
     pub fn candidates(&'a self) -> Vec<InspectCandidate<'a, 'tcx>> {
         let mut candidates = vec![];
-        let last_eval_step = match self.evaluation.evaluation.kind {
+        let last_eval_step = match self.evaluation_kind {
             inspect::CanonicalGoalEvaluationKind::Overflow
             | inspect::CanonicalGoalEvaluationKind::CycleInStack
             | inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit => {
-                warn!("unexpected root evaluation: {:?}", self.evaluation);
+                warn!("unexpected root evaluation: {:?}", self.evaluation_kind);
                 return vec![];
             }
             inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } => {
@@ -191,20 +303,44 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
         candidates
     }
 
+    /// Returns the single candidate applicable for the current goal, if it exists.
+    ///
+    /// Returns `None` if there are either no or multiple applicable candidates.
+    pub fn unique_applicable_candidate(&'a self) -> Option<InspectCandidate<'a, 'tcx>> {
+        // FIXME(-Znext-solver): This does not handle impl candidates
+        // hidden by env candidates.
+        let mut candidates = self.candidates();
+        candidates.retain(|c| c.result().is_ok());
+        candidates.pop().filter(|_| candidates.is_empty())
+    }
+
     fn new(
         infcx: &'a InferCtxt<'tcx>,
         depth: usize,
-        root: &'a inspect::GoalEvaluation<'tcx>,
+        root: inspect::GoalEvaluation<'tcx>,
+        normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
     ) -> Self {
-        match root.kind {
-            inspect::GoalEvaluationKind::Root { ref orig_values } => InspectGoal {
-                infcx,
-                depth,
-                orig_values,
-                goal: infcx.resolve_vars_if_possible(root.uncanonicalized_goal),
-                evaluation: root,
-            },
-            inspect::GoalEvaluationKind::Nested { .. } => unreachable!(),
+        let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
+        let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() };
+
+        let result = evaluation.result.and_then(|ok| {
+            if let Some(term_hack) = normalizes_to_term_hack {
+                infcx
+                    .probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env))
+                    .map(|certainty| ok.value.certainty.unify_with(certainty))
+            } else {
+                Ok(ok.value.certainty)
+            }
+        });
+
+        InspectGoal {
+            infcx,
+            depth,
+            orig_values,
+            goal: uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)),
+            result,
+            evaluation_kind: evaluation.kind,
+            normalizes_to_term_hack,
         }
     }
 }
@@ -213,6 +349,12 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
 pub trait ProofTreeVisitor<'tcx> {
     type Result: VisitorResult = ();
 
+    fn span(&self) -> Span;
+
+    fn config(&self) -> InspectConfig {
+        InspectConfig { max_depth: 10 }
+    }
+
     fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result;
 }
 
@@ -223,10 +365,8 @@ impl<'tcx> InferCtxt<'tcx> {
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
         visitor: &mut V,
     ) -> V::Result {
-        self.probe(|_| {
-            let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
-            let proof_tree = proof_tree.unwrap();
-            visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree))
-        })
+        let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
+        let proof_tree = proof_tree.unwrap();
+        visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None))
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
index 43c76cc5f4a..466d0d80060 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
@@ -5,6 +5,8 @@
 //! see the comment on [ProofTreeBuilder].
 use std::mem;
 
+use rustc_infer::infer::InferCtxt;
+use rustc_middle::infer::canonical::CanonicalVarValues;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
     CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult,
@@ -12,7 +14,8 @@ use rustc_middle::traits::solve::{
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::DumpSolverProofTree;
 
-use crate::solve::{self, inspect, EvalCtxt, GenerateProofTree};
+use crate::solve::eval_ctxt::canonical;
+use crate::solve::{self, inspect, GenerateProofTree};
 
 /// The core data structure when building proof trees.
 ///
@@ -47,9 +50,7 @@ enum DebugSolver<'tcx> {
     Root,
     GoalEvaluation(WipGoalEvaluation<'tcx>),
     CanonicalGoalEvaluation(WipCanonicalGoalEvaluation<'tcx>),
-    AddedGoalsEvaluation(WipAddedGoalsEvaluation<'tcx>),
     GoalEvaluationStep(WipGoalEvaluationStep<'tcx>),
-    Probe(WipProbe<'tcx>),
 }
 
 impl<'tcx> From<WipGoalEvaluation<'tcx>> for DebugSolver<'tcx> {
@@ -64,24 +65,12 @@ impl<'tcx> From<WipCanonicalGoalEvaluation<'tcx>> for DebugSolver<'tcx> {
     }
 }
 
-impl<'tcx> From<WipAddedGoalsEvaluation<'tcx>> for DebugSolver<'tcx> {
-    fn from(g: WipAddedGoalsEvaluation<'tcx>) -> DebugSolver<'tcx> {
-        DebugSolver::AddedGoalsEvaluation(g)
-    }
-}
-
 impl<'tcx> From<WipGoalEvaluationStep<'tcx>> for DebugSolver<'tcx> {
     fn from(g: WipGoalEvaluationStep<'tcx>) -> DebugSolver<'tcx> {
         DebugSolver::GoalEvaluationStep(g)
     }
 }
 
-impl<'tcx> From<WipProbe<'tcx>> for DebugSolver<'tcx> {
-    fn from(p: WipProbe<'tcx>) -> DebugSolver<'tcx> {
-        DebugSolver::Probe(p)
-    }
-}
-
 #[derive(Eq, PartialEq, Debug)]
 struct WipGoalEvaluation<'tcx> {
     pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
@@ -184,12 +173,41 @@ impl<'tcx> WipAddedGoalsEvaluation<'tcx> {
 
 #[derive(Eq, PartialEq, Debug)]
 struct WipGoalEvaluationStep<'tcx> {
+    /// Unlike `EvalCtxt::var_values`, we append a new
+    /// generic arg here whenever we create a new inference
+    /// variable.
+    ///
+    /// This is necessary as we otherwise don't unify these
+    /// vars when instantiating multiple `CanonicalState`.
+    var_values: Vec<ty::GenericArg<'tcx>>,
     instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
-
+    probe_depth: usize,
     evaluation: WipProbe<'tcx>,
 }
 
 impl<'tcx> WipGoalEvaluationStep<'tcx> {
+    fn current_evaluation_scope(&mut self) -> &mut WipProbe<'tcx> {
+        let mut current = &mut self.evaluation;
+        for _ in 0..self.probe_depth {
+            match current.steps.last_mut() {
+                Some(WipProbeStep::NestedProbe(p)) => current = p,
+                _ => bug!(),
+            }
+        }
+        current
+    }
+
+    fn added_goals_evaluation(&mut self) -> &mut WipAddedGoalsEvaluation<'tcx> {
+        let mut current = &mut self.evaluation;
+        loop {
+            match current.steps.last_mut() {
+                Some(WipProbeStep::NestedProbe(p)) => current = p,
+                Some(WipProbeStep::EvaluateGoals(evaluation)) => return evaluation,
+                _ => bug!(),
+            }
+        }
+    }
+
     fn finalize(self) -> inspect::GoalEvaluationStep<'tcx> {
         let evaluation = self.evaluation.finalize();
         match evaluation.kind {
@@ -202,8 +220,10 @@ impl<'tcx> WipGoalEvaluationStep<'tcx> {
 
 #[derive(Eq, PartialEq, Debug)]
 struct WipProbe<'tcx> {
-    pub steps: Vec<WipProbeStep<'tcx>>,
-    pub kind: Option<inspect::ProbeKind<'tcx>>,
+    initial_num_var_values: usize,
+    steps: Vec<WipProbeStep<'tcx>>,
+    kind: Option<inspect::ProbeKind<'tcx>>,
+    final_state: Option<inspect::CanonicalState<'tcx, ()>>,
 }
 
 impl<'tcx> WipProbe<'tcx> {
@@ -211,6 +231,7 @@ impl<'tcx> WipProbe<'tcx> {
         inspect::Probe {
             steps: self.steps.into_iter().map(WipProbeStep::finalize).collect(),
             kind: self.kind.unwrap(),
+            final_state: self.final_state.unwrap(),
         }
     }
 }
@@ -220,6 +241,7 @@ enum WipProbeStep<'tcx> {
     AddGoal(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>),
     EvaluateGoals(WipAddedGoalsEvaluation<'tcx>),
     NestedProbe(WipProbe<'tcx>),
+    MakeCanonicalResponse { shallow_certainty: Certainty },
 }
 
 impl<'tcx> WipProbeStep<'tcx> {
@@ -228,6 +250,9 @@ impl<'tcx> WipProbeStep<'tcx> {
             WipProbeStep::AddGoal(source, goal) => inspect::ProbeStep::AddGoal(source, goal),
             WipProbeStep::EvaluateGoals(eval) => inspect::ProbeStep::EvaluateGoals(eval.finalize()),
             WipProbeStep::NestedProbe(probe) => inspect::ProbeStep::NestedProbe(probe.finalize()),
+            WipProbeStep::MakeCanonicalResponse { shallow_certainty } => {
+                inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty }
+            }
         }
     }
 }
@@ -245,6 +270,12 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
         self.state.as_deref_mut()
     }
 
+    pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<'tcx> {
+        let mut nested = ProofTreeBuilder { state: self.state.take() };
+        nested.enter_probe();
+        nested
+    }
+
     pub fn finalize(self) -> Option<inspect::GoalEvaluation<'tcx>> {
         match *self.state? {
             DebugSolver::GoalEvaluation(wip_goal_evaluation) => {
@@ -362,11 +393,14 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
         if let Some(this) = self.as_mut() {
             match (this, *goal_evaluation.state.unwrap()) {
                 (
-                    DebugSolver::AddedGoalsEvaluation(WipAddedGoalsEvaluation {
-                        evaluations, ..
-                    }),
+                    DebugSolver::GoalEvaluationStep(state),
                     DebugSolver::GoalEvaluation(goal_evaluation),
-                ) => evaluations.last_mut().unwrap().push(goal_evaluation),
+                ) => state
+                    .added_goals_evaluation()
+                    .evaluations
+                    .last_mut()
+                    .unwrap()
+                    .push(goal_evaluation),
                 (this @ DebugSolver::Root, goal_evaluation) => *this = goal_evaluation,
                 _ => unreachable!(),
             }
@@ -375,13 +409,22 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
 
     pub fn new_goal_evaluation_step(
         &mut self,
+        var_values: CanonicalVarValues<'tcx>,
         instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
     ) -> ProofTreeBuilder<'tcx> {
         self.nested(|| WipGoalEvaluationStep {
+            var_values: var_values.var_values.to_vec(),
             instantiated_goal,
-            evaluation: WipProbe { steps: vec![], kind: None },
+            evaluation: WipProbe {
+                initial_num_var_values: var_values.len(),
+                steps: vec![],
+                kind: None,
+                final_state: None,
+            },
+            probe_depth: 0,
         })
     }
+
     pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<'tcx>) {
         if let Some(this) = self.as_mut() {
             match (this, *goal_evaluation_step.state.unwrap()) {
@@ -396,112 +439,159 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
         }
     }
 
-    pub fn new_probe(&mut self) -> ProofTreeBuilder<'tcx> {
-        self.nested(|| WipProbe { steps: vec![], kind: None })
+    pub fn add_var_value<T: Into<ty::GenericArg<'tcx>>>(&mut self, arg: T) {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                state.var_values.push(arg.into());
+            }
+            Some(s) => bug!("tried to add var values to {s:?}"),
+        }
+    }
+
+    pub fn enter_probe(&mut self) {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                let initial_num_var_values = state.var_values.len();
+                state.current_evaluation_scope().steps.push(WipProbeStep::NestedProbe(WipProbe {
+                    initial_num_var_values,
+                    steps: vec![],
+                    kind: None,
+                    final_state: None,
+                }));
+                state.probe_depth += 1;
+            }
+            Some(s) => bug!("tried to start probe to {s:?}"),
+        }
     }
 
     pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<'tcx>) {
-        if let Some(this) = self.as_mut() {
-            match this {
-                DebugSolver::Probe(this) => {
-                    assert_eq!(this.kind.replace(probe_kind), None)
-                }
-                _ => unreachable!(),
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                let prev = state.current_evaluation_scope().kind.replace(probe_kind);
+                assert_eq!(prev, None);
             }
+            _ => bug!(),
         }
     }
 
-    pub fn add_normalizes_to_goal(
-        ecx: &mut EvalCtxt<'_, 'tcx>,
-        goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
+    pub fn probe_final_state(
+        &mut self,
+        infcx: &InferCtxt<'tcx>,
+        max_input_universe: ty::UniverseIndex,
     ) {
-        if ecx.inspect.is_noop() {
-            return;
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                let final_state = canonical::make_canonical_state(
+                    infcx,
+                    &state.var_values,
+                    max_input_universe,
+                    (),
+                );
+                let prev = state.current_evaluation_scope().final_state.replace(final_state);
+                assert_eq!(prev, None);
+            }
+            _ => bug!(),
         }
+    }
 
-        Self::add_goal(ecx, GoalSource::Misc, goal.with(ecx.tcx(), goal.predicate));
+    pub fn add_normalizes_to_goal(
+        &mut self,
+        infcx: &InferCtxt<'tcx>,
+        max_input_universe: ty::UniverseIndex,
+        goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
+    ) {
+        self.add_goal(
+            infcx,
+            max_input_universe,
+            GoalSource::Misc,
+            goal.with(infcx.tcx, goal.predicate),
+        );
     }
 
     pub fn add_goal(
-        ecx: &mut EvalCtxt<'_, 'tcx>,
+        &mut self,
+        infcx: &InferCtxt<'tcx>,
+        max_input_universe: ty::UniverseIndex,
         source: GoalSource,
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
     ) {
-        // Can't use `if let Some(this) = ecx.inspect.as_mut()` here because
-        // we have to immutably use the `EvalCtxt` for `make_canonical_state`.
-        if ecx.inspect.is_noop() {
-            return;
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                let goal = canonical::make_canonical_state(
+                    infcx,
+                    &state.var_values,
+                    max_input_universe,
+                    goal,
+                );
+                state.current_evaluation_scope().steps.push(WipProbeStep::AddGoal(source, goal))
+            }
+            _ => bug!(),
         }
+    }
 
-        let goal = Self::make_canonical_state(ecx, goal);
-
-        match ecx.inspect.as_mut().unwrap() {
-            DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
-                evaluation: WipProbe { steps, .. },
-                ..
-            })
-            | DebugSolver::Probe(WipProbe { steps, .. }) => {
-                steps.push(WipProbeStep::AddGoal(source, goal))
+    pub fn make_canonical_response(&mut self, shallow_certainty: Certainty) {
+        match self.as_mut() {
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                state
+                    .current_evaluation_scope()
+                    .steps
+                    .push(WipProbeStep::MakeCanonicalResponse { shallow_certainty });
             }
-            s => unreachable!("tried to add {goal:?} to {s:?}"),
+            None => {}
+            _ => {}
         }
     }
 
-    pub fn finish_probe(&mut self, probe: ProofTreeBuilder<'tcx>) {
-        if let Some(this) = self.as_mut() {
-            match (this, *probe.state.unwrap()) {
-                (
-                    DebugSolver::Probe(WipProbe { steps, .. })
-                    | DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
-                        evaluation: WipProbe { steps, .. },
-                        ..
-                    }),
-                    DebugSolver::Probe(probe),
-                ) => steps.push(WipProbeStep::NestedProbe(probe)),
-                _ => unreachable!(),
+    pub fn finish_probe(mut self) -> ProofTreeBuilder<'tcx> {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                assert_ne!(state.probe_depth, 0);
+                let num_var_values = state.current_evaluation_scope().initial_num_var_values;
+                state.var_values.truncate(num_var_values);
+                state.probe_depth -= 1;
             }
+            _ => bug!(),
         }
-    }
 
-    pub fn new_evaluate_added_goals(&mut self) -> ProofTreeBuilder<'tcx> {
-        self.nested(|| WipAddedGoalsEvaluation { evaluations: vec![], result: None })
+        self
     }
 
-    pub fn evaluate_added_goals_loop_start(&mut self) {
-        if let Some(this) = self.as_mut() {
-            match this {
-                DebugSolver::AddedGoalsEvaluation(this) => {
-                    this.evaluations.push(vec![]);
-                }
-                _ => unreachable!(),
+    pub fn start_evaluate_added_goals(&mut self) {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                state.current_evaluation_scope().steps.push(WipProbeStep::EvaluateGoals(
+                    WipAddedGoalsEvaluation { evaluations: vec![], result: None },
+                ));
             }
+            _ => bug!(),
         }
     }
 
-    pub fn eval_added_goals_result(&mut self, result: Result<Certainty, NoSolution>) {
-        if let Some(this) = self.as_mut() {
-            match this {
-                DebugSolver::AddedGoalsEvaluation(this) => {
-                    assert_eq!(this.result.replace(result), None);
-                }
-                _ => unreachable!(),
+    pub fn start_evaluate_added_goals_step(&mut self) {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                state.added_goals_evaluation().evaluations.push(vec![]);
             }
+            _ => bug!(),
         }
     }
 
-    pub fn added_goals_evaluation(&mut self, added_goals_evaluation: ProofTreeBuilder<'tcx>) {
-        if let Some(this) = self.as_mut() {
-            match (this, *added_goals_evaluation.state.unwrap()) {
-                (
-                    DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
-                        evaluation: WipProbe { steps, .. },
-                        ..
-                    })
-                    | DebugSolver::Probe(WipProbe { steps, .. }),
-                    DebugSolver::AddedGoalsEvaluation(added_goals_evaluation),
-                ) => steps.push(WipProbeStep::EvaluateGoals(added_goals_evaluation)),
-                _ => unreachable!(),
+    pub fn evaluate_added_goals_result(&mut self, result: Result<Certainty, NoSolution>) {
+        match self.as_mut() {
+            None => {}
+            Some(DebugSolver::GoalEvaluationStep(state)) => {
+                let prev = state.added_goals_evaluation().result.replace(result);
+                assert_eq!(prev, None);
             }
+            _ => bug!(),
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index da5cd15a10d..b2b076e28e6 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -16,6 +16,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_infer::traits::query::NoSolution;
+use rustc_macros::extension;
 use rustc_middle::infer::canonical::CanonicalVarInfos;
 use rustc_middle::traits::solve::{
     CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, QueryResult, Response,
@@ -200,18 +201,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self))]
-    fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) {
-        inspect::ProofTreeBuilder::add_normalizes_to_goal(self, goal);
-        self.nested_goals.normalizes_to_goals.push(goal);
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) {
-        inspect::ProofTreeBuilder::add_goal(self, source, goal);
-        self.nested_goals.goals.push((source, goal));
-    }
-
     #[instrument(level = "debug", skip(self, goals))]
     fn add_goals(
         &mut self,
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index c662ab23c53..dab87fffe46 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -8,11 +8,10 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::solve::inspect::ProbeKind;
+use rustc_infer::traits::solve::MaybeCause;
 use rustc_infer::traits::specialization_graph::LeafDef;
 use rustc_infer::traits::Reveal;
-use rustc_middle::traits::solve::{
-    CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult,
-};
+use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::NormalizesTo;
@@ -119,14 +118,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
+        source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if let Some(projection_pred) = assumption.as_projection_clause() {
             if projection_pred.projection_def_id() == goal.predicate.def_id() {
                 let tcx = ecx.tcx();
-                ecx.probe_misc_candidate("assumption").enter(|ecx| {
+                ecx.probe_trait_candidate(source).enter(|ecx| {
                     let assumption_projection_pred =
                         ecx.instantiate_binder_with_infer(projection_pred);
                     ecx.eq(
@@ -300,14 +300,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_error_guaranteed_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         _guar: ErrorGuaranteed,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         Err(NoSolution)
     }
 
     fn consider_auto_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         ecx.tcx().dcx().span_delayed_bug(
             ecx.tcx().def_span(goal.predicate.def_id()),
             "associated types not allowed on auto traits",
@@ -318,35 +318,35 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_trait_alias_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("trait aliases do not have associated types: {:?}", goal);
     }
 
     fn consider_builtin_sized_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`Sized` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_copy_clone_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_pointer_like_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`PointerLike` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_fn_ptr_trait_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`FnPtr` does not have an associated type: {:?}", goal);
     }
 
@@ -354,7 +354,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         goal_kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = ecx.tcx();
         let tupled_inputs_and_output =
             match structural_traits::extract_tupled_inputs_and_output_from_callable(
@@ -364,8 +364,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             )? {
                 Some(tupled_inputs_and_output) => tupled_inputs_and_output,
                 None => {
-                    return ecx
-                        .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+                    return ecx.forced_ambiguity(MaybeCause::Ambiguity);
                 }
             };
         let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
@@ -385,14 +384,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        Self::consider_implied_clause(ecx, goal, pred, [goal.with(tcx, output_is_sized_pred)])
+        Self::probe_and_consider_implied_clause(
+            ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
+            goal,
+            pred,
+            [goal.with(tcx, output_is_sized_pred)],
+        )
     }
 
     fn consider_builtin_async_fn_trait_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         goal_kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = ecx.tcx();
 
         let env_region = match goal_kind {
@@ -461,8 +466,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         // A built-in `AsyncFn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             pred,
             [goal.with(tcx, output_is_sized_pred)]
@@ -474,7 +480,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_async_fn_kind_helper_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let [
             closure_fn_kind_ty,
             goal_kind_ty,
@@ -489,7 +495,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         // Bail if the upvars haven't been constrained.
         if tupled_upvars_ty.expect_ty().is_ty_var() {
-            return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+            return ecx.forced_ambiguity(MaybeCause::Ambiguity);
         }
 
         let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else {
@@ -512,25 +518,27 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             borrow_region.expect_region(),
         );
 
-        ecx.instantiate_normalizes_to_term(goal, upvars_ty.into());
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+            ecx.instantiate_normalizes_to_term(goal, upvars_ty.into());
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
     }
 
     fn consider_builtin_tuple_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`Tuple` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_pointee_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = ecx.tcx();
         let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
         assert_eq!(metadata_def_id, goal.predicate.def_id());
-        ecx.probe_misc_candidate("builtin pointee").enter(|ecx| {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let metadata_ty = match goal.predicate.self_ty().kind() {
                 ty::Bool
                 | ty::Char
@@ -609,7 +617,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_future_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let ty::Coroutine(def_id, args) = *self_ty.kind() else {
             return Err(NoSolution);
@@ -623,8 +631,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         let term = args.as_coroutine().return_ty().into();
 
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
                 projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
@@ -640,7 +649,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let ty::Coroutine(def_id, args) = *self_ty.kind() else {
             return Err(NoSolution);
@@ -654,8 +663,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         let term = args.as_coroutine().yield_ty().into();
 
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
                 projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]),
@@ -671,14 +681,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_fused_iterator_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`FusedIterator` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_async_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let ty::Coroutine(def_id, args) = *self_ty.kind() else {
             return Err(NoSolution);
@@ -690,7 +700,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             return Err(NoSolution);
         }
 
-        ecx.probe_misc_candidate("builtin AsyncIterator kind").enter(|ecx| {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let expected_ty = ecx.next_ty_infer();
             // Take `AsyncIterator<Item = I>` and turn it into the corresponding
             // coroutine yield ty `Poll<Option<I>>`.
@@ -714,7 +724,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_coroutine_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let ty::Coroutine(def_id, args) = *self_ty.kind() else {
             return Err(NoSolution);
@@ -737,8 +747,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             bug!("unexpected associated item `<{self_ty} as Coroutine>::{name}`")
         };
 
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::ProjectionPredicate {
                 projection_ty: ty::AliasTy::new(
@@ -758,14 +769,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_structural_builtin_unsize_candidates(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
+    ) -> Vec<Candidate<'tcx>> {
         bug!("`Unsize` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_discriminant_kind_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let discriminant_ty = match *self_ty.kind() {
             ty::Bool
@@ -808,7 +819,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             ),
         };
 
-        ecx.probe_misc_candidate("builtin discriminant kind").enter(|ecx| {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             ecx.instantiate_normalizes_to_term(goal, discriminant_ty.into());
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
@@ -817,7 +828,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_async_destruct_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         let async_destructor_ty = match *self_ty.kind() {
             ty::Bool
@@ -860,7 +871,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             ),
         };
 
-        ecx.probe_misc_candidate("builtin async destruct").enter(|ecx| {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             ecx.eq(goal.param_env, goal.predicate.term, async_destructor_ty.into())
                 .expect("expected goal term to be fully unconstrained");
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
@@ -870,14 +881,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
     fn consider_builtin_destruct_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`Destruct` does not have an associated type: {:?}", goal);
     }
 
     fn consider_builtin_transmute_candidate(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         bug!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f6d12a9a013..c8cb14abb55 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -9,10 +9,9 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, Movability};
 use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::solve::MaybeCause;
 use rustc_middle::traits::solve::inspect::ProbeKind;
-use rustc_middle::traits::solve::{
-    CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult,
-};
+use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
 use rustc_middle::traits::{BuiltinImplSource, Reveal};
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
@@ -94,21 +93,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_error_guaranteed_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         _guar: ErrorGuaranteed,
-    ) -> QueryResult<'tcx> {
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+    ) -> Result<Candidate<'tcx>, NoSolution> {
+        // FIXME: don't need to enter a probe here.
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn probe_and_match_goal_against_assumption(
         ecx: &mut EvalCtxt<'_, 'tcx>,
+        source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
         then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if let Some(trait_clause) = assumption.as_trait_clause() {
             if trait_clause.def_id() == goal.predicate.def_id()
                 && trait_clause.polarity() == goal.predicate.polarity
             {
-                ecx.probe_misc_candidate("assumption").enter(|ecx| {
+                ecx.probe_trait_candidate(source).enter(|ecx| {
                     let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
                     ecx.eq(
                         goal.param_env,
@@ -128,7 +130,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_auto_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -162,6 +164,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         }
 
         ecx.probe_and_evaluate_goal_for_constituent_tys(
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             structural_traits::instantiate_constituent_tys_for_auto_trait,
         )
@@ -170,14 +173,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_trait_alias_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         let tcx = ecx.tcx();
 
-        ecx.probe_misc_candidate("trait alias").enter(|ecx| {
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let nested_obligations = tcx
                 .predicates_of(goal.predicate.def_id())
                 .instantiate(tcx, goal.predicate.trait_ref.args);
@@ -193,12 +196,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_sized_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         ecx.probe_and_evaluate_goal_for_constituent_tys(
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             structural_traits::instantiate_constituent_tys_for_sized_trait,
         )
@@ -207,12 +211,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_copy_clone_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         ecx.probe_and_evaluate_goal_for_constituent_tys(
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
         )
@@ -221,7 +226,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_pointer_like_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -234,14 +239,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         let key = tcx.erase_regions(goal.param_env.and(goal.predicate.self_ty()));
         // But if there are inference variables, we have to wait until it's resolved.
         if key.has_non_region_infer() {
-            return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+            return ecx.forced_ambiguity(MaybeCause::Ambiguity);
         }
 
         if let Ok(layout) = tcx.layout_of(key)
             && layout.layout.is_pointer_like(&tcx.data_layout)
         {
             // FIXME: We could make this faster by making a no-constraints response
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
         } else {
             Err(NoSolution)
         }
@@ -250,13 +256,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_fn_ptr_trait_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let self_ty = goal.predicate.self_ty();
         match goal.predicate.polarity {
             // impl FnPtr for FnPtr {}
             ty::PredicatePolarity::Positive => {
                 if self_ty.is_fn_ptr() {
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                    ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+                        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                    })
                 } else {
                     Err(NoSolution)
                 }
@@ -266,7 +274,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                 // If a type is rigid and not a fn ptr, then we know for certain
                 // that it does *not* implement `FnPtr`.
                 if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() {
-                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                    ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+                        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                    })
                 } else {
                     Err(NoSolution)
                 }
@@ -278,7 +288,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         goal_kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -292,8 +302,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             )? {
                 Some(a) => a,
                 None => {
-                    return ecx
-                        .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
+                    return ecx.forced_ambiguity(MaybeCause::Ambiguity);
                 }
             };
         let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
@@ -307,14 +316,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             .to_predicate(tcx);
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        Self::consider_implied_clause(ecx, goal, pred, [goal.with(tcx, output_is_sized_pred)])
+        Self::probe_and_consider_implied_clause(
+            ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
+            goal,
+            pred,
+            [goal.with(tcx, output_is_sized_pred)],
+        )
     }
 
     fn consider_builtin_async_fn_trait_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         goal_kind: ty::ClosureKind,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -345,8 +360,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             .to_predicate(tcx);
         // A built-in `AsyncFn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             pred,
             [goal.with(tcx, output_is_sized_pred)]
@@ -358,7 +374,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_async_fn_kind_helper_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else {
             bug!();
         };
@@ -369,7 +385,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         };
         let goal_kind = goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap();
         if closure_kind.extends(goal_kind) {
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
         } else {
             Err(NoSolution)
         }
@@ -384,13 +401,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_tuple_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
         } else {
             Err(NoSolution)
         }
@@ -399,18 +417,19 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_pointee_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_future_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -428,13 +447,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         // Async coroutine unconditionally implement `Future`
         // Technically, we need to check that the future output type is Sized,
         // but that's already proven by the coroutine being WF.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        // FIXME: use `consider_implied`
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -452,13 +473,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         // Gen coroutines unconditionally implement `Iterator`
         // Technically, we need to check that the iterator output type is Sized,
         // but that's already proven by the coroutines being WF.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        // FIXME: use `consider_implied`
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_fused_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -474,13 +497,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         }
 
         // Gen coroutines unconditionally implement `FusedIterator`
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        // FIXME: use `consider_implied`
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_async_iterator_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -498,13 +523,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         // Gen coroutines unconditionally implement `Iterator`
         // Technically, we need to check that the iterator output type is Sized,
         // but that's already proven by the coroutines being WF.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        // FIXME: use `consider_implied`
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_coroutine_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -521,8 +548,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         }
 
         let coroutine = args.as_coroutine();
-        Self::consider_implied_clause(
+        Self::probe_and_consider_implied_clause(
             ecx,
+            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             ty::TraitRef::new(tcx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()])
                 .to_predicate(tcx),
@@ -535,31 +563,33 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_builtin_discriminant_kind_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         // `DiscriminantKind` is automatically implemented for every type.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_async_destruct_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
         // `AsyncDestruct` is automatically implemented for every type.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_destruct_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -568,13 +598,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
 
         // `Destruct` is automatically implemented for every type in
         // non-const environments.
-        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     fn consider_builtin_transmute_candidate(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
@@ -594,11 +625,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             return Err(NoSolution);
         };
 
-        let certainty = ecx.is_transmutable(
-            rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
-            assume,
-        )?;
-        ecx.evaluate_added_goals_and_make_canonical_response(certainty)
+        // FIXME: This actually should destructure the `Result` we get from transmutability and
+        // register candiates. We probably need to register >1 since we may have an OR of ANDs.
+        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+            let certainty = ecx.is_transmutable(
+                rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
+                assume,
+            )?;
+            ecx.evaluate_added_goals_and_make_canonical_response(certainty)
+        })
     }
 
     /// ```ignore (builtin impl example)
@@ -611,20 +646,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
     fn consider_structural_builtin_unsize_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
-    ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
+    ) -> Vec<Candidate<'tcx>> {
         if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return vec![];
         }
 
-        let misc_candidate = |ecx: &mut EvalCtxt<'_, 'tcx>, certainty| {
-            (
-                ecx.evaluate_added_goals_and_make_canonical_response(certainty).unwrap(),
-                BuiltinImplSource::Misc,
-            )
-        };
-
-        let result_to_single = |result, source| match result {
-            Ok(resp) => vec![(resp, source)],
+        let result_to_single = |result| match result {
+            Ok(resp) => vec![resp],
             Err(NoSolution) => vec![],
         };
 
@@ -642,7 +670,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             let goal = goal.with(ecx.tcx(), (a_ty, b_ty));
             match (a_ty.kind(), b_ty.kind()) {
                 (ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"),
-                (_, ty::Infer(ty::TyVar(..))) => vec![misc_candidate(ecx, Certainty::AMBIGUOUS)],
+
+                (_, ty::Infer(ty::TyVar(..))) => {
+                    result_to_single(ecx.forced_ambiguity(MaybeCause::Ambiguity))
+                }
 
                 // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`.
                 (
@@ -655,14 +686,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                 // `T` -> `dyn Trait` unsizing.
                 (_, &ty::Dynamic(b_region, b_data, ty::Dyn)) => result_to_single(
                     ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data),
-                    BuiltinImplSource::Misc,
                 ),
 
                 // `[T; N]` -> `[T]` unsizing
-                (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => result_to_single(
-                    ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty),
-                    BuiltinImplSource::Misc,
-                ),
+                (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => {
+                    result_to_single(ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty))
+                }
 
                 // `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
                 (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
@@ -670,7 +699,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                 {
                     result_to_single(
                         ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args),
-                        BuiltinImplSource::Misc,
                     )
                 }
 
@@ -678,10 +706,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                 (&ty::Tuple(a_tys), &ty::Tuple(b_tys))
                     if a_tys.len() == b_tys.len() && !a_tys.is_empty() =>
                 {
-                    result_to_single(
-                        ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys),
-                        BuiltinImplSource::TupleUnsizing,
-                    )
+                    result_to_single(ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys))
                 }
 
                 _ => vec![],
@@ -707,7 +732,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         a_region: ty::Region<'tcx>,
         b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
         b_region: ty::Region<'tcx>,
-    ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
+    ) -> Vec<Candidate<'tcx>> {
         let tcx = self.tcx();
         let Goal { predicate: (a_ty, _b_ty), .. } = goal;
 
@@ -715,35 +740,32 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         // If the principal def ids match (or are both none), then we're not doing
         // trait upcasting. We're just removing auto traits (or shortening the lifetime).
         if a_data.principal_def_id() == b_data.principal_def_id() {
-            if let Ok(resp) = self.consider_builtin_upcast_to_principal(
+            responses.extend(self.consider_builtin_upcast_to_principal(
                 goal,
+                CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
                 a_data,
                 a_region,
                 b_data,
                 b_region,
                 a_data.principal(),
-            ) {
-                responses.push((resp, BuiltinImplSource::Misc));
-            }
+            ));
         } else if let Some(a_principal) = a_data.principal() {
             self.walk_vtable(
                 a_principal.with_self_ty(tcx, a_ty),
                 |ecx, new_a_principal, _, vtable_vptr_slot| {
-                    if let Ok(resp) = ecx.probe_misc_candidate("dyn upcast").enter(|ecx| {
-                        ecx.consider_builtin_upcast_to_principal(
-                            goal,
-                            a_data,
-                            a_region,
-                            b_data,
-                            b_region,
-                            Some(new_a_principal.map_bound(|trait_ref| {
-                                ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
-                            })),
-                        )
-                    }) {
-                        responses
-                            .push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }));
-                    }
+                    responses.extend(ecx.consider_builtin_upcast_to_principal(
+                        goal,
+                        CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting {
+                            vtable_vptr_slot,
+                        }),
+                        a_data,
+                        a_region,
+                        b_data,
+                        b_region,
+                        Some(new_a_principal.map_bound(|trait_ref| {
+                            ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+                        })),
+                    ));
                 },
             );
         }
@@ -756,7 +778,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
         b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
         b_region: ty::Region<'tcx>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = self.tcx();
         let Goal { predicate: (a_ty, _), .. } = goal;
 
@@ -765,37 +787,40 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             return Err(NoSolution);
         }
 
-        // Check that the type implements all of the predicates of the trait object.
-        // (i.e. the principal, all of the associated types match, and any auto traits)
-        self.add_goals(
-            GoalSource::ImplWhereBound,
-            b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
-        );
-
-        // The type must be `Sized` to be unsized.
-        if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
-            self.add_goal(
+        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+            // Check that the type implements all of the predicates of the trait object.
+            // (i.e. the principal, all of the associated types match, and any auto traits)
+            ecx.add_goals(
                 GoalSource::ImplWhereBound,
-                goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
+                b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
             );
-        } else {
-            return Err(NoSolution);
-        }
 
-        // The type must outlive the lifetime of the `dyn` we're unsizing into.
-        self.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            // The type must be `Sized` to be unsized.
+            if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
+                ecx.add_goal(
+                    GoalSource::ImplWhereBound,
+                    goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
+                );
+            } else {
+                return Err(NoSolution);
+            }
+
+            // The type must outlive the lifetime of the `dyn` we're unsizing into.
+            ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
     }
 
     fn consider_builtin_upcast_to_principal(
         &mut self,
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
+        source: CandidateSource,
         a_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
         a_region: ty::Region<'tcx>,
         b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
         b_region: ty::Region<'tcx>,
         upcast_principal: Option<ty::PolyExistentialTraitRef<'tcx>>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let param_env = goal.param_env;
 
         // We may upcast to auto traits that are either explicitly listed in
@@ -814,7 +839,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         // having any inference side-effects. We process obligations because
         // unification may initially succeed due to deferred projection equality.
         let projection_may_match =
-            |ecx: &mut Self,
+            |ecx: &mut EvalCtxt<'_, 'tcx>,
              source_projection: ty::PolyExistentialProjection<'tcx>,
              target_projection: ty::PolyExistentialProjection<'tcx>| {
                 source_projection.item_def_id() == target_projection.item_def_id()
@@ -828,54 +853,60 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                         .is_ok()
             };
 
-        for bound in b_data {
-            match bound.skip_binder() {
-                // Check that a's supertrait (upcast_principal) is compatible
-                // with the target (b_ty).
-                ty::ExistentialPredicate::Trait(target_principal) => {
-                    self.eq(param_env, upcast_principal.unwrap(), bound.rebind(target_principal))?;
-                }
-                // Check that b_ty's projection is satisfied by exactly one of
-                // a_ty's projections. First, we look through the list to see if
-                // any match. If not, error. Then, if *more* than one matches, we
-                // return ambiguity. Otherwise, if exactly one matches, equate
-                // it with b_ty's projection.
-                ty::ExistentialPredicate::Projection(target_projection) => {
-                    let target_projection = bound.rebind(target_projection);
-                    let mut matching_projections =
-                        a_data.projection_bounds().filter(|source_projection| {
-                            projection_may_match(self, *source_projection, target_projection)
-                        });
-                    let Some(source_projection) = matching_projections.next() else {
-                        return Err(NoSolution);
-                    };
-                    if matching_projections.next().is_some() {
-                        return self.evaluate_added_goals_and_make_canonical_response(
-                            Certainty::AMBIGUOUS,
-                        );
+        self.probe_trait_candidate(source).enter(|ecx| {
+            for bound in b_data {
+                match bound.skip_binder() {
+                    // Check that a's supertrait (upcast_principal) is compatible
+                    // with the target (b_ty).
+                    ty::ExistentialPredicate::Trait(target_principal) => {
+                        ecx.eq(
+                            param_env,
+                            upcast_principal.unwrap(),
+                            bound.rebind(target_principal),
+                        )?;
                     }
-                    self.eq(param_env, source_projection, target_projection)?;
-                }
-                // Check that b_ty's auto traits are present in a_ty's bounds.
-                ty::ExistentialPredicate::AutoTrait(def_id) => {
-                    if !a_auto_traits.contains(&def_id) {
-                        return Err(NoSolution);
+                    // Check that b_ty's projection is satisfied by exactly one of
+                    // a_ty's projections. First, we look through the list to see if
+                    // any match. If not, error. Then, if *more* than one matches, we
+                    // return ambiguity. Otherwise, if exactly one matches, equate
+                    // it with b_ty's projection.
+                    ty::ExistentialPredicate::Projection(target_projection) => {
+                        let target_projection = bound.rebind(target_projection);
+                        let mut matching_projections =
+                            a_data.projection_bounds().filter(|source_projection| {
+                                projection_may_match(ecx, *source_projection, target_projection)
+                            });
+                        let Some(source_projection) = matching_projections.next() else {
+                            return Err(NoSolution);
+                        };
+                        if matching_projections.next().is_some() {
+                            return ecx.evaluate_added_goals_and_make_canonical_response(
+                                Certainty::AMBIGUOUS,
+                            );
+                        }
+                        ecx.eq(param_env, source_projection, target_projection)?;
+                    }
+                    // Check that b_ty's auto traits are present in a_ty's bounds.
+                    ty::ExistentialPredicate::AutoTrait(def_id) => {
+                        if !a_auto_traits.contains(&def_id) {
+                            return Err(NoSolution);
+                        }
                     }
                 }
             }
-        }
 
-        // Also require that a_ty's lifetime outlives b_ty's lifetime.
-        self.add_goal(
-            GoalSource::ImplWhereBound,
-            Goal::new(
-                self.tcx(),
-                param_env,
-                ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
-            ),
-        );
+            // Also require that a_ty's lifetime outlives b_ty's lifetime.
+            ecx.add_goal(
+                GoalSource::ImplWhereBound,
+                Goal::new(
+                    ecx.tcx(),
+                    param_env,
+                    ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
+                ),
+            );
 
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
     }
 
     /// We have the following builtin impls for arrays:
@@ -891,9 +922,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
         a_elem_ty: Ty<'tcx>,
         b_elem_ty: Ty<'tcx>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         self.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     /// We generate a builtin `Unsize` impls for structs with generic parameters only
@@ -915,7 +947,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         def: ty::AdtDef<'tcx>,
         a_args: ty::GenericArgsRef<'tcx>,
         b_args: ty::GenericArgsRef<'tcx>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = self.tcx();
         let Goal { predicate: (_a_ty, b_ty), .. } = goal;
 
@@ -957,7 +989,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 ),
             ),
         );
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     /// We generate the following builtin impl for tuples of all sizes.
@@ -975,7 +1008,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
         a_tys: &'tcx ty::List<Ty<'tcx>>,
         b_tys: &'tcx ty::List<Ty<'tcx>>,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = self.tcx();
         let Goal { predicate: (_a_ty, b_ty), .. } = goal;
 
@@ -999,7 +1032,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 ),
             ),
         );
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing)
+            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
     // Return `Some` if there is an impl (built-in or user provided) that may
@@ -1009,7 +1043,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     fn disqualify_auto_trait_candidate_due_to_possible_impl(
         &mut self,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
-    ) -> Option<QueryResult<'tcx>> {
+    ) -> Option<Result<Candidate<'tcx>, NoSolution>> {
         let self_ty = goal.predicate.self_ty();
         match *self_ty.kind() {
             // Stall int and float vars until they are resolved to a concrete
@@ -1018,7 +1052,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // we probably don't want to treat an `impl !AutoTrait for i32` as
             // disqualifying the built-in auto impl for `i64: AutoTrait` either.
             ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
-                Some(self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS))
+                Some(self.forced_ambiguity(MaybeCause::Ambiguity))
             }
 
             // These types cannot be structurally decomposed into constituent
@@ -1039,9 +1073,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             {
                 match self.tcx().coroutine_movability(def_id) {
                     Movability::Static => Some(Err(NoSolution)),
-                    Movability::Movable => {
-                        Some(self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
-                    }
+                    Movability::Movable => Some(
+                        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
+                            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                        }),
+                    ),
                 }
             }
 
@@ -1106,13 +1142,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// wrapped in one.
     fn probe_and_evaluate_goal_for_constituent_tys(
         &mut self,
+        source: CandidateSource,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
         constituent_tys: impl Fn(
             &EvalCtxt<'_, 'tcx>,
             Ty<'tcx>,
         ) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution>,
-    ) -> QueryResult<'tcx> {
-        self.probe_misc_candidate("constituent tys").enter(|ecx| {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
+        self.probe_trait_candidate(source).enter(|ecx| {
             ecx.add_goals(
                 GoalSource::ImplWhereBound,
                 constituent_tys(ecx, goal.predicate.self_ty())?
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 36028b51659..59725ce9de0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -6,12 +6,9 @@
 
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::InferOk;
-use crate::regions::InferCtxtRegionExt;
 use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
-use crate::solve::{deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt};
-use crate::traits::engine::TraitEngineExt as _;
+use crate::solve::{deeply_normalize_for_diagnostics, inspect};
 use crate::traits::select::IntercrateAmbiguityCause;
-use crate::traits::structural_normalize::StructurallyNormalizeExt;
 use crate::traits::NormalizeExt;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{
@@ -20,30 +17,45 @@ use crate::traits::{
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt};
+use rustc_infer::traits::{util, FulfillmentErrorCode};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
-use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
+use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::symbol::sym;
-use rustc_span::DUMMY_SP;
+use rustc_span::{Span, DUMMY_SP};
 use std::fmt::Debug;
 use std::ops::ControlFlow;
 
 use super::error_reporting::suggest_new_overflow_limit;
+use super::ObligationCtxt;
 
-/// Whether we do the orphan check relative to this crate or
-/// to some remote crate.
+/// Whether we do the orphan check relative to this crate or to some remote crate.
 #[derive(Copy, Clone, Debug)]
-enum InCrate {
-    Local,
+pub enum InCrate {
+    Local { mode: OrphanCheckMode },
     Remote,
 }
 
+#[derive(Copy, Clone, Debug)]
+pub enum OrphanCheckMode {
+    /// Proper orphan check.
+    Proper,
+    /// Improper orphan check for backward compatibility.
+    ///
+    /// In this mode, type params inside projections are considered to be covered
+    /// even if the projection may normalize to a type that doesn't actually cover
+    /// them. This is unsound. See also [#124559] and [#99554].
+    ///
+    /// [#124559]: https://github.com/rust-lang/rust/issues/124559
+    /// [#99554]: https://github.com/rust-lang/rust/issues/99554
+    Compat,
+}
+
 #[derive(Debug, Copy, Clone)]
 pub enum Conflict {
     Upstream,
@@ -347,23 +359,27 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
     let infcx = selcx.infcx;
 
     if infcx.next_trait_solver() {
-        let mut fulfill_cx = FulfillmentCtxt::new(infcx);
-        fulfill_cx.register_predicate_obligations(infcx, obligations.iter().cloned());
-
+        let ocx = ObligationCtxt::new(infcx);
+        ocx.register_obligations(obligations.iter().cloned());
+        let errors_and_ambiguities = ocx.select_all_or_error();
         // We only care about the obligations that are *definitely* true errors.
         // Ambiguities do not prove the disjointness of two impls.
-        let errors = fulfill_cx.select_where_possible(infcx);
+        let (errors, ambiguities): (Vec<_>, Vec<_>) =
+            errors_and_ambiguities.into_iter().partition(|error| error.is_true_error());
+
         if errors.is_empty() {
-            let overflow_errors = fulfill_cx.collect_remaining_errors(infcx);
-            let overflowing_predicates = overflow_errors
-                .into_iter()
-                .filter(|e| match e.code {
-                    FulfillmentErrorCode::Ambiguity { overflow: Some(true) } => true,
-                    _ => false,
-                })
-                .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
-                .collect();
-            IntersectionHasImpossibleObligations::No { overflowing_predicates }
+            IntersectionHasImpossibleObligations::No {
+                overflowing_predicates: ambiguities
+                    .into_iter()
+                    .filter(|error| {
+                        matches!(
+                            error.code,
+                            FulfillmentErrorCode::Ambiguity { overflow: Some(true) }
+                        )
+                    })
+                    .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
+                    .collect(),
+            }
         } else {
             IntersectionHasImpossibleObligations::Yes
         }
@@ -575,13 +591,14 @@ fn try_prove_negated_where_clause<'tcx>(
     // Without this, we over-eagerly register coherence ambiguity candidates when
     // impl candidates do exist.
     let ref infcx = root_infcx.fork_with_intercrate(false);
-    let mut fulfill_cx = FulfillmentCtxt::new(infcx);
-
-    fulfill_cx.register_predicate_obligation(
-        infcx,
-        Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, negative_predicate),
-    );
-    if !fulfill_cx.select_all_or_error(infcx).is_empty() {
+    let ocx = ObligationCtxt::new(infcx);
+    ocx.register_obligation(Obligation::new(
+        infcx.tcx,
+        ObligationCause::dummy(),
+        param_env,
+        negative_predicate,
+    ));
+    if !ocx.select_all_or_error().is_empty() {
         return false;
     }
 
@@ -589,8 +606,7 @@ fn try_prove_negated_where_clause<'tcx>(
     // if that wasn't implemented just for LocalDefId, and we'd need to do
     // the normalization ourselves since this is totally fallible...
     let outlives_env = OutlivesEnvironment::new(param_env);
-
-    let errors = infcx.resolve_regions(&outlives_env);
+    let errors = ocx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
         return false;
     }
@@ -604,19 +620,20 @@ fn try_prove_negated_where_clause<'tcx>(
 /// This both checks whether any downstream or sibling crates could
 /// implement it and whether an upstream crate can add this impl
 /// without breaking backwards compatibility.
-#[instrument(level = "debug", skip(tcx, lazily_normalize_ty), ret)]
+#[instrument(level = "debug", skip(infcx, lazily_normalize_ty), ret)]
 pub fn trait_ref_is_knowable<'tcx, E: Debug>(
-    tcx: TyCtxt<'tcx>,
+    infcx: &InferCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
     mut lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
 ) -> Result<Result<(), Conflict>, E> {
-    if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() {
+    if orphan_check_trait_ref(infcx, trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok()
+    {
         // A downstream or cousin crate is allowed to implement some
         // generic parameters of this trait-ref.
         return Ok(Err(Conflict::Downstream));
     }
 
-    if trait_ref_is_local_or_fundamental(tcx, trait_ref) {
+    if trait_ref_is_local_or_fundamental(infcx.tcx, trait_ref) {
         // This is a local or fundamental trait, so future-compatibility
         // is no concern. We know that downstream/cousin crates are not
         // allowed to implement a generic parameter of this trait ref,
@@ -633,7 +650,14 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>(
     // and if we are an intermediate owner, then we don't care
     // about future-compatibility, which means that we're OK if
     // we are an owner.
-    if orphan_check_trait_ref(trait_ref, InCrate::Local, &mut lazily_normalize_ty)?.is_ok() {
+    if orphan_check_trait_ref(
+        infcx,
+        trait_ref,
+        InCrate::Local { mode: OrphanCheckMode::Proper },
+        &mut lazily_normalize_ty,
+    )?
+    .is_ok()
+    {
         Ok(Ok(()))
     } else {
         Ok(Err(Conflict::Upstream))
@@ -644,7 +668,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
 ) -> bool {
-    trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
+    trait_ref.def_id.is_local() || tcx.has_attr(trait_ref.def_id, sym::fundamental)
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -663,31 +687,15 @@ impl From<bool> for IsFirstInputType {
 }
 
 #[derive(Debug)]
-pub enum OrphanCheckErr<'tcx> {
+pub enum OrphanCheckErr<'tcx, T> {
     NonLocalInputType(Vec<(Ty<'tcx>, IsFirstInputType)>),
-    UncoveredTy(Ty<'tcx>, Option<Ty<'tcx>>),
+    UncoveredTyParams(UncoveredTyParams<'tcx, T>),
 }
 
-/// Checks the coherence orphan rules. `impl_def_id` should be the
-/// `DefId` of a trait impl. To pass, either the trait must be local, or else
-/// two conditions must be satisfied:
-///
-/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
-/// 2. Some local type must appear in `Self`.
-#[instrument(level = "debug", skip(tcx), ret)]
-pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanCheckErr<'_>> {
-    // We only except this routine to be invoked on implementations
-    // of a trait, not inherent implementations.
-    let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
-    debug!(?trait_ref);
-
-    // If the *trait* is local to the crate, ok.
-    if trait_ref.def_id.is_local() {
-        debug!("trait {:?} is local to current crate", trait_ref.def_id);
-        return Ok(());
-    }
-
-    orphan_check_trait_ref::<!>(trait_ref, InCrate::Local, |ty| Ok(ty)).unwrap()
+#[derive(Debug)]
+pub struct UncoveredTyParams<'tcx, T> {
+    pub uncovered: T,
+    pub local_ty: Option<Ty<'tcx>>,
 }
 
 /// Checks whether a trait-ref is potentially implementable by a crate.
@@ -735,6 +743,9 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
 ///    To check that a local impl follows the orphan rules, we check it in
 ///    InCrate::Local mode, using type parameters for the "generic" types.
 ///
+///    In InCrate::Local mode the orphan check succeeds if the current crate
+///    is definitely allowed to implement the given trait (no false positives).
+///
 /// 2. They ground negative reasoning for coherence. If a user wants to
 ///    write both a conditional blanket impl and a specific impl, we need to
 ///    make sure they do not overlap. For example, if we write
@@ -753,6 +764,9 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
 ///    try to implement this trait-ref. To check for this, we use InCrate::Remote
 ///    mode. That is sound because we already know all the impls from known crates.
 ///
+///    In InCrate::Remote mode the orphan check succeeds if a foreign crate
+///    *could* implement the given trait (no false negatives).
+///
 /// 3. For non-`#[fundamental]` traits, they guarantee that parent crates can
 ///    add "non-blanket" impls without breaking negative reasoning in dependent
 ///    crates. This is the "rebalancing coherence" (RFC 1023) restriction.
@@ -776,54 +790,56 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
 ///
 /// Note that this function is never called for types that have both type
 /// parameters and inference variables.
-#[instrument(level = "trace", skip(lazily_normalize_ty), ret)]
-fn orphan_check_trait_ref<'tcx, E: Debug>(
+#[instrument(level = "trace", skip(infcx, lazily_normalize_ty), ret)]
+pub fn orphan_check_trait_ref<'tcx, E: Debug>(
+    infcx: &InferCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
     in_crate: InCrate,
     lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
-) -> Result<Result<(), OrphanCheckErr<'tcx>>, E> {
-    if trait_ref.has_infer() && trait_ref.has_param() {
-        bug!(
-            "can't orphan check a trait ref with both params and inference variables {:?}",
-            trait_ref
-        );
+) -> Result<Result<(), OrphanCheckErr<'tcx, Ty<'tcx>>>, E> {
+    if trait_ref.has_param() {
+        bug!("orphan check only expects inference variables: {trait_ref:?}");
     }
 
-    let mut checker = OrphanChecker::new(in_crate, lazily_normalize_ty);
+    let mut checker = OrphanChecker::new(infcx, in_crate, lazily_normalize_ty);
     Ok(match trait_ref.visit_with(&mut checker) {
         ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)),
-        ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)) => return Err(err),
-        ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(ty)) => {
-            // Does there exist some local type after the `ParamTy`.
-            checker.search_first_local_ty = true;
-            if let Some(OrphanCheckEarlyExit::LocalTy(local_ty)) =
-                trait_ref.visit_with(&mut checker).break_value()
-            {
-                Err(OrphanCheckErr::UncoveredTy(ty, Some(local_ty)))
-            } else {
-                Err(OrphanCheckErr::UncoveredTy(ty, None))
+        ControlFlow::Break(residual) => match residual {
+            OrphanCheckEarlyExit::NormalizationFailure(err) => return Err(err),
+            OrphanCheckEarlyExit::UncoveredTyParam(ty) => {
+                // Does there exist some local type after the `ParamTy`.
+                checker.search_first_local_ty = true;
+                let local_ty = match trait_ref.visit_with(&mut checker).break_value() {
+                    Some(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty),
+                    _ => None,
+                };
+                Err(OrphanCheckErr::UncoveredTyParams(UncoveredTyParams {
+                    uncovered: ty,
+                    local_ty,
+                }))
             }
-        }
-        ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(_)) => Ok(()),
+            OrphanCheckEarlyExit::LocalTy(_) => Ok(()),
+        },
     })
 }
 
-struct OrphanChecker<'tcx, F> {
+struct OrphanChecker<'a, 'tcx, F> {
+    infcx: &'a InferCtxt<'tcx>,
     in_crate: InCrate,
     in_self_ty: bool,
     lazily_normalize_ty: F,
-    /// Ignore orphan check failures and exclusively search for the first
-    /// local type.
+    /// Ignore orphan check failures and exclusively search for the first local type.
     search_first_local_ty: bool,
     non_local_tys: Vec<(Ty<'tcx>, IsFirstInputType)>,
 }
 
-impl<'tcx, F, E> OrphanChecker<'tcx, F>
+impl<'a, 'tcx, F, E> OrphanChecker<'a, 'tcx, F>
 where
     F: FnOnce(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
 {
-    fn new(in_crate: InCrate, lazily_normalize_ty: F) -> Self {
+    fn new(infcx: &'a InferCtxt<'tcx>, in_crate: InCrate, lazily_normalize_ty: F) -> Self {
         OrphanChecker {
+            infcx,
             in_crate,
             in_self_ty: true,
             lazily_normalize_ty,
@@ -837,17 +853,20 @@ where
         ControlFlow::Continue(())
     }
 
-    fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> {
+    fn found_uncovered_ty_param(
+        &mut self,
+        ty: Ty<'tcx>,
+    ) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> {
         if self.search_first_local_ty {
-            ControlFlow::Continue(())
-        } else {
-            ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(t))
+            return ControlFlow::Continue(());
         }
+
+        ControlFlow::Break(OrphanCheckEarlyExit::UncoveredTyParam(ty))
     }
 
     fn def_id_is_local(&mut self, def_id: DefId) -> bool {
         match self.in_crate {
-            InCrate::Local => def_id.is_local(),
+            InCrate::Local { .. } => def_id.is_local(),
             InCrate::Remote => false,
         }
     }
@@ -855,23 +874,25 @@ where
 
 enum OrphanCheckEarlyExit<'tcx, E> {
     NormalizationFailure(E),
-    ParamTy(Ty<'tcx>),
+    UncoveredTyParam(Ty<'tcx>),
     LocalTy(Ty<'tcx>),
 }
 
-impl<'tcx, F, E> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx, F>
+impl<'a, 'tcx, F, E> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'a, 'tcx, F>
 where
     F: FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
 {
     type Result = ControlFlow<OrphanCheckEarlyExit<'tcx, E>>;
+
     fn visit_region(&mut self, _r: ty::Region<'tcx>) -> Self::Result {
         ControlFlow::Continue(())
     }
 
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
-        // Need to lazily normalize here in with `-Znext-solver=coherence`.
+        let ty = self.infcx.shallow_resolve(ty);
         let ty = match (self.lazily_normalize_ty)(ty) {
-            Ok(ty) => ty,
+            Ok(norm_ty) if norm_ty.is_ty_var() => ty,
+            Ok(norm_ty) => norm_ty,
             Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)),
         };
 
@@ -889,19 +910,46 @@ where
             | ty::Slice(..)
             | ty::RawPtr(..)
             | ty::Never
-            | ty::Tuple(..)
-            | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) => {
-                self.found_non_local_ty(ty)
+            | ty::Tuple(..) => self.found_non_local_ty(ty),
+
+            ty::Param(..) => bug!("unexpected ty param"),
+
+            ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => {
+                match self.in_crate {
+                    InCrate::Local { .. } => self.found_uncovered_ty_param(ty),
+                    // The inference variable might be unified with a local
+                    // type in that remote crate.
+                    InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
+                }
             }
 
-            ty::Param(..) => self.found_param_ty(ty),
+            ty::Alias(kind @ (ty::Projection | ty::Inherent | ty::Weak), ..) => {
+                if ty.has_type_flags(ty::TypeFlags::HAS_TY_PARAM) {
+                    bug!("unexpected ty param in alias ty");
+                }
 
-            ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match self.in_crate {
-                InCrate::Local => self.found_non_local_ty(ty),
-                // The inference variable might be unified with a local
-                // type in that remote crate.
-                InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
-            },
+                if ty.has_type_flags(
+                    ty::TypeFlags::HAS_TY_PLACEHOLDER
+                        | ty::TypeFlags::HAS_TY_BOUND
+                        | ty::TypeFlags::HAS_TY_INFER,
+                ) {
+                    match self.in_crate {
+                        InCrate::Local { mode } => match kind {
+                            ty::Projection if let OrphanCheckMode::Compat = mode => {
+                                ControlFlow::Continue(())
+                            }
+                            _ => self.found_uncovered_ty_param(ty),
+                        },
+                        InCrate::Remote => {
+                            // The inference variable might be unified with a local
+                            // type in that remote crate.
+                            ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
+                        }
+                    }
+                } else {
+                    ControlFlow::Continue(())
+                }
+            }
 
             // For fundamental types, we just look inside of them.
             ty::Ref(_, ty, _) => ty.visit_with(self),
@@ -1022,10 +1070,14 @@ struct AmbiguityCausesVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
+    fn span(&self) -> Span {
+        DUMMY_SP
+    }
+
     fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
         let infcx = goal.infcx();
         for cand in goal.candidates() {
-            cand.visit_nested(self);
+            cand.visit_nested_in_probe(self);
         }
         // When searching for intercrate ambiguity causes, we only need to look
         // at ambiguous goals, as for others the coherence unknowable candidate
@@ -1074,32 +1126,26 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
         // Add ambiguity causes for unknowable goals.
         let mut ambiguity_cause = None;
         for cand in goal.candidates() {
-            // FIXME: boiiii, using string comparisions here sure is scuffed.
-            if let inspect::ProbeKind::MiscCandidate {
-                name: "coherence unknowable",
+            if let inspect::ProbeKind::TraitCandidate {
+                source: CandidateSource::CoherenceUnknowable,
                 result: Ok(_),
             } = cand.kind()
             {
-                let lazily_normalize_ty = |ty: Ty<'tcx>| {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx);
+                let lazily_normalize_ty = |mut ty: Ty<'tcx>| {
                     if matches!(ty.kind(), ty::Alias(..)) {
-                        // FIXME(-Znext-solver=coherence): we currently don't
-                        // normalize opaque types here, resulting in diverging behavior
-                        // for TAITs.
-                        match infcx
-                            .at(&ObligationCause::dummy(), param_env)
-                            .structurally_normalize(ty, &mut *fulfill_cx)
-                        {
-                            Ok(ty) => Ok(ty),
-                            Err(_errs) => Err(()),
+                        let ocx = ObligationCtxt::new(infcx);
+                        ty = ocx
+                            .structurally_normalize(&ObligationCause::dummy(), param_env, ty)
+                            .map_err(|_| ())?;
+                        if !ocx.select_where_possible().is_empty() {
+                            return Err(());
                         }
-                    } else {
-                        Ok(ty)
                     }
+                    Ok(ty)
                 };
 
                 infcx.probe(|_| {
-                    match trait_ref_is_knowable(infcx.tcx, trait_ref, lazily_normalize_ty) {
+                    match trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty) {
                         Err(()) => {}
                         Ok(Ok(())) => warn!("expected an unknowable trait ref: {trait_ref:?}"),
                         Ok(Err(conflict)) => {
@@ -1157,5 +1203,5 @@ fn search_ambiguity_causes<'tcx>(
     goal: Goal<'tcx, ty::Predicate<'tcx>>,
     causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
 ) {
-    infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes });
+    infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }));
 }
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 9fbec174ce8..551c8e7702e 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -7,6 +7,7 @@ use crate::regions::InferCtxtRegionExt;
 use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
 use crate::traits::error_reporting::TypeErrCtxtExt;
 use crate::traits::NormalizeExt;
+use crate::traits::StructurallyNormalizeExt;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -15,10 +16,12 @@ use rustc_infer::infer::canonical::{
     Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
 };
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::RegionResolutionError;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
 use rustc_infer::traits::{
     FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
 };
+use rustc_macros::extension;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::error::TypeError;
@@ -116,6 +119,17 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
     }
 
+    pub fn structurally_normalize(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        value: Ty<'tcx>,
+    ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
+        self.infcx
+            .at(cause, param_env)
+            .structurally_normalize(value, &mut **self.engine.borrow_mut())
+    }
+
     pub fn eq<T: ToTrace<'tcx>>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -181,6 +195,18 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.engine.borrow_mut().select_all_or_error(self.infcx)
     }
 
+    /// Returns the not-yet-processed and stalled obligations from the
+    /// `ObligationCtxt`.
+    ///
+    /// Takes ownership of the context as doing operations such as
+    /// [`ObligationCtxt::eq`] afterwards will result in other obligations
+    /// getting ignored. You can make a new `ObligationCtxt` if this
+    /// needs to be done in a loop, for example.
+    #[must_use]
+    pub fn into_pending_obligations(self) -> Vec<PredicateObligation<'tcx>> {
+        self.engine.borrow().pending_obligations()
+    }
+
     /// Resolves regions and reports errors.
     ///
     /// Takes ownership of the context as doing trait solving afterwards
@@ -198,6 +224,18 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         }
     }
 
+    /// Resolves regions and reports errors.
+    ///
+    /// Takes ownership of the context as doing trait solving afterwards
+    /// will result in region constraints getting ignored.
+    #[must_use]
+    pub fn resolve_regions(
+        self,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+    ) -> Vec<RegionResolutionError<'tcx>> {
+        self.infcx.resolve_regions(outlives_env)
+    }
+
     pub fn assumed_wf_types_and_report_errors(
         &self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
index d41d43bad71..9e5701ffffc 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
@@ -4,6 +4,7 @@ use crate::traits::{Obligation, ObligationCause, ObligationCtxt};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, Diag};
 use rustc_hir as hir;
 use rustc_hir::Node;
+use rustc_macros::extension;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, DUMMY_SP};
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index b418219fb95..07bd209e623 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -9,6 +9,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_macros::{extension, LintDiagnostic};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
 use rustc_parse_format::{ParseMode, Parser, Piece, Position};
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index d24942f3f46..3d2574ac92b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -26,6 +26,7 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
 use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
+use rustc_macros::extension;
 use rustc_middle::hir::map;
 use rustc_middle::traits::IsConstable;
 use rustc_middle::ty::error::TypeError::{self, Sorts};
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 1971136e54c..e50cb2af4b8 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -32,6 +32,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::{GenericParam, Item, Node};
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::{InferOk, TypeTrace};
+use rustc_macros::extension;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::traits::SignatureMismatchData;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@@ -780,7 +781,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             && self.fallback_has_occurred
                         {
                             let predicate = trait_predicate.map_bound(|trait_pred| {
-                                trait_pred.with_self_ty(self.tcx, Ty::new_unit(self.tcx))
+                                trait_pred.with_self_ty(self.tcx, tcx.types.unit)
                             });
                             let unit_obligation = obligation.with(tcx, predicate);
                             if self.predicate_may_hold(&unit_obligation) {
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 8cd9f39d5d8..1f10cb71543 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -73,7 +73,7 @@ pub struct PendingPredicateObligation<'tcx> {
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_pointer_width = "64")]
-static_assert_size!(PendingPredicateObligation<'_>, 72);
+rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72);
 
 impl<'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 88ebf8754d3..56f8b4b9cdb 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -41,8 +41,9 @@ use rustc_span::Span;
 use std::fmt::Debug;
 use std::ops::ControlFlow;
 
-pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
-pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult};
+pub use self::coherence::{add_placeholder_note, orphan_check_trait_ref, overlapping_impls};
+pub use self::coherence::{InCrate, IsFirstInputType, UncoveredTyParams};
+pub use self::coherence::{OrphanCheckErr, OrphanCheckMode, OverlapResult};
 pub use self::engine::{ObligationCtxt, TraitEngineExt};
 pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
 pub use self::normalize::NormalizeExt;
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index b4969926f64..43f4fa8e81c 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -8,6 +8,7 @@ use rustc_infer::infer::at::At;
 use rustc_infer::infer::InferOk;
 use rustc_infer::traits::PredicateObligation;
 use rustc_infer::traits::{FulfillmentError, Normalized, Obligation, TraitEngine};
+use rustc_macros::extension;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder};
 use rustc_middle::ty::{TypeFoldable, TypeSuperFoldable, TypeVisitable, TypeVisitableExt};
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 5e1343b50ce..0e15dd27537 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -519,7 +519,7 @@ fn virtual_call_violations_for_method<'tcx>(
 
             // e.g., `Rc<()>`
             let unit_receiver_ty =
-                receiver_for_self_ty(tcx, receiver_ty, Ty::new_unit(tcx), method.def_id);
+                receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method.def_id);
 
             match abi_of_ty(unit_receiver_ty) {
                 Some(Abi::Scalar(..)) => (),
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index c4110df45db..1dd2ada3356 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -3,6 +3,7 @@ use crate::traits::{ObligationCause, ObligationCtxt};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::infer::InferOk;
+use rustc_macros::extension;
 use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints};
 use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 16ee9fadab4..87d240cf8ac 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -1,8 +1,10 @@
-use rustc_infer::traits::{TraitEngine, TraitEngineExt};
+use rustc_macros::extension;
 
 use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferCtxt;
-use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
+use crate::traits::{
+    EvaluationResult, ObligationCtxt, OverflowError, PredicateObligation, SelectionContext,
+};
 
 #[extension(pub trait InferCtxtExt<'tcx>)]
 impl<'tcx> InferCtxt<'tcx> {
@@ -66,21 +68,22 @@ impl<'tcx> InferCtxt<'tcx> {
 
         if self.next_trait_solver() {
             self.probe(|snapshot| {
-                let mut fulfill_cx = crate::solve::FulfillmentCtxt::new(self);
-                fulfill_cx.register_predicate_obligation(self, obligation.clone());
-                // True errors
-                // FIXME(-Znext-solver): Overflows are reported as ambig here, is that OK?
-                if !fulfill_cx.select_where_possible(self).is_empty() {
-                    Ok(EvaluationResult::EvaluatedToErr)
-                } else if !fulfill_cx.select_all_or_error(self).is_empty() {
-                    Ok(EvaluationResult::EvaluatedToAmbig)
-                } else if self.opaque_types_added_in_snapshot(snapshot) {
-                    Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes)
+                let ocx = ObligationCtxt::new(self);
+                ocx.register_obligation(obligation.clone());
+                let mut result = EvaluationResult::EvaluatedToOk;
+                for error in ocx.select_all_or_error() {
+                    if error.is_true_error() {
+                        return Ok(EvaluationResult::EvaluatedToErr);
+                    } else {
+                        result = result.max(EvaluationResult::EvaluatedToAmbig);
+                    }
+                }
+                if self.opaque_types_added_in_snapshot(snapshot) {
+                    result = result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes);
                 } else if self.region_constraints_added_in_snapshot(snapshot) {
-                    Ok(EvaluationResult::EvaluatedToOkModuloRegions)
-                } else {
-                    Ok(EvaluationResult::EvaluatedToOk)
+                    result = result.max(EvaluationResult::EvaluatedToOkModuloRegions);
                 }
+                Ok(result)
             })
         } else {
             assert!(!self.intercrate);
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index c520e699bf5..8b39c23da56 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -13,6 +13,7 @@ use crate::traits::{ObligationCause, PredicateObligation, Reveal};
 use rustc_data_structures::sso::SsoHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_infer::traits::Normalized;
+use rustc_macros::extension;
 use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 423ed0f7105..f7e84a46639 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -7,6 +7,7 @@ use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::query::OutlivesBound;
+use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_middle::infer::canonical::CanonicalQueryResponse;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
index 07587e37411..3e7aa52dcfe 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs
@@ -3,6 +3,7 @@ use crate::traits::query::dropck_outlives::{
     compute_dropck_outlives_inner, trivial_dropck_outlives,
 };
 use crate::traits::ObligationCtxt;
+use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
 use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution};
 use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index fc12fed3537..18cb3184fe1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1497,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // bound regions.
         let trait_ref = predicate.skip_binder().trait_ref;
 
-        coherence::trait_ref_is_knowable::<!>(self.tcx(), trait_ref, |ty| Ok(ty)).unwrap()
+        coherence::trait_ref_is_knowable::<!>(self.infcx, trait_ref, |ty| Ok(ty)).unwrap()
     }
 
     /// Returns `true` if the global caches can be used.
@@ -2001,7 +2001,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     // any associated items and there are no where-clauses.
                     //
                     // We can just arbitrarily drop one of the impls.
-                    Some(ty::ImplOverlapKind::Issue33140) => {
+                    Some(ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects) => {
                         assert_eq!(other.evaluation, victim.evaluation);
                         DropVictim::Yes
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 46a0a4eb5ef..390e711a18d 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -453,7 +453,7 @@ fn report_conflicting_impls<'tcx>(
             overlap.trait_ref.print_trait_sugared(),
             overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
             match used_to_be_allowed {
-                Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
+                Some(FutureCompatOverlapErrorKind::OrderDepTraitObjects) => ": (E0119)",
                 _ => "",
             }
         )
@@ -480,7 +480,7 @@ fn report_conflicting_impls<'tcx>(
         }
         Some(kind) => {
             let lint = match kind {
-                FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS,
+                FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS,
                 FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
             };
             tcx.node_span_lint(
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index dba014d58b0..b6c2fcb46eb 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -3,6 +3,7 @@ use super::OverlapError;
 use crate::traits;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
+use rustc_macros::extension;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 
@@ -10,7 +11,7 @@ pub use rustc_middle::traits::specialization_graph::*;
 
 #[derive(Copy, Clone, Debug)]
 pub enum FutureCompatOverlapErrorKind {
-    Issue33140,
+    OrderDepTraitObjects,
     LeakCheck,
 }
 
@@ -149,10 +150,10 @@ impl<'tcx> Children {
                 {
                     match overlap_kind {
                         ty::ImplOverlapKind::Permitted { marker: _ } => {}
-                        ty::ImplOverlapKind::Issue33140 => {
+                        ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects => {
                             *last_lint_mut = Some(FutureCompatOverlapError {
                                 error: create_overlap_error(overlap),
-                                kind: FutureCompatOverlapErrorKind::Issue33140,
+                                kind: FutureCompatOverlapErrorKind::OrderDepTraitObjects,
                             });
                         }
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 5746e20490d..64ab8378abb 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -1,6 +1,7 @@
 use rustc_infer::infer::at::At;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
 use rustc_infer::traits::{FulfillmentError, TraitEngine};
+use rustc_macros::extension;
 use rustc_middle::ty::{self, Ty};
 
 use crate::traits::{NormalizeExt, Obligation};
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index a8ca7d164a0..b2ba7854f18 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_span::Span;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
 pub use rustc_infer::traits::util::*;
 
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index 46a68508753..178f3c63ef7 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry};
 use rustc_span::{sym, Span};
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
 use std::fmt::Debug;
 use std::ops::ControlFlow;
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index b2b5c6cd909..b96b1b67a74 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -4,14 +4,15 @@
 // general routines.
 
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
+use rustc_infer::traits::FulfillmentErrorCode;
+use rustc_middle::bug;
 use rustc_middle::traits::CodegenObligationError;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::{
-    ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
-    Unimplemented,
+    ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, Unimplemented,
 };
+use tracing::debug;
 
 /// Attempts to resolve an obligation to an `ImplSource`. The result is
 /// a shallow `ImplSource` resolution, meaning that we do not
@@ -49,15 +50,15 @@ pub fn codegen_select_candidate<'tcx>(
     // Currently, we use a fulfillment context to completely resolve
     // all nested obligations. This is because they can inform the
     // inference of the impl's type parameters.
-    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&infcx);
-    let impl_source = selection.map(|predicate| {
-        fulfill_cx.register_predicate_obligation(&infcx, predicate);
+    let ocx = ObligationCtxt::new(&infcx);
+    let impl_source = selection.map(|obligation| {
+        ocx.register_obligation(obligation);
     });
 
     // In principle, we only need to do this so long as `impl_source`
     // contains unbound type parameters. It could be a slight
     // optimization to stop iterating early.
-    let errors = fulfill_cx.select_all_or_error(&infcx);
+    let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
         // `rustc_monomorphize::collector` assumes there are no type errors.
         // Cycle errors are the only post-monomorphization errors possible; emit them now so
diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs
index f40c3614e1c..55abd6098ec 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult};
 use rustc_middle::ty::GenericArgs;
@@ -11,6 +12,7 @@ use rustc_trait_selection::traits::query::dropck_outlives::{
     compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner,
 };
 use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution};
+use tracing::debug;
 
 pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p };
diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs
index ce22da23fff..c9ad096c6e9 100644
--- a/compiler/rustc_traits/src/evaluate_obligation.rs
+++ b/compiler/rustc_traits/src/evaluate_obligation.rs
@@ -6,6 +6,7 @@ use rustc_trait_selection::traits::query::CanonicalPredicateGoal;
 use rustc_trait_selection::traits::{
     EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
 };
+use tracing::debug;
 
 pub(crate) fn provide(p: &mut Providers) {
     *p = Providers { evaluate_obligation, ..*p };
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index e73bbf6048e..bc5436f76f1 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -2,11 +2,6 @@
 
 #![recursion_limit = "256"]
 
-#[macro_use]
-extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
-
 mod codegen;
 mod dropck_outlives;
 mod evaluate_obligation;
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 0576fe01027..c5ebc2d26a7 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -4,6 +4,7 @@ use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
 use rustc_trait_selection::traits::{Normalized, ObligationCause};
+use tracing::debug;
 
 pub(crate) fn provide(p: &mut Providers) {
     *p = Providers {
diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs
index 92a19fb9119..559c05eb3e7 100644
--- a/compiler/rustc_traits/src/normalize_projection_ty.rs
+++ b/compiler/rustc_traits/src/normalize_projection_ty.rs
@@ -10,6 +10,7 @@ use rustc_trait_selection::traits::query::{
 use rustc_trait_selection::traits::{
     self, FulfillmentErrorCode, ObligationCause, SelectionContext,
 };
+use tracing::debug;
 
 pub(crate) fn provide(p: &mut Providers) {
     *p = Providers {
diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs
index 77d5a48f158..3378d1c6754 100644
--- a/compiler/rustc_transmute/src/layout/dfa.rs
+++ b/compiler/rustc_transmute/src/layout/dfa.rs
@@ -2,6 +2,7 @@ use super::{nfa, Byte, Nfa, Ref};
 use crate::Map;
 use std::fmt;
 use std::sync::atomic::{AtomicU32, Ordering};
+use tracing::instrument;
 
 #[derive(PartialEq, Clone, Debug)]
 pub(crate) struct Dfa<R>
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index edd3227210b..604b68d2cd4 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -266,7 +266,7 @@ pub(crate) mod rustc {
 
                 ty::Ref(lifetime, ty, mutability) => {
                     let ty_and_layout = cx.layout_of(*ty)?;
-                    let align = ty_and_layout.align.abi.bytes() as usize;
+                    let align = ty_and_layout.align.abi.bytes_usize();
                     let size = ty_and_layout.size.bytes_usize();
                     Ok(Tree::Ref(Ref {
                         lifetime: *lifetime,
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 12312271646..8d7d81d8f73 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -2,9 +2,6 @@
 #![feature(never_type)]
 #![allow(unused_variables)]
 
-#[macro_use]
-extern crate tracing;
-
 pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
 
 pub mod layout;
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
index 2789fe8f6b1..dee5a72c3bc 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
@@ -1,3 +1,5 @@
+use tracing::{debug, instrument, trace};
+
 pub(crate) mod query_context;
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index f0cea1f0baf..c6b83628506 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -854,7 +854,7 @@ fn make_thin_self_ptr<'tcx>(
     // we now have a type like `*mut RcBox<dyn Trait>`
     // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
     // this is understood as a special case elsewhere in the compiler
-    let unit_ptr_ty = Ty::new_mut_ptr(tcx, Ty::new_unit(tcx));
+    let unit_ptr_ty = Ty::new_mut_ptr(tcx, tcx.types.unit);
 
     TyAndLayout {
         ty: fat_pointer_ty,
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 2139b8c665b..fa1085c7cd7 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -243,37 +243,39 @@ fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamE
     tcx.param_env(def_id).with_reveal_all_normalized(tcx)
 }
 
-/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
+/// If the given trait impl enables exploiting the former order dependence of trait objects,
+/// returns its self type; otherwise, returns `None`.
 ///
-/// See [`ty::ImplOverlapKind::Issue33140`] for more details.
-fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'_>>> {
-    debug!("issue33140_self_ty({:?})", def_id);
-
-    let impl_ = tcx
-        .impl_trait_header(def_id)
-        .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id));
+/// See [`ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects`] for more details.
+#[instrument(level = "debug", skip(tcx))]
+fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
+    tcx: TyCtxt<'_>,
+    def_id: DefId,
+) -> Option<EarlyBinder<Ty<'_>>> {
+    let impl_ =
+        tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}"));
 
     let trait_ref = impl_.trait_ref.skip_binder();
-    debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref);
+    debug!(?trait_ref);
 
     let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive
         && tcx.associated_item_def_ids(trait_ref.def_id).is_empty();
 
     // Check whether these impls would be ok for a marker trait.
     if !is_marker_like {
-        debug!("issue33140_self_ty - not marker-like!");
+        debug!("not marker-like!");
         return None;
     }
 
     // impl must be `impl Trait for dyn Marker1 + Marker2 + ...`
     if trait_ref.args.len() != 1 {
-        debug!("issue33140_self_ty - impl has args!");
+        debug!("impl has args!");
         return None;
     }
 
     let predicates = tcx.predicates_of(def_id);
     if predicates.parent.is_some() || !predicates.predicates.is_empty() {
-        debug!("issue33140_self_ty - impl has predicates {:?}!", predicates);
+        debug!(?predicates, "impl has predicates!");
         return None;
     }
 
@@ -284,10 +286,10 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'
     };
 
     if self_ty_matches {
-        debug!("issue33140_self_ty - MATCHES!");
+        debug!("MATCHES!");
         Some(EarlyBinder::bind(self_ty))
     } else {
-        debug!("issue33140_self_ty - non-matching self type");
+        debug!("non-matching self type");
         None
     }
 }
@@ -351,7 +353,7 @@ pub(crate) fn provide(providers: &mut Providers) {
         adt_sized_constraint,
         param_env,
         param_env_reveal_all_normalized,
-        issue33140_self_ty,
+        self_ty_of_trait_impl_enabling_order_dep_trait_object_hack,
         defaultness,
         unsizing_params_for_adt,
         ..*providers
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 06a5051956a..f041c5831fc 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -1,5 +1,7 @@
 use rustc_ast_ir::try_visit;
 use rustc_ast_ir::visit::VisitorResult;
+#[cfg(feature = "nightly")]
+use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
 use std::fmt;
 use std::hash::Hash;
 
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index 5b08140db3a..c1506f9252b 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -1,5 +1,7 @@
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+#[cfg(feature = "nightly")]
+use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
 use std::fmt;
 
 use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs
index 997b410f819..6a1ac642b70 100644
--- a/compiler/rustc_type_ir/src/flags.rs
+++ b/compiler/rustc_type_ir/src/flags.rs
@@ -1,4 +1,4 @@
-bitflags! {
+bitflags::bitflags! {
     /// Flags that we track on types. These flags are propagated upwards
     /// through the type during type construction, so that we can quickly check
     /// whether the type has various kinds of types in it without recursing
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index a5b33a8125d..ef7437c2542 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -8,14 +8,10 @@
 #[cfg(feature = "nightly")]
 extern crate self as rustc_type_ir;
 
-#[macro_use]
-extern crate bitflags;
-#[cfg(feature = "nightly")]
-#[macro_use]
-extern crate rustc_macros;
-
 #[cfg(feature = "nightly")]
 use rustc_data_structures::sync::Lrc;
+#[cfg(feature = "nightly")]
+use rustc_macros::{Decodable, Encodable, HashStable_NoContext};
 use std::fmt;
 use std::hash::Hash;
 #[cfg(not(feature = "nightly"))]
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs
index 112f617fe16..5260d9061cf 100644
--- a/compiler/rustc_type_ir/src/predicate_kind.rs
+++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -1,5 +1,7 @@
 use rustc_ast_ir::try_visit;
 use rustc_ast_ir::visit::VisitorResult;
+#[cfg(feature = "nightly")]
+use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
 use std::fmt;
 
 use crate::fold::{FallibleTypeFolder, TypeFoldable};
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs
index e1247e2661a..d1b86b495e9 100644
--- a/compiler/rustc_type_ir/src/region_kind.rs
+++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -1,5 +1,7 @@
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+#[cfg(feature = "nightly")]
+use rustc_macros::{TyDecodable, TyEncodable};
 use std::fmt;
 
 use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 3924b371bbc..f2e4afecc40 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -3,6 +3,8 @@ use rustc_ast_ir::try_visit;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 #[cfg(feature = "nightly")]
 use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
+#[cfg(feature = "nightly")]
+use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
 use std::fmt;
 
 use crate::fold::{FallibleTypeFolder, TypeFoldable};
diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs
index e82d1f4813e..231d9ba49a3 100644
--- a/compiler/stable_mir/src/compiler_interface.rs
+++ b/compiler/stable_mir/src/compiler_interface.rs
@@ -221,7 +221,7 @@ pub trait Context {
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
 // datastructures and stable MIR datastructures
-scoped_thread_local!(static TLV: Cell<*const ()>);
+scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>);
 
 pub fn run<F, T>(context: &dyn Context, f: F) -> Result<T, Error>
 where
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index d1a2948ea77..d9f988935ab 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -16,8 +16,6 @@
 //!
 //! The goal is to eventually be published on
 //! [crates.io](https://crates.io).
-#[macro_use]
-extern crate scoped_tls;
 
 use std::fmt;
 use std::fmt::Debug;
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index b6b6246baa6..42f8a08a9e4 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -4,9 +4,9 @@
 
 use core::cmp::Ordering;
 use core::hash::{Hash, Hasher};
-use core::ops::Deref;
 #[cfg(not(no_global_oom_handling))]
 use core::ops::{Add, AddAssign};
+use core::ops::{Deref, DerefPure};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::borrow::{Borrow, BorrowMut};
@@ -343,6 +343,9 @@ where
     }
 }
 
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<B: ?Sized + ToOwned> DerefPure for Cow<'_, B> where B::Owned: Borrow<B> {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: ?Sized> Eq for Cow<'_, B> where B: Eq + ToOwned {}
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b417513aaa2..b93936869b3 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -137,7 +137,6 @@
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(maybe_uninit_uninit_array_transpose)]
-#![feature(non_null_convenience)]
 #![feature(panic_internals)]
 #![feature(pattern)]
 #![feature(ptr_internals)]
@@ -161,15 +160,11 @@
 #![feature(tuple_trait)]
 #![feature(unicode_internals)]
 #![feature(unsize)]
-#![feature(utf8_chunks)]
 #![feature(vec_pop_if)]
 // tidy-alphabetical-end
 //
 // Language features:
 // tidy-alphabetical-start
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
-#![cfg_attr(bootstrap, feature(inline_const))]
-#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
 #![cfg_attr(not(test), feature(coroutine_trait))]
 #![cfg_attr(test, feature(panic_update_hook))]
 #![cfg_attr(test, feature(test))]
@@ -200,6 +195,7 @@
 #![feature(unboxed_closures)]
 #![feature(unsized_fn_params)]
 #![feature(with_negative_coherence)]
+#![rustc_preserve_ub_checks]
 // tidy-alphabetical-end
 //
 // Rustdoc features:
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index a320a244abd..c245b42c3e8 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -3029,13 +3029,10 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
     /// [`as_ptr`]: Weak::as_ptr
     #[inline]
     #[unstable(feature = "allocator_api", issue = "32838")]
-    pub fn into_raw_and_alloc(self) -> (*const T, A)
-    where
-        A: Clone,
-    {
-        let result = self.as_ptr();
-        let alloc = self.alloc.clone();
-        mem::forget(self);
+    pub fn into_raw_and_alloc(self) -> (*const T, A) {
+        let rc = mem::ManuallyDrop::new(self);
+        let result = rc.as_ptr();
+        let alloc = unsafe { ptr::read(&rc.alloc) };
         (result, alloc)
     }
 
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index ade114678b7..c0d292cd208 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -53,7 +53,7 @@ pub use core::str::{RSplit, Split};
 pub use core::str::{RSplitN, SplitN};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::{RSplitTerminator, SplitTerminator};
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 pub use core::str::{Utf8Chunk, Utf8Chunks};
 
 /// Note: `str` in `Concat<str>` is not meaningful here.
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 082af1447ec..2a859ad55ee 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -58,8 +58,6 @@ use core::ops::{self, Range, RangeBounds};
 use core::ptr;
 use core::slice;
 use core::str::pattern::Pattern;
-#[cfg(not(no_global_oom_handling))]
-use core::str::Utf8Chunks;
 
 #[cfg(not(no_global_oom_handling))]
 use crate::borrow::{Cow, ToOwned};
@@ -633,7 +631,7 @@ impl String {
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
-        let mut iter = Utf8Chunks::new(v);
+        let mut iter = v.utf8_chunks();
 
         let first_valid = if let Some(chunk) = iter.next() {
             let valid = chunk.valid();
@@ -1384,7 +1382,7 @@ impl String {
 
     /// Shortens this `String` to the specified length.
     ///
-    /// If `new_len` is greater than the string's current length, this has no
+    /// If `new_len` is greater than or equal to the string's current length, this has no
     /// effect.
     ///
     /// Note that this method has no effect on the allocated capacity
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index b5175a8487f..0eae4ca4b8b 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -1,4 +1,3 @@
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(allocator_api)]
 #![feature(alloc_layout_extra)]
 #![feature(iter_array_chunks)]
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index ae0436bc520..4b491ffdafa 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -239,7 +239,7 @@ use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
 use crate::marker::{PhantomData, Unsize};
 use crate::mem::{self, size_of};
-use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn};
+use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
 use crate::ptr::{self, NonNull};
 
 mod lazy;
@@ -1452,6 +1452,9 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
     }
 }
 
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized> DerefPure for Ref<'_, T> {}
+
 impl<'b, T: ?Sized> Ref<'b, T> {
     /// Copies a `Ref`.
     ///
@@ -1844,6 +1847,9 @@ impl<T: ?Sized> DerefMut for RefMut<'_, T> {
     }
 }
 
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized> DerefPure for RefMut<'_, T> {}
+
 #[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
 
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 2fd9e17c994..fc6022ab753 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -379,7 +379,7 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
 // This is a lang item only so that `BinOp::Cmp` in MIR can return it.
 // It has no special behaviour, but does require that the three variants
 // `Less`/`Equal`/`Greater` remain `-1_i8`/`0_i8`/`+1_i8` respectively.
-#[cfg_attr(not(bootstrap), lang = "Ordering")]
+#[lang = "Ordering"]
 #[repr(i8)]
 pub enum Ordering {
     /// An ordering where a compared value is less than another.
@@ -852,7 +852,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_max")]
+    #[rustc_diagnostic_item = "cmp_ord_max"]
     fn max(self, other: Self) -> Self
     where
         Self: Sized,
@@ -873,7 +873,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_min")]
+    #[rustc_diagnostic_item = "cmp_ord_min"]
     fn min(self, other: Self) -> Self
     where
         Self: Sized,
@@ -1160,7 +1160,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_cmp")]
+    #[rustc_diagnostic_item = "cmp_partialord_cmp"]
     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
 
     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
@@ -1175,7 +1175,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_lt")]
+    #[rustc_diagnostic_item = "cmp_partialord_lt"]
     fn lt(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Less))
     }
@@ -1193,7 +1193,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_le")]
+    #[rustc_diagnostic_item = "cmp_partialord_le"]
     fn le(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Less | Equal))
     }
@@ -1210,7 +1210,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_gt")]
+    #[rustc_diagnostic_item = "cmp_partialord_gt"]
     fn gt(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Greater))
     }
@@ -1228,7 +1228,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_ge")]
+    #[rustc_diagnostic_item = "cmp_partialord_ge"]
     fn ge(&self, other: &Rhs) -> bool {
         matches!(self.partial_cmp(other), Some(Greater | Equal))
     }
@@ -1558,14 +1558,7 @@ mod impls {
             impl PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
-                    #[cfg(bootstrap)]
-                    {
-                        Some(self.cmp(other))
-                    }
-                    #[cfg(not(bootstrap))]
-                    {
-                        Some(crate::intrinsics::three_way_compare(*self, *other))
-                    }
+                    Some(crate::intrinsics::three_way_compare(*self, *other))
                 }
                 #[inline(always)]
                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
@@ -1581,18 +1574,7 @@ mod impls {
             impl Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &$t) -> Ordering {
-                    #[cfg(bootstrap)]
-                    {
-                        // The order here is important to generate more optimal assembly.
-                        // See <https://github.com/rust-lang/rust/issues/63758> for more info.
-                        if *self < *other { Less }
-                        else if *self == *other { Equal }
-                        else { Greater }
-                    }
-                    #[cfg(not(bootstrap))]
-                    {
-                        crate::intrinsics::three_way_compare(*self, *other)
-                    }
+                    crate::intrinsics::three_way_compare(*self, *other)
                 }
             }
         )*)
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index e717a8d022f..4524b352ec8 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -178,9 +178,7 @@ default_impl! { i32, 0, "Returns the default value of `0`" }
 default_impl! { i64, 0, "Returns the default value of `0`" }
 default_impl! { i128, 0, "Returns the default value of `0`" }
 
-#[cfg(not(bootstrap))]
 default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" }
 default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
 default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
-#[cfg(not(bootstrap))]
 default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" }
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index f4f33f8584b..aefb30463d3 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -528,7 +528,7 @@ impl CStr {
     #[inline]
     #[must_use]
     #[doc(alias("len", "strlen"))]
-    #[stable(feature = "cstr_count_bytes", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "cstr_count_bytes", since = "1.79.0")]
     #[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
     pub const fn count_bytes(&self) -> usize {
         self.inner.len() - 1
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index cbdae2ac766..27dacbb23d9 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -213,7 +213,7 @@ impl fmt::Debug for c_void {
         not(target_arch = "s390x"),
         not(target_arch = "x86_64")
     ),
-    all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")),
+    all(target_arch = "aarch64", target_vendor = "apple"),
     target_family = "wasm",
     target_os = "uefi",
     windows,
@@ -241,7 +241,7 @@ pub struct VaListImpl<'f> {
         not(target_arch = "s390x"),
         not(target_arch = "x86_64")
     ),
-    all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")),
+    all(target_arch = "aarch64", target_vendor = "apple"),
     target_family = "wasm",
     target_os = "uefi",
     windows,
@@ -265,7 +265,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> {
 /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
 #[cfg(all(
     target_arch = "aarch64",
-    not(any(target_os = "macos", target_os = "ios", target_os = "tvos")),
+    not(target_vendor = "apple"),
     not(target_os = "uefi"),
     not(windows),
 ))]
@@ -362,10 +362,7 @@ pub struct VaList<'a, 'f: 'a> {
             not(target_arch = "s390x"),
             not(target_arch = "x86_64")
         ),
-        all(
-            target_arch = "aarch64",
-            any(target_os = "macos", target_os = "ios", target_os = "tvos")
-        ),
+        all(target_arch = "aarch64", target_vendor = "apple"),
         target_family = "wasm",
         target_os = "uefi",
         windows,
@@ -379,10 +376,7 @@ pub struct VaList<'a, 'f: 'a> {
             target_arch = "s390x",
             target_arch = "x86_64"
         ),
-        any(
-            not(target_arch = "aarch64"),
-            not(any(target_os = "macos", target_os = "ios", target_os = "tvos"))
-        ),
+        any(not(target_arch = "aarch64"), not(target_vendor = "apple")),
         not(target_family = "wasm"),
         not(target_os = "uefi"),
         not(windows),
@@ -399,7 +393,7 @@ pub struct VaList<'a, 'f: 'a> {
         not(target_arch = "s390x"),
         not(target_arch = "x86_64")
     ),
-    all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")),
+    all(target_arch = "aarch64", target_vendor = "apple"),
     target_family = "wasm",
     target_os = "uefi",
     windows,
@@ -425,10 +419,7 @@ impl<'f> VaListImpl<'f> {
         target_arch = "s390x",
         target_arch = "x86_64"
     ),
-    any(
-        not(target_arch = "aarch64"),
-        not(any(target_os = "macos", target_os = "ios", target_os = "tvos"))
-    ),
+    any(not(target_arch = "aarch64"), not(target_vendor = "apple")),
     not(target_family = "wasm"),
     not(target_os = "uefi"),
     not(windows),
diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs
index c3bd18e30aa..873cccc7e96 100644
--- a/library/core/src/future/mod.rs
+++ b/library/core/src/future/mod.rs
@@ -12,7 +12,6 @@
 use crate::ptr::NonNull;
 use crate::task::Context;
 
-#[cfg(not(bootstrap))]
 mod async_drop;
 mod future;
 mod into_future;
@@ -38,7 +37,6 @@ pub use ready::{ready, Ready};
 #[stable(feature = "future_poll_fn", since = "1.64.0")]
 pub use poll_fn::{poll_fn, PollFn};
 
-#[cfg(not(bootstrap))]
 #[unstable(feature = "async_drop", issue = "none")]
 pub use async_drop::{async_drop, async_drop_in_place, AsyncDrop, AsyncDropInPlace};
 
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 7ace874fa90..d23764abe7a 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1128,7 +1128,7 @@ extern "rust-intrinsic" {
     /// any safety invariants.
     ///
     /// Consider using [`core::panic::Location::caller`] instead.
-    #[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_caller_location", since = "1.79.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn caller_location() -> &'static crate::panic::Location<'static>;
@@ -1987,18 +1987,11 @@ extern "rust-intrinsic" {
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `count_ones` method. For example,
     /// [`u32::count_ones`]
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn ctpop<T: Copy>(x: T) -> u32;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn ctpop<T: Copy>(x: T) -> T;
-
     /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2035,18 +2028,11 @@ extern "rust-intrinsic" {
     /// let num_leading = ctlz(x);
     /// assert_eq!(num_leading, 16);
     /// ```
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn ctlz<T: Copy>(x: T) -> u32;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn ctlz<T: Copy>(x: T) -> T;
-
     /// Like `ctlz`, but extra-unsafe as it returns `undef` when
     /// given an `x` with value `0`.
     ///
@@ -2064,16 +2050,10 @@ extern "rust-intrinsic" {
     /// let num_leading = unsafe { ctlz_nonzero(x) };
     /// assert_eq!(num_leading, 3);
     /// ```
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "constctlz", since = "1.50.0")]
     #[rustc_nounwind]
     pub fn ctlz_nonzero<T: Copy>(x: T) -> u32;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "constctlz", since = "1.50.0")]
-    #[rustc_nounwind]
-    pub fn ctlz_nonzero<T: Copy>(x: T) -> T;
-
     /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2110,18 +2090,11 @@ extern "rust-intrinsic" {
     /// let num_trailing = cttz(x);
     /// assert_eq!(num_trailing, 16);
     /// ```
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn cttz<T: Copy>(x: T) -> u32;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn cttz<T: Copy>(x: T) -> T;
-
     /// Like `cttz`, but extra-unsafe as it returns `undef` when
     /// given an `x` with value `0`.
     ///
@@ -2139,16 +2112,10 @@ extern "rust-intrinsic" {
     /// let num_trailing = unsafe { cttz_nonzero(x) };
     /// assert_eq!(num_trailing, 3);
     /// ```
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")]
     #[rustc_nounwind]
     pub fn cttz_nonzero<T: Copy>(x: T) -> u32;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")]
-    #[rustc_nounwind]
-    pub fn cttz_nonzero<T: Copy>(x: T) -> T;
-
     /// Reverses the bytes in an integer type `T`.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2186,7 +2153,6 @@ extern "rust-intrinsic" {
     /// large and difficult to optimize.
     ///
     /// The stabilized version of this intrinsic is [`Ord::cmp`].
-    #[cfg(not(bootstrap))]
     #[rustc_const_unstable(feature = "const_three_way_compare", issue = "none")]
     #[rustc_safe_intrinsic]
     pub fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> crate::cmp::Ordering;
@@ -2269,7 +2235,6 @@ extern "rust-intrinsic" {
     /// Safe wrappers for this intrinsic are available on the integer
     /// primitives via the `checked_shl` method. For example,
     /// [`u32::checked_shl`]
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
     #[rustc_nounwind]
     pub fn unchecked_shl<T: Copy, U: Copy>(x: T, y: U) -> T;
@@ -2279,7 +2244,6 @@ extern "rust-intrinsic" {
     /// Safe wrappers for this intrinsic are available on the integer
     /// primitives via the `checked_shr` method. For example,
     /// [`u32::checked_shr`]
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
     #[rustc_nounwind]
     pub fn unchecked_shr<T: Copy, U: Copy>(x: T, y: U) -> T;
@@ -2289,7 +2253,7 @@ extern "rust-intrinsic" {
     ///
     /// The stable counterpart of this intrinsic is `unchecked_add` on the various
     /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`].
-    #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
     #[rustc_nounwind]
     pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
 
@@ -2298,7 +2262,7 @@ extern "rust-intrinsic" {
     ///
     /// The stable counterpart of this intrinsic is `unchecked_sub` on the various
     /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`].
-    #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
     #[rustc_nounwind]
     pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
 
@@ -2307,7 +2271,7 @@ extern "rust-intrinsic" {
     ///
     /// The stable counterpart of this intrinsic is `unchecked_mul` on the various
     /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`].
-    #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
     #[rustc_nounwind]
     pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
 
@@ -2321,18 +2285,11 @@ extern "rust-intrinsic" {
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_left` method. For example,
     /// [`u32::rotate_left`]
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn rotate_left<T: Copy>(x: T, shift: u32) -> T;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn rotate_left<T: Copy>(x: T, y: T) -> T;
-
     /// Performs rotate right.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2343,18 +2300,11 @@ extern "rust-intrinsic" {
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_right` method. For example,
     /// [`u32::rotate_right`]
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn rotate_right<T: Copy>(x: T, shift: u32) -> T;
 
-    #[cfg(bootstrap)]
-    #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
-
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
     /// Note that, unlike most intrinsics, this is safe to call;
@@ -2507,12 +2457,6 @@ extern "rust-intrinsic" {
     #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
     #[rustc_nounwind]
     pub fn ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
-
-    #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    #[cfg(bootstrap)]
-    pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
 }
 
 /// See documentation of `<*const T>::guaranteed_eq` for details.
@@ -2522,7 +2466,6 @@ extern "rust-intrinsic" {
 #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
-#[cfg(not(bootstrap))]
 #[rustc_nounwind]
 #[rustc_do_not_const_check]
 #[inline]
@@ -2581,28 +2524,6 @@ extern "rust-intrinsic" {
     #[rustc_safe_intrinsic]
     #[rustc_nounwind]
     pub fn black_box<T>(dummy: T) -> T;
-
-    #[rustc_nounwind]
-    #[cfg(bootstrap)]
-    pub fn vtable_size(ptr: *const ()) -> usize;
-
-    /// `ptr` must point to a vtable.
-    /// The intrinsic will return the alignment stored in that vtable.
-    #[rustc_nounwind]
-    #[cfg(bootstrap)]
-    pub fn vtable_align(ptr: *const ()) -> usize;
-
-    #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
-    #[rustc_safe_intrinsic]
-    #[cfg(bootstrap)]
-    pub fn const_eval_select<ARG: Tuple, F, G, RET>(
-        arg: ARG,
-        called_in_const: F,
-        called_at_rt: G,
-    ) -> RET
-    where
-        G: FnOnce<ARG, Output = RET>,
-        F: FnOnce<ARG, Output = RET>;
 }
 
 /// Selects which function to call depending on the context.
@@ -2637,11 +2558,9 @@ extern "rust-intrinsic" {
 /// #![feature(const_eval_select)]
 /// #![feature(core_intrinsics)]
 /// # #![allow(internal_features)]
-/// # #![cfg_attr(bootstrap, allow(unused))]
 /// use std::intrinsics::const_eval_select;
 ///
 /// // Standard library
-/// # #[cfg(not(bootstrap))]
 /// pub const fn inconsistent() -> i32 {
 ///     fn runtime() -> i32 { 1 }
 ///     const fn compiletime() -> i32 { 2 }
@@ -2650,8 +2569,6 @@ extern "rust-intrinsic" {
 ///     // and `runtime`.
 ///     const_eval_select((), compiletime, runtime)
 /// }
-/// # #[cfg(bootstrap)]
-/// # pub const fn inconsistent() -> i32 { 0 }
 ///
 /// // User Crate
 /// const X: i32 = inconsistent();
@@ -2661,9 +2578,7 @@ extern "rust-intrinsic" {
 ///
 /// Currently such an assertion would always succeed; until Rust decides
 /// otherwise, that principle should not be violated.
-#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
-#[unstable(feature = "core_intrinsics", issue = "none")]
-#[cfg(not(bootstrap))]
+#[rustc_const_unstable(feature = "const_eval_select", issue = "124625")]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
@@ -2717,10 +2632,45 @@ where
 /// particular value, ever. However, the compiler will generally make it
 /// return `true` only if the value of the argument is actually known.
 ///
-/// When calling this in a `const fn`, both paths must be semantically
-/// equivalent, that is, the result of the `true` branch and the `false`
-/// branch must return the same value and have the same side-effects *no
-/// matter what*.
+/// # Stability concerns
+///
+/// While it is safe to call, this intrinsic may behave differently in
+/// a `const` context than otherwise. See the [`const_eval_select`]
+/// documentation for an explanation of the issues this can cause. Unlike
+/// `const_eval_select`, this intrinsic isn't guaranteed to behave
+/// deterministically even in a `const` context.
+///
+/// # Type Requirements
+///
+/// `T` must be either a `bool`, a `char`, a primitive numeric type (e.g. `f32`,
+/// but not `NonZeroISize`), or any thin pointer (e.g. `*mut String`).
+/// Any other argument types *may* cause a compiler error.
+///
+/// ## Pointers
+///
+/// When the input is a pointer, only the pointer itself is
+/// ever considered. The pointee has no effect. Currently, these functions
+/// behave identically:
+///
+/// ```
+/// #![feature(is_val_statically_known)]
+/// #![feature(core_intrinsics)]
+/// # #![allow(internal_features)]
+/// #![feature(strict_provenance)]
+/// use std::intrinsics::is_val_statically_known;
+///
+/// fn foo(x: &i32) -> bool {
+///     is_val_statically_known(x)
+/// }
+///
+/// fn bar(x: &i32) -> bool {
+///     is_val_statically_known(
+///         (x as *const i32).addr()
+///     )
+/// }
+/// # _ = foo(&5_i32);
+/// # _ = bar(&5_i32);
+/// ```
 #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
@@ -2741,7 +2691,7 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 /// `x` and `y` are readable and writable as `T`, and non-overlapping.
 #[rustc_nounwind]
 #[inline]
-#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[rustc_intrinsic]
 // This has fallback `const fn` MIR, so shouldn't need stability, see #122652
 #[rustc_const_unstable(feature = "const_typed_swap", issue = "none")]
 pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
@@ -2766,8 +2716,8 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
 #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[inline(always)]
-#[cfg_attr(not(bootstrap), rustc_intrinsic)] // just make it a regular fn in bootstrap
-pub(crate) const fn ub_checks() -> bool {
+#[rustc_intrinsic]
+pub const fn ub_checks() -> bool {
     cfg!(debug_assertions)
 }
 
@@ -2810,7 +2760,6 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
-#[cfg(not(bootstrap))]
 pub unsafe fn vtable_size(_ptr: *const ()) -> usize {
     unreachable!()
 }
@@ -2821,7 +2770,6 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize {
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
-#[cfg(not(bootstrap))]
 pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
     unreachable!()
 }
@@ -2836,7 +2784,6 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
 #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
-#[cfg(not(bootstrap))]
 pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
     // To implement a fallback we'd have to assume the layout of the pointer,
     // but the whole point of this intrinsic is that we shouldn't do that.
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index eeff4ec609a..ceea6790129 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -540,12 +540,8 @@ extern "rust-intrinsic" {
     /// `T` must be a vector of pointers.
     ///
     /// `U` must be a vector of `usize` with the same length as `T`.
-    #[cfg(not(bootstrap))]
     #[rustc_nounwind]
     pub fn simd_expose_provenance<T, U>(ptr: T) -> U;
-    #[cfg(bootstrap)]
-    #[rustc_nounwind]
-    pub fn simd_expose_addr<T, U>(ptr: T) -> U;
 
     /// Create a vector of pointers from a vector of addresses.
     ///
@@ -553,11 +549,7 @@ extern "rust-intrinsic" {
     ///
     /// `U` must be a vector of pointers, with the same length as `T`.
     #[rustc_nounwind]
-    #[cfg(not(bootstrap))]
     pub fn simd_with_exposed_provenance<T, U>(addr: T) -> U;
-    #[rustc_nounwind]
-    #[cfg(bootstrap)]
-    pub fn simd_from_exposed_addr<T, U>(addr: T) -> U;
 
     /// Swap bytes of each element.
     ///
@@ -663,8 +655,3 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn simd_flog<T>(a: T) -> T;
 }
-
-#[cfg(bootstrap)]
-pub use simd_expose_addr as simd_expose_provenance;
-#[cfg(bootstrap)]
-pub use simd_from_exposed_addr as simd_with_exposed_provenance;
diff --git a/library/core/src/iter/sources/from_coroutine.rs b/library/core/src/iter/sources/from_coroutine.rs
index 9bac9037a02..710ba504ded 100644
--- a/library/core/src/iter/sources/from_coroutine.rs
+++ b/library/core/src/iter/sources/from_coroutine.rs
@@ -14,7 +14,7 @@ use crate::pin::Pin;
 /// #![feature(coroutines)]
 /// #![feature(iter_from_coroutine)]
 ///
-/// let it = std::iter::from_coroutine(#[cfg_attr(not(bootstrap), coroutine)] || {
+/// let it = std::iter::from_coroutine(#[coroutine] || {
 ///     yield 1;
 ///     yield 2;
 ///     yield 3;
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index 2ebbe2bf274..563781230c0 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -169,7 +169,7 @@ pub trait FromIterator<A>: Sized {
 /// assert_eq!(lengths, [1, 1, 3, 1]);
 /// # Ok(()) }
 /// ```
-#[stable(feature = "from_iterator_for_tuple", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "from_iterator_for_tuple", since = "1.79.0")]
 impl<A, B, AE, BE> FromIterator<(AE, BE)> for (A, B)
 where
     A: Default + Extend<AE>,
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 7c1c6122efe..cee99e28b5a 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -974,6 +974,7 @@ pub trait Iterator {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_do_not_const_check]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "enumerate_method")]
     fn enumerate(self) -> Enumerate<Self>
     where
         Self: Sized,
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index ad4d63d83b5..2e756a6dd67 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -28,7 +28,7 @@ pub unsafe trait TrustedFused {}
 #[rustc_unsafe_specialization_marker]
 // FIXME: this should be a #[marker] and have another blanket impl for T: TrustedFused
 // but that ICEs iter::Fuse specializations.
-#[cfg_attr(not(bootstrap), lang = "fused_iterator")]
+#[lang = "fused_iterator"]
 pub trait FusedIterator: Iterator {}
 
 #[stable(feature = "fused", since = "1.26.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 6925a7d1da1..5dcef638954 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -90,7 +90,7 @@
 ))]
 #![no_core]
 #![rustc_coherence_is_core]
-#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
+#![rustc_preserve_ub_checks]
 //
 // Lints:
 #![deny(rust_2021_incompatible_or_patterns)]
@@ -109,7 +109,6 @@
 //
 // Library features:
 // tidy-alphabetical-start
-#![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(array_ptr_get)]
 #![feature(asm_experimental_arch)]
 #![feature(char_indices_offset)]
@@ -180,7 +179,6 @@
 #![feature(isqrt)]
 #![feature(link_cfg)]
 #![feature(maybe_uninit_uninit_array)]
-#![feature(non_null_convenience)]
 #![feature(offset_of_enum)]
 #![feature(offset_of_nested)]
 #![feature(panic_internals)]
@@ -193,6 +191,7 @@
 #![feature(str_split_inclusive_remainder)]
 #![feature(str_split_remainder)]
 #![feature(strict_provenance)]
+#![feature(ub_checks)]
 #![feature(unchecked_shifts)]
 #![feature(utf16_extra)]
 #![feature(utf16_extra_const)]
@@ -201,7 +200,6 @@
 //
 // Language features:
 // tidy-alphabetical-start
-#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -370,7 +368,8 @@ pub mod hint;
 pub mod intrinsics;
 pub mod mem;
 pub mod ptr;
-mod ub_checks;
+#[unstable(feature = "ub_checks", issue = "none")]
+pub mod ub_checks;
 
 /* Core language traits */
 
@@ -401,7 +400,6 @@ pub mod net;
 pub mod option;
 pub mod panic;
 pub mod panicking;
-#[cfg(not(bootstrap))]
 #[unstable(feature = "core_pattern_types", issue = "none")]
 pub mod pat;
 pub mod pin;
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 6da05a1ca86..2ddedfa37fe 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1711,11 +1711,11 @@ pub(crate) mod builtin {
         issue = "23416",
         reason = "placeholder syntax for type ascription"
     )]
+    #[rustfmt::skip]
     pub macro type_ascribe($expr:expr, $ty:ty) {
         builtin # type_ascribe($expr, $ty)
     }
 
-    #[cfg(not(bootstrap))]
     /// Unstable placeholder for deref patterns.
     #[allow_internal_unstable(builtin_syntax)]
     #[unstable(
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 98cff3493a7..955efb9b0f9 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -1,4 +1,4 @@
-use crate::ops::{Deref, DerefMut};
+use crate::ops::{Deref, DerefMut, DerefPure};
 use crate::ptr;
 
 /// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
@@ -161,3 +161,6 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
         &mut self.value
     }
 }
+
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized> DerefPure for ManuallyDrop<T> {}
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 75d42edbaa0..9054ade2d79 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1340,8 +1340,8 @@ impl<T> SizedTypeProperties for T {}
 /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
 /// ```
 #[stable(feature = "offset_of", since = "1.77.0")]
-#[allow_internal_unstable(builtin_syntax, hint_must_use)]
+#[allow_internal_unstable(builtin_syntax)]
 pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
     // The `{}` is for better error messages
-    crate::hint::must_use({builtin # offset_of($Container, $($fields)+)})
+    {builtin # offset_of($Container, $($fields)+)}
 }
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index a92da88dd3f..77b1039039b 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -481,8 +481,8 @@ macro_rules! int_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")]
         #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -623,8 +623,8 @@ macro_rules! int_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")]
         #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -765,8 +765,8 @@ macro_rules! int_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")]
         #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -1234,18 +1234,9 @@ macro_rules! int_impl {
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
-            #[cfg(bootstrap)]
-            {
-                // For bootstrapping, just use built-in primitive shift.
-                // panicking is a legal manifestation of UB
-                self << rhs
-            }
-            #[cfg(not(bootstrap))]
-            {
                 // SAFETY: the caller must uphold the safety contract for
                 // `unchecked_shl`.
                 unsafe { intrinsics::unchecked_shl(self, rhs) }
-            }
         }
 
         /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
@@ -1332,18 +1323,9 @@ macro_rules! int_impl {
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
-            #[cfg(bootstrap)]
-            {
-                // For bootstrapping, just use built-in primitive shift.
-                // panicking is a legal manifestation of UB
-                self >> rhs
-            }
-            #[cfg(not(bootstrap))]
-            {
-                // SAFETY: the caller must uphold the safety contract for
-                // `unchecked_shr`.
-                unsafe { intrinsics::unchecked_shr(self, rhs) }
-            }
+            // SAFETY: the caller must uphold the safety contract for
+            // `unchecked_shr`.
+            unsafe { intrinsics::unchecked_shr(self, rhs) }
         }
 
         /// Checked absolute value. Computes `self.abs()`, returning `None` if
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 443401c5dba..c02f73fdf03 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -67,7 +67,7 @@ pub use error::ParseIntError;
 )]
 pub use nonzero::ZeroablePrimitive;
 
-#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "generic_nonzero", since = "1.79.0")]
 pub use nonzero::NonZero;
 
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 5a0958fdc89..5d3ae7316b1 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -109,7 +109,7 @@ impl_zeroable_primitive!(
 ///
 /// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>());
 /// ```
-#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "generic_nonzero", since = "1.79.0")]
 #[repr(transparent)]
 #[rustc_nonnull_optimization_guaranteed]
 #[rustc_diagnostic_item = "NonZero"]
@@ -528,10 +528,7 @@ macro_rules! nonzero_integer {
             pub const fn leading_zeros(self) -> u32 {
                 // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
                 unsafe {
-                    #[cfg(not(bootstrap))]
-                    return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive);
-                    #[cfg(bootstrap)]
-                    return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) as u32;
+                    intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive)
                 }
             }
 
@@ -557,10 +554,7 @@ macro_rules! nonzero_integer {
             pub const fn trailing_zeros(self) -> u32 {
                 // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
                 unsafe {
-                    #[cfg(not(bootstrap))]
-                    return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive);
-                    #[cfg(bootstrap)]
-                    return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) as u32;
+                    intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive)
                 }
             }
 
@@ -861,7 +855,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
             }
         }
 
-        #[stable(feature = "nonzero_div_assign", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "nonzero_div_assign", since = "1.79.0")]
         impl DivAssign<$Ty> for $Int {
             /// This operation rounds towards zero,
             /// truncating any fractional part of the exact result, and cannot panic.
@@ -884,7 +878,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
             }
         }
 
-        #[stable(feature = "nonzero_div_assign", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "nonzero_div_assign", since = "1.79.0")]
         impl RemAssign<$Ty> for $Int {
             /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
             #[inline]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index ea14d769cc1..9effa279b48 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -77,10 +77,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline(always)]
         pub const fn count_ones(self) -> u32 {
-            #[cfg(not(bootstrap))]
             return intrinsics::ctpop(self as $ActualT);
-            #[cfg(bootstrap)]
-            return intrinsics::ctpop(self as $ActualT) as u32;
         }
 
         /// Returns the number of zeros in the binary representation of `self`.
@@ -122,10 +119,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline(always)]
         pub const fn leading_zeros(self) -> u32 {
-            #[cfg(not(bootstrap))]
             return intrinsics::ctlz(self as $ActualT);
-            #[cfg(bootstrap)]
-            return intrinsics::ctlz(self as $ActualT) as u32;
         }
 
         /// Returns the number of trailing zeros in the binary representation
@@ -146,10 +140,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline(always)]
         pub const fn trailing_zeros(self) -> u32 {
-            #[cfg(not(bootstrap))]
             return intrinsics::cttz(self);
-            #[cfg(bootstrap)]
-            return intrinsics::cttz(self) as u32;
         }
 
         /// Returns the number of leading ones in the binary representation of `self`.
@@ -214,10 +205,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline(always)]
         pub const fn rotate_left(self, n: u32) -> Self {
-            #[cfg(not(bootstrap))]
             return intrinsics::rotate_left(self, n);
-            #[cfg(bootstrap)]
-            return intrinsics::rotate_left(self, n as $SelfT);
         }
 
         /// Shifts the bits to the right by a specified amount, `n`,
@@ -242,10 +230,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline(always)]
         pub const fn rotate_right(self, n: u32) -> Self {
-            #[cfg(not(bootstrap))]
             return intrinsics::rotate_right(self, n);
-            #[cfg(bootstrap)]
-            return intrinsics::rotate_right(self, n as $SelfT);
         }
 
         /// Reverses the byte order of the integer.
@@ -503,8 +488,8 @@ macro_rules! uint_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")]
         #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -660,8 +645,8 @@ macro_rules! uint_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")]
         #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -746,8 +731,8 @@ macro_rules! uint_impl {
         /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
         #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")]
         #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")]
-        #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "unchecked_math", since = "1.79.0")]
+        #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
@@ -1324,18 +1309,9 @@ macro_rules! uint_impl {
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
-            #[cfg(bootstrap)]
-            {
-                // For bootstrapping, just use built-in primitive shift.
-                // panicking is a legal manifestation of UB
-                self << rhs
-            }
-            #[cfg(not(bootstrap))]
-            {
-                // SAFETY: the caller must uphold the safety contract for
-                // `unchecked_shl`.
-                unsafe { intrinsics::unchecked_shl(self, rhs) }
-            }
+            // SAFETY: the caller must uphold the safety contract for
+            // `unchecked_shl`.
+            unsafe { intrinsics::unchecked_shl(self, rhs) }
         }
 
         /// Checked shift right. Computes `self >> rhs`, returning `None`
@@ -1422,18 +1398,9 @@ macro_rules! uint_impl {
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
-            #[cfg(bootstrap)]
-            {
-                // For bootstrapping, just use built-in primitive shift.
-                // panicking is a legal manifestation of UB
-                self >> rhs
-            }
-            #[cfg(not(bootstrap))]
-            {
                 // SAFETY: the caller must uphold the safety contract for
                 // `unchecked_shr`.
                 unsafe { intrinsics::unchecked_shr(self, rhs) }
-            }
         }
 
         /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs
index 5250be15fe4..6a6c5db1ab1 100644
--- a/library/core/src/ops/coroutine.rs
+++ b/library/core/src/ops/coroutine.rs
@@ -46,7 +46,7 @@ pub enum CoroutineState<Y, R> {
 /// use std::pin::Pin;
 ///
 /// fn main() {
-///     let mut coroutine = #[cfg_attr(not(bootstrap), coroutine)] || {
+///     let mut coroutine = #[coroutine] || {
 ///         yield 1;
 ///         "foo"
 ///     };
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 3795a81c2c1..9849410d484 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -285,7 +285,7 @@ impl<T: ?Sized> DerefMut for &mut T {
 /// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise
 /// unchanged.
 #[unstable(feature = "deref_pure_trait", issue = "87121")]
-#[cfg_attr(not(bootstrap), lang = "deref_pure")]
+#[lang = "deref_pure"]
 pub unsafe trait DerefPure {}
 
 #[unstable(feature = "deref_pure_trait", issue = "87121")]
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index 1325d90e4f3..36ae581e3f7 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -240,7 +240,6 @@ pub trait Drop {
 }
 
 /// Fallback function to call surface level `Drop::drop` function
-#[cfg(not(bootstrap))]
 #[allow(drop_bounds)]
 #[lang = "fallback_surface_drop"]
 pub(crate) fn fallback_surface_drop<T: Drop + ?Sized>(x: &mut T) {
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index 81d5e5c949e..7bcfaadbe37 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -174,7 +174,6 @@ pub use self::deref::Receiver;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::drop::Drop;
 
-#[cfg(not(bootstrap))]
 pub(crate) use self::drop::fallback_surface_drop;
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs
index 4ad507d8b86..eb27da1724e 100644
--- a/library/core/src/panic/location.rs
+++ b/library/core/src/panic/location.rs
@@ -81,7 +81,7 @@ impl<'a> Location<'a> {
     /// ```
     #[must_use]
     #[stable(feature = "track_caller", since = "1.46.0")]
-    #[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_caller_location", since = "1.79.0")]
     #[track_caller]
     #[inline]
     pub const fn caller() -> &'static Location<'static> {
@@ -123,7 +123,7 @@ impl<'a> Location<'a> {
     /// ```
     #[must_use]
     #[stable(feature = "panic_hooks", since = "1.10.0")]
-    #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
     #[inline]
     pub const fn file(&self) -> &str {
         self.file
@@ -148,7 +148,7 @@ impl<'a> Location<'a> {
     /// ```
     #[must_use]
     #[stable(feature = "panic_hooks", since = "1.10.0")]
-    #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
     #[inline]
     pub const fn line(&self) -> u32 {
         self.line
@@ -173,7 +173,7 @@ impl<'a> Location<'a> {
     /// ```
     #[must_use]
     #[stable(feature = "panic_col", since = "1.25.0")]
-    #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
     #[inline]
     pub const fn column(&self) -> u32 {
         self.col
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 3ee56e6c579..ca06e059b75 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -156,7 +156,6 @@ pub const fn panic(expr: &'static str) -> ! {
 // reducing binary size impact.
 macro_rules! panic_const {
     ($($lang:ident = $message:expr,)+) => {
-        #[cfg(not(bootstrap))]
         pub mod panic_const {
             use super::*;
 
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index a11c6c742d7..d8fc3b7177f 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -923,7 +923,7 @@
 use crate::cmp;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
+use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver};
 
 #[allow(unused_imports)]
 use crate::{
@@ -1684,6 +1684,9 @@ impl<Ptr: DerefMut<Target: Unpin>> DerefMut for Pin<Ptr> {
     }
 }
 
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<Ptr: DerefPure> DerefPure for Pin<Ptr> {}
+
 #[unstable(feature = "receiver_trait", issue = "none")]
 impl<Ptr: Receiver> Receiver for Pin<Ptr> {}
 
@@ -1809,7 +1812,7 @@ impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr> where Ptr: DispatchFromDyn<U>
 /// fn coroutine_fn() -> impl Coroutine<Yield = usize, Return = ()> /* not Unpin */ {
 ///  // Allow coroutine to be self-referential (not `Unpin`)
 ///  // vvvvvv        so that locals can cross yield points.
-///     #[cfg_attr(not(bootstrap), coroutine)] static || {
+///     #[coroutine] static || {
 ///         let foo = String::from("foo");
 ///         let foo_ref = &foo; // ------+
 ///         yield 0;                  // | <- crosses yield point!
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index b98f3a4659b..afc6817aa1d 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -97,7 +97,6 @@ pub use crate::macros::builtin::cfg_eval;
 )]
 pub use crate::macros::builtin::type_ascribe;
 
-#[cfg(not(bootstrap))]
 #[unstable(
     feature = "deref_patterns",
     issue = "87121",
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index bda1ee6f457..18a9503cfd2 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -268,6 +268,53 @@ mod prim_bool {}
 /// [`Debug`]: fmt::Debug
 /// [`default()`]: Default::default
 ///
+/// # Never type fallback
+///
+/// When the compiler sees a value of type `!` in a [coercion site], it implicitly inserts a
+/// coercion to allow the type checker to infer any type:
+///
+/// ```rust,ignore (illustrative-and-has-placeholders)
+/// // this
+/// let x: u8 = panic!();
+///
+/// // is (essentially) turned by the compiler into
+/// let x: u8 = absurd(panic!());
+///
+/// // where absurd is a function with the following signature
+/// // (it's sound, because `!` always marks unreachable code):
+/// fn absurd<T>(_: !) -> T { ... }
+// FIXME: use `core::convert::absurd` here instead, once it's merged
+/// ```
+///
+/// This can lead to compilation errors if the type cannot be inferred:
+///
+/// ```compile_fail
+/// // this
+/// { panic!() };
+///
+/// // gets turned into this
+/// { absurd(panic!()) }; // error: can't infer the type of `absurd`
+/// ```
+///
+/// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and
+/// if it can't infer the type, it uses the fallback type instead:
+/// ```rust, ignore
+/// type Fallback = /* An arbitrarily selected type! */;
+/// { absurd::<Fallback>(panic!()) }
+/// ```
+///
+/// This is what is known as "never type fallback".
+///
+/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously
+/// coerced to `()`, even when it would not infer `()` without the fallback. There are plans to
+/// change it in the [2024 edition] (and possibly in all editions on a later date); see
+/// [Tracking Issue for making `!` fall back to `!`][fallback-ti].
+///
+/// [coercion site]: <https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites>
+/// [`()`]: prim@unit
+/// [fallback-ti]: <https://github.com/rust-lang/rust/issues/123748>
+/// [2024 edition]: <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html>
+///
 #[unstable(feature = "never_type", issue = "35121")]
 mod prim_never {}
 
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 9737fb8816e..e9eeb315330 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1496,7 +1496,7 @@ impl<T: ?Sized> *const T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "pointer_is_aligned", since = "1.79.0")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned(self) -> bool
     where
@@ -1653,8 +1653,8 @@ impl<T> *const [T] {
     /// assert_eq!(slice.len(), 3);
     /// ```
     #[inline]
-    #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
+    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
     #[rustc_allow_const_fn_unstable(ptr_metadata)]
     pub const fn len(self) -> usize {
         metadata(self)
@@ -1671,8 +1671,8 @@ impl<T> *const [T] {
     /// assert!(!slice.is_empty());
     /// ```
     #[inline(always)]
-    #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
+    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
     pub const fn is_empty(self) -> bool {
         self.len() == 0
     }
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 1226c8e2419..eb815b6d822 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -2,7 +2,6 @@
 
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-#[cfg(not(bootstrap))]
 use crate::intrinsics::aggregate_raw_ptr;
 use crate::marker::Freeze;
 
@@ -115,17 +114,7 @@ pub const fn from_raw_parts<T: ?Sized>(
     data_pointer: *const (),
     metadata: <T as Pointee>::Metadata,
 ) -> *const T {
-    #[cfg(bootstrap)]
-    {
-        // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
-        // and PtrComponents<T> have the same memory layouts. Only std can make this
-        // guarantee.
-        unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
-    }
-    #[cfg(not(bootstrap))]
-    {
-        aggregate_raw_ptr(data_pointer, metadata)
-    }
+    aggregate_raw_ptr(data_pointer, metadata)
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
@@ -139,17 +128,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
     data_pointer: *mut (),
     metadata: <T as Pointee>::Metadata,
 ) -> *mut T {
-    #[cfg(bootstrap)]
-    {
-        // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
-        // and PtrComponents<T> have the same memory layouts. Only std can make this
-        // guarantee.
-        unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
-    }
-    #[cfg(not(bootstrap))]
-    {
-        aggregate_raw_ptr(data_pointer, metadata)
-    }
+    aggregate_raw_ptr(data_pointer, metadata)
 }
 
 #[repr(C)]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index f12ab3d50cd..5f3815859c8 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1784,15 +1784,6 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz
         assume, cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_sub,
         wrapping_add, wrapping_mul, wrapping_sub,
     };
-    #[cfg(bootstrap)]
-    const unsafe fn unchecked_shl(value: usize, shift: usize) -> usize {
-        value << shift
-    }
-    #[cfg(bootstrap)]
-    const unsafe fn unchecked_shr(value: usize, shift: usize) -> usize {
-        value >> shift
-    }
-    #[cfg(not(bootstrap))]
     use intrinsics::{unchecked_shl, unchecked_shr};
 
     /// Calculate multiplicative modular inverse of `x` modulo `m`.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index d8f91f1996b..c5a188dc7d4 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1756,7 +1756,7 @@ impl<T: ?Sized> *mut T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "pointer_is_aligned", since = "1.79.0")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned(self) -> bool
     where
@@ -1915,8 +1915,8 @@ impl<T> *mut [T] {
     /// assert_eq!(slice.len(), 3);
     /// ```
     #[inline(always)]
-    #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
+    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
     #[rustc_allow_const_fn_unstable(ptr_metadata)]
     pub const fn len(self) -> usize {
         metadata(self)
@@ -1933,8 +1933,8 @@ impl<T> *mut [T] {
     /// assert!(!slice.is_empty());
     /// ```
     #[inline(always)]
-    #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
+    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
     pub const fn is_empty(self) -> bool {
         self.len() == 0
     }
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 96ce3cd3a3f..617890cf083 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -512,7 +512,6 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
     /// use std::ptr::NonNull;
     ///
     /// let mut s = [1, 2, 3];
@@ -523,12 +522,12 @@ impl<T: ?Sized> NonNull<T> {
     ///     println!("{}", ptr.offset(2).read());
     /// }
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
-    pub const unsafe fn offset(self, count: isize) -> NonNull<T>
+    #[must_use = "returns a new pointer rather than modifying its argument"]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    pub const unsafe fn offset(self, count: isize) -> Self
     where
         T: Sized,
     {
@@ -549,11 +548,11 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// For non-`Sized` pointees this operation changes only the data pointer,
     /// leaving the metadata untouched.
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[must_use]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn byte_offset(self, count: isize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `offset` and `byte_offset` has
         // the same safety contract.
@@ -599,7 +598,6 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
     /// use std::ptr::NonNull;
     ///
     /// let s: &str = "123";
@@ -610,11 +608,11 @@ impl<T: ?Sized> NonNull<T> {
     ///     println!("{}", ptr.add(2).read() as char);
     /// }
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[must_use = "returns a new pointer rather than modifying its argument"]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn add(self, count: usize) -> Self
     where
         T: Sized,
@@ -636,12 +634,12 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// For non-`Sized` pointees this operation changes only the data pointer,
     /// leaving the metadata untouched.
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[must_use]
     #[inline(always)]
-    #[rustc_allow_const_fn_unstable(set_ptr_value)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[rustc_allow_const_fn_unstable(set_ptr_value)]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn byte_add(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `add` and `byte_add` has the same
         // safety contract.
@@ -688,7 +686,6 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
     /// use std::ptr::NonNull;
     ///
     /// let s: &str = "123";
@@ -699,11 +696,11 @@ impl<T: ?Sized> NonNull<T> {
     ///     println!("{}", end.sub(2).read() as char);
     /// }
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[must_use = "returns a new pointer rather than modifying its argument"]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn sub(self, count: usize) -> Self
     where
         T: Sized,
@@ -730,12 +727,12 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// For non-`Sized` pointees this operation changes only the data pointer,
     /// leaving the metadata untouched.
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[must_use]
     #[inline(always)]
-    #[rustc_allow_const_fn_unstable(set_ptr_value)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[rustc_allow_const_fn_unstable(set_ptr_value)]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn byte_sub(self, count: usize) -> Self {
         // SAFETY: the caller must uphold the safety contract for `sub` and `byte_sub` has the same
         // safety contract.
@@ -816,7 +813,6 @@ impl<T: ?Sized> NonNull<T> {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
     /// use std::ptr::NonNull;
     ///
     /// let a = [0; 5];
@@ -833,7 +829,7 @@ impl<T: ?Sized> NonNull<T> {
     /// *Incorrect* usage:
     ///
     /// ```rust,no_run
-    /// #![feature(non_null_convenience, strict_provenance)]
+    /// #![feature(strict_provenance)]
     /// use std::ptr::NonNull;
     ///
     /// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap();
@@ -845,14 +841,13 @@ impl<T: ?Sized> NonNull<T> {
     /// // Since ptr2_other and ptr2 are derived from pointers to different objects,
     /// // computing their offset is undefined behavior, even though
     /// // they point to the same address!
-    /// unsafe {
-    ///     let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
-    /// }
+    ///
+    /// let zero = unsafe { ptr2_other.offset_from(ptr2) }; // Undefined Behavior
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn offset_from(self, origin: NonNull<T>) -> isize
     where
         T: Sized,
@@ -870,10 +865,10 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// For non-`Sized` pointees this operation considers only the data pointers,
     /// ignoring the metadata.
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize {
         // SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
         unsafe { self.pointer.byte_offset_from(origin.pointer) }
@@ -897,7 +892,7 @@ impl<T: ?Sized> NonNull<T> {
     /// to [`sub`](#method.sub)).  The following are all equivalent, assuming
     /// that their safety preconditions are met:
     /// ```rust
-    /// # #![feature(non_null_convenience)]
+    /// # #![feature(ptr_sub_ptr)]
     /// # unsafe fn blah(ptr: std::ptr::NonNull<u32>, origin: std::ptr::NonNull<u32>, count: usize) -> bool {
     /// ptr.sub_ptr(origin) == count
     /// # &&
@@ -926,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
+    /// #![feature(ptr_sub_ptr)]
     /// use std::ptr::NonNull;
     ///
     /// let a = [0; 5];
@@ -942,12 +937,10 @@ impl<T: ?Sized> NonNull<T> {
     /// // This would be incorrect, as the pointers are not correctly ordered:
     /// // ptr1.sub_ptr(ptr2)
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    // #[unstable(feature = "ptr_sub_ptr", issue = "95892")]
-    // #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[unstable(feature = "ptr_sub_ptr", issue = "95892")]
+    #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
     pub const unsafe fn sub_ptr(self, subtracted: NonNull<T>) -> usize
     where
         T: Sized,
@@ -962,10 +955,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::read`] for safety concerns and examples.
     ///
     /// [`ptr::read`]: crate::ptr::read()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn read(self) -> T
     where
         T: Sized,
@@ -984,9 +977,9 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::read_volatile`] for safety concerns and examples.
     ///
     /// [`ptr::read_volatile`]: crate::ptr::read_volatile()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub unsafe fn read_volatile(self) -> T
     where
         T: Sized,
@@ -1003,10 +996,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::read_unaligned`] for safety concerns and examples.
     ///
     /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn read_unaligned(self) -> T
     where
         T: Sized,
@@ -1023,10 +1016,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     pub const unsafe fn copy_to(self, dest: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -1043,10 +1036,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -1063,10 +1056,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     pub const unsafe fn copy_from(self, src: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -1083,10 +1076,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull<T>, count: usize)
     where
         T: Sized,
@@ -1100,8 +1093,8 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::drop_in_place`] for safety concerns and examples.
     ///
     /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub unsafe fn drop_in_place(self) {
         // SAFETY: the caller must uphold the safety contract for `drop_in_place`.
         unsafe { ptr::drop_in_place(self.as_ptr()) }
@@ -1113,11 +1106,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::write`] for safety concerns and examples.
     ///
     /// [`ptr::write`]: crate::ptr::write()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     pub const unsafe fn write(self, val: T)
     where
         T: Sized,
@@ -1132,12 +1124,11 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::write_bytes`] for safety concerns and examples.
     ///
     /// [`ptr::write_bytes`]: crate::ptr::write_bytes()
-    #[doc(alias = "memset")]
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[inline(always)]
+    #[doc(alias = "memset")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     pub const unsafe fn write_bytes(self, val: u8, count: usize)
     where
         T: Sized,
@@ -1156,9 +1147,9 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::write_volatile`] for safety concerns and examples.
     ///
     /// [`ptr::write_volatile`]: crate::ptr::write_volatile()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub unsafe fn write_volatile(self, val: T)
     where
         T: Sized,
@@ -1175,11 +1166,10 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::write_unaligned`] for safety concerns and examples.
     ///
     /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     pub const unsafe fn write_unaligned(self, val: T)
     where
         T: Sized,
@@ -1194,8 +1184,8 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::replace`] for safety concerns and examples.
     ///
     /// [`ptr::replace`]: crate::ptr::replace()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
     #[inline(always)]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
     pub unsafe fn replace(self, src: T) -> T
     where
         T: Sized,
@@ -1211,10 +1201,9 @@ impl<T: ?Sized> NonNull<T> {
     /// See [`ptr::swap`] for safety concerns and examples.
     ///
     /// [`ptr::swap`]: crate::ptr::swap()
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    //#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
     #[inline(always)]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_swap", issue = "83163")]
     pub const unsafe fn swap(self, with: NonNull<T>)
     where
         T: Sized,
@@ -1246,7 +1235,6 @@ impl<T: ?Sized> NonNull<T> {
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// #![feature(non_null_convenience)]
     /// use std::mem::align_of;
     /// use std::ptr::NonNull;
     ///
@@ -1264,11 +1252,10 @@ impl<T: ?Sized> NonNull<T> {
     /// }
     /// # }
     /// ```
-    #[unstable(feature = "non_null_convenience", issue = "117691")]
-    #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
-    //#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
-    #[must_use]
     #[inline]
+    #[must_use]
+    #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
     pub const fn align_offset(self, align: usize) -> usize
     where
         T: Sized,
@@ -1312,10 +1299,9 @@ impl<T: ?Sized> NonNull<T> {
     /// underlying allocation.
     ///
     /// ```
-    /// #![feature(const_pointer_is_aligned)]
-    /// #![feature(non_null_convenience)]
-    /// #![feature(const_option)]
     /// #![feature(const_nonnull_new)]
+    /// #![feature(const_option)]
+    /// #![feature(const_pointer_is_aligned)]
     /// use std::ptr::NonNull;
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1390,10 +1376,10 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     ///
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
-    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
-    #[must_use]
     #[inline]
+    #[must_use]
+    #[stable(feature = "pointer_is_aligned", since = "1.79.0")]
+    #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned(self) -> bool
     where
         T: Sized,
@@ -1505,10 +1491,10 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     ///
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
+    #[inline]
+    #[must_use]
     #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
-    #[must_use]
-    #[inline]
     pub const fn is_aligned_to(self, align: usize) -> bool {
         self.pointer.is_aligned_to(align)
     }
@@ -1578,11 +1564,8 @@ impl<T> NonNull<[T]> {
     /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3);
     /// assert!(!slice.is_empty());
     /// ```
-    #[stable(feature = "slice_ptr_is_empty_nonnull", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(
-        feature = "const_slice_ptr_is_empty_nonnull",
-        since = "CURRENT_RUSTC_VERSION"
-    )]
+    #[stable(feature = "slice_ptr_is_empty_nonnull", since = "1.79.0")]
+    #[rustc_const_stable(feature = "const_slice_ptr_is_empty_nonnull", since = "1.79.0")]
     #[must_use]
     #[inline]
     pub const fn is_empty(self) -> bool {
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 7910981d0f5..0b8ff5cc012 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -70,21 +70,19 @@ macro_rules! iterator {
         $into_ref:ident,
         {$($extra:tt)*}
     ) => {
-        // Returns the first element and moves the start of the iterator forwards by 1.
-        // Greatly improves performance compared to an inlined function. The iterator
-        // must not be empty.
-        macro_rules! next_unchecked {
-            ($self: ident) => { $self.post_inc_start(1).$into_ref() }
-        }
-
-        // Returns the last element and moves the end of the iterator backwards by 1.
-        // Greatly improves performance compared to an inlined function. The iterator
-        // must not be empty.
-        macro_rules! next_back_unchecked {
-            ($self: ident) => { $self.pre_dec_end(1).$into_ref() }
-        }
-
         impl<'a, T> $name<'a, T> {
+            /// Returns the last element and moves the end of the iterator backwards by 1.
+            ///
+            /// # Safety
+            ///
+            /// The iterator must not be empty
+            #[inline]
+            unsafe fn next_back_unchecked(&mut self) -> $elem {
+                // SAFETY: the caller promised it's not empty, so
+                // the offsetting is in-bounds and there's an element to return.
+                unsafe { self.pre_dec_end(1).$into_ref() }
+            }
+
             // Helper function for creating a slice from the iterator.
             #[inline(always)]
             fn make_slice(&self) -> &'a [T] {
@@ -156,13 +154,13 @@ macro_rules! iterator {
             fn next(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
 
-                // SAFETY: The call to `next_unchecked!` is
+                // SAFETY: The call to `next_unchecked` is
                 // safe since we check if the iterator is empty first.
                 unsafe {
                     if is_empty!(self) {
                         None
                     } else {
-                        Some(next_unchecked!(self))
+                        Some(self.next_unchecked())
                     }
                 }
             }
@@ -191,7 +189,7 @@ macro_rules! iterator {
                 // SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
                 unsafe {
                     self.post_inc_start(n);
-                    Some(next_unchecked!(self))
+                    Some(self.next_unchecked())
                 }
             }
 
@@ -392,13 +390,13 @@ macro_rules! iterator {
             fn next_back(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
 
-                // SAFETY: The call to `next_back_unchecked!`
+                // SAFETY: The call to `next_back_unchecked`
                 // is safe since we check if the iterator is empty first.
                 unsafe {
                     if is_empty!(self) {
                         None
                     } else {
-                        Some(next_back_unchecked!(self))
+                        Some(self.next_back_unchecked())
                     }
                 }
             }
@@ -416,7 +414,7 @@ macro_rules! iterator {
                 // SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
                 unsafe {
                     self.pre_dec_end(n);
-                    Some(next_back_unchecked!(self))
+                    Some(self.next_back_unchecked())
                 }
             }
 
@@ -436,10 +434,11 @@ macro_rules! iterator {
         unsafe impl<T> TrustedLen for $name<'_, T> {}
 
         impl<'a, T> UncheckedIterator for $name<'a, T> {
+            #[inline]
             unsafe fn next_unchecked(&mut self) -> $elem {
                 // SAFETY: The caller promised there's at least one more item.
                 unsafe {
-                    next_unchecked!(self)
+                    self.post_inc_start(1).$into_ref()
                 }
             }
         }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 6e1ba74f72b..9c523fd6295 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1964,7 +1964,7 @@ impl<T> [T] {
     ///     assert_eq!(right, []);
     /// }
     /// ```
-    #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")]
     #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")]
     #[inline]
     #[must_use]
@@ -2017,7 +2017,7 @@ impl<T> [T] {
     /// }
     /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
     /// ```
-    #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")]
     #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
     #[inline]
     #[must_use]
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 59f873d1268..51a0777c2d6 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -6,6 +6,46 @@ use crate::iter::FusedIterator;
 use super::from_utf8_unchecked;
 use super::validations::utf8_char_width;
 
+impl [u8] {
+    /// Creates an iterator over the contiguous valid UTF-8 ranges of this
+    /// slice, and the non-UTF-8 fragments in between.
+    ///
+    /// # Examples
+    ///
+    /// This function formats arbitrary but mostly-UTF-8 bytes into Rust source
+    /// code in the form of a C-string literal (`c"..."`).
+    ///
+    /// ```
+    /// use std::fmt::Write as _;
+    ///
+    /// pub fn cstr_literal(bytes: &[u8]) -> String {
+    ///     let mut repr = String::new();
+    ///     repr.push_str("c\"");
+    ///     for chunk in bytes.utf8_chunks() {
+    ///         for ch in chunk.valid().chars() {
+    ///             // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+    ///             write!(repr, "{}", ch.escape_debug()).unwrap();
+    ///         }
+    ///         for byte in chunk.invalid() {
+    ///             write!(repr, "\\x{:02X}", byte).unwrap();
+    ///         }
+    ///     }
+    ///     repr.push('"');
+    ///     repr
+    /// }
+    ///
+    /// fn main() {
+    ///     let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    ///     let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    ///     assert_eq!(lit, expected);
+    /// }
+    /// ```
+    #[stable(feature = "utf8_chunks", since = "1.79.0")]
+    pub fn utf8_chunks(&self) -> Utf8Chunks<'_> {
+        Utf8Chunks { source: self }
+    }
+}
+
 /// An item returned by the [`Utf8Chunks`] iterator.
 ///
 /// A `Utf8Chunk` stores a sequence of [`u8`] up to the first broken character
@@ -14,15 +54,11 @@ use super::validations::utf8_char_width;
 /// # Examples
 ///
 /// ```
-/// #![feature(utf8_chunks)]
-///
-/// use std::str::Utf8Chunks;
-///
 /// // An invalid UTF-8 string
 /// let bytes = b"foo\xF1\x80bar";
 ///
 /// // Decode the first `Utf8Chunk`
-/// let chunk = Utf8Chunks::new(bytes).next().unwrap();
+/// let chunk = bytes.utf8_chunks().next().unwrap();
 ///
 /// // The first three characters are valid UTF-8
 /// assert_eq!("foo", chunk.valid());
@@ -30,7 +66,7 @@ use super::validations::utf8_char_width;
 /// // The fourth character is broken
 /// assert_eq!(b"\xF1\x80", chunk.invalid());
 /// ```
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Utf8Chunk<'a> {
     valid: &'a str,
@@ -43,7 +79,7 @@ impl<'a> Utf8Chunk<'a> {
     /// This substring can be empty at the start of the string or between
     /// broken UTF-8 characters.
     #[must_use]
-    #[unstable(feature = "utf8_chunks", issue = "99543")]
+    #[stable(feature = "utf8_chunks", since = "1.79.0")]
     pub fn valid(&self) -> &'a str {
         self.valid
     }
@@ -63,7 +99,7 @@ impl<'a> Utf8Chunk<'a> {
     /// [`valid`]: Self::valid
     /// [`U+FFFD REPLACEMENT CHARACTER`]: crate::char::REPLACEMENT_CHARACTER
     #[must_use]
-    #[unstable(feature = "utf8_chunks", issue = "99543")]
+    #[stable(feature = "utf8_chunks", since = "1.79.0")]
     pub fn invalid(&self) -> &'a [u8] {
         self.invalid
     }
@@ -78,7 +114,7 @@ impl fmt::Debug for Debug<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.write_char('"')?;
 
-        for chunk in Utf8Chunks::new(self.0) {
+        for chunk in self.0.utf8_chunks() {
             // Valid part.
             // Here we partially parse UTF-8 again which is suboptimal.
             {
@@ -123,12 +159,8 @@ impl fmt::Debug for Debug<'_> {
 /// [`String::from_utf8_lossy`] without allocating heap memory:
 ///
 /// ```
-/// #![feature(utf8_chunks)]
-///
-/// use std::str::Utf8Chunks;
-///
 /// fn from_utf8_lossy<F>(input: &[u8], mut push: F) where F: FnMut(&str) {
-///     for chunk in Utf8Chunks::new(input) {
+///     for chunk in input.utf8_chunks() {
 ///         push(chunk.valid());
 ///
 ///         if !chunk.invalid().is_empty() {
@@ -140,19 +172,13 @@ impl fmt::Debug for Debug<'_> {
 ///
 /// [`String::from_utf8_lossy`]: ../../std/string/struct.String.html#method.from_utf8_lossy
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 #[derive(Clone)]
 pub struct Utf8Chunks<'a> {
     source: &'a [u8],
 }
 
 impl<'a> Utf8Chunks<'a> {
-    /// Creates a new iterator to decode the bytes.
-    #[unstable(feature = "utf8_chunks", issue = "99543")]
-    pub fn new(bytes: &'a [u8]) -> Self {
-        Self { source: bytes }
-    }
-
     #[doc(hidden)]
     #[unstable(feature = "str_internals", issue = "none")]
     pub fn debug(&self) -> Debug<'_> {
@@ -160,7 +186,7 @@ impl<'a> Utf8Chunks<'a> {
     }
 }
 
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 impl<'a> Iterator for Utf8Chunks<'a> {
     type Item = Utf8Chunk<'a>;
 
@@ -259,10 +285,10 @@ impl<'a> Iterator for Utf8Chunks<'a> {
     }
 }
 
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 impl FusedIterator for Utf8Chunks<'_> {}
 
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 impl fmt::Debug for Utf8Chunks<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish()
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 61a60456145..adccbe02d46 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -24,7 +24,7 @@ use crate::slice::{self, SliceIndex};
 pub mod pattern;
 
 mod lossy;
-#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[stable(feature = "utf8_chunks", since = "1.79.0")]
 pub use lossy::{Utf8Chunk, Utf8Chunks};
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 073459fcb00..232ec589093 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -512,7 +512,6 @@ impl AtomicBool {
     ///
     /// ```
     /// #![feature(atomic_from_mut)]
-    /// # #![cfg_attr(bootstrap, feature(inline_const))]
     /// use std::sync::atomic::{AtomicBool, Ordering};
     ///
     /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
@@ -579,7 +578,7 @@ impl AtomicBool {
     /// ```
     #[inline]
     #[stable(feature = "atomic_access", since = "1.15.0")]
-    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
     pub const fn into_inner(self) -> bool {
         self.v.primitive_into_inner() != 0
     }
@@ -1315,7 +1314,6 @@ impl<T> AtomicPtr<T> {
     ///
     /// ```
     /// #![feature(atomic_from_mut)]
-    /// # #![cfg_attr(bootstrap, feature(inline_const))]
     /// use std::ptr::null_mut;
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
@@ -1399,7 +1397,7 @@ impl<T> AtomicPtr<T> {
     /// ```
     #[inline]
     #[stable(feature = "atomic_access", since = "1.15.0")]
-    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
     pub const fn into_inner(self) -> *mut T {
         self.p.primitive_into_inner()
     }
@@ -2306,7 +2304,6 @@ macro_rules! atomic_int {
             ///
             /// ```
             /// #![feature(atomic_from_mut)]
-            /// # #![cfg_attr(bootstrap, feature(inline_const))]
             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
             ///
             #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
@@ -2381,7 +2378,7 @@ macro_rules! atomic_int {
             /// ```
             #[inline]
             #[$stable_access]
-            #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")]
+            #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
             pub const fn into_inner(self) -> $int_type {
                 self.v.primitive_into_inner()
             }
diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs
index ff6b2d30539..1aa6a288e70 100644
--- a/library/core/src/ub_checks.rs
+++ b/library/core/src/ub_checks.rs
@@ -46,6 +46,8 @@ use crate::intrinsics::{self, const_eval_select};
 /// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
 /// debuginfo to have a measurable compile-time impact on debug builds.
 #[allow_internal_unstable(const_ub_checks)] // permit this to be called in stably-const fn
+#[macro_export]
+#[unstable(feature = "ub_checks", issue = "none")]
 macro_rules! assert_unsafe_precondition {
     ($kind:ident, $message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
         {
@@ -75,11 +77,13 @@ macro_rules! assert_unsafe_precondition {
         }
     };
 }
-pub(crate) use assert_unsafe_precondition;
+#[unstable(feature = "ub_checks", issue = "none")]
+pub use assert_unsafe_precondition;
 
 /// Checking library UB is always enabled when UB-checking is done
 /// (and we use a reexport so that there is no unnecessary wrapper function).
-pub(crate) use intrinsics::ub_checks as check_library_ub;
+#[unstable(feature = "ub_checks", issue = "none")]
+pub use intrinsics::ub_checks as check_library_ub;
 
 /// Determines whether we should check for language UB.
 ///
diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs
index eb1e1a0b9b1..8b731cf5b25 100644
--- a/library/core/tests/intrinsics.rs
+++ b/library/core/tests/intrinsics.rs
@@ -100,7 +100,6 @@ fn test_const_deallocate_at_runtime() {
     }
 }
 
-#[cfg(not(bootstrap))]
 #[test]
 fn test_three_way_compare_in_const_contexts() {
     use core::cmp::Ordering::{self, *};
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index d6e705a37a7..797108a8425 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -21,7 +21,7 @@
 #![feature(const_pointer_is_aligned)]
 #![feature(const_ptr_as_ref)]
 #![feature(const_ptr_write)]
-#![cfg_attr(not(bootstrap), feature(const_three_way_compare))]
+#![feature(const_three_way_compare)]
 #![feature(const_trait_impl)]
 #![feature(const_likely)]
 #![feature(core_intrinsics)]
@@ -46,7 +46,6 @@
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(try_find)]
-#![cfg_attr(bootstrap, feature(inline_const))]
 #![feature(is_sorted)]
 #![feature(layout_for_ptr)]
 #![feature(pattern)]
@@ -117,7 +116,6 @@
 #![feature(error_generic_member_access)]
 #![feature(error_in_core)]
 #![feature(trait_upcasting)]
-#![feature(utf8_chunks)]
 #![feature(is_ascii_octdigit)]
 #![feature(get_many_mut)]
 #![feature(iter_map_windows)]
diff --git a/library/core/tests/str_lossy.rs b/library/core/tests/str_lossy.rs
index 9d3f0b65fdb..6e70ea3e285 100644
--- a/library/core/tests/str_lossy.rs
+++ b/library/core/tests/str_lossy.rs
@@ -1,10 +1,8 @@
-use core::str::Utf8Chunks;
-
 #[test]
 fn chunks() {
     macro_rules! assert_chunks {
         ( $string:expr, $(($valid:expr, $invalid:expr)),* $(,)? ) => {{
-            let mut iter = Utf8Chunks::new($string);
+            let mut iter = $string.utf8_chunks();
             $(
                 let chunk = iter.next().expect("missing chunk");
                 assert_eq!($valid, chunk.valid());
@@ -79,7 +77,7 @@ fn debug() {
         "\"Hello\\xC0\\x80 There\\xE6\\x83 Goodbye\\u{10d4ea}\"",
         &format!(
             "{:?}",
-            Utf8Chunks::new(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa").debug(),
+            b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa".utf8_chunks().debug(),
         ),
     );
 }
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 1ceff2e506c..23ae2e7dc0d 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1360,7 +1360,7 @@ impl Literal {
     }
 
     /// Byte character literal.
-    #[stable(feature = "proc_macro_byte_character", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "proc_macro_byte_character", since = "1.79.0")]
     pub fn byte_character(byte: u8) -> Literal {
         let string = [byte].escape_ascii().to_string();
         Literal::new(bridge::LitKind::Byte, &string, None)
@@ -1374,7 +1374,7 @@ impl Literal {
     }
 
     /// C string literal.
-    #[stable(feature = "proc_macro_c_str_literals", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")]
     pub fn c_string(string: &CStr) -> Literal {
         let string = string.to_bytes().escape_ascii().to_string();
         Literal::new(bridge::LitKind::CStr, &string, None)
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index cba9ff4485d..52729ba1f84 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -64,12 +64,10 @@ r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
 
 [features]
 backtrace = [
-  "gimli-symbolize",
   'addr2line/rustc-dep-of-std',
   'object/rustc-dep-of-std',
   'miniz_oxide/rustc-dep-of-std',
 ]
-gimli-symbolize = []
 
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index de9bde51f2a..4fc82fec0ad 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -371,9 +371,10 @@ impl f32 {
     /// It might have a different sequence of rounding operations than `powf`,
     /// so the results are not guaranteed to agree.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -393,9 +394,10 @@ impl f32 {
 
     /// Raises a number to a floating point power.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -444,9 +446,10 @@ impl f32 {
 
     /// Returns `e^(self)`, (the exponential function).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -470,9 +473,10 @@ impl f32 {
 
     /// Returns `2^(self)`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -494,9 +498,10 @@ impl f32 {
 
     /// Returns the natural logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -524,9 +529,10 @@ impl f32 {
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -548,9 +554,10 @@ impl f32 {
 
     /// Returns the base 2 logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -572,9 +579,10 @@ impl f32 {
 
     /// Returns the base 10 logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -599,9 +607,10 @@ impl f32 {
     /// * If `self <= other`: `0.0`
     /// * Else: `self - other`
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `fdimf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -637,9 +646,10 @@ impl f32 {
 
     /// Returns the cube root of a number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `cbrtf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -666,9 +676,10 @@ impl f32 {
     /// right-angle triangle with other sides having length `x.abs()` and
     /// `y.abs()`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `hypotf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -693,9 +704,10 @@ impl f32 {
 
     /// Computes the sine of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -716,9 +728,10 @@ impl f32 {
 
     /// Computes the cosine of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -739,9 +752,10 @@ impl f32 {
 
     /// Computes the tangent of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tanf` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -765,9 +779,10 @@ impl f32 {
     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
     /// [-1, 1].
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `asinf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -794,9 +809,10 @@ impl f32 {
     /// the range [0, pi] or NaN if the number is outside the range
     /// [-1, 1].
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `acosf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -822,9 +838,10 @@ impl f32 {
     /// Computes the arctangent of a number. Return value is in radians in the
     /// range [-pi/2, pi/2];
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `atanf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -854,9 +871,10 @@ impl f32 {
     /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
     /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `atan2f` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -890,9 +908,10 @@ impl f32 {
     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
     /// `(sin(x), cos(x))`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `(f32::sin(x),
     /// f32::cos(x))`. Note that this might change in the future.
     ///
@@ -919,9 +938,10 @@ impl f32 {
     /// Returns `e^(self) - 1` in a way that is accurate even if the
     /// number is close to zero.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `expm1f` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -947,9 +967,10 @@ impl f32 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `log1pf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -975,9 +996,10 @@ impl f32 {
 
     /// Hyperbolic sine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `sinhf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1004,9 +1026,10 @@ impl f32 {
 
     /// Hyperbolic cosine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `coshf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1033,9 +1056,10 @@ impl f32 {
 
     /// Hyperbolic tangent function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tanhf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1062,9 +1086,10 @@ impl f32 {
 
     /// Inverse hyperbolic sine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1089,9 +1114,10 @@ impl f32 {
 
     /// Inverse hyperbolic cosine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1118,9 +1144,10 @@ impl f32 {
 
     /// Inverse hyperbolic tangent function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1143,9 +1170,10 @@ impl f32 {
 
     /// Gamma function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tgammaf` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1171,9 +1199,10 @@ impl f32 {
     ///
     /// The integer part of the tuple indicates the sign of the gamma function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `lgamma_r` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 944186d602c..f8c66a3e717 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -371,9 +371,10 @@ impl f64 {
     /// It might have a different sequence of rounding operations than `powf`,
     /// so the results are not guaranteed to agree.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -393,9 +394,10 @@ impl f64 {
 
     /// Raises a number to a floating point power.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -444,9 +446,10 @@ impl f64 {
 
     /// Returns `e^(self)`, (the exponential function).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -470,9 +473,10 @@ impl f64 {
 
     /// Returns `2^(self)`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -494,9 +498,10 @@ impl f64 {
 
     /// Returns the natural logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -524,9 +529,10 @@ impl f64 {
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -548,9 +554,10 @@ impl f64 {
 
     /// Returns the base 2 logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -572,9 +579,10 @@ impl f64 {
 
     /// Returns the base 10 logarithm of the number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -599,9 +607,10 @@ impl f64 {
     /// * If `self <= other`: `0.0`
     /// * Else: `self - other`
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `fdim` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -637,9 +646,10 @@ impl f64 {
 
     /// Returns the cube root of a number.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `cbrt` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -666,9 +676,10 @@ impl f64 {
     /// right-angle triangle with other sides having length `x.abs()` and
     /// `y.abs()`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `hypot` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -693,9 +704,10 @@ impl f64 {
 
     /// Computes the sine of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -716,9 +728,10 @@ impl f64 {
 
     /// Computes the cosine of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -739,9 +752,10 @@ impl f64 {
 
     /// Computes the tangent of a number (in radians).
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tan` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -765,9 +779,10 @@ impl f64 {
     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
     /// [-1, 1].
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `asin` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -794,9 +809,10 @@ impl f64 {
     /// the range [0, pi] or NaN if the number is outside the range
     /// [-1, 1].
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `acos` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -822,9 +838,10 @@ impl f64 {
     /// Computes the arctangent of a number. Return value is in radians in the
     /// range [-pi/2, pi/2];
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `atan` from libc on Unix and
     /// Windows. Note that this might change in the future.
     ///
@@ -854,9 +871,10 @@ impl f64 {
     /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
     /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `atan2` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -890,9 +908,10 @@ impl f64 {
     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
     /// `(sin(x), cos(x))`.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `(f64::sin(x),
     /// f64::cos(x))`. Note that this might change in the future.
     ///
@@ -919,9 +938,10 @@ impl f64 {
     /// Returns `e^(self) - 1` in a way that is accurate even if the
     /// number is close to zero.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `expm1` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -947,9 +967,10 @@ impl f64 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `log1p` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -975,9 +996,10 @@ impl f64 {
 
     /// Hyperbolic sine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `sinh` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1004,9 +1026,10 @@ impl f64 {
 
     /// Hyperbolic cosine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `cosh` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1033,9 +1056,10 @@ impl f64 {
 
     /// Hyperbolic tangent function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tanh` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1062,9 +1086,10 @@ impl f64 {
 
     /// Inverse hyperbolic sine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1089,9 +1114,10 @@ impl f64 {
 
     /// Inverse hyperbolic cosine function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1118,9 +1144,10 @@ impl f64 {
 
     /// Inverse hyperbolic tangent function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     ///
     /// # Examples
     ///
@@ -1143,9 +1170,10 @@ impl f64 {
 
     /// Gamma function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `tgamma` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
@@ -1171,9 +1199,10 @@ impl f64 {
     ///
     /// The integer part of the tuple indicates the sign of the gamma function.
     ///
-    /// # Platform-specific precision
+    /// # Unspecified precision
     ///
-    /// The precision of this function varies by platform and Rust version.
+    /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+    /// can even differ within the same execution from one invocation to the next.
     /// This function currently corresponds to the `lgamma_r` from libc on Unix
     /// and Windows. Note that this might change in the future.
     ///
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 20ebe1c4f8a..9dd3d7d3fa1 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -532,6 +532,12 @@ impl OsString {
         let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
         unsafe { Box::from_raw(rw) }
     }
+
+    /// Part of a hack to make PathBuf::push/pop more efficient.
+    #[inline]
+    pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
+        self.inner.as_mut_vec_for_path_buf()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index ff399a0acd5..dfa05671ab0 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1657,23 +1657,9 @@ fn test_file_times() {
     let accessed = SystemTime::UNIX_EPOCH + Duration::from_secs(12345);
     let modified = SystemTime::UNIX_EPOCH + Duration::from_secs(54321);
     times = times.set_accessed(accessed).set_modified(modified);
-    #[cfg(any(
-        windows,
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos",
-    ))]
+    #[cfg(any(windows, target_vendor = "apple"))]
     let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123);
-    #[cfg(any(
-        windows,
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos",
-    ))]
+    #[cfg(any(windows, target_vendor = "apple"))]
     {
         times = times.set_created(created);
     }
@@ -1698,27 +1684,14 @@ fn test_file_times() {
     let metadata = file.metadata().unwrap();
     assert_eq!(metadata.accessed().unwrap(), accessed);
     assert_eq!(metadata.modified().unwrap(), modified);
-    #[cfg(any(
-        windows,
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos",
-    ))]
+    #[cfg(any(windows, target_vendor = "apple"))]
     {
         assert_eq!(metadata.created().unwrap(), created);
     }
 }
 
 #[test]
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos"
-))]
+#[cfg(target_vendor = "apple")]
 fn test_file_times_pre_epoch_with_nanos() {
     #[cfg(target_os = "ios")]
     use crate::os::ios::fs::FileTimesExt;
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 5b782fff7e5..f6680b211c7 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -95,7 +95,7 @@ impl<T> Cursor<T> {
     /// # force_inference(&buff);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
     pub const fn new(inner: T) -> Cursor<T> {
         Cursor { pos: 0, inner }
     }
@@ -132,7 +132,7 @@ impl<T> Cursor<T> {
     /// let reference = buff.get_ref();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
     pub const fn get_ref(&self) -> &T {
         &self.inner
     }
@@ -178,7 +178,7 @@ impl<T> Cursor<T> {
     /// assert_eq!(buff.position(), 1);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
     pub const fn position(&self) -> u64 {
         self.pos
     }
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 801621c6112..f366cb8f42b 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -921,7 +921,7 @@ impl Error {
     /// assert!(io_error.raw_os_error().is_none());
     /// # }
     /// ```
-    #[stable(feature = "io_error_downcast", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_downcast", since = "1.79.0")]
     pub fn downcast<E>(self) -> result::Result<E, Self>
     where
         E: error::Error + Send + Sync + 'static,
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 98973a43e1d..a3fdcdc2d07 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -266,7 +266,7 @@
 //! its file descriptors with no operations being performed by any other part of the program.
 //!
 //! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the
-//! underlying kernel object that the file descriptor references (also called "file description" on
+//! underlying kernel object that the file descriptor references (also called "open file description" on
 //! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned
 //! file descriptor, you cannot know whether there are any other file descriptors that reference the
 //! same kernel object. However, when you create a new kernel object, you know that you are holding
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index 266a447f06b..b4c4dffc371 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -51,7 +51,7 @@ pub struct Empty;
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
 pub const fn empty() -> Empty {
     Empty
 }
@@ -173,7 +173,7 @@ pub struct Repeat {
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
 pub const fn repeat(byte: u8) -> Repeat {
     Repeat { byte }
 }
@@ -276,7 +276,7 @@ pub struct Sink;
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
 pub const fn sink() -> Sink {
     Sink
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index aa908f0499f..27b46b46204 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -224,7 +224,7 @@
             `#![no_std]` or overriding this warning by enabling this feature."
     )
 )]
-#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
+#![rustc_preserve_ub_checks]
 #![doc(
     html_playground_url = "https://play.rust-lang.org/",
     issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
@@ -314,7 +314,6 @@
 #![feature(thread_local)]
 #![feature(try_blocks)]
 #![feature(type_alias_impl_trait)]
-#![feature(utf8_chunks)]
 // tidy-alphabetical-end
 //
 // Library features (core):
@@ -357,6 +356,7 @@
 #![feature(str_internals)]
 #![feature(strict_provenance)]
 #![feature(strict_provenance_atomic_ptr)]
+#![feature(ub_checks)]
 // tidy-alphabetical-end
 //
 // Library features (alloc):
@@ -592,7 +592,6 @@ pub mod net;
 pub mod num;
 pub mod os;
 pub mod panic;
-#[cfg(not(bootstrap))]
 #[unstable(feature = "core_pattern_types", issue = "none")]
 pub mod pat;
 pub mod path;
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index fbe68f7e303..8910cdea7c0 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -23,7 +23,7 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
 )]
 pub use core::num::ZeroablePrimitive;
 
-#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "generic_nonzero", since = "1.79.0")]
 pub use core::num::NonZero;
 
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 010ce4e5076..8c7fc4cb2e4 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -176,7 +176,12 @@ impl Drop for OwnedFd {
             // something like EINTR), we might close another valid file descriptor
             // opened after we closed ours.
             #[cfg(not(target_os = "hermit"))]
-            let _ = libc::close(self.fd);
+            {
+                #[cfg(unix)]
+                crate::sys::fs::debug_assert_fd_is_open(self.fd);
+
+                let _ = libc::close(self.fd);
+            }
             #[cfg(target_os = "hermit")]
             let _ = hermit_abi::close(self.fd);
         }
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 827278f8b26..6d4090ee31c 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -12,8 +12,8 @@
 //! | Type               | Analogous to |
 //! | ------------------ | ------------ |
 //! | [`RawFd`]          | `*const _`   |
-//! | [`BorrowedFd<'a>`] | `&'a _`      |
-//! | [`OwnedFd`]        | `Box<_>`     |
+//! | [`BorrowedFd<'a>`] | `&'a Arc<_>` |
+//! | [`OwnedFd`]        | `Arc<_>`     |
 //!
 //! Like raw pointers, `RawFd` values are primitive values. And in new code,
 //! they should be considered unsafe to do I/O on (analogous to dereferencing
@@ -23,22 +23,31 @@
 //! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
 //! using to `BorrowedFd` or `OwnedFd` instead.
 //!
+//! The use of `Arc` for borrowed/owned file descriptors may be surprising. Unix file descriptors
+//! are mere references to internal kernel objects called "open file descriptions", and the same
+//! open file description can be referenced by multiple file descriptors (e.g. if `dup` is used).
+//! State such as the offset within the file is shared among all file descriptors that refer to the
+//! same open file description, and the kernel internally does reference-counting to only close the
+//! underlying resource once all file descriptors referencing it are closed. That's why `Arc` (and
+//! not `Box`) is the closest Rust analogy to an "owned" file descriptor.
+//!
 //! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
 //! that they don't outlive the resource they point to. These are safe to
 //! use. `BorrowedFd` values may be used in APIs which provide safe access to
 //! any system call except for:
 //!
 //!  - `close`, because that would end the dynamic lifetime of the resource
-//!    without ending the lifetime of the file descriptor.
+//!    without ending the lifetime of the file descriptor. (Equivalently:
+//!    an `&Arc<_>` cannot be `drop`ed.)
 //!
 //!  - `dup2`/`dup3`, in the second argument, because this argument is
-//!    closed and assigned a new resource, which may break the assumptions
+//!    closed and assigned a new resource, which may break the assumptions of
 //!    other code using that file descriptor.
 //!
-//! `BorrowedFd` values may be used in APIs which provide safe access to `dup`
-//! system calls, so types implementing `AsFd` or `From<OwnedFd>` should not
-//! assume they always have exclusive access to the underlying file
-//! description.
+//! `BorrowedFd` values may be used in APIs which provide safe access to `dup` system calls, so code
+//! working with `OwnedFd` cannot assume to have exclusive access to the underlying open file
+//! description. (Equivalently: `&Arc` may be used in APIs that provide safe access to `clone`, so
+//! code working with an `Arc` cannot assume that the reference count is 1.)
 //!
 //! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the
 //! provided file descriptor in a manner similar to `dup` and does not require
@@ -52,8 +61,10 @@
 //! take full responsibility for ensuring that safe Rust code cannot evoke
 //! undefined behavior through it.
 //!
-//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
-//! and free (close) it when they are dropped.
+//! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to,
+//! and decrement the reference count when they are dropped (by calling `close`).
+//! When the reference count reaches 0, the underlying open file description will be freed
+//! by the kernel.
 //!
 //! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
 //!
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 16d9cd915ac..3e45e3533ed 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -17,14 +17,10 @@ mod tests;
     target_os = "linux",
     target_os = "dragonfly",
     target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "nto",
+    target_vendor = "apple",
 ))]
 mod ucred;
 
@@ -44,14 +40,10 @@ pub use self::stream::*;
     target_os = "linux",
     target_os = "dragonfly",
     target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "nto",
+    target_vendor = "apple",
 ))]
 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
 pub use self::ucred::*;
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 82b24dca1c4..19fc7b3d853 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -3,14 +3,10 @@
     target_os = "linux",
     target_os = "dragonfly",
     target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "macos",
-    target_os = "watchos",
-    target_os = "visionos",
     target_os = "netbsd",
     target_os = "openbsd",
-    target_os = "nto"
+    target_os = "nto",
+    target_vendor = "apple",
 ))]
 use super::{peer_cred, UCred};
 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
@@ -231,14 +227,10 @@ impl UnixStream {
         target_os = "linux",
         target_os = "dragonfly",
         target_os = "freebsd",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "macos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "nto"
+        target_os = "nto",
+        target_vendor = "apple",
     ))]
     pub fn peer_cred(&self) -> io::Result<UCred> {
         peer_cred(self)
diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs
index 3a752a53a50..1497e730bbf 100644
--- a/library/std/src/os/unix/net/ucred.rs
+++ b/library/std/src/os/unix/net/ucred.rs
@@ -35,14 +35,8 @@ pub(super) use self::impl_linux::peer_cred;
 ))]
 pub(super) use self::impl_bsd::peer_cred;
 
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos"
-))]
-pub(super) use self::impl_mac::peer_cred;
+#[cfg(target_vendor = "apple")]
+pub(super) use self::impl_apple::peer_cred;
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 mod impl_linux {
@@ -103,14 +97,8 @@ mod impl_bsd {
     }
 }
 
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos"
-))]
-mod impl_mac {
+#[cfg(target_vendor = "apple")]
+mod impl_apple {
     use super::UCred;
     use crate::os::unix::io::AsRawFd;
     use crate::os::unix::net::UnixStream;
diff --git a/library/std/src/os/unix/net/ucred/tests.rs b/library/std/src/os/unix/net/ucred/tests.rs
index 2a0797877c6..a6cc81318fc 100644
--- a/library/std/src/os/unix/net/ucred/tests.rs
+++ b/library/std/src/os/unix/net/ucred/tests.rs
@@ -7,12 +7,8 @@ use libc::{getegid, geteuid, getpid};
     target_os = "linux",
     target_os = "dragonfly",
     target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "macos",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "openbsd"
+    target_os = "openbsd",
+    target_vendor = "apple",
 ))]
 fn test_socket_pair() {
     // Create two connected sockets and get their peer credentials. They should be equal.
@@ -28,14 +24,7 @@ fn test_socket_pair() {
 }
 
 #[test]
-#[cfg(any(
-    target_os = "linux",
-    target_os = "ios",
-    target_os = "macos",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "tvos",
-))]
+#[cfg(any(target_os = "linux", target_vendor = "apple"))]
 fn test_socket_pair_pids(arg: Type) -> RetType {
     // Create two connected sockets and get their peer credentials.
     let (sock_a, sock_b) = UnixStream::pair().unwrap();
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 1c58671a0cf..79d800ff072 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1158,12 +1158,6 @@ impl FusedIterator for Ancestors<'_> {}
 /// Which method works best depends on what kind of situation you're in.
 #[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// `PathBuf::as_mut_vec` current implementation relies
-// on `PathBuf` being layout-compatible with `Vec<u8>`.
-// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
-// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
-// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
-#[cfg_attr(not(doc), repr(transparent))]
 pub struct PathBuf {
     inner: OsString,
 }
@@ -1171,7 +1165,7 @@ pub struct PathBuf {
 impl PathBuf {
     #[inline]
     fn as_mut_vec(&mut self) -> &mut Vec<u8> {
-        unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
+        self.inner.as_mut_vec_for_path_buf()
     }
 
     /// Allocates an empty `PathBuf`.
@@ -3380,7 +3374,7 @@ impl Error for StripPrefixError {
 ///
 /// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
 /// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
-#[stable(feature = "absolute_path", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "absolute_path", since = "1.79.0")]
 pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
     let path = path.as_ref();
     if path.as_os_str().is_empty() {
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index f61e04e02b6..01936734d75 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -84,7 +84,6 @@ pub use core::prelude::v1::cfg_eval;
 )]
 pub use core::prelude::v1::type_ascribe;
 
-#[cfg(not(bootstrap))]
 // Do not `doc(no_inline)` either.
 #[unstable(
     feature = "deref_patterns",
diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
index 4ca3f1cd185..18b969bca85 100644
--- a/library/std/src/sys/os_str/bytes.rs
+++ b/library/std/src/sys/os_str/bytes.rs
@@ -11,8 +11,6 @@ use crate::str;
 use crate::sync::Arc;
 use crate::sys_common::{AsInner, IntoInner};
 
-use core::str::Utf8Chunks;
-
 #[cfg(test)]
 mod tests;
 
@@ -29,7 +27,7 @@ pub struct Slice {
 
 impl fmt::Debug for Slice {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&Utf8Chunks::new(&self.inner).debug(), f)
+        fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f)
     }
 }
 
@@ -41,7 +39,7 @@ impl fmt::Display for Slice {
             return "".fmt(f);
         }
 
-        for chunk in Utf8Chunks::new(&self.inner) {
+        for chunk in self.inner.utf8_chunks() {
             let valid = chunk.valid();
             // If we successfully decoded the whole chunk as a valid string then
             // we can return a direct formatting of the string which will also
@@ -198,6 +196,12 @@ impl Buf {
     pub fn into_rc(&self) -> Rc<Slice> {
         self.as_slice().into_rc()
     }
+
+    /// Part of a hack to make PathBuf::push/pop more efficient.
+    #[inline]
+    pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
+        &mut self.inner
+    }
 }
 
 impl Slice {
diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs
index 352bd735903..b3ceb55802d 100644
--- a/library/std/src/sys/os_str/wtf8.rs
+++ b/library/std/src/sys/os_str/wtf8.rs
@@ -158,6 +158,12 @@ impl Buf {
     pub fn into_rc(&self) -> Rc<Slice> {
         self.as_slice().into_rc()
     }
+
+    /// Part of a hack to make PathBuf::push/pop more efficient.
+    #[inline]
+    pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
+        self.inner.as_mut_vec_for_path_buf()
+    }
 }
 
 impl Slice {
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs
index acf8100d47f..2a3298e8b4c 100644
--- a/library/std/src/sys/pal/unix/args.rs
+++ b/library/std/src/sys/pal/unix/args.rs
@@ -98,12 +98,10 @@ mod imp {
     }
 
     #[inline(always)]
-    pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
-        // On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize
-        // `ARGC` and `ARGV`. But in Miri that does not actually happen so we
-        // still initialize here.
-        #[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))]
-        really_init(_argc, _argv);
+    pub unsafe fn init(argc: isize, argv: *const *const u8) {
+        // on GNU/Linux if we are main then we will init argv and argc twice, it "duplicates work"
+        // BUT edge-cases are real: only using .init_array can break most emulators, dlopen, etc.
+        really_init(argc, argv);
     }
 
     /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension.
@@ -170,13 +168,7 @@ mod imp {
     }
 }
 
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "tvos"
-))]
+#[cfg(target_vendor = "apple")]
 mod imp {
     use super::Args;
     use crate::ffi::CStr;
@@ -217,12 +209,7 @@ mod imp {
     // for i in (0..[args count])
     //      res.push([args objectAtIndex:i])
     // res
-    #[cfg(any(
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos"
-    ))]
+    #[cfg(not(target_os = "macos"))]
     pub fn args() -> Args {
         use crate::ffi::{c_char, c_void, OsString};
         use crate::mem;
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 3456155509e..32cdd13fbeb 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -20,14 +20,7 @@ use crate::sys::time::SystemTime;
 use crate::sys::{cvt, cvt_r};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
-#[cfg(any(
-    all(target_os = "linux", target_env = "gnu"),
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
-))]
+#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
 use crate::sys::weak::syscall;
 #[cfg(any(target_os = "android", target_os = "macos", target_os = "solaris"))]
 use crate::sys::weak::weak;
@@ -35,13 +28,9 @@ use crate::sys::weak::weak;
 use libc::{c_int, mode_t};
 
 #[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
     target_os = "solaris",
-    all(target_os = "linux", target_env = "gnu")
+    all(target_os = "linux", target_env = "gnu"),
+    target_vendor = "apple",
 ))]
 use libc::c_char;
 #[cfg(any(
@@ -198,20 +187,16 @@ cfg_has_statx! {{
                 return Some(Err(err));
             }
 
-            // `ENOSYS` might come from a faulty FUSE driver.
-            //
-            // Other errors are not a good enough indicator either -- it is
-            // known that `EPERM` can be returned as a result of using seccomp to
-            // block the syscall.
+            // We're not yet entirely sure whether `statx` is usable on this kernel
+            // or not. Syscalls can return errors from things other than the kernel
+            // per se, e.g. `EPERM` can be returned if seccomp is used to block the
+            // syscall, or `ENOSYS` might be returned from a faulty FUSE driver.
             //
             // Availability is checked by performing a call which expects `EFAULT`
             // if the syscall is usable.
             //
             // See: https://github.com/rust-lang/rust/issues/65662
             //
-            // FIXME this can probably just do the call if `EPERM` was received, but
-            // previous iteration of the code checked it for all errors and for now
-            // this is retained.
             // FIXME what about transient conditions like `ENOMEM`?
             let err2 = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut()))
                 .err()
@@ -379,13 +364,7 @@ pub struct FilePermissions {
 pub struct FileTimes {
     accessed: Option<SystemTime>,
     modified: Option<SystemTime>,
-    #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos"
-    ))]
+    #[cfg(target_vendor = "apple")]
     created: Option<SystemTime>,
 }
 
@@ -558,15 +537,7 @@ impl FileAttr {
         SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
     }
 
-    #[cfg(any(
-        target_os = "freebsd",
-        target_os = "openbsd",
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
-    ))]
+    #[cfg(any(target_os = "freebsd", target_os = "openbsd", target_vendor = "apple"))]
     pub fn created(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)
     }
@@ -574,12 +545,8 @@ impl FileAttr {
     #[cfg(not(any(
         target_os = "freebsd",
         target_os = "openbsd",
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "vita",
+        target_vendor = "apple",
     )))]
     pub fn created(&self) -> io::Result<SystemTime> {
         cfg_has_statx! {
@@ -659,13 +626,7 @@ impl FileTimes {
         self.modified = Some(t);
     }
 
-    #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos"
-    ))]
+    #[cfg(target_vendor = "apple")]
     pub fn set_created(&mut self, t: SystemTime) {
         self.created = Some(t);
     }
@@ -868,8 +829,43 @@ impl Iterator for ReadDir {
     }
 }
 
+/// Aborts the process if a file desceriptor is not open, if debug asserts are enabled
+///
+/// Many IO syscalls can't be fully trusted about EBADF error codes because those
+/// might get bubbled up from a remote FUSE server rather than the file descriptor
+/// in the current process being invalid.
+///
+/// So we check file flags instead which live on the file descriptor and not the underlying file.
+/// The downside is that it costs an extra syscall, so we only do it for debug.
+#[inline]
+pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
+    use crate::sys::os::errno;
+
+    // this is similar to assert_unsafe_precondition!() but it doesn't require const
+    if core::ub_checks::check_library_ub() {
+        if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF {
+            rtabort!("IO Safety violation: owned file descriptor already closed");
+        }
+    }
+}
+
 impl Drop for Dir {
     fn drop(&mut self) {
+        // dirfd isn't supported everywhere
+        #[cfg(not(any(
+            miri,
+            target_os = "redox",
+            target_os = "nto",
+            target_os = "vita",
+            target_os = "hurd",
+            target_os = "espidf",
+            target_os = "fuchsia",
+            target_os = "horizon",
+        )))]
+        {
+            let fd = unsafe { libc::dirfd(self.0) };
+            debug_assert_fd_is_open(fd);
+        }
         let r = unsafe { libc::closedir(self.0) };
         assert!(
             r == 0 || crate::io::Error::last_os_error().is_interrupted(),
@@ -966,11 +962,6 @@ impl DirEntry {
     }
 
     #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "linux",
         target_os = "emscripten",
         target_os = "android",
@@ -987,6 +978,7 @@ impl DirEntry {
         target_os = "aix",
         target_os = "nto",
         target_os = "hurd",
+        target_vendor = "apple",
     ))]
     pub fn ino(&self) -> u64 {
         self.entry.d_ino as u64
@@ -1003,15 +995,11 @@ impl DirEntry {
     }
 
     #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
         target_os = "freebsd",
-        target_os = "dragonfly"
+        target_os = "dragonfly",
+        target_vendor = "apple",
     ))]
     fn name_bytes(&self) -> &[u8] {
         use crate::slice;
@@ -1023,15 +1011,11 @@ impl DirEntry {
         }
     }
     #[cfg(not(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
         target_os = "freebsd",
-        target_os = "dragonfly"
+        target_os = "dragonfly",
+        target_vendor = "apple",
     )))]
     fn name_bytes(&self) -> &[u8] {
         self.name_cstr().to_bytes()
@@ -1209,23 +1193,11 @@ impl File {
         cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?;
         return Ok(());
 
-        #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "watchos",
-            target_os = "visionos",
-        ))]
+        #[cfg(target_vendor = "apple")]
         unsafe fn os_fsync(fd: c_int) -> c_int {
             libc::fcntl(fd, libc::F_FULLFSYNC)
         }
-        #[cfg(not(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "watchos",
-            target_os = "visionos",
-        )))]
+        #[cfg(not(target_vendor = "apple"))]
         unsafe fn os_fsync(fd: c_int) -> c_int {
             libc::fsync(fd)
         }
@@ -1235,13 +1207,7 @@ impl File {
         cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?;
         return Ok(());
 
-        #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "watchos",
-            target_os = "visionos",
-        ))]
+        #[cfg(target_vendor = "apple")]
         unsafe fn os_datasync(fd: c_int) -> c_int {
             libc::fcntl(fd, libc::F_FULLFSYNC)
         }
@@ -1260,16 +1226,12 @@ impl File {
         #[cfg(not(any(
             target_os = "android",
             target_os = "freebsd",
-            target_os = "ios",
-            target_os = "tvos",
             target_os = "linux",
-            target_os = "macos",
             target_os = "netbsd",
             target_os = "openbsd",
-            target_os = "watchos",
-            target_os = "visionos",
             target_os = "nto",
             target_os = "hurd",
+            target_vendor = "apple",
         )))]
         unsafe fn os_datasync(fd: c_int) -> c_int {
             libc::fsync(fd)
@@ -1378,7 +1340,7 @@ impl File {
                     io::ErrorKind::Unsupported,
                     "setting file times not supported",
                 ))
-            } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] {
+            } else if #[cfg(target_vendor = "apple")] {
                 let mut buf = [mem::MaybeUninit::<libc::timespec>::uninit(); 3];
                 let mut num_times = 0;
                 let mut attrlist: libc::attrlist = unsafe { mem::zeroed() };
@@ -1910,15 +1872,7 @@ fn open_to_and_set_permissions(
     Ok((writer, writer_metadata))
 }
 
-#[cfg(not(any(
-    target_os = "linux",
-    target_os = "android",
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
-)))]
+#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     let (mut reader, reader_metadata) = open_from(from)?;
     let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?;
@@ -1944,13 +1898,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     }
 }
 
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "tvos"
-))]
+#[cfg(target_vendor = "apple")]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     use crate::sync::atomic::{AtomicBool, Ordering};
 
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 3ef43a923a3..01d7fb31d7d 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -78,16 +78,12 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_os = "emscripten",
             target_os = "fuchsia",
             target_os = "vxworks",
-            // The poll on Darwin doesn't set POLLNVAL for closed fds.
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "watchos",
-            target_os = "visionos",
             target_os = "redox",
             target_os = "l4re",
             target_os = "horizon",
             target_os = "vita",
+            // The poll on Darwin doesn't set POLLNVAL for closed fds.
+            target_vendor = "apple",
         )))]
         'poll: {
             use crate::sys::os::errno;
@@ -406,7 +402,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "macos")] {
         #[link(name = "System")]
         extern "C" {}
-    } else if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] {
+    } else if #[cfg(all(target_vendor = "apple", not(target_os = "macos")))] {
         #[link(name = "System")]
         #[link(name = "objc")]
         #[link(name = "Foundation", kind = "framework")]
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 96492fedece..3a281525f8d 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -63,17 +63,7 @@ extern "C" {
     )]
     #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
     #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")]
-    #[cfg_attr(
-        any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "freebsd",
-            target_os = "watchos",
-            target_os = "visionos",
-        ),
-        link_name = "__error"
-    )]
+    #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
     #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
     #[cfg_attr(target_os = "aix", link_name = "_Errno")]
     fn errno_location() -> *mut c_int;
@@ -431,13 +421,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     Ok(PathBuf::from(OsString::from_vec(e)))
 }
 
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "tvos"
-))]
+#[cfg(target_vendor = "apple")]
 pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         let mut sz: u32 = 0;
@@ -703,32 +687,26 @@ pub fn home_dir() -> Option<PathBuf> {
 
     #[cfg(any(
         target_os = "android",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "emscripten",
         target_os = "redox",
         target_os = "vxworks",
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
+        all(target_vendor = "apple", not(target_os = "macos")),
     ))]
     unsafe fn fallback() -> Option<OsString> {
         None
     }
     #[cfg(not(any(
         target_os = "android",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "emscripten",
         target_os = "redox",
         target_os = "vxworks",
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
+        all(target_vendor = "apple", not(target_os = "macos")),
     )))]
     unsafe fn fallback() -> Option<OsString> {
         let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index d65657790c4..f2947161cd5 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -420,13 +420,11 @@ impl Command {
     }
 
     #[cfg(not(any(
-        target_os = "macos",
-        target_os = "tvos",
-        target_os = "watchos",
         target_os = "freebsd",
         all(target_os = "linux", target_env = "gnu"),
         all(target_os = "linux", target_env = "musl"),
         target_os = "nto",
+        target_vendor = "apple",
     )))]
     fn posix_spawn(
         &mut self,
@@ -439,14 +437,11 @@ impl Command {
     // Only support platforms for which posix_spawn() can return ENOENT
     // directly.
     #[cfg(any(
-        target_os = "macos",
-        // FIXME: `target_os = "ios"`?
-        target_os = "tvos",
-        target_os = "watchos",
         target_os = "freebsd",
         all(target_os = "linux", target_env = "gnu"),
         all(target_os = "linux", target_env = "musl"),
         target_os = "nto",
+        target_vendor = "apple",
     ))]
     fn posix_spawn(
         &mut self,
@@ -530,7 +525,7 @@ impl Command {
         }
         let addchdir = match self.get_cwd() {
             Some(cwd) => {
-                if cfg!(any(target_os = "macos", target_os = "tvos", target_os = "watchos")) {
+                if cfg!(target_vendor = "apple") {
                     // There is a bug in macOS where a relative executable
                     // path like "../myprogram" will cause `posix_spawn` to
                     // successfully launch the program, but erroneously return
@@ -1040,24 +1035,20 @@ fn signal_string(signal: i32) -> &'static str {
         #[cfg(any(target_os = "linux", target_os = "nto"))]
         libc::SIGPWR => " (SIGPWR)",
         #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
             target_os = "freebsd",
             target_os = "netbsd",
             target_os = "openbsd",
             target_os = "dragonfly",
             target_os = "nto",
+            target_vendor = "apple",
         ))]
         libc::SIGEMT => " (SIGEMT)",
         #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
             target_os = "freebsd",
             target_os = "netbsd",
             target_os = "openbsd",
-            target_os = "dragonfly"
+            target_os = "dragonfly",
+            target_vendor = "apple",
         ))]
         libc::SIGINFO => " (SIGINFO)",
         #[cfg(target_os = "hurd")]
diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs
index de087d98eb8..d8f227b4ef4 100644
--- a/library/std/src/sys/pal/unix/rand.rs
+++ b/library/std/src/sys/pal/unix/rand.rs
@@ -12,11 +12,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 
 #[cfg(all(
     unix,
-    not(target_os = "macos"),
-    not(target_os = "ios"),
-    not(target_os = "tvos"),
-    not(target_os = "watchos"),
-    not(target_os = "visionos"),
     not(target_os = "openbsd"),
     not(target_os = "netbsd"),
     not(target_os = "fuchsia"),
@@ -24,6 +19,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
     not(target_os = "vxworks"),
     not(target_os = "emscripten"),
     not(target_os = "vita"),
+    not(target_vendor = "apple"),
 ))]
 mod imp {
     use crate::fs::File;
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 6a6bfc77a85..853ef8736de 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -150,13 +150,7 @@ impl Thread {
         }
     }
 
-    #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "tvos"
-    ))]
+    #[cfg(target_vendor = "apple")]
     pub fn set_name(name: &CStr) {
         unsafe {
             let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name);
@@ -301,14 +295,10 @@ impl Drop for Thread {
 
 #[cfg(any(
     target_os = "linux",
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
     target_os = "nto",
     target_os = "solaris",
     target_os = "illumos",
+    target_vendor = "apple",
 ))]
 fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] {
     let mut result = [0; MAX_WITH_NUL];
@@ -325,11 +315,9 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
             target_os = "emscripten",
             target_os = "fuchsia",
             target_os = "hurd",
-            target_os = "ios",
-            target_os = "tvos",
             target_os = "linux",
-            target_os = "macos",
             target_os = "aix",
+            target_vendor = "apple",
         ))] {
             #[allow(unused_assignments)]
             #[allow(unused_mut)]
diff --git a/library/std/src/sys/pal/unix/thread_local_dtor.rs b/library/std/src/sys/pal/unix/thread_local_dtor.rs
index 1164c1782f4..75db6e112ed 100644
--- a/library/std/src/sys/pal/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/pal/unix/thread_local_dtor.rs
@@ -76,13 +76,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
 // workaround below is to register, via _tlv_atexit, a custom DTOR list once per
 // thread. thread_local dtors are pushed to the DTOR list without calling
 // _tlv_atexit.
-#[cfg(any(
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "watchos",
-    target_os = "visionos",
-    target_os = "tvos"
-))]
+#[cfg(target_vendor = "apple")]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     use crate::cell::{Cell, RefCell};
     use crate::ptr;
diff --git a/library/std/src/sys/pal/unix/thread_parking/mod.rs b/library/std/src/sys/pal/unix/thread_parking/mod.rs
index 3348d4b366d..c7fa39f07b6 100644
--- a/library/std/src/sys/pal/unix/thread_parking/mod.rs
+++ b/library/std/src/sys/pal/unix/thread_parking/mod.rs
@@ -11,16 +11,7 @@
 )))]
 
 cfg_if::cfg_if! {
-    if #[cfg(all(
-        any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "watchos",
-            target_os = "visionos",
-            target_os = "tvos",
-        ),
-        not(miri),
-    ))] {
+    if #[cfg(all(target_vendor = "apple", not(miri)))] {
         mod darwin;
         pub use darwin::Parker;
     } else if #[cfg(target_os = "netbsd")] {
diff --git a/library/std/src/sys/pal/unix/thread_parking/pthread.rs b/library/std/src/sys/pal/unix/thread_parking/pthread.rs
index d0ad3e2ce3e..8e295453d76 100644
--- a/library/std/src/sys/pal/unix/thread_parking/pthread.rs
+++ b/library/std/src/sys/pal/unix/thread_parking/pthread.rs
@@ -43,15 +43,7 @@ unsafe fn wait_timeout(
 ) {
     // Use the system clock on systems that do not support pthread_condattr_setclock.
     // This unfortunately results in problems when the system time changes.
-    #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "espidf",
-        target_os = "horizon",
-    ))]
+    #[cfg(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple"))]
     let (now, dur) = {
         use crate::cmp::min;
         use crate::sys::time::SystemTime;
@@ -72,15 +64,7 @@ unsafe fn wait_timeout(
         (now, dur)
     };
     // Use the monotonic clock on other systems.
-    #[cfg(not(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
-        target_os = "espidf",
-        target_os = "horizon",
-    )))]
+    #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple")))]
     let (now, dur) = {
         use crate::sys::time::Timespec;
 
@@ -122,15 +106,11 @@ impl Parker {
 
         cfg_if::cfg_if! {
             if #[cfg(any(
-                target_os = "macos",
-                target_os = "ios",
-                target_os = "tvos",
-                target_os = "watchos",
-                target_os = "visionos",
                 target_os = "l4re",
                 target_os = "android",
                 target_os = "redox",
                 target_os = "vita",
+                target_vendor = "apple",
             ))] {
                 addr_of_mut!((*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER));
             } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] {
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index e69775be8cf..535fe6b27d9 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -86,13 +86,7 @@ impl Timespec {
         // Please note that Apple OS nonetheless accepts the standard unix format when
         // setting file times, which makes this compensation round-trippable and generally
         // transparent.
-        #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "tvos",
-            target_os = "watchos",
-            target_os = "visionos",
-        ))]
+        #[cfg(target_vendor = "apple")]
         let (tv_sec, tv_nsec) =
             if (tv_sec <= 0 && tv_sec > i64::MIN) && (tv_nsec < 0 && tv_nsec > -1_000_000_000) {
                 (tv_sec - 1, tv_nsec + 1_000_000_000)
@@ -275,21 +269,9 @@ impl Instant {
         //
         // Instant on macos was historically implemented using mach_absolute_time;
         // we preserve this value domain out of an abundance of caution.
-        #[cfg(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "watchos",
-            target_os = "visionos",
-            target_os = "tvos"
-        ))]
+        #[cfg(target_vendor = "apple")]
         const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
-        #[cfg(not(any(
-            target_os = "macos",
-            target_os = "ios",
-            target_os = "watchos",
-            target_os = "visionos",
-            target_os = "tvos"
-        )))]
+        #[cfg(not(target_vendor = "apple"))]
         const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
         Instant { t: Timespec::now(clock_id) }
     }
diff --git a/library/std/src/sys/sync/condvar/pthread.rs b/library/std/src/sys/sync/condvar/pthread.rs
index 0475f985078..a2a96410d93 100644
--- a/library/std/src/sys/sync/condvar/pthread.rs
+++ b/library/std/src/sys/sync/condvar/pthread.rs
@@ -30,14 +30,10 @@ impl LazyInit for AllocatedCondvar {
 
         cfg_if::cfg_if! {
             if #[cfg(any(
-                target_os = "macos",
-                target_os = "ios",
-                target_os = "tvos",
-                target_os = "watchos",
-                target_os = "visionos",
                 target_os = "l4re",
                 target_os = "android",
-                target_os = "redox"
+                target_os = "redox",
+                target_vendor = "apple",
             ))] {
                 // `pthread_condattr_setclock` is unfortunately not supported on these platforms.
             } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] {
@@ -124,14 +120,10 @@ impl Condvar {
     // default system clock). This approach avoids all problems that result
     // from changes made to the system time.
     #[cfg(not(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "android",
         target_os = "espidf",
-        target_os = "horizon"
+        target_os = "horizon",
+        target_vendor = "apple",
     )))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::sys::time::Timespec;
@@ -160,14 +152,10 @@ impl Condvar {
     // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
     // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
     #[cfg(any(
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "visionos",
         target_os = "android",
         target_os = "espidf",
-        target_os = "horizon"
+        target_os = "horizon",
+        target_vendor = "apple",
     ))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::sys::time::SystemTime;
diff --git a/library/std/src/sys/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs
index 69ee70de30c..49b51a729e4 100644
--- a/library/std/src/sys/thread_local/fast_local.rs
+++ b/library/std/src/sys/thread_local/fast_local.rs
@@ -1,7 +1,7 @@
 use super::lazy::LazyKeyInner;
 use crate::cell::Cell;
 use crate::sys::thread_local_dtor::register_dtor;
-use crate::{fmt, mem, panic};
+use crate::{fmt, mem, panic, ptr};
 
 #[doc(hidden)]
 #[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
@@ -237,8 +237,9 @@ unsafe extern "C" fn destroy_value<T>(ptr: *mut u8) {
     // Wrap the call in a catch to ensure unwinding is caught in the event
     // a panic takes place in a destructor.
     if let Err(_) = panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe {
-        let value = (*ptr).inner.take();
-        (*ptr).dtor_state.set(DtorState::RunningOrHasRun);
+        let Key { inner, dtor_state } = &*ptr;
+        let value = inner.take();
+        dtor_state.set(DtorState::RunningOrHasRun);
         drop(value);
     })) {
         rtabort!("thread local panicked on drop");
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index 8b2c839f837..7500c95d8b4 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -91,13 +91,15 @@ mod lazy {
             }
         }
 
-        /// The other methods hand out references while taking &self.
-        /// As such, callers of this method must ensure no `&` and `&mut` are
-        /// available and used at the same time.
+        /// Watch out: unsynchronized internal mutability!
+        ///
+        /// # Safety
+        /// Causes UB if any reference to the value is used after this.
         #[allow(unused)]
-        pub unsafe fn take(&mut self) -> Option<T> {
-            // SAFETY: See doc comment for this method.
-            unsafe { (*self.inner.get()).take() }
+        pub(crate) unsafe fn take(&self) -> Option<T> {
+            let mutable: *mut _ = UnsafeCell::get(&self.inner);
+            // SAFETY: That's the caller's problem.
+            unsafe { mutable.replace(None) }
         }
     }
 }
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 6a268633f72..95ca67fc2e0 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -17,10 +17,17 @@ use crate::ffi::{c_int, c_void};
 
 cfg_if::cfg_if! {
     if #[cfg(any(
-        target_os = "dragonfly", target_os = "freebsd",
-        target_os = "ios", target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "visionos",
-        target_os = "openbsd", target_os = "netbsd", target_os = "illumos",
-        target_os = "solaris", target_os = "haiku", target_os = "l4re", target_os = "nto"))] {
+        target_os = "dragonfly",
+        target_os = "freebsd",
+        target_os = "openbsd",
+        target_os = "netbsd",
+        target_os = "illumos",
+        target_os = "solaris",
+        target_os = "haiku",
+        target_os = "l4re",
+        target_os = "nto",
+        target_vendor = "apple",
+    ))] {
         use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
         use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
     } else {
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 2dbd19d7171..38e15f9f549 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -468,6 +468,12 @@ impl Wtf8Buf {
         let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
         Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false }
     }
+
+    /// Part of a hack to make PathBuf::push/pop more efficient.
+    #[inline]
+    pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
+        &mut self.bytes
+    }
 }
 
 /// Creates a new WTF-8 string from an iterator of code points.
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 494513f2c75..1fb1333be0e 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -40,11 +40,7 @@ fn test_named_thread() {
 #[cfg(any(
     // Note: musl didn't add pthread_getname_np until 1.2.3
     all(target_os = "linux", target_env = "gnu"),
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "visionos",
+    target_vendor = "apple",
 ))]
 #[test]
 fn test_named_thread_truncation() {
diff --git a/rustfmt.toml b/rustfmt.toml
index 0b0674af8b4..850d01ea7cb 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -13,7 +13,13 @@ ignore = [
 
     # tests for now are not formatted, as they are sometimes pretty-printing constrained
     # (and generally rustfmt can move around comments in UI-testing incompatible ways)
-    "/tests/",
+    "/tests/*",
+
+    # but we still want to format rmake.rs files in tests/run-make/ so we need to do this
+    # dance to avoid the parent directory from being excluded
+    "!/tests/run-make/",
+    "/tests/run-make/*/*.rs",
+    "!/tests/run-make/*/rmake.rs",
 
     # do not format submodules
     # FIXME: sync submodule list with tidy/bootstrap/etc
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 39add60e705..e464e444fea 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1035,14 +1035,8 @@ class RustBuild(object):
         if self.use_vendored_sources:
             vendor_dir = os.path.join(self.rust_root, 'vendor')
             if not os.path.exists(vendor_dir):
-                sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \
-                            "--sync ./src/tools/rust-analyzer/Cargo.toml " \
-                            "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \
-                            "--sync ./compiler/rustc_codegen_gcc/Cargo.toml " \
-                            "--sync ./src/bootstrap/Cargo.toml "
                 eprint('ERROR: vendoring required, but vendor directory does not exist.')
-                eprint('       Run `cargo vendor {}` to initialize the '
-                      'vendor directory.'.format(sync_dirs))
+                eprint('       Run `x.py vendor` to initialize the vendor directory.')
                 eprint('       Alternatively, use the pre-vendored `rustc-src` dist component.')
                 eprint('       To get a stable/beta/nightly version, download it from: ')
                 eprint('       '
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 3cfd0240794..fc433bc5843 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -53,15 +53,12 @@ check-aux:
 		src/tools/cargotest \
 		$(BOOTSTRAP_ARGS)
 	# Run standard library tests in Miri.
-	# We use a 64bit little-endian and a 32bit big-endian target for max coverage.
 	$(Q)BOOTSTRAP_SKIP_TARGET_SANITY=1 \
 		$(BOOTSTRAP) miri --stage 2 \
-		--target x86_64-unknown-linux-gnu,mips-unknown-linux-gnu \
 		library/core \
 		library/alloc \
 		--no-doc
 	# Some doctests have intentional memory leaks.
-	# Also, they work only on the host.
 	$(Q)MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" \
 		$(BOOTSTRAP) miri --stage 2 \
 		library/core \
diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs
index 5bcaeed7faa..a81d6403013 100644
--- a/src/bootstrap/src/core/build_steps/clean.rs
+++ b/src/bootstrap/src/core/build_steps/clean.rs
@@ -1,4 +1,4 @@
-//! Implementation of `make clean` in rustbuild.
+//! `./x.py clean`
 //!
 //! Responsible for cleaning out a build directory of all old and stale
 //! artifacts to prepare for a fresh build. Currently doesn't remove the
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 0eca20901b7..5bc9d7615e2 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -25,7 +25,7 @@ use crate::core::build_steps::llvm;
 use crate::core::build_steps::tool::{self, Tool};
 use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::TargetSelection;
-use crate::utils::channel;
+use crate::utils::channel::{self, Info};
 use crate::utils::helpers::{exe, is_dylib, output, t, target_supports_cranelift_backend, timeit};
 use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball};
 use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
@@ -830,6 +830,12 @@ fn copy_src_dirs(
             return false;
         }
 
+        // Cargo tests use some files like `.gitignore` that we would otherwise exclude.
+        const CARGO_TESTS: &[&str] = &["tools/cargo/tests", "tools\\cargo\\tests"];
+        if CARGO_TESTS.iter().any(|path| spath.contains(path)) {
+            return true;
+        }
+
         let full_path = Path::new(dir).join(path);
         if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
             return false;
@@ -985,10 +991,17 @@ impl Step for PlainSourceTarball {
 
         // Create the version file
         builder.create(&plain_dst_src.join("version"), &builder.rust_version());
-        if let Some(info) = builder.rust_info().info() {
-            channel::write_commit_hash_file(plain_dst_src, &info.sha);
-            channel::write_commit_info_file(plain_dst_src, info);
-        }
+
+        // Create the files containing git info, to ensure --version outputs the same.
+        let write_git_info = |info: Option<&Info>, path: &Path| {
+            if let Some(info) = info {
+                t!(std::fs::create_dir_all(path));
+                channel::write_commit_hash_file(path, &info.sha);
+                channel::write_commit_info_file(path, info);
+            }
+        };
+        write_git_info(builder.rust_info().info(), plain_dst_src);
+        write_git_info(builder.cargo_info.info(), &plain_dst_src.join("./src/tools/cargo"));
 
         // If we're building from git or tarball sources, we need to vendor
         // a complete distribution.
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 9fc65a0a73a..d9dc34c0137 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -115,7 +115,11 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
     let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
     let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
     for ignore in rustfmt_config.ignore {
-        fmt_override.add(&format!("!{ignore}")).expect(&ignore);
+        if let Some(ignore) = ignore.strip_prefix('!') {
+            fmt_override.add(ignore).expect(ignore);
+        } else {
+            fmt_override.add(&format!("!{ignore}")).expect(&ignore);
+        }
     }
     let git_available = match Command::new("git")
         .arg("--version")
diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs
index 9b7378165de..381ee7ef53b 100644
--- a/src/bootstrap/src/core/build_steps/mod.rs
+++ b/src/bootstrap/src/core/build_steps/mod.rs
@@ -14,3 +14,4 @@ pub(crate) mod synthetic_targets;
 pub(crate) mod test;
 pub(crate) mod tool;
 pub(crate) mod toolstate;
+pub(crate) mod vendor;
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 7028bffea54..354eb2b6003 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -1,3 +1,8 @@
+//! Build-and-run steps for in-repo tools
+//!
+//! A bit of a hodge-podge as e.g. if a tool's a test fixture it should be in `build_steps::test`.
+//! If it can be reached from `./x.py run` it can go here.
+
 use std::path::PathBuf;
 use std::process::Command;
 
@@ -10,32 +15,6 @@ use crate::core::config::TargetSelection;
 use crate::utils::helpers::output;
 use crate::Mode;
 
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ExpandYamlAnchors;
-
-impl Step for ExpandYamlAnchors {
-    type Output = ();
-
-    /// Runs the `expand-yaml_anchors` tool.
-    ///
-    /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the
-    /// anchors in them, since GitHub Actions doesn't support them.
-    fn run(self, builder: &Builder<'_>) {
-        builder.info("Expanding YAML anchors in the GitHub Actions configuration");
-        builder.run_delaying_failure(
-            builder.tool_cmd(Tool::ExpandYamlAnchors).arg("generate").arg(&builder.src),
-        );
-    }
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/expand-yaml-anchors")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(ExpandYamlAnchors);
-    }
-}
-
 #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
 pub struct BuildManifest;
 
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index c0683cdda1e..df38d6166eb 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -1,3 +1,10 @@
+//! First time setup of a dev environment
+//!
+//! These are build-and-run steps for `./x.py setup`, which allows quickly setting up the directory
+//! for modifying, building, and running the compiler and library. Running arbitrary configuration
+//! allows setting up things that cannot be simply captured inside the config.toml, in addition to
+//! leading people away from manually editing most of the config.toml values.
+
 use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::t;
 use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
@@ -25,6 +32,8 @@ pub enum Profile {
     None,
 }
 
+static PROFILE_DIR: &str = "src/bootstrap/defaults";
+
 /// A list of historical hashes of `src/etc/rust_analyzer_settings.json`.
 /// New entries should be appended whenever this is updated so we can detect
 /// outdated vs. user-modified settings files.
@@ -41,7 +50,7 @@ static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyze
 
 impl Profile {
     fn include_path(&self, src_path: &Path) -> PathBuf {
-        PathBuf::from(format!("{}/src/bootstrap/defaults/config.{}.toml", src_path.display(), self))
+        PathBuf::from(format!("{}/{PROFILE_DIR}/config.{}.toml", src_path.display(), self))
     }
 
     pub fn all() -> impl Iterator<Item = Self> {
@@ -220,7 +229,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
 
     let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id;
     let settings = format!(
-        "# Includes one of the default files in src/bootstrap/defaults\n\
+        "# Includes one of the default files in {PROFILE_DIR}\n\
     profile = \"{profile}\"\n\
     change-id = {latest_change_id}\n"
     );
diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs
index c057fa9a566..754d1e61da8 100644
--- a/src/bootstrap/src/core/build_steps/suggest.rs
+++ b/src/bootstrap/src/core/build_steps/suggest.rs
@@ -1,3 +1,5 @@
+//! Attempt to magically identify good tests to run
+
 #![cfg_attr(feature = "build-metrics", allow(unused))]
 
 use clap::Parser;
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index ca10a128b98..9a585a39e1e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1,7 +1,7 @@
-//! Implementation of the test-related targets of the build system.
+//! Build-and-run steps for `./x.py test` test fixtures
 //!
-//! This file implements the various regression test suites that we execute on
-//! our CI.
+//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
+//! However, this contains ~all test parts we expect people to be able to build and run locally.
 
 use std::env;
 use std::ffi::OsStr;
@@ -1146,8 +1146,6 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
         builder.info("tidy check");
         builder.run_delaying_failure(&mut cmd);
 
-        builder.ensure(ExpandYamlAnchors);
-
         builder.info("x.py completions check");
         let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"]
             .map(|filename| builder.src.join("src/etc/completions").join(filename));
@@ -1175,39 +1173,6 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ExpandYamlAnchors;
-
-impl Step for ExpandYamlAnchors {
-    type Output = ();
-    const ONLY_HOSTS: bool = true;
-
-    /// Ensure the `generate-ci-config` tool was run locally.
-    ///
-    /// The tool in `src/tools` reads the CI definition in `src/ci/builders.yml` and generates the
-    /// appropriate configuration for all our CI providers. This step ensures the tool was called
-    /// by the user before committing CI changes.
-    fn run(self, builder: &Builder<'_>) {
-        // NOTE: `.github/` is not included in dist-src tarballs
-        if !builder.src.join(".github/workflows/ci.yml").exists() {
-            builder.info("Skipping YAML anchors check: GitHub Actions config not found");
-            return;
-        }
-        builder.info("Ensuring the YAML anchors in the GitHub Actions config were expanded");
-        builder.run_delaying_failure(
-            builder.tool_cmd(Tool::ExpandYamlAnchors).arg("check").arg(&builder.src),
-        );
-    }
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/expand-yaml-anchors")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(ExpandYamlAnchors);
-    }
-}
-
 fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf {
     builder.out.join(host.triple).join("test")
 }
@@ -1371,6 +1336,7 @@ impl Step for RunMakeSupport {
         run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() });
     }
 
+    /// Builds run-make-support and returns the path to the resulting rlib.
     fn run(self, builder: &Builder<'_>) -> PathBuf {
         builder.ensure(compile::Std::new(self.compiler, self.target));
 
@@ -1397,6 +1363,53 @@ impl Step for RunMakeSupport {
     }
 }
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct CrateRunMakeSupport {
+    host: TargetSelection,
+}
+
+impl Step for CrateRunMakeSupport {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/run-make-support")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(CrateRunMakeSupport { host: run.target });
+    }
+
+    /// Runs `cargo test` for run-make-support.
+    fn run(self, builder: &Builder<'_>) {
+        let host = self.host;
+        let compiler = builder.compiler(builder.top_stage, host);
+
+        builder.ensure(compile::Std::new(compiler, host));
+        let mut cargo = tool::prepare_tool_cargo(
+            builder,
+            compiler,
+            Mode::ToolStd,
+            host,
+            "test",
+            "src/tools/run-make-support",
+            SourceType::InTree,
+            &[],
+        );
+        cargo.allow_features("test");
+        run_cargo_test(
+            cargo,
+            &[],
+            &[],
+            "run-make-support",
+            "run-make-support self test",
+            compiler,
+            host,
+            builder,
+        );
+    }
+}
+
 default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" });
 
 default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" });
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 994f0bef0dc..2e2c5e9e6f8 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -302,7 +302,6 @@ bootstrap_tool!(
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
     RustInstaller, "src/tools/rust-installer", "rust-installer";
     RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes";
-    ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors";
     LintDocs, "src/tools/lint-docs", "lint-docs";
     JsonDocCk, "src/tools/jsondocck", "jsondocck";
     JsonDocLint, "src/tools/jsondoclint", "jsondoclint";
diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs
index f88c1b3ee82..ca3756df4d7 100644
--- a/src/bootstrap/src/core/build_steps/toolstate.rs
+++ b/src/bootstrap/src/core/build_steps/toolstate.rs
@@ -1,3 +1,9 @@
+//! [Toolstate] checks to keep tools building
+//!
+//! Reachable via `./x.py test` but mostly relevant for CI, since it isn't run locally by default.
+//!
+//! [Toolstate]: https://forge.rust-lang.org/infra/toolstate.html
+
 use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::utils::helpers::t;
 use serde_derive::{Deserialize, Serialize};
diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs
new file mode 100644
index 00000000000..68f1b1bef3f
--- /dev/null
+++ b/src/bootstrap/src/core/build_steps/vendor.rs
@@ -0,0 +1,61 @@
+use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
+use std::path::PathBuf;
+use std::process::Command;
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub(crate) struct Vendor {
+    sync_args: Vec<PathBuf>,
+    versioned_dirs: bool,
+    root_dir: PathBuf,
+}
+
+impl Step for Vendor {
+    type Output = ();
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("placeholder").default_condition(true)
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Vendor {
+            sync_args: run.builder.config.cmd.vendor_sync_args(),
+            versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(),
+            root_dir: run.builder.src.clone(),
+        });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let mut cmd = Command::new(&builder.initial_cargo);
+        cmd.arg("vendor");
+
+        if self.versioned_dirs {
+            cmd.arg("--versioned-dirs");
+        }
+
+        // Sync these paths by default.
+        for p in [
+            "src/tools/cargo/Cargo.toml",
+            "src/tools/rust-analyzer/Cargo.toml",
+            "compiler/rustc_codegen_cranelift/Cargo.toml",
+            "compiler/rustc_codegen_gcc/Cargo.toml",
+            "src/bootstrap/Cargo.toml",
+        ] {
+            cmd.arg("--sync").arg(builder.src.join(p));
+        }
+
+        // Also sync explicitly requested paths.
+        for sync_arg in self.sync_args {
+            cmd.arg("--sync").arg(sync_arg);
+        }
+
+        // Will read the libstd Cargo.toml
+        // which uses the unstable `public-dependency` feature.
+        cmd.env("RUSTC_BOOTSTRAP", "1");
+
+        cmd.current_dir(self.root_dir);
+
+        builder.run(&mut cmd);
+    }
+}
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index adef9ebd0e3..0ad6c959309 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -14,8 +14,9 @@ use std::sync::OnceLock;
 use std::time::{Duration, Instant};
 
 use crate::core::build_steps::tool::{self, SourceType};
-use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test};
-use crate::core::build_steps::{clippy, llvm};
+use crate::core::build_steps::{
+    check, clean, clippy, compile, dist, doc, install, llvm, run, setup, test, vendor,
+};
 use crate::core::config::flags::{Color, Subcommand};
 use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection};
 use crate::prepare_behaviour_dump_dir;
@@ -34,13 +35,34 @@ use once_cell::sync::Lazy;
 #[cfg(test)]
 mod tests;
 
+/// Builds and performs different [`Self::kind`]s of stuff and actions, taking
+/// into account build configuration from e.g. config.toml.
 pub struct Builder<'a> {
+    /// Build configuration from e.g. config.toml.
     pub build: &'a Build,
+
+    /// The stage to use. Either implicitly determined based on subcommand, or
+    /// explicitly specified with `--stage N`. Normally this is the stage we
+    /// use, but sometimes we want to run steps with a lower stage than this.
     pub top_stage: u32,
+
+    /// What to build or what action to perform.
     pub kind: Kind,
+
+    /// A cache of outputs of [`Step`]s so we can avoid running steps we already
+    /// ran.
     cache: Cache,
+
+    /// A stack of [`Step`]s to run before we can run this builder. The output
+    /// of steps is cached in [`Self::cache`].
     stack: RefCell<Vec<Box<dyn Any>>>,
+
+    /// The total amount of time we spent running [`Step`]s in [`Self::stack`].
     time_spent_on_dependencies: Cell<Duration>,
+
+    /// The paths passed on the command line. Used by steps to figure out what
+    /// to do. For example: with `./x check foo bar` we get `paths=["foo",
+    /// "bar"]`.
     pub paths: Vec<PathBuf>,
 }
 
@@ -638,6 +660,7 @@ pub enum Kind {
     Run,
     Setup,
     Suggest,
+    Vendor,
 }
 
 impl Kind {
@@ -658,6 +681,7 @@ impl Kind {
             Kind::Run => "run",
             Kind::Setup => "setup",
             Kind::Suggest => "suggest",
+            Kind::Vendor => "vendor",
         }
     }
 
@@ -767,7 +791,6 @@ impl<'a> Builder<'a> {
             ),
             Kind::Test => describe!(
                 crate::core::build_steps::toolstate::ToolStateCheck,
-                test::ExpandYamlAnchors,
                 test::Tidy,
                 test::Ui,
                 test::Crashes,
@@ -817,6 +840,7 @@ impl<'a> Builder<'a> {
                 test::Clippy,
                 test::RustDemangler,
                 test::CompiletestTest,
+                test::CrateRunMakeSupport,
                 test::RustdocJSStd,
                 test::RustdocJSNotStd,
                 test::RustdocGUI,
@@ -908,7 +932,6 @@ impl<'a> Builder<'a> {
                 install::Src,
             ),
             Kind::Run => describe!(
-                run::ExpandYamlAnchors,
                 run::BuildManifest,
                 run::BumpStage0,
                 run::ReplaceVersionPlaceholder,
@@ -920,6 +943,7 @@ impl<'a> Builder<'a> {
             ),
             Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
             Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
+            Kind::Vendor => describe!(vendor::Vendor),
             // special-cased in Build::build()
             Kind::Format | Kind::Suggest => vec![],
         }
@@ -992,6 +1016,7 @@ impl<'a> Builder<'a> {
                 Kind::Setup,
                 path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)),
             ),
+            Subcommand::Vendor { .. } => (Kind::Vendor, &paths[..]),
         };
 
         Self::new_internal(build, kind, paths.to_owned())
@@ -2099,13 +2124,10 @@ impl<'a> Builder<'a> {
             // during incremental builds" heuristic for the standard library.
             rustflags.arg("-Zinline-mir");
 
-            // FIXME: always pass this after the next `#[cfg(bootstrap)]` update.
-            if compiler.stage != 0 {
-                // Similarly, we need to keep debug info for functions inlined into other std functions,
-                // even if we're not going to output debuginfo for the crate we're currently building,
-                // so that it'll be available when downstream consumers of std try to use it.
-                rustflags.arg("-Zinline-mir-preserve-debug");
-            }
+            // Similarly, we need to keep debug info for functions inlined into other std functions,
+            // even if we're not going to output debuginfo for the crate we're currently building,
+            // so that it'll be available when downstream consumers of std try to use it.
+            rustflags.arg("-Zinline-mir-preserve-debug");
         }
 
         if self.config.rustc_parallel
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 2acce627359..ed45bc30362 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -345,6 +345,8 @@ pub struct Config {
     #[cfg(test)]
     pub initial_rustfmt: RefCell<RustfmtState>,
 
+    /// The paths to work with. For example: with `./x check foo bar` we get
+    /// `paths=["foo", "bar"]`.
     pub paths: Vec<PathBuf>,
 }
 
@@ -2027,7 +2029,8 @@ impl Config {
             | Subcommand::Run { .. }
             | Subcommand::Setup { .. }
             | Subcommand::Format { .. }
-            | Subcommand::Suggest { .. } => flags.stage.unwrap_or(0),
+            | Subcommand::Suggest { .. }
+            | Subcommand::Vendor { .. } => flags.stage.unwrap_or(0),
         };
 
         // CI should always run stage 2 builds, unless it specifically states otherwise
@@ -2054,7 +2057,8 @@ impl Config {
                 | Subcommand::Run { .. }
                 | Subcommand::Setup { .. }
                 | Subcommand::Format { .. }
-                | Subcommand::Suggest { .. } => {}
+                | Subcommand::Suggest { .. }
+                | Subcommand::Vendor { .. } => {}
             }
         }
 
@@ -2488,11 +2492,6 @@ impl Config {
 
                 b
             }
-            // FIXME: "if-available" is deprecated. Remove this block later (around mid 2024)
-            // to not break builds between the recent-to-old checkouts.
-            Some(StringOrBool::String(s)) if s == "if-available" => {
-                llvm::is_ci_llvm_available(self, asserts)
-            }
             Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(),
             Some(StringOrBool::String(other)) => {
                 panic!("unrecognized option for download-ci-llvm: {:?}", other)
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index aaa2a2c47e0..f4ed7e76fba 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -41,72 +41,72 @@ pub struct Flags {
     #[command(subcommand)]
     pub cmd: Subcommand,
 
-    #[arg(global(true), short, long, action = clap::ArgAction::Count)]
+    #[arg(global = true, short, long, action = clap::ArgAction::Count)]
     /// use verbose output (-vv for very verbose)
     pub verbose: u8, // each extra -v after the first is passed to Cargo
-    #[arg(global(true), short, long)]
+    #[arg(global = true, short, long)]
     /// use incremental compilation
     pub incremental: bool,
-    #[arg(global(true), long, value_hint = clap::ValueHint::FilePath, value_name = "FILE")]
+    #[arg(global = true, long, value_hint = clap::ValueHint::FilePath, value_name = "FILE")]
     /// TOML configuration file for build
     pub config: Option<PathBuf>,
-    #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")]
+    #[arg(global = true, long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")]
     /// Build directory, overrides `build.build-dir` in `config.toml`
     pub build_dir: Option<PathBuf>,
 
-    #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "BUILD")]
+    #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "BUILD")]
     /// build target of the stage0 compiler
     pub build: Option<String>,
 
-    #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)]
+    #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)]
     /// host targets to build
     pub host: Option<TargetSelectionList>,
 
-    #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)]
+    #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)]
     /// target targets to build
     pub target: Option<TargetSelectionList>,
 
-    #[arg(global(true), long, value_name = "PATH")]
+    #[arg(global = true, long, value_name = "PATH")]
     /// build paths to exclude
     pub exclude: Vec<PathBuf>, // keeping for client backward compatibility
-    #[arg(global(true), long, value_name = "PATH")]
+    #[arg(global = true, long, value_name = "PATH")]
     /// build paths to skip
     pub skip: Vec<PathBuf>,
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     /// include default paths in addition to the provided ones
     pub include_default_paths: bool,
 
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long)]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long)]
     pub rustc_error_format: Option<String>,
 
-    #[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")]
+    #[arg(global = true, long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")]
     /// command to run on failure
     pub on_fail: Option<String>,
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     /// dry run; don't build anything
     pub dry_run: bool,
     /// Indicates whether to dump the work done from bootstrap shims
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     pub dump_bootstrap_shims: bool,
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")]
     /// stage to build (indicates compiler to use/test, e.g., stage 0 uses the
     /// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)
     pub stage: Option<u32>,
 
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")]
     /// stage(s) to keep without recompiling
     /// (pass multiple times to keep e.g., both stages 0 and 1)
     pub keep_stage: Vec<u32>,
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")]
     /// stage(s) of the standard library to keep without recompiling
     /// (pass multiple times to keep e.g., both stages 0 and 1)
     pub keep_stage_std: Vec<u32>,
-    #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")]
+    #[arg(global = true, long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")]
     /// path to the root of the rust checkout
     pub src: Option<PathBuf>,
 
     #[arg(
-        global(true),
+        global = true,
         short,
         long,
         value_hint = clap::ValueHint::Other,
@@ -117,26 +117,26 @@ pub struct Flags {
     pub jobs: usize,
     // This overrides the deny-warnings configuration option,
     // which passes -Dwarnings to the compiler invocations.
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     #[arg(value_enum, default_value_t=Warnings::Default, value_name = "deny|warn")]
     /// if value is deny, will deny warnings
     /// if value is warn, will emit warnings
     /// otherwise, use the default configured behaviour
     pub warnings: Warnings,
 
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")]
     /// rustc error format
     pub error_format: Option<String>,
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     /// use message-format=json
     pub json_output: bool,
 
-    #[arg(global(true), long, value_name = "STYLE")]
+    #[arg(global = true, long, value_name = "STYLE")]
     #[arg(value_enum, default_value_t = Color::Auto)]
     /// whether to use color in cargo and rustc output
     pub color: Color,
 
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     /// Bootstrap uses this value to decide whether it should bypass locking the build process.
     /// This is rarely needed (e.g., compiling the std library for different targets in parallel).
     ///
@@ -144,41 +144,41 @@ pub struct Flags {
     pub bypass_bootstrap_lock: bool,
 
     /// whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml
-    #[arg(global(true), long, value_name = "VALUE")]
+    #[arg(global = true, long, value_name = "VALUE")]
     pub llvm_skip_rebuild: Option<bool>,
     /// generate PGO profile with rustc build
-    #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
+    #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
     pub rust_profile_generate: Option<String>,
     /// use PGO profile for rustc build
-    #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
+    #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
     pub rust_profile_use: Option<String>,
     /// use PGO profile for LLVM build
-    #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
+    #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
     pub llvm_profile_use: Option<String>,
     // LLVM doesn't support a custom location for generating profile
     // information.
     //
     // llvm_out/build/profiles/ is the location this writes to.
     /// generate PGO profile with llvm built for rustc
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     pub llvm_profile_generate: bool,
     /// Enable BOLT link flags
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     pub enable_bolt_settings: bool,
     /// Skip stage0 compiler validation
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     pub skip_stage0_validation: bool,
     /// Additional reproducible artifacts that should be added to the reproducible artifacts archive.
-    #[arg(global(true), long)]
+    #[arg(global = true, long)]
     pub reproducible_artifact: Vec<String>,
-    #[arg(global(true))]
+    #[arg(global = true)]
     /// paths for the subcommand
     pub paths: Vec<PathBuf>,
     /// override options in config.toml
-    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")]
+    #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")]
     pub set: Vec<String>,
     /// arguments passed to subcommands
-    #[arg(global(true), last(true), value_name = "ARGS")]
+    #[arg(global = true, last(true), value_name = "ARGS")]
     pub free_args: Vec<String>,
 }
 
@@ -192,7 +192,7 @@ impl Flags {
         struct HelpVerboseOnly {
             #[arg(short, long)]
             help: bool,
-            #[arg(global(true), short, long, action = clap::ArgAction::Count)]
+            #[arg(global = true, short, long, action = clap::ArgAction::Count)]
             pub verbose: u8,
             #[arg(value_enum)]
             cmd: Kind,
@@ -260,16 +260,16 @@ pub enum Subcommand {
         #[arg(long, requires = "fix")]
         allow_staged: bool,
         /// clippy lints to allow
-        #[arg(global(true), short = 'A', action = clap::ArgAction::Append, value_name = "LINT")]
+        #[arg(global = true, short = 'A', action = clap::ArgAction::Append, value_name = "LINT")]
         allow: Vec<String>,
         /// clippy lints to deny
-        #[arg(global(true), short = 'D', action = clap::ArgAction::Append, value_name = "LINT")]
+        #[arg(global = true, short = 'D', action = clap::ArgAction::Append, value_name = "LINT")]
         deny: Vec<String>,
         /// clippy lints to warn on
-        #[arg(global(true), short = 'W', action = clap::ArgAction::Append, value_name = "LINT")]
+        #[arg(global = true, short = 'W', action = clap::ArgAction::Append, value_name = "LINT")]
         warn: Vec<String>,
         /// clippy lints to forbid
-        #[arg(global(true), short = 'F', action = clap::ArgAction::Append, value_name = "LINT")]
+        #[arg(global = true, short = 'F', action = clap::ArgAction::Append, value_name = "LINT")]
         forbid: Vec<String>,
     },
     /// Run cargo fix
@@ -420,7 +420,7 @@ pub enum Subcommand {
     Arguments:
         This subcommand accepts a number of paths to tools to build and run. For
         example:
-            ./x.py run src/tools/expand-yaml-anchors
+            ./x.py run src/tools/bump-stage0
         At least a tool needs to be called.")]
     /// Run tools contained in this repository
     Run {
@@ -456,6 +456,15 @@ Arguments:
         #[arg(long)]
         run: bool,
     },
+    /// Vendor dependencies
+    Vendor {
+        /// Additional `Cargo.toml` to sync and vendor
+        #[arg(long)]
+        sync: Vec<PathBuf>,
+        /// Always include version in subdir name
+        #[arg(long)]
+        versioned_dirs: bool,
+    },
 }
 
 impl Subcommand {
@@ -476,6 +485,7 @@ impl Subcommand {
             Subcommand::Run { .. } => Kind::Run,
             Subcommand::Setup { .. } => Kind::Setup,
             Subcommand::Suggest { .. } => Kind::Suggest,
+            Subcommand::Vendor { .. } => Kind::Vendor,
         }
     }
 
@@ -581,6 +591,20 @@ impl Subcommand {
             _ => false,
         }
     }
+
+    pub fn vendor_versioned_dirs(&self) -> bool {
+        match *self {
+            Subcommand::Vendor { versioned_dirs, .. } => versioned_dirs,
+            _ => false,
+        }
+    }
+
+    pub fn vendor_sync_args(&self) -> Vec<PathBuf> {
+        match self {
+            Subcommand::Vendor { sync, .. } => sync.clone(),
+            _ => vec![],
+        }
+    }
 }
 
 /// Returns the shell completion for a given shell, if the result differs from the current
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index e03b1e17908..0c069a54069 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -14,6 +14,7 @@ use std::ffi::{OsStr, OsString};
 use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
+use walkdir::WalkDir;
 
 use crate::builder::Kind;
 use crate::core::config::Target;
@@ -25,6 +26,17 @@ pub struct Finder {
     path: OsString,
 }
 
+// During sanity checks, we search for target names to determine if they exist in the compiler's built-in
+// target list (`rustc --print target-list`). While a target name may be present in the stage2 compiler,
+// it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
+//
+// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
+const STAGE0_MISSING_TARGETS: &[&str] = &[
+    // just a dummy comment so the list doesn't get onelined
+    "aarch64-apple-visionos",
+    "aarch64-apple-visionos-sim",
+];
+
 impl Finder {
     pub fn new() -> Self {
         Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
@@ -177,6 +189,42 @@ than building it.
             continue;
         }
 
+        let target_str = target.to_string();
+
+        // Ignore fake targets that are only used for unit tests in bootstrap.
+        if !["A", "B", "C"].contains(&target_str.as_str()) {
+            let mut has_target = false;
+
+            let supported_target_list =
+                output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]));
+
+            // Check if it's a built-in target.
+            has_target |= supported_target_list.contains(&target_str);
+            has_target |= STAGE0_MISSING_TARGETS.contains(&target_str.as_str());
+
+            if !has_target {
+                // This might also be a custom target, so check the target file that could have been specified by the user.
+                if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") {
+                    let mut target_filename = OsString::from(&target_str);
+                    // Target filename ends with `.json`.
+                    target_filename.push(".json");
+
+                    // Recursively traverse through nested directories.
+                    let walker = WalkDir::new(custom_target_path).into_iter();
+                    for entry in walker.filter_map(|e| e.ok()) {
+                        has_target |= entry.file_name() == target_filename;
+                    }
+                }
+            }
+
+            if !has_target {
+                panic!(
+                    "No such target exists in the target list,
+                specify a correct location of the JSON specification file for custom targets!"
+                );
+            }
+        }
+
         if !build.config.dry_run() {
             cmd_finder.must_have(build.cc(*target));
             if let Some(ar) = build.ar(*target) {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 663a2d8e17c..c599709a322 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -376,11 +376,16 @@ impl Build {
             .expect("failed to read src/version");
         let version = version.trim();
 
-        let bootstrap_out = std::env::current_exe()
+        let mut bootstrap_out = std::env::current_exe()
             .expect("could not determine path to running process")
             .parent()
             .unwrap()
             .to_path_buf();
+        // Since bootstrap is hardlink to deps/bootstrap-*, Solaris can sometimes give
+        // path with deps/ which is bad and needs to be avoided.
+        if bootstrap_out.ends_with("deps") {
+            bootstrap_out.pop();
+        }
         if !bootstrap_out.join(exe("rustc", config.build)).exists() && !cfg!(test) {
             // this restriction can be lifted whenever https://github.com/rust-lang/rfcs/pull/3028 is implemented
             panic!(
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 0eff7ca5962..d0da7d30660 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -42,11 +42,10 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 
-ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
-           # Check library crates on all tier 1 targets.
-           # We disable optimized compiler built-ins because that requires a C toolchain for the target.
-           # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
-           python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
+# Check library crates on all tier 1 targets.
+# We disable optimized compiler built-ins because that requires a C toolchain for the target.
+# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
+ENV SCRIPT python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
            python3 ../x.py clippy bootstrap -Dwarnings && \
            python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py
index 124c22bd979..68565f489c9 100755
--- a/src/ci/github-actions/calculate-job-matrix.py
+++ b/src/ci/github-actions/calculate-job-matrix.py
@@ -44,7 +44,7 @@ def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]:
     return jobs
 
 
-class JobType(enum.Enum):
+class WorkflowRunType(enum.Enum):
     PR = enum.auto()
     Try = enum.auto()
     Auto = enum.auto()
@@ -57,9 +57,9 @@ class GitHubCtx:
     repository: str
 
 
-def find_job_type(ctx: GitHubCtx) -> Optional[JobType]:
+def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]:
     if ctx.event_name == "pull_request":
-        return JobType.PR
+        return WorkflowRunType.PR
     elif ctx.event_name == "push":
         old_bors_try_build = (
             ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and
@@ -72,20 +72,20 @@ def find_job_type(ctx: GitHubCtx) -> Optional[JobType]:
         try_build = old_bors_try_build or new_bors_try_build
 
         if try_build:
-            return JobType.Try
+            return WorkflowRunType.Try
 
         if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust":
-            return JobType.Auto
+            return WorkflowRunType.Auto
 
     return None
 
 
-def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Job]:
-    if job_type == JobType.PR:
+def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[Job]:
+    if run_type == WorkflowRunType.PR:
         return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"])
-    elif job_type == JobType.Try:
+    elif run_type == WorkflowRunType.Try:
         return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"])
-    elif job_type == JobType.Auto:
+    elif run_type == WorkflowRunType.Auto:
         return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"])
 
     return []
@@ -106,6 +106,17 @@ def get_github_ctx() -> GitHubCtx:
     )
 
 
+def format_run_type(run_type: WorkflowRunType) -> str:
+    if run_type == WorkflowRunType.PR:
+        return "pr"
+    elif run_type == WorkflowRunType.Auto:
+        return "auto"
+    elif run_type == WorkflowRunType.Try:
+        return "try"
+    else:
+        raise AssertionError()
+
+
 if __name__ == "__main__":
     logging.basicConfig(level=logging.INFO)
 
@@ -114,16 +125,18 @@ if __name__ == "__main__":
 
     github_ctx = get_github_ctx()
 
-    job_type = find_job_type(github_ctx)
-    logging.info(f"Job type: {job_type}")
+    run_type = find_run_type(github_ctx)
+    logging.info(f"Job type: {run_type}")
 
     with open(CI_DIR / "channel") as f:
         channel = f.read().strip()
 
     jobs = []
-    if job_type is not None:
-        jobs = calculate_jobs(job_type, data)
+    if run_type is not None:
+        jobs = calculate_jobs(run_type, data)
     jobs = skip_jobs(jobs, channel)
+    run_type = format_run_type(run_type)
 
-    logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}")
+    logging.info(f"Output:\n{yaml.dump(dict(jobs=jobs, run_type=run_type), indent=4)}")
     print(f"jobs={json.dumps(jobs)}")
+    print(f"run_type={run_type}")
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
deleted file mode 100644
index bc4b1b815cf..00000000000
--- a/src/ci/github-actions/ci.yml
+++ /dev/null
@@ -1,390 +0,0 @@
-######################################################
-#   WARNING! Action needed when changing this file   #
-######################################################
-
-# Due to GitHub Actions limitations, we can't use YAML Anchors directly in the
-# CI configuration stored on the repository. To work around that this file is
-# expanded by a tool in the repository, and the expansion is committed as well.
-#
-# After you make any change to the file you'll need to run this command:
-#
-#   ./x.py run src/tools/expand-yaml-anchors
-#
-# ...and commit the file it updated in addition to this one. If you forget this
-# step CI will fail.
-
----
-###############################
-#   YAML Anchors Definition   #
-###############################
-
-# This key contains most of the YAML anchors that will be used later in the
-# document. YAML anchors allows us to greatly reduce duplication inside the CI
-# configuration by reusing parts of the configuration.
-#
-# YAML anchors work by defining an anchor with `&anchor-name` and reusing its
-# content in another place with `*anchor-name`. The special `<<` map key merges
-# the content of the map with the content of the anchor (or list of anchors).
-#
-# The expand-yaml-anchors tool will automatically remove this block from the
-# output YAML file.
-x--expand-yaml-anchors--remove:
-  - &shared-ci-variables
-    CI_JOB_NAME: ${{ matrix.name }}
-    CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
-    # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
-    HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
-    DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-  - &public-variables
-    SCCACHE_BUCKET: rust-lang-ci-sccache2
-    TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate
-    CACHE_DOMAIN: ci-caches.rust-lang.org
-
-  - &prod-variables
-    SCCACHE_BUCKET: rust-lang-ci-sccache2
-    DEPLOY_BUCKET: rust-lang-ci2
-    TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate
-    TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues
-    TOOLSTATE_PUBLISH: 1
-    # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named
-    # AWS_SECRET_ACCESS_KEY_<keyid>. Including the key id in the name allows to
-    # rotate them in a single branch while keeping the old key in another
-    # branch, which wouldn't be possible if the key was named with the kind
-    # (caches, artifacts...).
-    CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
-    ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
-    AWS_REGION: us-west-1
-    CACHE_DOMAIN: ci-caches.rust-lang.org
-
-  - &dummy-variables
-    SCCACHE_BUCKET: rust-lang-gha-caches
-    DEPLOY_BUCKET: rust-lang-gha
-    TOOLSTATE_REPO: https://github.com/pietroalbini/rust-toolstate
-    TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/pietroalbini/rust-toolstate/issues
-    TOOLSTATE_PUBLISH: 1
-    # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named
-    # AWS_SECRET_ACCESS_KEY_<keyid>. Including the key id in the name allows to
-    # rotate them in a single branch while keeping the old key in another
-    # branch, which wouldn't be possible if the key was named with the kind
-    # (caches, artifacts...).
-    CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5
-    ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF
-    AWS_REGION: us-west-1
-    CACHE_DOMAIN: ci-caches-gha.rust-lang.org
-
-  - &base-job
-    env: {}
-
-  - &job-linux-4c
-    os: ubuntu-20.04-4core-16gb
-    <<: *base-job
-
-  - &job-linux-8c
-    os: ubuntu-20.04-8core-32gb
-    <<: *base-job
-
-  - &job-linux-16c
-    os: ubuntu-20.04-16core-64gb
-    <<: *base-job
-
-  - &job-macos-xl
-    os: macos-13 # We use the standard runner for now
-    <<: *base-job
-
-  - &job-macos-m1
-    os: macos-14
-    <<: *base-job
-
-  - &job-windows-8c
-    os: windows-2019-8core-32gb
-    <<: *base-job
-
-  - &job-windows-16c
-    os: windows-2019-16core-64gb
-    <<: *base-job
-
-  - &job-aarch64-linux
-    os: [self-hosted, ARM64, linux]
-
-  - &base-ci-job
-    defaults:
-      run:
-        shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}
-    timeout-minutes: 600
-    runs-on: "${{ matrix.os }}"
-    env: *shared-ci-variables
-    steps:
-      - if: contains(matrix.os, 'windows')
-        uses: msys2/setup-msys2@v2.22.0
-        with:
-          # i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64.
-          msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}
-          # don't try to download updates for already installed packages
-          update: false
-          # don't try to use the msys that comes built-in to the github runner,
-          # so we can control what is installed (i.e. not python)
-          release: true
-          # Inherit the full path from the Windows environment, with MSYS2's */bin/
-          # dirs placed in front. This lets us run Windows-native Python etc.
-          path-type: inherit
-          install: >
-            make
-            dos2unix
-            diffutils
-
-      - name: disable git crlf conversion
-        run: git config --global core.autocrlf false
-
-      - name: checkout the source code
-        uses: actions/checkout@v4
-        with:
-          fetch-depth: 2
-
-      # Rust Log Analyzer can't currently detect the PR number of a GitHub
-      # Actions build on its own, so a hint in the log message is needed to
-      # point it in the right direction.
-      - name: configure the PR in which the error message will be posted
-        run: echo "[CI_PR_NUMBER=$num]"
-        env:
-          num: ${{ github.event.number }}
-        if: success() && github.event_name == 'pull_request'
-
-      - name: add extra environment variables
-        run: src/ci/scripts/setup-environment.sh
-        env:
-          # Since it's not possible to merge `${{ matrix.env }}` with the other
-          # variables in `job.<name>.env`, the variables defined in the matrix
-          # are passed to the `setup-environment.sh` script encoded in JSON,
-          # which then uses log commands to actually set them.
-          EXTRA_VARIABLES: ${{ toJson(matrix.env) }}
-
-      - name: ensure the channel matches the target branch
-        run: src/ci/scripts/verify-channel.sh
-
-      - name: collect CPU statistics
-        run: src/ci/scripts/collect-cpu-stats.sh
-
-      - name: show the current environment
-        run: src/ci/scripts/dump-environment.sh
-
-      - name: install awscli
-        run: src/ci/scripts/install-awscli.sh
-
-      - name: install sccache
-        run: src/ci/scripts/install-sccache.sh
-
-      - name: select Xcode
-        run: src/ci/scripts/select-xcode.sh
-
-      - name: install clang
-        run: src/ci/scripts/install-clang.sh
-
-      - name: install tidy
-        run: src/ci/scripts/install-tidy.sh
-
-      - name: install WIX
-        run: src/ci/scripts/install-wix.sh
-
-      - name: disable git crlf conversion
-        run: src/ci/scripts/disable-git-crlf-conversion.sh
-
-      - name: checkout submodules
-        run: src/ci/scripts/checkout-submodules.sh
-
-      - name: install MSYS2
-        run: src/ci/scripts/install-msys2.sh
-
-      - name: install MinGW
-        run: src/ci/scripts/install-mingw.sh
-
-      - name: install ninja
-        run: src/ci/scripts/install-ninja.sh
-
-      - name: enable ipv6 on Docker
-        run: src/ci/scripts/enable-docker-ipv6.sh
-
-      # Disable automatic line ending conversion (again). On Windows, when we're
-      # installing dependencies, something switches the git configuration directory or
-      # re-enables autocrlf. We've not tracked down the exact cause -- and there may
-      # be multiple -- but this should ensure submodules are checked out with the
-      # appropriate line endings.
-      - name: disable git crlf conversion
-        run: src/ci/scripts/disable-git-crlf-conversion.sh
-
-      - name: ensure line endings are correct
-        run: src/ci/scripts/verify-line-endings.sh
-
-      - name: ensure backported commits are in upstream branches
-        run: src/ci/scripts/verify-backported-commits.sh
-
-      - name: ensure the stable version number is correct
-        run: src/ci/scripts/verify-stable-version-number.sh
-
-      - name: run the build
-        # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
-        run: src/ci/scripts/run-build-from-ci.sh 2>&1
-        env:
-          AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }}
-          AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}
-          TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
-
-      - name: create github artifacts
-        run: src/ci/scripts/create-doc-artifacts.sh
-
-      - name: upload artifacts to github
-        uses: actions/upload-artifact@v4
-        with:
-          # name is set in previous step
-          name: ${{ env.DOC_ARTIFACT_NAME }}
-          path: obj/artifacts/doc
-          if-no-files-found: ignore
-          retention-days: 5
-
-      - name: upload artifacts to S3
-        run: src/ci/scripts/upload-artifacts.sh
-        env:
-          AWS_ACCESS_KEY_ID: ${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}
-          AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}
-        # Adding a condition on DEPLOY=1 or DEPLOY_ALT=1 is not needed as all deploy
-        # builders *should* have the AWS credentials available. Still, explicitly
-        # adding the condition is helpful as this way CI will not silently skip
-        # deploying artifacts from a dist builder if the variables are misconfigured,
-        # erroring about invalid credentials instead.
-        if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')
-
-  # These snippets are used by the try-success, try-failure, auto-success and auto-failure jobs.
-  # Check out their documentation for more information on why they're needed.
-
-  - &base-outcome-job
-    name: bors build finished
-    runs-on: ubuntu-latest
-
-  - &base-success-job
-    steps:
-      - name: mark the job as a success
-        run: exit 0
-        shell: bash
-    <<: *base-outcome-job
-
-  - &base-failure-job
-    steps:
-      - name: mark the job as a failure
-        run: exit 1
-        shell: bash
-    <<: *base-outcome-job
-
-###########################
-#   Builders definition   #
-###########################
-
-name: CI
-on:
-  push:
-    branches:
-      - auto
-      - try
-      - try-perf
-      - automation/bors/try
-      - master
-  pull_request:
-    branches:
-      - "**"
-
-permissions:
-  contents: read
-  packages: write
-
-defaults:
-  run:
-    # On Linux, macOS, and Windows, use the system-provided bash as the default
-    # shell. (This should only make a difference on Windows, where the default
-    # shell is PowerShell.)
-    shell: bash
-
-concurrency:
-  # For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
-  # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
-  # are all triggered on the same branch, but which should be able to run concurrently.
-  group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml.
-  # It calculates which jobs should be executed, based on the data of the ${{ github }} context.
-  # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml.
-  calculate_matrix:
-    name: Calculate job matrix
-    runs-on: ubuntu-latest
-    outputs:
-      jobs: ${{ steps.jobs.outputs.jobs }}
-    steps:
-      - name: Checkout the source code
-        uses: actions/checkout@v4
-      - name: Calculate the CI job matrix
-        run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT
-        id: jobs
-  job:
-    <<: *base-ci-job
-    name: ${{ matrix.name }}
-    needs: [ calculate_matrix ]
-    env:
-      CI_JOB_NAME: ${{ matrix.image }}
-      CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
-      # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
-      HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
-      DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-      SCCACHE_BUCKET: rust-lang-ci-sccache2
-      TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate
-      CACHE_DOMAIN: ci-caches.rust-lang.org
-    continue-on-error: ${{ matrix.continue_on_error || false }}
-    strategy:
-      matrix:
-        # Check the `calculate_matrix` job to see how is the matrix defined.
-        include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}
-    # GitHub Actions fails the workflow if an empty list of jobs is provided to
-    # the workflow, so we need to skip this job if nothing was produced by
-    # the Python script.
-    #
-    # Unfortunately checking whether a list is empty is not possible in a nice
-    # way due to GitHub Actions expressions limits.
-    # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82
-    if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null
-
-  master:
-    name: master
-    runs-on: ubuntu-latest
-    env:
-      <<: [*prod-variables]
-    if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'
-    steps:
-      - name: checkout the source code
-        uses: actions/checkout@v4
-        with:
-          fetch-depth: 2
-
-      - name: publish toolstate
-        run: src/ci/publish_toolstate.sh
-        shell: bash
-        env:
-          TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
-
-  # These jobs don't actually test anything, but they're used to tell bors the
-  # build completed, as there is no practical way to detect when a workflow is
-  # successful listening to webhooks only.
-  try-success:
-    needs: [ job ]
-    if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
-    <<: *base-success-job
-  try-failure:
-    needs: [ job ]
-    if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'"
-    <<: *base-failure-job
-  auto-success:
-    needs: [ job ]
-    if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
-    <<: *base-success-job
-  auto-failure:
-    needs: [ job ]
-    if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
-    <<: *base-failure-job
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index df6c5d6079d..1fabf889e38 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -1,7 +1,5 @@
 # This file contains definitions of CI job parameters that are loaded
 # dynamically in CI from ci.yml.
-# You *do not* need to re-run `src/tools/expand-yaml-anchors` when you
-# modify this file.
 runners:
   - &base-job
     env: { }
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 31096b6df92..c9c0ee4067f 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -3,6 +3,7 @@
 - [What is rustc?](what-is-rustc.md)
 - [Command-line Arguments](command-line-arguments.md)
     - [Codegen Options](codegen-options/index.md)
+- [Jobserver](jobserver.md)
 - [Lints](lints/index.md)
     - [Lint Levels](lints/levels.md)
     - [Lint Groups](lints/groups.md)
@@ -55,6 +56,11 @@
     - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
     - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
+    - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md)
+    - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
+    - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md)
+    - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
+    - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
     - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md
index bbd81e7437c..32dc992c42f 100644
--- a/src/doc/rustc/src/instrument-coverage.md
+++ b/src/doc/rustc/src/instrument-coverage.md
@@ -348,11 +348,7 @@ $ llvm-cov report \
 
 ## `-Z coverage-options=<options>`
 
-This unstable option provides finer control over some aspects of coverage
-instrumentation. Pass one or more of the following values, separated by commas.
-
-- Either `no-branch`, `branch` or `mcdc`
-  - `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation, which is same as do not pass `branch` or `mcdc`.
+[This unstable option is described in the Unstable Book.](../unstable-book/compiler-flags/coverage-options.html)
 
 ## Other references
 
diff --git a/src/doc/rustc/src/jobserver.md b/src/doc/rustc/src/jobserver.md
new file mode 100644
index 00000000000..da82b0df7c6
--- /dev/null
+++ b/src/doc/rustc/src/jobserver.md
@@ -0,0 +1,86 @@
+# Jobserver
+
+Internally, `rustc` may take advantage of parallelism. `rustc` will coordinate
+with the build system calling it if a [GNU Make jobserver] is passed in the
+`MAKEFLAGS` environment variable. Other flags may have an effect as well, such
+as [`CARGO_MAKEFLAGS`]. If a jobserver is not passed, then `rustc` will choose
+the number of jobs to use.
+
+Starting with Rust 1.76.0, `rustc` will warn if a jobserver appears to be
+available but is not accessible, e.g.:
+
+```console
+$ echo 'fn main() {}' | MAKEFLAGS=--jobserver-auth=3,4 rustc -
+warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=3,4"`: cannot open file descriptor 3 from the jobserver environment variable value: Bad file descriptor (os error 9)
+  |
+  = note: the build environment is likely misconfigured
+```
+
+## Integration with build systems
+
+The following subsections contain recommendations on how to integrate `rustc`
+with build systems so that the jobserver is handled appropriately.
+
+### GNU Make
+
+When calling `rustc` from GNU Make, it is recommended that all `rustc`
+invocations are marked as recursive in the `Makefile` (by prefixing the command
+line with the `+` indicator), so that GNU Make enables the jobserver for them.
+For instance:
+
+<!-- ignore-tidy-tab -->
+
+```make
+x:
+	+@echo 'fn main() {}' | rustc -
+```
+
+In particular, GNU Make 4.3 (a widely used version as of 2024) passes a simple
+pipe jobserver in `MAKEFLAGS` even when it was not made available for the child
+process, which in turn means `rustc` will warn about it. For instance, if the
+`+` indicator is removed from the example above and GNU Make is called with e.g.
+`make -j2`, then the aforementioned warning will trigger.
+
+For calls to `rustc` inside `$(shell ...)` inside a recursive Make, one can
+disable the jobserver manually by clearing the `MAKEFLAGS` variable, e.g.:
+
+```make
+S := $(shell MAKEFLAGS= rustc --print sysroot)
+
+x:
+	@$(MAKE) y
+
+y:
+	@echo $(S)
+```
+
+### CMake
+
+CMake 3.28 supports the `JOB_SERVER_AWARE` option in its [`add_custom_target`]
+command, e.g.:
+
+```cmake
+cmake_minimum_required(VERSION 3.28)
+project(x)
+add_custom_target(x
+    JOB_SERVER_AWARE TRUE
+    COMMAND echo 'fn main() {}' | rustc -
+)
+```
+
+For earlier versions, when using CMake with the Makefile generator, one
+workaround is to have [`$(MAKE)`] somewhere in the command so that GNU Make
+treats it as a recursive Make call, e.g.:
+
+```cmake
+cmake_minimum_required(VERSION 3.22)
+project(x)
+add_custom_target(x
+    COMMAND DUMMY_VARIABLE=$(MAKE) echo 'fn main() {}' | rustc -
+)
+```
+
+[GNU Make jobserver]: https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html
+[`CARGO_MAKEFLAGS`]: https://doc.rust-lang.org/cargo/reference/environment-variables.html
+[`add_custom_target`]: https://cmake.org/cmake/help/latest/command/add_custom_target.html
+[`$(MAKE)`]: https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 2578b71a158..764798a80e6 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -89,9 +89,9 @@ target | notes
 `aarch64-apple-darwin` | ARM64 macOS (11.0+, Big Sur+)
 `aarch64-pc-windows-msvc` | ARM64 Windows MSVC
 `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3
-`arm-unknown-linux-gnueabi` | ARMv6 Linux (kernel 3.2, glibc 2.17)
-`arm-unknown-linux-gnueabihf` | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
-`armv7-unknown-linux-gnueabihf` | ARMv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
+`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
 [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
 `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
 `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
@@ -143,21 +143,21 @@ target | std | notes
 `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
 `aarch64-unknown-none` | * | Bare ARM64, hardfloat
 [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI
-[`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv6 Android
-`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with musl 1.2.3
-`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with musl 1.2.3, hardfloat
-[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, Big Endian
-[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, Big Endian, hardfloat
-`armv5te-unknown-linux-gnueabi` | ✓ | ARMv5TE Linux (kernel 4.4, glibc 2.23)
-`armv5te-unknown-linux-musleabi` | ✓ | ARMv5TE Linux with musl 1.2.3
-[`armv7-linux-androideabi`](platform-support/android.md) | ✓ | ARMv7-A Android
-`armv7-unknown-linux-gnueabi` | ✓ | ARMv7-A Linux (kernel 4.15, glibc 2.27)
-`armv7-unknown-linux-musleabi` | ✓ | ARMv7-A Linux with musl 1.2.3
-`armv7-unknown-linux-musleabihf` | ✓ | ARMv7-A Linux with musl 1.2.3, hardfloat
-[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARMv7-A OpenHarmony
-[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7-A
-[`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R
-[`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, hardfloat
+[`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android
+`arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3
+`arm-unknown-linux-musleabihf` | ✓ | Armv6 Linux with musl 1.2.3, hardfloat
+[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
+[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
+`armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23)
+`armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3
+[`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android
+`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27)
+`armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3
+`armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat
+[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony
+[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A
+[`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R
+[`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat
 `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87]
 `i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87]
 `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, musl 1.2.3 [^x86_32-floats-x87]
@@ -178,15 +178,15 @@ target | std | notes
 `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
 `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
 `sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos
-[`thumbv6m-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv6-M
-[`thumbv7em-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7E-M
-[`thumbv7em-none-eabihf`](platform-support/arm-none-eabi.md) | * | Bare ARMV7E-M, hardfloat
-[`thumbv7m-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7-M
-[`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode ARMv7-A Android with NEON
-`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7-A Linux with NEON (kernel 4.4, glibc 2.23)
-[`thumbv8m.base-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Baseline
-[`thumbv8m.main-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Mainline
-[`thumbv8m.main-none-eabihf`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Mainline, hardfloat
+[`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M
+[`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M
+[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat
+[`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare Armv7-M
+[`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode Armv7-A Android with NEON
+`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4, glibc 2.23)
+[`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline
+[`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-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
@@ -264,27 +264,27 @@ target | std | host | notes
 `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
 `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
 [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian)
-[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARM Apple WatchOS 64-bit with 32-bit pointers
-[`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | ARM BE8 the default ARM big-endian architecture since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en).
-[`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * |  | Bare ARMv4T
-`armv4t-unknown-linux-gnueabi` | ? |  | ARMv4T Linux
-[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * |  | Bare ARMv5TE
-`armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
-`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
-[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv6 NetBSD w/hard-float
-[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
-[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ |  | ARMv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
-[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7-A Linux with uClibc, softfloat
-[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7-A Linux with uClibc, hardfloat
-`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7-A FreeBSD
-[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv7-A NetBSD w/hard-float
-`armv7-wrs-vxworks-eabihf` | ? |  | ARMv7-A for VxWorks
+[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | Arm Apple WatchOS 64-bit with 32-bit pointers
+[`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en).
+[`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * |  | Bare Armv4T
+`armv4t-unknown-linux-gnueabi` | ? |  | Armv4T Linux
+[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * |  | Bare Armv5TE
+`armv5te-unknown-linux-uclibceabi` | ? |  | Armv5TE Linux with uClibc
+`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD
+[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
+[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? |  | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain)
+[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ |  | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
+[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
+[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
+`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD
+[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float
+`armv7-wrs-vxworks-eabihf` | ? |  | 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
-[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * |  | Bare ARMv7-A, hardfloat
-[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARMv7-A Apple WatchOS
-`armv7s-apple-ios` | ✓ |  | ARMv7-A Apple-A6 Apple iOS
-[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * |  | Bare ARMv8-R, hardfloat
+[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * |  | Bare Armv7-A, hardfloat
+[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | Armv7-A Apple WatchOS
+`armv7s-apple-ios` | ✓ |  | Armv7-A Apple-A6 Apple iOS
+[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * |  | Bare Armv8-R, hardfloat
 `avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
 `bpfel-unknown-none` | * |  | BPF (little endian)
@@ -360,11 +360,11 @@ target | std | host | notes
 [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * |  | Bare 32-bit SPARC V7+
 [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64
 [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64
-[`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * |  | Thumb-mode Bare ARMv4T
-[`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * |  | Thumb-mode Bare ARMv5TE
+[`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * |  | Thumb-mode Bare Armv4T
+[`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * |  | Thumb-mode Bare Armv5TE
 `thumbv7a-pc-windows-msvc` | ? |  |
 `thumbv7a-uwp-windows-msvc` | ✓ |  |
-`thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode ARMv7-A Linux with NEON, musl 1.2.3
+`thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3
 [`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ |  | WebAssembly
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index 6335a6405a1..0b1b10e4762 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -1,25 +1,131 @@
 # `{arm,thumb}*-none-eabi(hf)?`
 
-**Tier: 2**
-- [arm(eb)?v7r-none-eabi(hf)?](armv7r-none-eabi.md)
-- armv7a-none-eabi
-- thumbv6m-none-eabi
-- thumbv7m-none-eabi
-- thumbv7em-none-eabi(hf)?
-- thumbv8m.base-none-eabi
-- thumbv8m.main-none-eabi(hf)?
-
-**Tier: 3**
-- [{arm,thumb}v4t-none-eabi](armv4t-none-eabi.md)
-- [{arm,thumb}v5te-none-eabi](armv5te-none-eabi.md)
-- armv7a-none-eabihf
-- [armv8r-none-eabihf](armv8r-none-eabihf.md)
-
-Bare-metal target for 32-bit ARM CPUs.
-
-If a target has a `*hf` variant, that variant uses the hardware floating-point
-ABI and enables some minimum set of floating-point features based on the FPU(s)
-available in that processor family.
+## Tier 2 Target List
+
+- Arm A-Profile Architectures
+  - `armv7a-none-eabi`
+- Arm R-Profile Architectures
+  - [`armv7r-none-eabi` and `armv7r-none-eabihf`](armv7r-none-eabi.md)
+  - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armv7r-none-eabi.md)
+- Arm M-Profile Architectures
+  - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md)
+  - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md)
+  - [`thumbv7em-none-eabi` and `thumbv7em-none-eabihf`](thumbv7em-none-eabi.md)
+  - [`thumbv8m.base-none-eabi`](thumbv8m.base-none-eabi.md)
+  - [`thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf`](thumbv8m.main-none-eabi.md)
+- *Legacy* Arm Architectures
+  - None
+
+## Tier 3 Target List
+
+- Arm A-Profile Architectures
+  - `armv7a-none-eabihf`
+- Arm R-Profile Architectures
+  - [`armv8r-none-eabihf`](armv8r-none-eabihf.md)
+- Arm M-Profile Architectures
+  - None
+- *Legacy* Arm Architectures
+  - [`armv4t-none-eabi` and `thumbv4t-none-eabi`](armv4t-none-eabi.md)
+  - [`armv5te-none-eabi` and `thumbv5te-none-eabi`](armv5te-none-eabi.md)
+
+## Common Target Details
+
+This documentation covers details that apply to a range of bare-metal targets
+for 32-bit Arm CPUs. In addition, target specific details may be covered in
+their own document.
+
+There are two 32-bit instruction set architectures (ISAs) defined by Arm:
+
+- The [*A32 ISA*][a32-isa], with fixed-width 32-bit instructions. Previously
+  known as the *Arm* ISA, this originated with the original ARM1 of 1985 and has
+  been updated by various revisions to the architecture specifications ever
+  since.
+- The [*T32 ISA*][t32-isa], with a mix of 16-bit and 32-bit width instructions.
+  Note that this term includes both the original 16-bit width *Thumb* ISA
+  introduced with the Armv4T architecture in 1994, and the later 16/32-bit sized
+  *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. Again, these
+  ISAs have been revised by subsequent revisions to the relevant Arm
+  architecture specifications.
+
+There is also a 64-bit ISA with fixed-width 32-bit instructions called the *A64
+ISA*, but targets which implement that instruction set generally start with
+`aarch64*` and are discussed elsewhere.
+
+Rust targets starting with `arm*` generate Arm (A32) code by default, whilst
+targets named `thumb*` generate Thumb (T32) code by default. Most Arm chips
+support both Thumb mode and Arm mode, with the notable exception that M-profile
+processors (`thumbv*m*-none-eabi*` targets) *only* support Thumb-mode.
+
+Rust targets ending with `eabi` use the so-called *soft-float ABI*: functions
+which take `f32` or `f64` as arguments will have those values packed into
+integer registers. This means that an FPU is not required from an ABI
+perspective, but within a function floating-point instructions may still be used
+if the code is compiled with a `target-cpu` or `target-feature` option that
+enables FPU support.
+
+Rust targets ending in `eabihf` use the so-called *hard-float ABI*: functions
+which take `f32` or `f64` as arguments will have them passed via FPU registers.
+These targets therefore require the availability of an FPU and will assume some
+baseline level of floating-point support is available (which can vary depending
+on the target). More advanced floating-point instructions may be generated if
+the code is compiled with a `target-cpu` or `target-feature` option that enables
+such additional FPU support. For example, if a given hard-float target has
+baseline *single-precision* (`f32`) support in hardware, there may be
+`target-cpu` or `target-feature` options that tell LLVM to assume your processor
+in fact also has *double-precision* (`f64`) support.
+
+You may of course use the `f32` and `f64` types in your code, regardless of the
+ABI being used, or the level of support your processor has for performing such
+operations in hardware. Any floating-point operations that LLVM assumes your
+processor cannot support will be lowered to library calls (like `__aeabi_dadd`)
+which perform the floating-point operation in software using integer
+instructions.
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[a32-isa]: https://developer.arm.com/Architectures/A32%20Instruction%20Set%20Architecture
+
+## Target CPU and Target Feature options
+
+It is possible to tell Rust (or LLVM) that you have a specific model of Arm
+processor, using the [`-C target-cpu`][target-cpu] option. You can also control
+whether Rust (or LLVM) will include instructions that target optional hardware
+features, e.g. hardware floating-point, or Advanced SIMD operations, using [`-C
+target-feature`][target-feature].
+
+It is important to note that selecting a *target-cpu* will typically enable
+*all* the optional features available from Arm on that model of CPU and your
+particular implementation of that CPU may not have those features available. In
+that case, you can use `-C target-feature=-option` to turn off the specific CPU
+features you do not have available, leaving you with the optimized instruction
+scheduling and support for the features you do have. More details are available
+in the detailed target-specific documentation.
+
+**Note:** Many target-features are currently unstable and subject to change, and
+if you use them you should disassemble the compiler output and manually inspect
+it to ensure only appropriate instructions for your CPU have been generated.
+
+If you wish to use the *target-cpu* and *target-feature* options, you can add
+them to your `.cargo/config.toml` file alongside any other flags your project
+uses (likely linker related ones):
+
+```toml
+rustflags = [
+  # Usual Arm bare-metal linker setup
+  "-Clink-arg=-Tlink.x",
+  "-Clink-arg=--nmagic",
+  # tell Rust we have a Cortex-M55
+  "-Ctarget-cpu=cortex-m55",
+  # tell Rust our Cortex-M55 doesn't have Floating-Point M-Profile Vector
+  # Extensions (but it does have everything else a Cortex-M55 could have).
+  "-Ctarget-feature=-mve.fp"
+]
+
+[build]
+target = "thumbv8m.main-none-eabihf"
+```
+
+[target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu
+[target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature
 
 ## Requirements
 
@@ -45,14 +151,11 @@ according to the specific device you are using. Pass
 `-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use
 `your_script.ld` during linking.
 
-Targets named `thumb*` instead of `arm*`
-generate Thumb-mode code by default. M-profile processors (`thumbv*m*-*`
-targets) only support Thumb-mode code.
-For the `arm*` targets, Thumb-mode code generation can be enabled by using
-`-C target-feature=+thumb-mode`. Using the unstable
-`#![feature(arm_target_feature)]`, the attribute
-`#[target_feature(enable = "thumb-mode")]` can be applied to individual
-`unsafe` functions to cause those functions to be compiled to Thumb-mode code.
+For the `arm*` targets, Thumb-mode code generation can be enabled by using `-C
+target-feature=+thumb-mode`. Using the unstable
+`#![feature(arm_target_feature)]`, the attribute `#[target_feature(enable =
+"thumb-mode")]` can be applied to individual `unsafe` functions to cause those
+functions to be compiled to Thumb-mode code.
 
 ## Building Rust Programs
 
@@ -69,16 +172,27 @@ build-std = ["core"]
 ```
 
 Most of `core` should work as expected, with the following notes:
-* If the target is not `*hf`, then floating-point operations are emulated in
-  software.
+
+* Floating-point operations are emulated in software unless LLVM is told to
+  enable FPU support (either by using an `eabihf` target, specifying a
+  `target-cpu` with FPU support, or using a `target-feature` to support for a
+  specific kind of FPU)
 * Integer division is also emulated in software on some targets, depending on
-  the CPU.
-* Architectures prior to ARMv7 don't have atomic instructions.
+  the target, `target-cpu` and `target-feature`s.
+* Older Arm architectures (e.g. Armv4, Armv5TE and Armv6-M) are limited to basic
+  [`load`][atomic-load] and [`store`][atomic-store] operations, and not more
+  advanced operations like [`fetch_add`][fetch-add] or
+  [`compare_exchange`][compare-exchange].
 
 `alloc` is also supported, as long as you provide your own global allocator.
 
 Rust programs are output as ELF files.
 
+[atomic-load]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.load
+[atomic-store]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.store
+[fetch-add]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.fetch_add
+[compare-exchange]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.compare_exchange
+
 ## Testing
 
 This is a cross-compiled target that you will need to emulate during testing.
diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
index 32d3440f1dc..e7e3fd01c4d 100644
--- a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
+++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md
@@ -1,22 +1,22 @@
 # armeb-unknown-linux-gnueabi
 **Tier: 3**
 
-Target for cross-compiling Linux user-mode applications targeting the ARM BE8 architecture.
+Target for cross-compiling Linux user-mode applications targeting the Arm BE8 architecture.
 
 ## Overview
-BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian ARM systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
+BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian Arm systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
 
 ## History
-BE8 architecture is the default big-endian architecture for ARM since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for ARMv4 and ARMv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On ARMv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [ARMv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards.
+BE8 architecture is the default big-endian architecture for Arm since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for Armv4 and Armv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On Armv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [Armv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards.
 
 ## Target Maintainers
 * [@WorksButNotTested](https://github.com/WorksButNotTested)
 
 ## Requirements
-The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard ARM configuration).
+The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard Arm configuration).
 
 ## Target definition
-The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the ARMv8 core. Though this can likely be modified as required.
+The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the Armv8 core. Though this can likely be modified as required.
 
 ## Building the target
 Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target.
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
index 29c47db8351..f4c8dd46f1d 100644
--- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -2,12 +2,12 @@
 
 Tier 3
 
-Bare-metal target for any cpu in the ARMv4T architecture family, supporting
-ARM/Thumb code interworking (aka `a32`/`t32`), with ARM code as the default code
+Bare-metal target for any cpu in the Armv4T architecture family, supporting
+ARM/Thumb code interworking (aka `A32`/`T32`), with ARM code as the default code
 generation.
 
 In particular this supports the Game Boy Advance (GBA), but there's nothing
-GBA-specific with this target, so any ARMv4T device should work fine.
+GBA-specific with this target, so any Armv4T device should work fine.
 
 See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 `arm-none-eabi` targets.
diff --git a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
index 37284ba7209..41621e070bb 100644
--- a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
@@ -2,11 +2,11 @@
 
 **Tier: 3**
 
-Bare-metal target for any cpu in the ARMv5TE architecture family, supporting
-ARM/Thumb code interworking (aka `a32`/`t32`), with `a32` code as the default code
+Bare-metal target for any cpu in the Armv5TE architecture family, supporting
+ARM/Thumb code interworking (aka `A32`/`T32`), with `A32` code as the default code
 generation.
 
-The `thumbv5te-none-eabi` target is the same as this one, but the instruction set defaults to `t32`.
+The `thumbv5te-none-eabi` target is the same as this one, but the instruction set defaults to `T32`.
 
 See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 `arm-none-eabi` targets.
diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
index 540e5a4af93..160986aeae9 100644
--- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
+++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
@@ -2,7 +2,7 @@
 
 **Tier: 3**
 
-The Nintendo 3DS platform, which has an ARMv6K processor, and its associated
+The Nintendo 3DS platform, which has an Armv6k processor, and its associated
 operating system (`horizon`).
 
 Rust support for this target is not affiliated with Nintendo, and is not derived
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
index e351ea00130..f22a20835c1 100644
--- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
@@ -2,7 +2,7 @@
 
 **Tier: 3**
 
-This target supports ARMv7 softfloat CPUs and uses the uclibc-ng standard library. This is a common configuration on many consumer routers (e.g., Netgear R7000, Asus RT-AC68U).
+This target supports Armv7-A softfloat CPUs and uses the uclibc-ng standard library. This is a common configuration on many consumer routers (e.g., Netgear R7000, Asus RT-AC68U).
 
 ## Target maintainers
 
@@ -16,7 +16,7 @@ This target supports host tools and std.
 
 ## Building the target
 
-You will need to download or build a `'C'` cross toolchain that targets ARMv7 softfloat and that uses the uclibc-ng standard library. If your target hardware is something like a router or an embedded device, keep in mind that manufacturer supplied SDKs for this class of CPU could be outdated and potentially unsuitable for bootstrapping rust.
+You will need to download or build a `'C'` cross toolchain that targets Armv7-A softfloat and that uses the uclibc-ng standard library. If your target hardware is something like a router or an embedded device, keep in mind that manufacturer supplied SDKs for this class of CPU could be outdated and potentially unsuitable for bootstrapping rust.
 
 [Here](https://github.com/lancethepants/tomatoware-toolchain) is a sample toolchain that is built using [buildroot](https://buildroot.org/). It uses modern toolchain components, older thus universal kernel headers (2.6.36.4), and is used for a project called [Tomatoware](https://github.com/lancethepants/tomatoware). This toolchain is patched so that its sysroot is located at /mmc (e.g., /mmc/bin, /mmc/lib, /mmc/include). This is useful in scenarios where the root filesystem is read-only but you are able attach external storage loaded with user applications. Tomatoware is an example of this that even allows you to run various compilers and developer tools natively on the target device.
 
@@ -46,7 +46,7 @@ The following assumes you are using the Tomatoware toolchain and environment. Ad
 
 ### Native compilation
 
-Since this target supports host tools, you can natively build rust applications directly on your target device. This can be convenient because it removes the complexities of cross compiling and you can immediately test and deploy your binaries. One downside is that compiling on your ARMv7 CPU will probably be much slower than cross compilation on your x86 machine.
+Since this target supports host tools, you can natively build rust applications directly on your target device. This can be convenient because it removes the complexities of cross compiling and you can immediately test and deploy your binaries. One downside is that compiling on your Armv7-A CPU will probably be much slower than cross compilation on your x86 machine.
 
 To setup native compilation:
 
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
index 1f029406367..1c8acc09c77 100644
--- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
@@ -2,7 +2,7 @@
 
 **Tier: 3**
 
-This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library.  It provides full support for rust and the rust standard library.
+This tier supports the Armv7-A processor running a Linux kernel and uClibc-ng standard library.  It provides full support for rust and the rust standard library.
 
 ## Designated Developers
 
diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
index 670cead9e00..5f0dc6a7115 100644
--- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
@@ -2,7 +2,7 @@
 
 **Tier: 2**
 
-Bare-metal target for CPUs in the ARMv7-R architecture family, supporting
+Bare-metal target for CPUs in the Armv7-R architecture family, supporting
 dual ARM/Thumb mode, with ARM mode as the default.
 
 Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r].
diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
index 588e5d7c994..6f80a06020f 100644
--- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
+++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
@@ -2,7 +2,7 @@
 
 **Tier: 3**
 
-Bare-metal target for CPUs in the ARMv8-R architecture family, supporting
+Bare-metal target for CPUs in the Armv8-R architecture family, supporting
 dual ARM/Thumb mode, with ARM mode as the default.
 
 Processors in this family include the Arm [Cortex-R52][cortex-r52]
diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
new file mode 100644
index 00000000000..f4ed6201bbd
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
@@ -0,0 +1,62 @@
+# `thumbv6m-none-eabi`
+
+**Tier: 2**
+
+Bare-metal target for CPUs in the [Armv6-M] architecture family, supporting a
+subset of the [T32 ISA][t32-isa].
+
+Processors in this family include the:
+
+* [Arm Cortex-M0][cortex-m0]
+* [Arm Cortex-M0+][cortex-m0plus]
+* [Arm Cortex-M1][cortex-m1]
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+This target uses the soft-float ABI: functions which take `f32` or `f64` as
+arguments will have those values packed into integer registers. This is the
+only option because there is no FPU support in [Armv6-M].
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[Armv6-M]: https://developer.arm.com/documentation/ddi0419/latest/
+[cortex-m0]: https://developer.arm.com/Processors/Cortex-M0
+[cortex-m0plus]: https://developer.arm.com/Processors/Cortex-M0+
+[cortex-m1]: https://developer.arm.com/Processors/Cortex-M1
+
+## Target maintainers
+
+* [Rust Embedded Devices Working Group Cortex-M
+  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+
+## Target CPU and Target Feature options
+
+See [the bare-metal Arm
+docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how
+to use these flags.
+
+### Table of supported CPUs
+
+| CPU        | FPU | Target CPU      | Target Features       |
+| ---------- | --- | --------------- | --------------------- |
+| Cortex-M0  | No  | `cortex-m0`     | None                  |
+| Cortex-M0+ | No  | `cortex-m0plus` | None                  |
+| Cortex-M1  | No  | `cortex-m1`     | None                  |
+
+### Arm Cortex-M0
+
+The target CPU option is `cortex-m0`.
+
+There are no relevant feature flags, and the FPU is not available.
+
+### Arm Cortex-M0+
+
+The target CPU option is `cortex-m0plus`.
+
+There are no relevant feature flags, and the FPU is not available.
+
+### Arm Cortex-M1
+
+The target CPU option is `cortex-m1`.
+
+There are no relevant feature flags, and the FPU is not available.
diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
new file mode 100644
index 00000000000..f25ef0383b1
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
@@ -0,0 +1,74 @@
+# `thumbv7em-none-eabi` and `thumbv7em-none-eabihf`
+
+**Tier: 2**
+
+Bare-metal target for CPUs in the [Armv7E-M] architecture family, supporting a
+subset of the [T32 ISA][t32-isa].
+
+Processors in this family include the:
+
+* [Arm Cortex-M4][cortex-m4] and Arm Cortex-M4F
+* [Arm Cortex-M7][cortex-m7] and Arm Cortex-M7F
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets, in particular the difference between the `eabi` and
+`eabihf` ABI.
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[Armv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/
+[cortex-m4]: https://developer.arm.com/Processors/Cortex-M4
+[cortex-m7]: https://developer.arm.com/Processors/Cortex-M7
+
+## Target maintainers
+
+* [Rust Embedded Devices Working Group Cortex-M
+  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+
+## Target CPU and Target Feature options
+
+See [the bare-metal Arm
+docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how
+to use these flags.
+
+### Table of supported CPUs for `thumbv7em-none-eabi`
+
+| CPU        | FPU | DSP | Target CPU  | Target Features |
+| ---------- | --- | --- | ----------- | --------------- |
+| Any        | No  | Yes | None        | None            |
+| Cortex-M4  | No  | Yes | `cortex-m4` | `+soft-float`   |
+| Cortex-M4F | SP  | Yes | `cortex-m4` | None            |
+| Cortex-M7  | No  | Yes | `cortex-m7` | `+soft-float`   |
+| Cortex-M7F | SP  | Yes | `cortex-m7` | `-fp64`         |
+| Cortex-M7F | DP  | Yes | `cortex-m7` | None            |
+
+### Table of supported CPUs for `thumbv7em-none-eabihf`
+
+| CPU        | FPU | DSP | Target CPU  | Target Features |
+| ---------- | --- | --- | ----------- | --------------- |
+| Any        | SP  | Yes | None        | None            |
+| Cortex-M4F | SP  | Yes | `cortex-m4` | None            |
+| Cortex-M7F | SP  | Yes | `cortex-m7` | `-fp64`         |
+| Cortex-M7F | DP  | Yes | `cortex-m7` | None            |
+
+### Arm Cortex-M4 and Arm Cortex-M4F
+
+The target CPU is `cortex-m4`.
+
+* All Cortex-M4 have DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target*
+* Cortex-M4F has a single precision FPU
+  * support is enabled by default with this *target-cpu*
+  * disable support using the `+soft-float` feature (`eabi` only)
+
+### Arm Cortex-M7 and Arm Cortex-M7F
+
+The target CPU is `cortex-m7`.
+
+* All Cortex-M7 have DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target*
+* Cortex-M7F have either a single-precision or double-precision FPU
+  * double-precision support is enabled by default with this *target-cpu*
+    * opt-out by using the `-f64` *target-feature*
+  * disable support entirely using the `+soft-float` feature (`eabi` only)
diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
new file mode 100644
index 00000000000..b258033bb0f
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
@@ -0,0 +1,44 @@
+# `thumbv7m-none-eabi`
+
+**Tier: 2**
+
+Bare-metal target for CPUs in the [Armv7-M] architecture family, supporting a
+subset of the [T32 ISA][t32-isa].
+
+Processors in this family include the:
+
+* [Arm Cortex-M3][cortex-m3]
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+This target uses the soft-float ABI: functions which take `f32` or `f64` as
+arguments will have those values packed into integer registers. This is the
+only option because there is no FPU support in [Armv7-M].
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[Armv7-M]: https://developer.arm.com/documentation/ddi0403/latest/
+[cortex-m3]: https://developer.arm.com/Processors/Cortex-M3
+
+## Target maintainers
+
+* [Rust Embedded Devices Working Group Cortex-M
+  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+
+## Target CPU and Target Feature options
+
+See [the bare-metal Arm
+docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how
+to use these flags.
+
+### Table of supported CPUs
+
+| CPU        | FPU | Target CPU  | Target Features       |
+| ---------- | --- | ----------- | --------------------- |
+| Cortex-M3  | No  | `cortex-m3` | None                  |
+
+### Arm Cortex-M3
+
+The target CPU option is `cortex-m3`.
+
+There are no relevant feature flags, and the FPU is not available.
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
new file mode 100644
index 00000000000..0ae4e3e94bd
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
@@ -0,0 +1,44 @@
+# `thumbv8m.base-none-eabi`
+
+**Tier: 2**
+
+Bare-metal target for CPUs in the Baseline [Armv8-M] architecture family,
+supporting a subset of the [T32 ISA][t32-isa].
+
+Processors in this family include the:
+
+* [Arm Cortex-M23][cortex-m23]
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+This target uses the soft-float ABI: functions which take `f32` or `f64` as
+arguments will have those values packed into integer registers. This is the
+only option because there is no FPU support in [Armv8-M] Baseline.
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[Armv8-M]: https://developer.arm.com/documentation/ddi0553/latest/
+[cortex-m23]: https://developer.arm.com/Processors/Cortex-M23
+
+## Target maintainers
+
+* [Rust Embedded Devices Working Group Cortex-M
+  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+
+## Target CPU and Target Feature options
+
+See [the bare-metal Arm
+docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how
+to use these flags.
+
+### Table of supported CPUs
+
+| CPU         | FPU | Target CPU   | Target Features       |
+| ----------- | --- | ------------ | --------------------- |
+| Cortex-M23  | No  | `cortex-m23` | None                  |
+
+### Arm Cortex-M23
+
+The target CPU option is `cortex-m23`.
+
+There are no relevant feature flags, and the FPU is not available.
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
new file mode 100644
index 00000000000..4e696f9c304
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
@@ -0,0 +1,135 @@
+# `thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf`
+
+**Tier: 2**
+
+Bare-metal target for CPUs in the Mainline [Armv8-M] architecture family,
+supporting a subset of the [T32 ISA][t32-isa].
+
+Processors in this family include the:
+
+* [Arm Cortex-M33][cortex-m33]
+* [Arm Cortex-M35P][cortex-m35p]
+* [Arm Cortex-M55][cortex-m55]
+* [Arm Cortex-M85][cortex-m85]
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets, in particular the difference between the `eabi` and
+`eabihf` ABI.
+
+[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture
+[Armv8-M]: https://developer.arm.com/documentation/ddi0553/latest/
+[cortex-m33]: https://developer.arm.com/Processors/Cortex-M33
+[cortex-m35p]: https://developer.arm.com/Processors/Cortex-M35P
+[cortex-m55]: https://developer.arm.com/Processors/Cortex-M55
+[cortex-m85]: https://developer.arm.com/Processors/Cortex-M85
+
+## Target maintainers
+
+* [Rust Embedded Devices Working Group Cortex-M
+  Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org`
+
+## Target CPU and Target Feature options
+
+See [the bare-metal Arm
+docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how
+to use these flags.
+
+### Table of supported CPUs for `thumbv8m.main-none-eabi`
+
+| CPU         | FPU | DSP | MVE       | Target CPU    | Target Features       |
+| ----------- | --- | --- | --------- | ------------- | --------------------- |
+| Unspecified | No  | No  | No        | None          | None                  |
+| Cortex-M33  | No  | No  | No        | `cortex-m33`  | `+soft-float,-dsp`    |
+| Cortex-M33  | No  | Yes | No        | `cortex-m33`  | `+soft-float`         |
+| Cortex-M33  | SP  | No  | No        | `cortex-m33`  | `-dsp`                |
+| Cortex-M33  | SP  | Yes | No        | `cortex-m33`  | None                  |
+| Cortex-M35P | No  | No  | No        | `cortex-m35p` | `+soft-float,-dsp`    |
+| Cortex-M35P | No  | Yes | No        | `cortex-m35p` | `+soft-float`         |
+| Cortex-M35P | SP  | No  | No        | `cortex-m35p` | `-dsp`                |
+| Cortex-M35P | SP  | Yes | No        | `cortex-m35p` | None                  |
+| Cortex-M55  | No  | Yes | No        | `cortex-m55`  | `+soft-float,-mve`    |
+| Cortex-M55  | DP  | Yes | No        | `cortex-m55`  | `-mve`                |
+| Cortex-M55  | No  | Yes | Int       | `cortex-m55`  | `+soft-float,-mve.fp` |
+| Cortex-M55  | DP  | Yes | Int       | `cortex-m55`  | `-mve.fp`             |
+| Cortex-M55  | DP  | Yes | Int+Float | `cortex-m55`  | None                  |
+| Cortex-M85  | No  | Yes | No        | `cortex-m85`  | `+soft-float,-mve`    |
+| Cortex-M85  | DP  | Yes | No        | `cortex-m85`  | `-mve`                |
+| Cortex-M85  | No  | Yes | Int       | `cortex-m85`  | `+soft-float,-mve.fp` |
+| Cortex-M85  | DP  | Yes | Int       | `cortex-m85`  | `-mve.fp`             |
+| Cortex-M85  | DP  | Yes | Int+Float | `cortex-m85`  | None                  |
+
+### Table of supported CPUs for `thumbv8m.main-none-eabihf`
+
+| CPU         | FPU | DSP | MVE       | Target CPU    | Target Features       |
+| ----------- | --- | --- | --------- | ------------- | --------------------- |
+| Unspecified | SP  | No  | No        | None          | None                  |
+| Cortex-M33  | SP  | No  | No        | `cortex-m33`  | `-dsp`                |
+| Cortex-M33  | SP  | Yes | No        | `cortex-m33`  | None                  |
+| Cortex-M33P | SP  | No  | No        | `cortex-m35p` | `-dsp`                |
+| Cortex-M33P | SP  | Yes | No        | `cortex-m35p` | None                  |
+| Cortex-M55  | DP  | Yes | No        | `cortex-m55`  | `-mve`                |
+| Cortex-M55  | DP  | Yes | Int       | `cortex-m55`  | `-mve.fp`             |
+| Cortex-M55  | DP  | Yes | Int+Float | `cortex-m55`  | None                  |
+| Cortex-M85  | DP  | Yes | No        | `cortex-m85`  | `-mve`                |
+| Cortex-M85  | DP  | Yes | Int       | `cortex-m85`  | `-mve.fp`             |
+| Cortex-M85  | DP  | Yes | Int+Float | `cortex-m85`  | None                  |
+
+### Arm Cortex-M33
+
+The target CPU is `cortex-m33`.
+
+* Has optional DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target-cpu*
+* Has an optional single precision FPU
+  * support is enabled by default with this *target-cpu*
+  * disable support using the `+soft-float` feature (`eabi` only)
+
+### Arm Cortex-M35P
+
+The target CPU is `cortex-m35p`.
+
+* Has optional DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target-cpu*
+* Has an optional single precision FPU
+  * support is enabled by default with this *target-cpu*
+  * disable support using the `+soft-float` feature (`eabi` only)
+
+### Arm Cortex-M55
+
+The target CPU is `cortex-m55`.
+
+* Has DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target-cpu*
+* Has an optional double-precision FPU that also supports half-precision FP16
+  values
+  * support is enabled by default with this *target-cpu*
+  * disable support using the `+soft-float` feature (`eabi` only)
+* Has optional support for M-Profile Vector Extensions
+  * Also known as *Helium Technology*
+  * Available with only integer support, or both integer/float support
+  * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp`
+    (float)
+  * `mve.fp` is enabled by default on this target CPU
+  * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE)
+
+### Arm Cortex-M85
+
+The target CPU is `cortex-m85`.
+
+* Has DSP extensions
+  * support is controlled by the `dsp` *target-feature*
+  * enabled by default with this *target-cpu*
+* Has an optional double-precision FPU that also supports half-precision FP16
+  values
+  * support is enabled by default with this *target-cpu*
+  * disable support using the `+soft-float` feature (`eabi` only)
+* Has optional support for M-Profile Vector Extensions
+  * Also known as *Helium Technology*
+  * Available with only integer support, or both integer/float support
+  * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp`
+    (float)
+  * `mve.fp` is enabled by default on this target CPU
+  * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE)
diff --git a/src/doc/unstable-book/src/compiler-flags/coverage-options.md b/src/doc/unstable-book/src/compiler-flags/coverage-options.md
index 5e192d9aca1..21278833550 100644
--- a/src/doc/unstable-book/src/compiler-flags/coverage-options.md
+++ b/src/doc/unstable-book/src/compiler-flags/coverage-options.md
@@ -5,4 +5,13 @@ This option controls details of the coverage instrumentation performed by
 
 Multiple options can be passed, separated by commas. Valid options are:
 
-- `no-branch`, `branch` or `mcdc`: `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation as well as mcdc instrumentation, which is same as do not pass `branch` or `mcdc`.
+- `block`, `branch`, `mcdc`:
+  Sets the level of coverage instrumentation.
+  Setting the level will override any previously-specified level.
+  - `block` (default):
+    Blocks in the control-flow graph will be instrumented for coverage.
+  - `branch`:
+    In addition to block coverage, also enables branch coverage instrumentation.
+  - `mcdc`:
+    In addition to block and branch coverage, also enables MC/DC instrumentation.
+    (Branch coverage instrumentation may differ in some cases.)
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 5ae27bc8c91..40a25f13fcb 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -47,6 +47,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "install" -d 'Install distribu
 complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained in this repository'
 complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development'
 complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
+complete -c x.py -n "__fish_use_subcommand" -f -a "vendor" -d 'Vendor dependencies'
 complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
 complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f
@@ -590,3 +591,39 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-genera
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny	'',warn	'',default	''}"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always	'',never	'',auto	''}"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true	'',false	''}"
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l versioned-dirs -d 'Always include version in subdir name'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_seen_subcommand_from vendor" -s h -l help -d 'Print help (see more with \'--help\')'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index d39639a1f91..f3d1d372c73 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -74,6 +74,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository')
             [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
             [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
+            [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies')
             break
         }
         'x.py;build' {
@@ -724,6 +725,49 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
+        'x.py;vendor' {
+            [CompletionResult]::new('--sync', 'sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor')
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+            [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('--versioned-dirs', 'versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name')
+            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', 'dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', 'bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', 'skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
     })
 
     $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 1f1a9a70767..82cacb52ffe 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -57,6 +57,9 @@ _x.py() {
             bootstrap,test)
                 cmd="bootstrap__test"
                 ;;
+            bootstrap,vendor)
+                cmd="bootstrap__vendor"
+                ;;
             *)
                 ;;
         esac
@@ -64,7 +67,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1879,6 +1882,120 @@ _x.py() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
+        x.py__vendor)
+            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --sync)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --llvm-skip-rebuild)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
     esac
 }
 
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index b920309ac2c..12e96dbd40a 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -743,6 +743,51 @@ _arguments "${_arguments_options[@]}" \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
+(vendor)
+_arguments "${_arguments_options[@]}" \
+'*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:( )' \
+'--host=[host targets to build]:HOST:( )' \
+'--target=[target targets to build]:TARGET:( )' \
+'*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:( )' \
+'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:( )' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
+'*--set=[override options in config.toml]:section.option=value:( )' \
+'--versioned-dirs[Always include version in subdir name]' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
         esac
     ;;
 esac
@@ -766,6 +811,7 @@ _x.py_commands() {
 'run:Run tools contained in this repository' \
 'setup:Set up the environment for development' \
 'suggest:Suggest a subset of tests to run, based on modified files' \
+'vendor:Vendor dependencies' \
     )
     _describe -t commands 'x.py commands' commands "$@"
 }
@@ -844,6 +890,11 @@ _x.py__test_commands() {
     local commands; commands=()
     _describe -t commands 'x.py test commands' commands "$@"
 }
+(( $+functions[_x.py__vendor_commands] )) ||
+_x.py__vendor_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py vendor commands' commands "$@"
+}
 
 if [ "$funcstack[1]" = "_x.py" ]; then
     _x.py "$@"
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 9a23811ed3f..31222f213d8 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -10,11 +10,9 @@ path = "lib.rs"
 arrayvec = { version = "0.7", default-features = false }
 askama = { version = "0.12", default-features = false, features = ["config"] }
 base64 = "0.21.7"
-byteorder = "1.5"
 itertools = "0.12"
 indexmap = "2"
 minifier = "0.3.0"
-once_cell = "1.10.0"
 regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
 serde_json = "1.0"
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 64f0e096cd0..5c5651f3ef0 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -35,13 +35,13 @@ use rustc_resolve::rustdoc::may_be_doc_link;
 use rustc_span::edition::Edition;
 use rustc_span::{Span, Symbol};
 
-use once_cell::sync::Lazy;
 use std::borrow::Cow;
 use std::collections::VecDeque;
 use std::fmt::Write;
 use std::iter::Peekable;
 use std::ops::{ControlFlow, Range};
 use std::str::{self, CharIndices};
+use std::sync::OnceLock;
 
 use crate::clean::RenderedLink;
 use crate::doctest;
@@ -1994,7 +1994,7 @@ pub struct IdMap {
 }
 
 // The map is pre-initialized and cloned each time to avoid reinitializing it repeatedly.
-static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(|| init_id_map());
+static DEFAULT_ID_MAP: OnceLock<FxHashMap<Cow<'static, str>, usize>> = OnceLock::new();
 
 fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     let mut map = FxHashMap::default();
@@ -2051,7 +2051,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
 
 impl IdMap {
     pub fn new() -> Self {
-        IdMap { map: DEFAULT_ID_MAP.clone() }
+        IdMap { map: DEFAULT_ID_MAP.get_or_init(init_id_map).clone() }
     }
 
     pub(crate) fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String {
diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs
index 54407c614c4..8d715814faa 100644
--- a/src/librustdoc/html/render/search_index/encode.rs
+++ b/src/librustdoc/html/render/search_index/encode.rs
@@ -166,13 +166,12 @@ pub(crate) fn write_bitmap_to_bytes(
         containers.push(container);
     }
     // https://github.com/RoaringBitmap/RoaringFormatSpec
-    use byteorder::{WriteBytesExt, LE};
     const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346;
     const SERIAL_COOKIE: u32 = 12347;
     const NO_OFFSET_THRESHOLD: u32 = 4;
     let size: u32 = containers.len().try_into().unwrap();
     let start_offset = if has_run {
-        out.write_u32::<LE>(SERIAL_COOKIE | ((size - 1) << 16))?;
+        out.write_all(&u32::to_le_bytes(SERIAL_COOKIE | ((size - 1) << 16)))?;
         for set in containers.chunks(8) {
             let mut b = 0;
             for (i, container) in set.iter().enumerate() {
@@ -180,7 +179,7 @@ pub(crate) fn write_bitmap_to_bytes(
                     b |= 1 << i;
                 }
             }
-            out.write_u8(b)?;
+            out.write_all(&[b])?;
         }
         if size < NO_OFFSET_THRESHOLD {
             4 + 4 * size + ((size + 7) / 8)
@@ -188,21 +187,21 @@ pub(crate) fn write_bitmap_to_bytes(
             4 + 8 * size + ((size + 7) / 8)
         }
     } else {
-        out.write_u32::<LE>(SERIAL_COOKIE_NO_RUNCONTAINER)?;
-        out.write_u32::<LE>(containers.len().try_into().unwrap())?;
+        out.write_all(&u32::to_le_bytes(SERIAL_COOKIE_NO_RUNCONTAINER))?;
+        out.write_all(&u32::to_le_bytes(containers.len().try_into().unwrap()))?;
         4 + 4 + 4 * size + 4 * size
     };
     for (&key, container) in keys.iter().zip(&containers) {
         // descriptive header
         let key: u32 = key.into();
         let count: u32 = container.popcount() - 1;
-        out.write_u32::<LE>((count << 16) | key)?;
+        out.write_all(&u32::to_le_bytes((count << 16) | key))?;
     }
     if !has_run || size >= NO_OFFSET_THRESHOLD {
         // offset header
         let mut starting_offset = start_offset;
         for container in &containers {
-            out.write_u32::<LE>(starting_offset)?;
+            out.write_all(&u32::to_le_bytes(starting_offset))?;
             starting_offset += match container {
                 Container::Bits(_) => 8192u32,
                 Container::Array(array) => u32::try_from(array.len()).unwrap() * 2,
@@ -214,19 +213,19 @@ pub(crate) fn write_bitmap_to_bytes(
         match container {
             Container::Bits(bits) => {
                 for chunk in bits.iter() {
-                    out.write_u64::<LE>(*chunk)?;
+                    out.write_all(&u64::to_le_bytes(*chunk))?;
                 }
             }
             Container::Array(array) => {
                 for value in array.iter() {
-                    out.write_u16::<LE>(*value)?;
+                    out.write_all(&u16::to_le_bytes(*value))?;
                 }
             }
             Container::Run(runs) => {
-                out.write_u16::<LE>((runs.len()).try_into().unwrap())?;
+                out.write_all(&u16::to_le_bytes(runs.len().try_into().unwrap()))?;
                 for (start, lenm1) in runs.iter().copied() {
-                    out.write_u16::<LE>(start)?;
-                    out.write_u16::<LE>(lenm1)?;
+                    out.write_all(&u16::to_le_bytes(start))?;
+                    out.write_all(&u16::to_le_bytes(lenm1))?;
                 }
             }
         }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 74c9130fd77..80a4ea0424a 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1133,6 +1133,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 .setting-check input:checked {
 	background-color: var(--settings-input-color);
 	border-width: 1px;
+	/* cross-mark image in the settings checkboxes */
 	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">\
 		<path d="M7,25L17,32L33,12" fill="none" stroke="black" stroke-width="5"/>\
 		<path d="M7,23L17,30L33,10" fill="none" stroke="white" stroke-width="5"/></svg>');
@@ -1608,12 +1609,26 @@ a.tooltip:hover::after {
 	font-size: 0;
 }
 #settings-menu > a:before {
-	content: url('wheel-63255fc4502dca9a.svg');
+	/* Wheel <https://www.svgrepo.com/svg/384069/settings-cog-gear> */
+	content: url('data:image/svg+xml,<svg width="22" height="22" 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: 22px;
 	height: 22px;
 }
 
 #sidebar-button > a:before {
+	/* sidebar resizer image */
 	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \
 		fill="none" stroke="black">\
 		<rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\
@@ -1636,7 +1651,17 @@ a.tooltip:hover::after {
 }
 #copy-path::before {
 	filter: var(--copy-path-img-filter);
-	content: url('clipboard-24048e6d87f63d07.svg');
+	/* clipboard <https://github.com/rust-lang/crates.io/commits/main/public/assets/copy.svg> */
+	content: url('data:image/svg+xml,<svg width="19" height="18" viewBox="0 0 24 25" \
+xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard">\
+<path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 \
+0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 \
+7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 \
+2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/>\
+<path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/>\
+</svg>');
+	width: 19px;
+	height: 18px;
 }
 #copy-path:hover::before {
 	filter: var(--copy-path-img-hover-filter);
@@ -1837,6 +1862,7 @@ However, it's not needed with smaller screen width because the doc/code block is
 /* sidebar button opens modal
 	use hamburger button */
 .src #sidebar-button > a:before, .sidebar-menu-toggle:before {
+	/* hamburger button image */
 	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
 		viewBox="0 0 22 22" fill="none" stroke="black">\
 		<path d="M3,5h16M3,11h16M3,17h16" stroke-width="2.75"/></svg>');
@@ -1850,6 +1876,7 @@ However, it's not needed with smaller screen width because the doc/code block is
 
 /* src sidebar button opens a folder view */
 .src #sidebar-button > a:before {
+	/* folder image */
 	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
 		viewBox="0 0 22 22" fill="none" stroke="black">\
 		<path d="M16,9v-4h-6v-1l-2,-2h-4l-2,2v16h13L21,9h-15L2,19" stroke-width="1.25"/>\
diff --git a/src/librustdoc/html/static/images/clipboard.svg b/src/librustdoc/html/static/images/clipboard.svg
deleted file mode 100644
index e437c83fb6b..00000000000
--- a/src/librustdoc/html/static/images/clipboard.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg width="19" height="18" viewBox="0 0 24 25" xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard"><path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/><path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/></svg>
diff --git a/src/librustdoc/html/static/images/wheel.svg b/src/librustdoc/html/static/images/wheel.svg
deleted file mode 100644
index ba30f13dd58..00000000000
--- a/src/librustdoc/html/static/images/wheel.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" enable-background="new 0 0 22 22" viewBox="0 0 27.434 29.5"><path d="M27.316 18.39a2.696 2.696 0 0 0-.98-1.46 1.62 1.62 0 0 1-.016-.762l.035-.176v-1.191c0-1.246-.003-1.278-.046-1.473a1.717 1.717 0 0 1 .007-.805c.477-.343.829-.859.997-1.472.257-.957.074-2.094-.508-3.117l-.594-1.032c-.746-1.304-1.965-2.117-3.18-2.117-.379 0-.75.078-1.086.235a1.958 1.958 0 0 1-.855-.391l-.102-.082-.117-.063-1.855-1.07-.094-.055-.106-.043c-.378-.156-.66-.41-.77-.554C17.919 1.172 16.349 0 14.297 0h-1.155c-2.043 0-3.61 1.152-3.75 2.723-.114.14-.391.382-.758.527l-.102.04-.094.05-1.94 1.066-.134.074-.117.094a2.019 2.019 0 0 1-.832.403 2.518 2.518 0 0 0-1.008-.211c-1.199 0-2.414.82-3.168 2.14l-.59 1.032c-.41.718-.64 1.523-.64 2.257-.004.953.36 1.758 1.012 2.258.035.152.058.445-.016.785-.04.168-.063.282-.063 1.563 0 1.148 0 1.148.016 1.261l.008.075.015.074c.075.344.047.64.012.8-.644.5-1.004 1.302-.992 2.259.008.726.238 1.52.648 2.242l.59 1.027c.758 1.332 1.965 2.16 3.149 2.16.324 0 .644-.062.937-.187.168.039.492.156.813.418l.11.086.124.07 2.047 1.156.102.059.105.043c.363.144.648.379.766.52.164 1.519 1.718 2.632 3.746 2.632h1.156c2.035 0 3.598-1.133 3.746-2.672.117-.144.402-.394.773-.55l.114-.047.101-.063 1.961-1.156.106-.063.097-.078c.309-.246.653-.37.832-.398.313.136.66.21 1.016.21 1.2 0 2.41-.82 3.164-2.14l.594-1.031c.59-1.028.777-2.164.52-3.117Zm-2.043 2.247-.59 1.031c-.437.766-1.105 1.25-1.636 1.25a.7.7 0 0 1-.371-.094 1.146 1.146 0 0 0-.567-.129c-.593 0-1.382.297-2.007.797l-1.961 1.156c-1.016.426-1.848 1.293-1.848 1.93 0 .64-.898 1.16-1.996 1.16H13.14c-1.102 0-2-.515-2-1.14 0-.63-.832-1.477-1.852-1.887l-2.047-1.16c-.637-.512-1.426-.813-2.008-.813-.199 0-.379.035-.515.114a.648.648 0 0 1-.332.085c-.52 0-1.18-.5-1.621-1.273l-.59-1.031c-.543-.953-.555-1.98-.024-2.285.532-.305.782-1.434.551-2.504V14.8c0-1.09.02-1.18.02-1.18.238-1.074-.008-2.203-.551-2.516-.54-.304-.54-1.34.008-2.293l.59-1.03c.437-.766 1.101-1.255 1.636-1.255a.73.73 0 0 1 .364.094c.152.086.343.125.566.125.594 0 1.379-.297 2.004-.793l1.945-1.066c1.02-.407 1.856-1.278 1.856-1.934 0-.656.898-1.191 2-1.191h1.156c1.098 0 1.996.543 1.996 1.21 0 .669.832 1.555 1.848 1.973L20 6.012c.617.492 1.402.777 2.012.777.242 0 .453-.047.62-.14a.79.79 0 0 1 .403-.102c.55 0 1.223.476 1.652 1.23l.59 1.032c.543.953.52 2.004-.062 2.336-.574.332-.86 1.48-.625 2.554 0 0 .008.04.008 1.102v1.011c-.215 1.051.07 2.176.636 2.5.567.325.586 1.368.04 2.325Zm0 0"/><path d="M13.61 7.61a7.084 7.084 0 0 0-7.083 7.085 7.085 7.085 0 1 0 14.168 0A7.088 7.088 0 0 0 13.61 7.61Zm0 12.41a5.33 5.33 0 0 1-5.325-5.325 5.33 5.33 0 0 1 5.324-5.32 5.327 5.327 0 0 1 5.325 5.32 5.328 5.328 0 0 1-5.325 5.325Zm0 0"/><path d="M13.684 9.906a4.722 4.722 0 0 0-4.72 4.719 4.722 4.722 0 0 0 4.72 4.719 4.724 4.724 0 0 0 4.714-4.719 4.724 4.724 0 0 0-4.714-4.719Zm0 7.676a2.954 2.954 0 1 1 0-5.91 2.953 2.953 0 0 1 2.953 2.953 2.957 2.957 0 0 1-2.953 2.957Zm0 0"/></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index d8874c2fda0..035376bace9 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -99,8 +99,6 @@ static_files! {
     src_script_js => "static/js/src-script.js",
     storage_js => "static/js/storage.js",
     scrape_examples_js => "static/js/scrape-examples.js",
-    wheel_svg => "static/images/wheel.svg",
-    clipboard_svg => "static/images/clipboard.svg",
     copyright => "static/COPYRIGHT.txt",
     license_apache => "static/LICENSE-APACHE.txt",
     license_mit => "static/LICENSE-MIT.txt",
diff --git a/src/stage0.json b/src/stage0.json
index a85fbf254fc..a9a53a7528f 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -18,431 +18,439 @@
     "tool is executed."
   ],
   "compiler": {
-    "date": "2024-03-19",
+    "date": "2024-04-29",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2024-03-19",
+    "date": "2024-04-29",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2024-03-19/cargo-beta-aarch64-apple-darwin.tar.gz": "d8aeeb8d427c346112020b84de85c1498d1ea043a01a45dd63d38da8ae0d35d1",
-    "dist/2024-03-19/cargo-beta-aarch64-apple-darwin.tar.xz": "f4c3aec8e916a93412c6c798c43dab1dd64c0095509a2a255191751a230730ad",
-    "dist/2024-03-19/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "d6161a55f808b6d54a061f9ffd9c33489b844f450f07a40e2f6cdb7def75792b",
-    "dist/2024-03-19/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "cba6e510866f9d920ee40e66069e8d152c0bfdabcc280ba0175a103460614839",
-    "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "e99299705d9b596554a4156ca7e8cd1bab95d926b519fd79e24d7b4c00bf4bbe",
-    "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "d006ecc2215a0b7b1d3040c64d72094589bfe11f1ffd34f63e5aaa8fb52ee4b2",
-    "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "9f6b9bd599948b48085bf592630963a5b69608abff67dd3674327d7efdcbf695",
-    "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "e3bd8ad798b098f1e03333bece43fe163f4d4b613bf38de4809106ca98b99c05",
-    "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "5ec13385ad03d14fa8fd48fd3f92df123a1626bb8a594df33c0bdee02d5a811c",
-    "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "bf201ad295272ee9435da1afcd4888c31bb14e467edb9638fdfe95b071bc869d",
-    "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "0e09177180c2822378bdb66dca69fb8bc7e7d5c51f414bdd95b9497c683d466f",
-    "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "5815c1421d474d8cd238fff80db5ba5231155abbd8642eeced84842d34f49ba9",
-    "dist/2024-03-19/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "36967ecac443fdcace710bae63eedcf65a4c2015793ed30ea3edae3d93f24707",
-    "dist/2024-03-19/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "1932898203f99c2aee95e71226c66b48d8dcbe40aa3a8b0782856fedcd291b13",
-    "dist/2024-03-19/cargo-beta-i686-pc-windows-gnu.tar.gz": "948157661b4b54b4c963933d97d4721efb6c8134242b96a82b86ee4be8dfe043",
-    "dist/2024-03-19/cargo-beta-i686-pc-windows-gnu.tar.xz": "26afbb06b1a47945172cee64470803670d1e41529f4e0f357f48633565efc489",
-    "dist/2024-03-19/cargo-beta-i686-pc-windows-msvc.tar.gz": "82e81f26ba6a207ac891a13bd9eb58c2cc33d31e78d354a210c4518b2d2b4dfd",
-    "dist/2024-03-19/cargo-beta-i686-pc-windows-msvc.tar.xz": "2b697674c4535bb58910dea6fdb9948a3b06ecdb723a638c01558615cbbf3fb0",
-    "dist/2024-03-19/cargo-beta-i686-unknown-linux-gnu.tar.gz": "2273118fc50fe605d53b078b5859d2694555f6c9ce2a61478f5af1765cffb997",
-    "dist/2024-03-19/cargo-beta-i686-unknown-linux-gnu.tar.xz": "53ae185d70ead1a251aac0793cbc784858d7a666530cacb63404541bef2a8bbd",
-    "dist/2024-03-19/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "f37429c8406938888600b180b60db99a5343866e8ba6c595350c60a631d6cc2e",
-    "dist/2024-03-19/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "ca49cac7f00c94ab5ac936c500a96092fc44a2cf9f1e10d52aa877ad9a57c548",
-    "dist/2024-03-19/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "262a48b6cfe9ebc8e19847e5ffa22459398395a9f9c9bb0891bf7b247b9d800a",
-    "dist/2024-03-19/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "6300c528f7457e0349eb2ff25e24122e5448855a4f05f265b810b328d4310516",
-    "dist/2024-03-19/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "e0dd3b037664c468eee9340235454b0a01310eae6025d5e2fb142027ff079cd5",
-    "dist/2024-03-19/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "36de5c67fdbc1eacdf00a51e2b44df5c1ee50ecd83755e893b6cb41bf49f30b5",
-    "dist/2024-03-19/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "cb5cdabb2d9d0398895b491f3cd128bd16488464fb3b8bc24f8e2e115154bbbf",
-    "dist/2024-03-19/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "e597718951b6f2973a68d587b84b6d4ce51e180e74b1060fdcbc3cfd05e04291",
-    "dist/2024-03-19/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "0a860fccb3f7ca44ca94ed76b1b81a2033e9c6806b32b428b49794508529e5be",
-    "dist/2024-03-19/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "10eaa329dc9a40337df22edd21a7396fd87852afcd0e68f1334cb374a56aa5bf",
-    "dist/2024-03-19/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "2f511c9d6ba6b489d96f531778af89baa3cce98ddc2e015198a0fbda95c0077a",
-    "dist/2024-03-19/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "d510515fa11961e56c05a946fb7200ce42b3831280177fda78260915f9b0192f",
-    "dist/2024-03-19/cargo-beta-x86_64-apple-darwin.tar.gz": "e4d542ce10c993bbdd1103d605c5c15771629750f204c5de76af93b0f0278391",
-    "dist/2024-03-19/cargo-beta-x86_64-apple-darwin.tar.xz": "36ff8a7806bd8bcb2c0054f994ec32bc5b30907c3ea2dd3cd07a440b6ee031c3",
-    "dist/2024-03-19/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "d3daaa2be8f7b761c37cfca9a1a242e2b0231795e1cb868246ed1e379c3969d8",
-    "dist/2024-03-19/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "1cda9d7c448336878071e6eb27338bd0346ec5ea28a8d29a6dcb3caa9b96fc54",
-    "dist/2024-03-19/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "cd1539eca02777df1ff8bf70d4f4abe59ea3a2d1cc625fb714b941502f863198",
-    "dist/2024-03-19/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "e97a05c1ba1a4aec2d424845b0b874712f15568c2e9cd61222663b96b759bb3f",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-freebsd.tar.gz": "aa2de3a607bc0fd4b4f99b2a6c8c024a75823d7ebea553748d24ad2841f3c919",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-freebsd.tar.xz": "6546733a7b4a34b5739b9a1d1cfac8eb7ae320a14a242e8298564e33b2b4208e",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-illumos.tar.gz": "e48ad6cfa052ee84226e79cd037b4ff02d6974139225a69edac26db10f894c12",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-illumos.tar.xz": "2a55ac5d8aecb87d7625a90a5f1560859f516a44825b189b7d0cbbe0de787bd6",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "19db36d6b51c3e16869fc4be4133e321b103211fa8fd7a072dfb8dfa5dd108b6",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "97a90f062125ed14fc9723ecf3e68e12fc5853efb83e0afeef97dadd1b0e032f",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "231529bb7dbefbdba9b741a03ed210963966e217b684b05bfe8ff61af46577c9",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "b5e82d094176f729dc500d67ef5f4102df558718020f43536155ac4a74d6a01b",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-netbsd.tar.gz": "c6b836aa6f7cd086a7316fbcaf9e3de080d310db60eacc0910a3b90bbf5c224e",
-    "dist/2024-03-19/cargo-beta-x86_64-unknown-netbsd.tar.xz": "dcb398fb25568a0e5374be22be14f8dc1c0a7221fc5e60dc9258d4767f774058",
-    "dist/2024-03-19/clippy-beta-aarch64-apple-darwin.tar.gz": "7f4cf1177f0f22f471b8bf219d13b59b626089b3c2a563b3559dc66a573c8375",
-    "dist/2024-03-19/clippy-beta-aarch64-apple-darwin.tar.xz": "78d5efca461180bfdcde7e4672ac06221a0809386624b4f6892e0037df8be572",
-    "dist/2024-03-19/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "8d3443465b4f0cbd6ba7e5bd8614071ce826798f80d7c6e35cc71ef463675952",
-    "dist/2024-03-19/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "4ea23f92b8f36a271c36df93008a00e0a0519dfdc0da69cc920f7edf317b4ae9",
-    "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "1eabd5f5bce761972022f52dc86cd408f7106a7df2a0d9b1701afc1bcb39ed39",
-    "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "05feb29e8c526ed85e331f091b046767c4a01d68129c6a873536703dee529323",
-    "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "c023d628e7d23ad3d94791e595b0ce4033c24b5e53f806947b88a6cddd93e1b8",
-    "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "96b29dba180d5bf4caa40b5c8538248b0b820991d91eab819b2ce0fe093640b9",
-    "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "5d9a8237c5d2258e7ff18cee7cad2308e6ce3935251c8fb74932ed84b1e23a52",
-    "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "625f0415d85c08281efb4cdd6d362636876360774297487ed92337e72058c896",
-    "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "5d9e03efe64eb1a60dfa011b1641a74979295cf6540e081672deed82fd130132",
-    "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "e9bed26481e7678e7e4388c0e6885ab323b9cecc270a3044b08cb681eed5333d",
-    "dist/2024-03-19/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "26e0a630657c7abe765132bfab93aa39013ff19aec1978e41968cb53e6c46693",
-    "dist/2024-03-19/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "30abee9b263f4ff6f7e696a41f5356957daae5953c224fcd1f253ce41dcd94ea",
-    "dist/2024-03-19/clippy-beta-i686-pc-windows-gnu.tar.gz": "845732a863b79922ed5057ddf7c911bae71381082bdcf68799c8f79c0f48d192",
-    "dist/2024-03-19/clippy-beta-i686-pc-windows-gnu.tar.xz": "75f1abca075af64656d176ac1ea37e24c000378f1750a708924b44fdc223c389",
-    "dist/2024-03-19/clippy-beta-i686-pc-windows-msvc.tar.gz": "e5a7d0ff6d1f8d9bfeaab8f8aaf1c18528c1eb447169454c965838a2b836c201",
-    "dist/2024-03-19/clippy-beta-i686-pc-windows-msvc.tar.xz": "ad5a7313ca6fbd8051c0db761bbae67d3405cc5a98ec20891f26c15b31b5b2b0",
-    "dist/2024-03-19/clippy-beta-i686-unknown-linux-gnu.tar.gz": "cf67172fcc26b9b45138f0ac12721c1fe226a892346145b4a0ff1931d60fb756",
-    "dist/2024-03-19/clippy-beta-i686-unknown-linux-gnu.tar.xz": "3adb4d8a782a80d85f4cdfc433f63656449a06dddc67f0b11bf399d9a8aae97a",
-    "dist/2024-03-19/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "175d58f41d0b08bc1ac733bee1d16db31a4a64f7703a87ea1f13ec72b19be4d7",
-    "dist/2024-03-19/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "73925325e092d84ba3a8aff695953142962221fecaab9d57dc61b4d03338bb12",
-    "dist/2024-03-19/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "cec90ecbdfd252e49de68fa69806f5662bd4f4ab093708104e19b228564c0ee4",
-    "dist/2024-03-19/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "eb085114c178c8e16ec77657fb658b537eff1125f3de5d7e07f1ccd62e8b834e",
-    "dist/2024-03-19/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b599d42a4100a7b1304eee34571abe1e6e38e873f8197e46d0d4d92dbb0ccd27",
-    "dist/2024-03-19/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "57338b860b283cfed3cf1eb38083113f026cfc91135e439b75de1a3acc9e42b3",
-    "dist/2024-03-19/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "00f756d858949ad83ad32dca5c5a93cd283da3c91f4976564afd5be3b4f5927b",
-    "dist/2024-03-19/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "4a8d250c30312dfd4f8d259ca4376555bbc6cf290a884aff92e6b06a852acf6d",
-    "dist/2024-03-19/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "992a77181709bf235c1e0a335a82b0ee01fe8f749956f2aad52a386685aeae6b",
-    "dist/2024-03-19/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "b523cf81d4ffbcc0bb9f4f5805eeb39624901eea591c852f9594690350848c54",
-    "dist/2024-03-19/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "5f22463a8c138fb3934a405bc0f7de4b5ea51c86b75f7739eccd7181fbeb4e9a",
-    "dist/2024-03-19/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "2b507322b80e562a0dfaba16210a2f1d65051a740869ce5a952bf83a9099e0f2",
-    "dist/2024-03-19/clippy-beta-x86_64-apple-darwin.tar.gz": "6873e1a437b6783e349d4fe1cd69f996f579b623c231d55933ec194de19d0a15",
-    "dist/2024-03-19/clippy-beta-x86_64-apple-darwin.tar.xz": "4b8f43b267b25bc5f60541fe6b98254c2731f0ee55129cc132e28c4f3b2bbc24",
-    "dist/2024-03-19/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "e697e4c34422519db58b44bf8ed164fc45dadf4ac114c3e662f6990d4d9a5522",
-    "dist/2024-03-19/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "5ffd1038684dc68bf97f9a74c08beca4c3eb66b39b11e32e7da45b763fe1f7f2",
-    "dist/2024-03-19/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "7e334464dbbe5be014de9ef6872a1b2066016204e7ae8c11e55fbf64bedb93da",
-    "dist/2024-03-19/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "55b4aaa0a64d9e3cc2489a678935277d91b1f8223186c52b59bd33dbd403d52a",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-freebsd.tar.gz": "6fa2e2bdd09242ab44ad35853cf9493ad57d602536406ecd3504db5af87b827a",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-freebsd.tar.xz": "b1b79f8130d61c92d3d101a4d24416ef37fd446f18de0745be2c1fed7b276b57",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-illumos.tar.gz": "ee1af20cc23288fecf8ebe33e877e1de3184711a38ea378a6f4da158919b4059",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-illumos.tar.xz": "af724f142b19b7436547a5eb2b2b40d1acf959a73feca03efd9178948af9326a",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "376cf1787e41ba9d231191f6cae260895be18c3ececc2f2e934e850de7f1cbda",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "8d7af83d3594a151564f351eed4cdfd1c7eb5b07e073e12c6d7b7ef9ad597007",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "218168e4817f70f65651f3b9561ba8e8dd3e0d8c8a33a88ba9ad0a4a501468bd",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "f55143ece3326ac8c004b77e59c1a60a70b3f1189c7e2e442183097f1cf639c2",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-netbsd.tar.gz": "9a5c08d2e00d2f38de5a9882fe7dcadd6307a333b8caf5826687301f8d97d09a",
-    "dist/2024-03-19/clippy-beta-x86_64-unknown-netbsd.tar.xz": "7be02599b4c2cd26365075ebfbb1534f6875d85501fe5a300895506e41ad0824",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-darwin.tar.gz": "7238015aa0e8553b6e820483e15f08119fa0b6c074abe127be99fa990f132c8f",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-darwin.tar.xz": "0dc783f3865ddf6512721abcd9c668f6d8533c3581015cfd4740b40cb09ce199",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "90541bf8f4c1fb838fff2620b55addee59687b16d3f10f92b59a41936ffa143d",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "b0d14d73d404197994e41deb2d92049ec043c875a81dda52c4e4fc64e53c8065",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-ios.tar.gz": "3105f19fd78bcdc5171cf4041aca9da236150e43ef9c32ee1163aafbc79d311f",
-    "dist/2024-03-19/rust-std-beta-aarch64-apple-ios.tar.xz": "13629cec9404312c6b42fd7aac14edc5eee98947be5152ae5708db899d2ebb4e",
-    "dist/2024-03-19/rust-std-beta-aarch64-linux-android.tar.gz": "3fb671809fafdabcb4cd8ea6c00caf3cfa2da3421770c08abf761456f079c425",
-    "dist/2024-03-19/rust-std-beta-aarch64-linux-android.tar.xz": "8f8f22bd89a29db1a549414440da19f3100abb689fb095c3e09ef28a223ee3cd",
-    "dist/2024-03-19/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "2326cc5061a6acc3cfea5a0e2ea965e07a0103052cfb4435e5dc947573b62e11",
-    "dist/2024-03-19/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "87327aa9f683ef9f574348cc0ec58b0f88fdcd6563d51b69664b3588897783ca",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "5f589736703a21a17366dd93c36ee6f597a40999ce6c305ff1e007918fe6aaef",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "65386ce4aa697b74c463e1c8d793ded996f6dbf1327242aaf61471968212c1e7",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "590b12f5fdf32251c1e0ad2af619b70b73a888d3a33a705f023b81369bcbbfa8",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "c22e0e88e1fd0041c95317bbc0e39e7d4e4e6a8d73eedc141628ec9e41d844f5",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "7e8e04e2bd58ac03c5dcf017562d3ad92993896a5f5a31e199990685adb206b7",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "8d0c5b70230122904e36731290f62dcf24fca2390d4c892aeb9b8f241d380563",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "89d476e9654dce23fb77cef86831813d143435e4e1a9547936f5eabb9a7e649b",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "b1b5c25e682961301e60f115eba6177a1be97b3157a0671c0ec64563765ddfdd",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "e8b2b4cd75800e5cd5b8f5ad97d6ef9fef8e6a7852a227406e89a3f7f50d33d2",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "e5c603df1515777eb1af5c9532194fde8ea3554abfefb93499025a9a98fdc182",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-none.tar.gz": "55605666a2bde23365937c811899f9e61855a28668d4b050834b83f5af8b03b5",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-none.tar.xz": "f68fa43e4ee4d86b7bba6c316efba5ef6e3d500b0659ba4a0295df814beca459",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-uefi.tar.gz": "5b9dbe42c686670836ba26acab3afa218fa70b616d3a7951298ce5cf2eff88bd",
-    "dist/2024-03-19/rust-std-beta-aarch64-unknown-uefi.tar.xz": "fcc8316db3cef3a3c3240a490d18162cf724fceecb595a0c40067c6a20a53caf",
-    "dist/2024-03-19/rust-std-beta-arm-linux-androideabi.tar.gz": "abdd4c98992cf2f9a9a558c5c74283826de3bb48d7743e67ef1f9d1dbc40f534",
-    "dist/2024-03-19/rust-std-beta-arm-linux-androideabi.tar.xz": "c597c457071b82c8842958c6ad383db30741952b06b40f138a5bed3bbca62c70",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "2a11714a2e5d18f7f255feece850a4c8ab7e1b14f6eb116c47eb972825abfdc2",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "5a6f054ebf50bf4bb196a32019276bed1cbcb74cbd3d46877a48ed77c09638c9",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "422d4d3a2f32a1739d18c208e89e5c490ce9b85c771726b21d265cb7632ffd49",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "d9fb3be5b4d577a469f4dc9cce5e4631741d6661a994d15cc1db847ab4edcaed",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "6a9c25b659a7d16f01148144883e47bddb29e2d79f7b590f58efd4b002abe38e",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "2c797105730a6a2a9d8ec5506f2028d42aef48d7ae09fad11e1ef3a0dc3c9a81",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "4f58e423159b7b5a8d546c288572dc644e73cfd5e22eb87f98670e1bdd4cfb42",
-    "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "d549997c4be8efe2feee163096b370ca6ddb0884dbf82af0c1d08e5f652a3b26",
-    "dist/2024-03-19/rust-std-beta-armebv7r-none-eabi.tar.gz": "2e199f5246edf22faf1b8876bec5290a7a111a38cffb831fedef3f4d4e57dded",
-    "dist/2024-03-19/rust-std-beta-armebv7r-none-eabi.tar.xz": "ffc4118d0520df6d4101c05c4df31bdbe91ce302b37d9d41e3dfdfd8fcb5b49a",
-    "dist/2024-03-19/rust-std-beta-armebv7r-none-eabihf.tar.gz": "39e2a7464ef3e48104873f59b6198cad8333835a0fe46805b00f2a3a8f1989aa",
-    "dist/2024-03-19/rust-std-beta-armebv7r-none-eabihf.tar.xz": "ff22a6f9b7c7873fe84943bbcffabba04e2632166ce63e405056ca0ee8fcdb62",
-    "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "51128c12bcd8935bed76a555da1e403e1b374155278ed957d078a2c887512a15",
-    "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "5370c2da10bc8efe00f0840d8ea6f664d38518288ed402a4ac164ae71cf1dfe9",
-    "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "ba104dbdcc3c8689dadb75c6a85d83419e32fe78f43039f5294020da2ab3b73a",
-    "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "7bb849dae31f472febd722dc7dd324f073b2739dc57c40a6590b10f61c26133e",
-    "dist/2024-03-19/rust-std-beta-armv7-linux-androideabi.tar.gz": "c44211a45a1ecb9b5800fb7a3b7fa88de4562845888588012b34e282e26cb4f8",
-    "dist/2024-03-19/rust-std-beta-armv7-linux-androideabi.tar.xz": "3a92cdd368559d06d290af58fda93eac98e6d4bfd4e6ad03db0f91fe01789504",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "f00db0fd04a921cebe68a21d3c923e44f8a1828cdfffa201826d333feb0b9bd6",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "af5ec7e114c8558080b8891269cca098b530809085577485ea96435d5f664e4b",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "5b2aa8f0c2a005a5c98dd08a6d4d231a11992356f857b706a19cefa66d62dc9a",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "7ab1a7cda6ae70836df20a70283af166ad2d5413755485d818d8760f3bf69f6c",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "9b970f2b3e0a01ecf56a9d32cdfbc47d76a2518838bc231d4488c2f4a9426fa7",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "934272fbb78cd09728ef03557fad7e2b1b9302f88579dee8a5a1f58c8f4b15bd",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "f70a1adf38b2d22b1706af807023154b626f656efb8d91c8ed7235bfe0855edf",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "a665e05bb8dff2e8dd0479cb8a63460c73ee3e86ec7e1b6f48fece2985c85e52",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "e0ec71714bceee0df1bcdb85e094b58359d41f273dc9abab7ac05346fcd3f4b9",
-    "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "afbcd9b7ecc92f69801d77185af0139136ba6c352d14a6c8ed76de64a87645f5",
-    "dist/2024-03-19/rust-std-beta-armv7a-none-eabi.tar.gz": "a0e55f17c1bab81bf836c1e373f77d25c42fbd05f04b8b0e96f66f1f744481d2",
-    "dist/2024-03-19/rust-std-beta-armv7a-none-eabi.tar.xz": "f2dd0221e76d7b9f51e9efdee2e40c8d7539b1d5f52257f89431f29931394510",
-    "dist/2024-03-19/rust-std-beta-armv7r-none-eabi.tar.gz": "e97324f421bb354bc841a20e8b1c0357e633595bec4fca510f06e56fb89b2a6a",
-    "dist/2024-03-19/rust-std-beta-armv7r-none-eabi.tar.xz": "1ce1ca60b9536ede90452621ba91539b8ca6b6bdf7cbda3bd6d0b04a28c09580",
-    "dist/2024-03-19/rust-std-beta-armv7r-none-eabihf.tar.gz": "9bffa04e8cd3f67d8892f851b269f9cd91f6c9e5f2c87c641e9f6ef24bf7b644",
-    "dist/2024-03-19/rust-std-beta-armv7r-none-eabihf.tar.xz": "2a3cd2ab92cc37698057629167a553d0654f7882bfc1eb46687e1014b4b8e379",
-    "dist/2024-03-19/rust-std-beta-i586-pc-windows-msvc.tar.gz": "284f13947d990587090beb32262e4a83089c56ce2c3a1ffb89ed0fc5f4661eb3",
-    "dist/2024-03-19/rust-std-beta-i586-pc-windows-msvc.tar.xz": "22e641bdd54b3a7030c2eda0ff20a5517607fb6e60ea6d3195a2cd3afb0e984a",
-    "dist/2024-03-19/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "adaaf6d3a291640ddaa3d522d8331cb27ea899999681d57713b57c879b55de96",
-    "dist/2024-03-19/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ebe80c2420c0eedd219cd539b87de75ffc0ed3b1656284cb81e2b2e8a927c738",
-    "dist/2024-03-19/rust-std-beta-i586-unknown-linux-musl.tar.gz": "c2e4691bf6956f97a214ef80f015a77ec4ece4ee32e9bc73300fe1c0267dcabe",
-    "dist/2024-03-19/rust-std-beta-i586-unknown-linux-musl.tar.xz": "e67059e579532ceb06a46702cc561acbeb3ba6258eda47418da587ec45759e26",
-    "dist/2024-03-19/rust-std-beta-i686-linux-android.tar.gz": "f112053adbcce7710383afe1681bd0096444a516f78f576e29f2f3c76468e7f0",
-    "dist/2024-03-19/rust-std-beta-i686-linux-android.tar.xz": "e63ae04fc20519fb5a56c2bae49f767807cb1ae1c01cab34dee1d129b34c4dee",
-    "dist/2024-03-19/rust-std-beta-i686-pc-windows-gnu.tar.gz": "14b36d2952ebaa84bf24645cd5d3464ae2b9df4d3ffee4bd48fedb07a4fdb09d",
-    "dist/2024-03-19/rust-std-beta-i686-pc-windows-gnu.tar.xz": "fef8c1bd4e1ceab680e1856b35f4ed426d07c224fa60c92d12efe0dfe700abc9",
-    "dist/2024-03-19/rust-std-beta-i686-pc-windows-msvc.tar.gz": "b42794fb8feda98c99d36dd978373afbfab56fd374fe42318107c453ab4d0fb7",
-    "dist/2024-03-19/rust-std-beta-i686-pc-windows-msvc.tar.xz": "855ed5996d9d8e4bc2424ce5ea6da6155b23357d700f1fc07d69d0bd12672a8f",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-freebsd.tar.gz": "0ac04b35b62c7d8fe42ee29854b6a40b7dcf0d3deb174031a7620d2c87a8b206",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-freebsd.tar.xz": "0287daaa3042c644d3190c6262b60b580a0cdfd80c64c299a36e0636d38e5674",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "647dd5ba2f4d842d6bd6377e99b67b3d65d3ee47ea800ace9d172e9d24f63eb0",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "d705b0cce3492e863c5d8fb28b4f2bedce68637fd7093d24a9e86ff6d2d0ca56",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-linux-musl.tar.gz": "561ca95399cbd2f6692e5194ab550e9e0f0f5016aa2802522131c1361d3ef467",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-linux-musl.tar.xz": "d4751c26585e512211157e162f0d1504a1854249dd6eff7262a55b09834d29fd",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-uefi.tar.gz": "4e0a84f3dbc742d589d35cd58980157072f17090472c31ed0e306dad049a75ec",
-    "dist/2024-03-19/rust-std-beta-i686-unknown-uefi.tar.xz": "e11820072ae90861c96b0c1c931d691a157cccbf5d44685e3d5ff9b075aa7500",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "4357b6646ed0f379d9d74358457db1a18289967a880567b9bbff480e72f13711",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "3ffb178cb4c24b3b6df4aacbfaa4280eb6e781cd471fe52ed0b9be8fa555617b",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "bc32e2189cfb3efd8365bcd31fad504cab0fdf62c9fe04a6a0389ff23486cc2b",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "0d2894fe5fa5360cb31e5267e980faddd8d9f7adc415747991381aae535210eb",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none.tar.gz": "16c134291f43694fb92d3efd92abc9c957d3ffa8ba8dee0c792d77f3b4d2cdd7",
-    "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none.tar.xz": "ca06f72e2bd7309831464152cc7532a27406c18e2d6cd02918109aa65896be1e",
-    "dist/2024-03-19/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "a2d4f9671514673abc87ade8237508bd41df1bb6b75b0ea92bb27dd7ab75303e",
-    "dist/2024-03-19/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "69a8f2751d0a86878b92bb052ca0d3394f5bc0545fd3f2c1ce7e03e1ecc6d0b5",
-    "dist/2024-03-19/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "95c4f0f944b4b8ad08c4d0350a09be233796991b8790fc0d48dbae895953d73d",
-    "dist/2024-03-19/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "8ae7b77e0c7be184f4f279365eb2d9b7e9182ec9ea10f987814d4f4b50937f95",
-    "dist/2024-03-19/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "4f886546746f227bff157959a9982529895d52737b6137bf44545e82fe522672",
-    "dist/2024-03-19/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "b9fd4eda7aa2d5eb70e47405ba5fac8d5d3d15d1de76bb5d2f9d0ba8da4a2115",
-    "dist/2024-03-19/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8e81b39b1d7cbc180fe9540e9420f68216aa9b3bd46d6cc6f758f473d8d54ae7",
-    "dist/2024-03-19/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "29d4e64b6e2a326bb695e42354e4f8a21382c63cd8a93fae64a44f3398de0a96",
-    "dist/2024-03-19/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "66eb8d049d50532512d442efef67993fa3da0fc0a585e549559d2e843c7e3c89",
-    "dist/2024-03-19/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "1919690c47b603ff6ddcf6d8f16573cc3acd960d27dfb97358dd9c92a907c766",
-    "dist/2024-03-19/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "e66c025f225b3cfc3399992b0dc3e5f6829ef03b6527656376a0575c970dd43a",
-    "dist/2024-03-19/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "75373475011adc1d3340dcf222e594be505116fa4c1099b493a6eb1018dc5f92",
-    "dist/2024-03-19/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "2dc076319958052445c0de0d34567162745d9a6de18edff2edbf6afa05feb124",
-    "dist/2024-03-19/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "f1225e56a378ac5b8790e9299815987c618f5d712a11e2a039580965679119a1",
-    "dist/2024-03-19/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "26bb1e505811310fecd47e7aa5b75cbbaf6794ce209df200ac554ff84a353392",
-    "dist/2024-03-19/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "35b4799e26da0d6220c0372bce45e6b3b18a4035b82a36505c052e0990cba754",
-    "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "5a79d8992906ab3db7be9716de2c6434e1c8d81c1ebf725a1b413af13f9c9091",
-    "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "7d63304af691b1ade5f9d6e50bf82eb9958f8b3da977fbf894f3c5dab15d0ff5",
-    "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "1a93efe919bcb44cae9fea48aa22a1591f041041e7c59e64461ddc3298ec954b",
-    "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0e17193cec07704e02fec9f4393a457f0f57082c86d4833f687a72be0a439008",
-    "dist/2024-03-19/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "3ccd73bfa0926858f95f1535f1297d6adf8be62afe0a94581d267782b4e8803c",
-    "dist/2024-03-19/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "e7b4ef2f7a7d9bee1b0dd6a12aec4d52150db2fed29af2668ef5a65b727f6ce8",
-    "dist/2024-03-19/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "3e755b9a8fc8b66da6795ef57d9d80ed239e10adb17c23a8a64ba96f0d0b6296",
-    "dist/2024-03-19/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "936807926232e6fdbd2e93a646460ca9d8850367afd82bb56d21245936f73b17",
-    "dist/2024-03-19/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "168c1fb8b6f633abb699c905eaf4e970ea94c789746d7cc3a7984ffb046df446",
-    "dist/2024-03-19/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "d64b6a01542d504fe2d4ccdba0e7574e5521841a0a4fffc3d66e78086e0343a3",
-    "dist/2024-03-19/rust-std-beta-sparcv9-sun-solaris.tar.gz": "34992b0a74cedbaf58057f965858cf26ffdff8bece7b2b0e167c8a1d61b6651d",
-    "dist/2024-03-19/rust-std-beta-sparcv9-sun-solaris.tar.xz": "957c38d5485d96d62fe46c4dff5726233d7c402708c4dbb0337cd740ad759a10",
-    "dist/2024-03-19/rust-std-beta-thumbv6m-none-eabi.tar.gz": "7eab40ea23f0758c5ace93224e1268e2929fb7d165b7877ea2540cc2b45664ce",
-    "dist/2024-03-19/rust-std-beta-thumbv6m-none-eabi.tar.xz": "d0c428c5a1aae6e78842577a5e8f3e4b393d4d3ec9c240ed3c3a0a36d4c0b19a",
-    "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabi.tar.gz": "450b39802145dc6ebcaad6fdf99b606fda18d3f272f18d0a5e21bffa930ec877",
-    "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabi.tar.xz": "649532a1c17da2afbcf0fb9395305bb46a76846bbc8c4fd5c153a170b525d35d",
-    "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "8068584665ce0468bd420d146cfb4643e745c4ee782b352bfc16c9e7f18ed25d",
-    "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "04c1d047e2ec0347cac5ab5591ae0eda6f52c6f9281aaa4d2f4ffcd8c5af11c8",
-    "dist/2024-03-19/rust-std-beta-thumbv7m-none-eabi.tar.gz": "6e954aeddadbbaf088fc8d671e590eba87d4317f8716a7cca286c764131c0d73",
-    "dist/2024-03-19/rust-std-beta-thumbv7m-none-eabi.tar.xz": "15f8ea37798f20559f5c6c91c42acd4c883852e14228bbfe5b65865d998beba7",
-    "dist/2024-03-19/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "1c7b6e92d8727602b8e41d44b66369ddf8e65937fb1a934b2115c18816cd66eb",
-    "dist/2024-03-19/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5679ddb9d7404a776861195ca708fc6132ce1e35fc5994946ba7a17ce61afa9c",
-    "dist/2024-03-19/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "44280bcc42edb6ff3f2d91c8a3e7005703150e7be749480577df96100d516b1c",
-    "dist/2024-03-19/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "abf86ce8dfd3bd5548cbc8c9c958eb75fbbff77cb7ae8a5e231e5ac9d46d3876",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "ca4fc4970411a503d11a30bbea94487a10dc5925cdf7b1dc3bea095c72e5d381",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "9752a30a7a2dbf64092cfb1901ef4e49e9521b794644710060eaf62c8acd1d5c",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "14d29c09f788bdc63550cb9cc0ecb8040b0e28e6e5a5bc65c06dca6a0fb34821",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "201eff5b741c735547226e9a4d22aed0e09f1c31a48673ce7fc094fb7fc95ba7",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "1a641bcc8c904a0c5b4e7ff0d52d105a1ce45c24d10bb1cdc1dc284222851d6d",
-    "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "48f8abb5d1dae87c22e4d24610be6a98d646150d7bddc1ca471a6a27976090e0",
-    "dist/2024-03-19/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "102f692ecc5233a2e8063c305a0d37ffb9689fc1a4927dcd8f4fa14501a04a0b",
-    "dist/2024-03-19/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "cd0407c881219b7586500c05b711ed78de9356d7c0db1065baab3833b5d2b738",
-    "dist/2024-03-19/rust-std-beta-wasm32-unknown-unknown.tar.gz": "3e588580f9298626c4bc3e4b0ad52495d97e4dfc61ca8778e97da3e67c624266",
-    "dist/2024-03-19/rust-std-beta-wasm32-unknown-unknown.tar.xz": "665dd07fe6ab4d2bcbdc7e88b674e90ff4ea8caff9251d572ff0a7edb32a509d",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasi.tar.gz": "c0249f7a3e1f8275323adc2a49840cfc677ce8ac3365886753135703a9276572",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasi.tar.xz": "aad18dde6feaf251af10398b9e7ba2e39828a4640a8f30cc66ee72cd2b1278b3",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasip1-threads.tar.gz": "95f5700c74feeecea7705d90d3022637e4fa96ee5db165d8fc76d4db05101005",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasip1-threads.tar.xz": "6787b24af02a7216a524104379517a158938bc2c940b56a60be2ac143d3de7f8",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasip1.tar.gz": "38d2130daea2bd3c71a456e4dfc44ad900838d15a18af123bfe971f036b43951",
-    "dist/2024-03-19/rust-std-beta-wasm32-wasip1.tar.xz": "a766d6af0392e913f42930a02fbe5c7b481120ebceadf6b33c7c21ba6067c7f0",
-    "dist/2024-03-19/rust-std-beta-x86_64-apple-darwin.tar.gz": "3de58d464ee9cfd01d245016b752d1740f9b3feca7c84dddcfeeefd288a4966e",
-    "dist/2024-03-19/rust-std-beta-x86_64-apple-darwin.tar.xz": "8854dbc047727f11dcdc2f243536a5a6c5e7d8986c4ecea026820630aa2cce59",
-    "dist/2024-03-19/rust-std-beta-x86_64-apple-ios.tar.gz": "79477ea1afc524ed9d4f3ae57df132affe03a3fa7a14b17214181543918b2391",
-    "dist/2024-03-19/rust-std-beta-x86_64-apple-ios.tar.xz": "b830688a420e5631406b00d40756739d71a5f8f9789a4b6f4a601db167893814",
-    "dist/2024-03-19/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "ceb9ac35511e08cbd14dcf6c4faed57107f0facd5ebe1b1634f2ce2b41781c27",
-    "dist/2024-03-19/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "532b77cbb488b445e0291997a21d0a94c44970c5793ecca07eedca2dc4b02be7",
-    "dist/2024-03-19/rust-std-beta-x86_64-linux-android.tar.gz": "5333bf0c8ea592ed316e21bb2938ed07d247f0f873b45f34abcaa62f2e33f741",
-    "dist/2024-03-19/rust-std-beta-x86_64-linux-android.tar.xz": "ab18128d48a1eac2e8577e4268d95efe9619a4789cf4ee322d5bd651f33c24c1",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-solaris.tar.gz": "6976af5df3468680d83f54e87f57b94ac121ee82d7887e3e21200434b993a219",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-solaris.tar.xz": "932ffbff886919acb32f77ab70560a0262bbf5ee83a78679598ec13fcad39e3b",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "0429be318b55a9c36bc2fdb0b9654a3cf39527cb05d75f46890f6fcc2ed003a3",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7e3f64dc9b5b6653e6adbc58499857c0df8f1765d8fb777f6cb2ada3f40543d4",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "07a7bb2d07bb72693e0bf0ddc365394dde55063ad572259a5d171e08cda592f2",
-    "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "efc20d952b248815bda4ab3950b2998b5326e2c5008e72ede921eacb79b3b504",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "04a46c5cbfe620dc5d3d05134e0501aa466c081f848df679c554d51ecc6e8bb6",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "9ed41c7d0c09409fbecf33eab630ec847a4af7ea5bcaf42d8e14e1074ed30bf4",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "de0c88a91d325087e5c28e9ca5d3092443c875b55ed08b8486e8fd1c01c7b7e8",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "e403921f889381097628bcb2c431e3b8a8c0773c0d5062d4d1a9ec8e7f88fa45",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-illumos.tar.gz": "ee045b5102673d085fbeead4d5b9daeb9497f90d341bd51c8ac85b666e9c9821",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-illumos.tar.xz": "bd24fda28c9b69cc68c90b910a75cd652ad3b4d4430f802d8a2354c2cd5d19e7",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "8c70c2d12202054329cf6fca88adf20d9d9f493cb057c30211454a49f96ad4e5",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "ea6673ea519a6eba60836b810c0531cac858ca74d0d756538a45a375ffb7db9f",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "52e104ce39ac5e8e44fbb332bc08f7ac3d564408f48a459f79ba2149caf47b32",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "fa098772e186acba6e85ea2f4d0270f01e00cbdd27eec1e92cbda808b7807284",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "d6785e6574b4a7ba61f66c1e7938a46a02f9430983a7aee1c3400eb5f8b57f0f",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "17c3e8254fbfed0f0a9b3209976e44a136d0f581d0713ddf7114753cfd0b983d",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "407f9c2d5d3bd76698af04711d9a06b7aa86d4c55cee9d8ed1ce3aa37055068e",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "5e0869bf268c9824c284e841b2bf5a13a6dc1bd2e55ce3b7b09788ba5608c9dc",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "9b5aa240c2a696af0d342ec26a6b6ea4f5888070e8b590122379302910a978f8",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "064c1925a8ac82d1474c240c6c9414b422a7b04211a49a7660625193a0c21c64",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-none.tar.gz": "8e48a645b2b8dda6deb5b706e415697d303830775032b69521265acfc9f8608e",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-none.tar.xz": "a3d28304c75a71680d7d40aca43bf638bb4def5ec10f873aca5261692b114743",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-redox.tar.gz": "e645a81d4884f09c9d7da242ae448cadaf7a9232475707ece014a57d02a23527",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-redox.tar.xz": "0cf089464b1949a4f24092e2782b306e9530489cc415df69ae433c23a438518e",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-uefi.tar.gz": "ba7eec56d4e8a5f8a6c206b6a12fcae77da9a24ffea824c1db128dcd4a7d9fbe",
-    "dist/2024-03-19/rust-std-beta-x86_64-unknown-uefi.tar.xz": "76aa9bf6ed668667d1d47feb2fb8e941f5446f2ce5b4e94aacf34f964ebb3171",
-    "dist/2024-03-19/rustc-beta-aarch64-apple-darwin.tar.gz": "e40614daaa2b0270d5f3153c8216f68419b96dd167632dc67c1fd641ac0a21ff",
-    "dist/2024-03-19/rustc-beta-aarch64-apple-darwin.tar.xz": "7c2106ea1a3d358e2893a62fcc2162e041ecbdd9143f2dabbe0fa7a6b5827aaa",
-    "dist/2024-03-19/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "7eb0678bc1b4dfcf366641dbb02390262e47ecade1db9007ae1d5bbc39b6c7c6",
-    "dist/2024-03-19/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "0caef4825f0a6e51fd05c5c32365fb3a80a2b7692de71ff0af10ce9aea1ecafe",
-    "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "bbf59310c1e60725aebed09a09f0df4b1c21c2d0744f34734472e46cd7248fee",
-    "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "a7687c89bf94d64119ee76029ed12d27d594d7716fbf542852333185385a5b44",
-    "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "d2bda016eaf8b988e3b5899ab1239c582ef9119c40267b79be2efa453ceb9ee1",
-    "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "940f0611384175521401f352f4fc18a587b3816f99c88a0e130b895918c340a9",
-    "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "3ef861f5980f899b6575e50844c14ad30fe739f80538118acc8e29fd8b00cbed",
-    "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "191a2bb6966e05d1db83acafeb3caf0e0421eec539e221837e3dcff5e9db4152",
-    "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9999f60a513864257a14ee58ac3b87d9e557e0c2fe720a5d4ba31d250debc378",
-    "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "7c824f67a45aaeb7cf4c7519aa72ce8a81013cf2edec2fb5600f68aaf6eaf84e",
-    "dist/2024-03-19/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "83fa3927f92945845c6cc5a6f123ce5301a24af81c9371e5c6bcc8964a182688",
-    "dist/2024-03-19/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "3469f087248e671351dc0bdda06c1a9b8d12fc64854148cc9404d419db8fdb02",
-    "dist/2024-03-19/rustc-beta-i686-pc-windows-gnu.tar.gz": "a219c9829d7e33a822947faeb3f8826d7f2f5c46aeaa9c338bc27bf7b1561395",
-    "dist/2024-03-19/rustc-beta-i686-pc-windows-gnu.tar.xz": "ee5f30b90bc43738eb9c9a3678a09768bcffd3bed413c50ec23fa14fea1157ac",
-    "dist/2024-03-19/rustc-beta-i686-pc-windows-msvc.tar.gz": "acdc6345b76ed52b5b58d2832ae61c904aa6d74955f2e31432ab363f217397ec",
-    "dist/2024-03-19/rustc-beta-i686-pc-windows-msvc.tar.xz": "13161baa6a6e0771fcfb65b0e26f77a1ce07c5dcdb029a624723231d5d3c1012",
-    "dist/2024-03-19/rustc-beta-i686-unknown-linux-gnu.tar.gz": "7188f7c598cd4f1579ca06819cac5461679513ff648f03b7f28e15fd5636467e",
-    "dist/2024-03-19/rustc-beta-i686-unknown-linux-gnu.tar.xz": "42e03380ac0070f1cbf47c674c1d529cb065960f5e8c0f92e24a5f994dfeca83",
-    "dist/2024-03-19/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "67a57b0a8a057a1d39b99e5232145d7c5a48b9e3ff0e97b9ad1f4cbda004587b",
-    "dist/2024-03-19/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "1c85e17bd524294ac64c2defce82eae336cc3c5d9795dab68e0d7419ede35a6a",
-    "dist/2024-03-19/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "1c243f95e823164a4b112fef4a70bd3cb0f368dfbff7efd106b7ec3a718f49dc",
-    "dist/2024-03-19/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "318d69391381a142b72a27c6e53be624691e465ffec2497676c2454bdc06f856",
-    "dist/2024-03-19/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "f8423ac9a207c9a43746b9299dab7ff55a747aba1980313f98b5aef67e489d66",
-    "dist/2024-03-19/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "f6e3552a9ad8a90dc0830f7c8beaaf10c90e4760bcb48904d4197c53a54a8b1e",
-    "dist/2024-03-19/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "3ab2d798cf0812b874198691993686e9c884d24806628242110dacfa5bc3446a",
-    "dist/2024-03-19/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "6cae9a4e5e88054800f11f028b92211173de4038ad1bb0a871cdd05bc6a0b8c1",
-    "dist/2024-03-19/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "368351e98c1e71b3fe40c687f478d52a43ba388811521e7807b314d750cb4f65",
-    "dist/2024-03-19/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "116171252c2f153066e9f8fa6eb1e63962aebdd67d14368560200c984ae38ccf",
-    "dist/2024-03-19/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "0445ba1954a7e6bbaf64561a33c01988a4f48aa8401669acd7c5e8ac11d27696",
-    "dist/2024-03-19/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "23aeed13a2c0143d14ab9fb26be47314318ee3014190ba08f5889bed14205799",
-    "dist/2024-03-19/rustc-beta-x86_64-apple-darwin.tar.gz": "91a1040d4b0d309fadae1b180c5cdf30c9c073245599064a075849795a8c84d6",
-    "dist/2024-03-19/rustc-beta-x86_64-apple-darwin.tar.xz": "996bb8bf522509e5ddf5e2d4fdfe0c19d4198605107575faba4a80e1f4de616c",
-    "dist/2024-03-19/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "82024a5d02148c7a0a0309105114f54dcdc6b9bb763d1e0456f0c18f96b16f57",
-    "dist/2024-03-19/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "b6c00535af0ef5815cfaf88bcf21b83935539785345b22abeb9d4fa97e2cc445",
-    "dist/2024-03-19/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "409a22e9a1ae89640059cb33d614abe84eef4096817b0fa750b3a38e0a153061",
-    "dist/2024-03-19/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "8fcc030bcbafdcfbd894653ce935ecb82fc04b3717718d34dd6b2a4e8d553889",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-freebsd.tar.gz": "79d39890188af98e9eaa1b5a15606517ad7e0b3c493bad09a59c5400bfff3d9d",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b69b370559cdf73f26b83a4b5276d10988f44d39d57608c44defa6b79f92121d",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-illumos.tar.gz": "f4bc2b510a230a09bae4b243f1297863907c9239a94bdf739f43c31a76238a04",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-illumos.tar.xz": "131b02eab07b50d8a99e0185090afd6c3fd1bd20b98fc0a4830910fea5b12ec5",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ed9d98b20a4868330c88563ec367078a4c5ed7bca497680ea690cb9da2d6ddbc",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "b6c0fec4e295b8eec2b7c8bbddec48aaba1d3c4d73803eaf887554d368b4efa5",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "e972c5ec3f9cc2661845bbb2e7153b9e90e59af2d4fcd74c588e3f326bbe9e6c",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "d576799dcd59b48ddb6d96545ec48ef517b5a7d9875033de6583387fc1d4b79a",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-netbsd.tar.gz": "39f5a43f70692f1bcfc6b82ef901fa86be82aa7db0f6161ea5025577976a0780",
-    "dist/2024-03-19/rustc-beta-x86_64-unknown-netbsd.tar.xz": "596e6681bb15420754ab1a7210157884f5e31b34a885b1d1cfcb8838ba5c28b3",
-    "dist/2024-03-19/rustc-nightly-aarch64-apple-darwin.tar.gz": "f91204bc62d9236adc75e2a7ba4ae41e0d9ea9c6b6bcaf0d211459cfc7d17d21",
-    "dist/2024-03-19/rustc-nightly-aarch64-apple-darwin.tar.xz": "7562f89f9bc9f2968ddcef0258cd5a1435855d87a1c40b9ead6b82c1cb5c58c3",
-    "dist/2024-03-19/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "2f1ab532837469eba7dca3cb4b45ce983384e30917b0af3108d2a8c7c88f38c5",
-    "dist/2024-03-19/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "fa69006e8189b1e624e0d9a9a212c15423fc1b428785f651a309eae045199f11",
-    "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "21905a47c616e3e43b05135621c17db635dfa897e2e64b124c03b042f74dff00",
-    "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "1efea63747a88b3baefe6602e047e84323867a3eeb77093b9e662ff254a85f28",
-    "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "1b693de287b60428bc1a0a23088c08680db2d0fbf4f7cf0d6e3f413cd9cfb150",
-    "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "7803e124610ad092f88b7cf4b65cd3fa1a80cb2cf5a36fe4391535ca4f3d9369",
-    "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "744bef406b6df5c610b605234375d8520abe24d8407b8bd22a0fe15de41d62b6",
-    "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "b90dc87a68c134e6fcdaa3ea20e9d0fc33b0422e4dc989c1cf0c85c8140fdfce",
-    "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "e235fd3258b7d1e42ff6609f1660a94aaafc00875c371543ad2b12ae226dd8c7",
-    "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b37ea15820c88ae1ab534277f8f7a7ad18b3d365f1d2d499a887665b715c6c21",
-    "dist/2024-03-19/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bf7cb8f0b21f2b0b8b067f88e31a2ce9e5754044b68437d4d52324fd95010161",
-    "dist/2024-03-19/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "3595940730b4cbcb00e0441458b07253677d148f4850b464d6df7706c203d1aa",
-    "dist/2024-03-19/rustc-nightly-i686-pc-windows-gnu.tar.gz": "3135f03a8388c13c6439ef0464e2086949a528cee7bebdfb955defd59e55952d",
-    "dist/2024-03-19/rustc-nightly-i686-pc-windows-gnu.tar.xz": "54b6ca29f64e454189f27135f9a40f0bc0d0b5abf4d2912aeb857f733721005e",
-    "dist/2024-03-19/rustc-nightly-i686-pc-windows-msvc.tar.gz": "d3b70b07c8c9cedd30dbebfff2bfe45316752a13d49c9feedfdae4f71bb74865",
-    "dist/2024-03-19/rustc-nightly-i686-pc-windows-msvc.tar.xz": "653a821d9a7789e19fdd32f82466e906c23e03e42752f7277c05b692c1459e20",
-    "dist/2024-03-19/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "4a37e87a3280997bb09deb6a3617395b1e898ecd07f0bd5469cb21e55c3c5f81",
-    "dist/2024-03-19/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "a66bd9287cc958a61f9989d5efb6162255f7eb9211af9a4ea98769971350384b",
-    "dist/2024-03-19/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "3ce931c54c96c72034392efcbcd73061d6f8a7c7f40f1e86c14ae6fd5248d2a6",
-    "dist/2024-03-19/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "cab19b60b91cd6549f89398f46b31fe440323c9669606f48a4029e8d3cdc1ee5",
-    "dist/2024-03-19/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "3d50b95e8f9ce5a2721e1ba0649378e8426fc4ba531bfa13bd9b96ef627aa46d",
-    "dist/2024-03-19/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "9286d55547a438008574267cc3a067ca50005a9397bf8aeccd76ea27233de2fe",
-    "dist/2024-03-19/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "61843b55a45909408b3005cee338de42d31aef852155c8bcd8f6cf9aa3077dfa",
-    "dist/2024-03-19/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "2de14af7b540c3302e6b1a0f77472362429c0a1a0026c2fc799b263817e3c942",
-    "dist/2024-03-19/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "816575061e2879d6855fa497b3bbced57f3201d64c6649c89ba9020c69889fd6",
-    "dist/2024-03-19/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "58962496e51cdc60f9a98fb2fdbbb2f4124beb3fdbb065cc6b52871eb4bdc2f9",
-    "dist/2024-03-19/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "cd649970e9b8a98e9dd0c1f506624832cb08516aa9cfd001381ad265cc42ee66",
-    "dist/2024-03-19/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "1a9a2bcdd263a205bd85c8fbb9733711ceeee372953a7573420fcb55d59d59b0",
-    "dist/2024-03-19/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "98d6631c6dbca97491d5f518dceddc07c53aa309c7db8da0a919eed96f9e45bd",
-    "dist/2024-03-19/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "ee1fcc2a1d3181c2a7b97df8525363159c47b1348c0db78f74c7181ad6c44166",
-    "dist/2024-03-19/rustc-nightly-x86_64-apple-darwin.tar.gz": "c2768511ca6e9c228e13815040eb56f43ba1ec223c7753ea0e613400989a20d9",
-    "dist/2024-03-19/rustc-nightly-x86_64-apple-darwin.tar.xz": "6c10e9e824d1bc7a3c75172375e3490e33627bcaef6315552147b89b81ecf328",
-    "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "6d3a1f7c97fd4115b524f990426b795be1b9ca9a10fc6fd68db1cf4355d3953b",
-    "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "86fbb08c51664be63b234b82894b1b8012d8f6bbbbd96b6fc7188c22b887049e",
-    "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "39b673d694aee6c5d25ba88ba7e9f38b6264f01ed6a5785ea44e07594b9a7d1a",
-    "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "43ebc08539300d736d1d41af2306b1bbcb0d9e04795033725807d4c9c06d590a",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "cd263eb4b6e027b834723f3748139db6f1742f885c2cfa2a4842c23c806b48fc",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "22fc109ec6293b799fd52398b72f90966b9efb95c433f826e31f54fe643132cb",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-illumos.tar.gz": "20b01c262d54731c471d6dd856fbe8c9a58674f88d0dea19c7e9b7adff6b5474",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-illumos.tar.xz": "584d1e3b9e6e2006767a6a1a46aacff34a2042b4094e51be0a1a82a50a4ab27e",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "71b98f184c4b3f3a40c5ab7cf6bdae6947a39c2a7e36e590750a37806cd98a2f",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "44510c19128801a465c70fbb4d1fa0250edd7c1ff0a67f1c374f1d921e1a4bb8",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "897728aae12523d33bad792c4275512383ae5cff008860406882ebeb273cca5a",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "b027abf370ef289d6b2e615dcafac3eda20c147dd2ac4a3c113e8689f6936655",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "97360bb700ee986b0a36ac4ed4f0fbcf3c875907bb6cfdbe4bfa0274893109f5",
-    "dist/2024-03-19/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "e8414dc178f2d1939b2d6411beda7bc6f8e9b7f500ccb30fc8a8659ddc0f945f",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "8515050a52addca9d5c0ea8b9f4e5c536d32ed275fd0922cbe567fbf7d5adcb6",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "97c68112bd8f4cd67eef50c994dd13967482ac1e55170dfd11d8505c582c689d",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "b3ff60427dfa13e3c9d4965e0f197ac2a0625fe64cb1e23ec46604adbafdc847",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "848938bd1436276ba813104cde9d969cbcd79d295eb045ced1d82080cdbae29f",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "063f25121c6a8055228763240f178b7f1e9b55f20b305b8e2ebc1b0a080e432d",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "89ab3a28357f3926fa4880010d0ec6b6fce06476050f42c71416c60528490f7b",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "6ece90be16f59b3a5871d8cee8638e18c233eb0e59253875e71bd16ee4c7eb76",
-    "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "7272af79200e1da8ab80b2e4408501ef8a54c24ba44420aaab0fb03653933ad6",
-    "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "7ba3404ab333e43dbacfda6d8860d800721a7f894c672d3ea88cb88127128c90",
-    "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "bd4087d9e70c0246c0606015c1e6d6b974c068118e50e2720c7ac75a6d338709",
-    "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "f87c7036539d18881cc0ad5647b523dd07cd29cd38c36665aacbdb37de316231",
-    "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "cd1b05cde5ccfc389df6d146f467a18455f22c7f23e508537c8de11b8d7aea4f",
-    "dist/2024-03-19/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "66b0bdfb271448861ccc403d7549b49316c5cda81bbdaa396ff66c01dfb052df",
-    "dist/2024-03-19/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "40e3df123160c8948ed06c8228df90de1368d286f9849a0a14de0725167dc8dc",
-    "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "da09c72f472b6bdbf7e794d84990153936ad1c7d275daa75b506ab72444b51a0",
-    "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "c9e2ea2216c4f7737919c63ed0e5ca362f6c3c9f227f1b3e6a243a870f229a52",
-    "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "ba468a1251b4bdb685cf5437222ccea45ba1f4d1b25ca65b82a9fae4ba93d6d9",
-    "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "64781d2017662c9973a22d322c92b242703a90895cefa584035b0d80ac966541",
-    "dist/2024-03-19/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "595fcdf3cf5b2511ec828936119334516d535c4dea95f60a04eaf1724a90a276",
-    "dist/2024-03-19/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "42f2537e87adc2cadee67e5dc1fd7fee4c7bf4347f88501752080a65b9e7fd89",
-    "dist/2024-03-19/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "3ecbee26e0b0cc43189dbd8d69a563bf71292974d0c5d313528a32012f38fb56",
-    "dist/2024-03-19/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "7a0918c6ad0dcdddac757c7f4580fa57ca188ff2edbf7eac07ce01626666bc95",
-    "dist/2024-03-19/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "08197220ca270180ff4d7f484000f6b7a52800e932937238cbf1f47ce3f1080f",
-    "dist/2024-03-19/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "dc7f03fa39872e59fab5f4d663ed092409849c62c8e4c958c6cd4ed59bc05902",
-    "dist/2024-03-19/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "c7744b4c88a5ac7ddbaa1b61b66b39f2799863c50b6e18c18874d5774d11fe53",
-    "dist/2024-03-19/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "0ed8aa4704e7d665843ea1ac532b1631cbf449180331d880466fc69483d4cd23",
-    "dist/2024-03-19/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "e67d83663cb54168fded400385a5cdf8b74c6483d91fd16d03846a6411ab1afb",
-    "dist/2024-03-19/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "fe4c2401281c07d1c3ed335575bd192ac57396973a3676226d57e5de32a63e3d",
-    "dist/2024-03-19/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "39c4739ef0281bb1eeade5c8f7360ee8dde5a8a7ae148b0f263ba650d092cced",
-    "dist/2024-03-19/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ea26063a71a4403a4aa49098a96a29b48aab5f9b9177e57b1790b92ed749ae1b",
-    "dist/2024-03-19/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "49591c34bcb82d6cc5c08c662c4c89aca07b406fa1b48b78c7dbcb63cbe6fb5c",
-    "dist/2024-03-19/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "df664d781e8104015c506178df751ba7130c677f050cae695428fbb6180b1af8",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "ff20c34ab85505c1957a677eb8123622c98f5e19e87cfa38eae76232e200242b",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "c4e8b76738bbfddf94defb88e9b0c0d0c488d9a5868f2be629322c041391b43c",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "8e0367ab0700e916956db6041e1c6a35b0c6fbd1127a17f9482691a103dc8d70",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "1aad45bb09a907effb39378acf5c57c741d7b0e29eec957d8be31eb1bf47ab23",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "f5fa93652040ba991c429d11c5e9ae2e76aa6f21f6850a777f2ba1b065e943fe",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "7d448e8ae9090467197d9bfc7ac3d8f7ab81cfdfd0be140afdbbbc6c3cf65295",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "8ea5bc3f374b5b63432151541715ab41d00f265e6cc8e57c61e175304363ca5e",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "666deba3f55f30e302642b3e2d3c86bdce12626ae78bb7134c7d90b1c7179592",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "edf75305baace32ab2955131357e30c73c736d823d6426125e5fde213c8f4c61",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "5b3ebd05d571474002c032aa2fedc788650d374b388eff9f6c00cf5bcdd10c08",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "e795bb7cfde3d71f9e964dbc9efd930251eb3209686d5c9348f24deecb01fcde",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "8e1c06e91fe7cd1ffa80f043b8342c611d8f923cc9b563fda0155855d8799660",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "a8a51ce3eceed87d192701abb699dc60dd3c28c86622b9aa3dae833feb8207ef",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "389cd5d4c0decb87eb24b9ce88d5e5f33a7292153e2eb37ca2a106e4f8a4e256",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "cbbdca68aa3ff10fb28d431ddd08b56bb4f0a0f85ebaf7c094b9740c8e2d1aa2",
-    "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "e1c1793bfd102241338f801ba8c28f83d15fafef09046b231e30d1ac42b5e372"
+    "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz": "5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb",
+    "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz": "0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2",
+    "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f",
+    "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb",
+    "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c",
+    "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81",
+    "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891",
+    "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c",
+    "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7",
+    "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486",
+    "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121",
+    "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c",
+    "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e",
+    "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c",
+    "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz": "d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84",
+    "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz": "65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db",
+    "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz": "d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403",
+    "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz": "23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba",
+    "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz": "b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c",
+    "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz": "6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9",
+    "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae",
+    "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da",
+    "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d",
+    "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c",
+    "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c",
+    "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3",
+    "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9",
+    "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f",
+    "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3",
+    "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a",
+    "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e",
+    "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee",
+    "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz": "f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791",
+    "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz": "96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05",
+    "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145",
+    "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317",
+    "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e",
+    "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz": "9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz": "7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz": "4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz": "0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz": "f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a",
+    "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz": "53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40",
+    "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz": "7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c",
+    "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz": "2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62",
+    "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736",
+    "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b",
+    "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73",
+    "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807",
+    "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b",
+    "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e",
+    "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03",
+    "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a",
+    "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399",
+    "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5",
+    "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd",
+    "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a",
+    "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz": "325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588",
+    "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz": "536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123",
+    "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz": "c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b",
+    "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz": "0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245",
+    "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511",
+    "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz": "6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304",
+    "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93",
+    "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514",
+    "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6",
+    "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8",
+    "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737",
+    "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf",
+    "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4",
+    "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e",
+    "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9",
+    "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f",
+    "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7",
+    "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1",
+    "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz": "9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326",
+    "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz": "49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af",
+    "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6",
+    "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb",
+    "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab",
+    "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz": "509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz": "2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz": "ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz": "5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz": "1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328",
+    "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz": "da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz": "2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz": "bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz": "56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751",
+    "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz": "3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163",
+    "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz": "bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03",
+    "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz": "46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de",
+    "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz": "9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d",
+    "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz": "87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8",
+    "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df",
+    "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz": "96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz": "3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz": "8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2",
+    "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz": "80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff",
+    "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz": "2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de",
+    "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz": "9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41",
+    "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729",
+    "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz": "345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5",
+    "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz": "6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65",
+    "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz": "a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423",
+    "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz": "3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae",
+    "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554",
+    "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a",
+    "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4",
+    "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c",
+    "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz": "6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f",
+    "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz": "9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4",
+    "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc",
+    "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz": "cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8",
+    "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz": "8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f",
+    "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz": "e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4",
+    "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz": "d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab",
+    "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz": "1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1",
+    "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz": "4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0",
+    "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz": "ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8",
+    "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz": "fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2",
+    "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568",
+    "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b",
+    "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz": "26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e",
+    "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz": "c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065",
+    "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz": "f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea",
+    "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz": "f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz": "8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz": "4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz": "cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz": "95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08",
+    "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz": "a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz": "d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz": "4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz": "dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz": "f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz": "3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887",
+    "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz": "72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz": "e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b",
+    "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz": "364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9",
+    "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a",
+    "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c",
+    "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39",
+    "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60",
+    "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270",
+    "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49",
+    "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7",
+    "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af",
+    "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd",
+    "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52",
+    "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz": "2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a",
+    "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz": "2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a",
+    "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c",
+    "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab",
+    "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271",
+    "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec",
+    "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17",
+    "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320",
+    "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63",
+    "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0",
+    "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d",
+    "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba",
+    "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5",
+    "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657",
+    "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6",
+    "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd",
+    "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7",
+    "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa",
+    "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz": "25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9",
+    "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz": "5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554",
+    "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz": "a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d",
+    "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz": "4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18",
+    "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz": "32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5",
+    "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz": "112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b",
+    "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12",
+    "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36",
+    "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz": "518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845",
+    "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz": "2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394",
+    "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17",
+    "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3",
+    "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc",
+    "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81",
+    "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb",
+    "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709",
+    "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07",
+    "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz": "7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0",
+    "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz": "d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz": "07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz": "79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz": "b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz": "2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz": "792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0",
+    "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz": "abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e",
+    "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz": "0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b",
+    "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz": "c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045",
+    "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz": "7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0",
+    "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz": "f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2",
+    "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556",
+    "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e",
+    "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz": "5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f",
+    "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz": "9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz": "d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz": "6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz": "ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz": "30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710",
+    "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz": "9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz": "d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz": "5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz": "0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz": "b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz": "24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1",
+    "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz": "1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc",
+    "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz": "ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2",
+    "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz": "e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4",
+    "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13",
+    "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df",
+    "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9",
+    "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9",
+    "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd",
+    "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1",
+    "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b",
+    "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085",
+    "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a",
+    "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc",
+    "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd",
+    "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc",
+    "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz": "de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1",
+    "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz": "a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b",
+    "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz": "88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db",
+    "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz": "1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9",
+    "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz": "3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18",
+    "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f",
+    "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b",
+    "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2",
+    "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec",
+    "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f",
+    "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651",
+    "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201",
+    "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249",
+    "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a",
+    "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71",
+    "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb",
+    "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a",
+    "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d",
+    "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz": "59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3",
+    "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz": "f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff",
+    "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1",
+    "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6",
+    "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8",
+    "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz": "38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz": "786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz": "7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz": "bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz": "4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf",
+    "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz": "45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1",
+    "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz": "0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f",
+    "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz": "143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46",
+    "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e",
+    "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a",
+    "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d",
+    "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4",
+    "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99",
+    "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8",
+    "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45",
+    "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2",
+    "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783",
+    "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37",
+    "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914",
+    "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98",
+    "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz": "a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58",
+    "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz": "4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54",
+    "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz": "1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4",
+    "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz": "27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7",
+    "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a",
+    "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad",
+    "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15",
+    "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c",
+    "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c",
+    "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272",
+    "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa",
+    "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c",
+    "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b",
+    "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e",
+    "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1",
+    "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed",
+    "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be",
+    "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb",
+    "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz": "64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c",
+    "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz": "0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030",
+    "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939",
+    "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707",
+    "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1",
+    "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz": "7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz": "d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a",
+    "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0",
+    "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2",
+    "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5",
+    "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02",
+    "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691",
+    "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb",
+    "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f",
+    "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec",
+    "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a",
+    "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0",
+    "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39",
+    "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942",
+    "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf",
+    "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e",
+    "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd",
+    "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57",
+    "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac",
+    "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08",
+    "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8",
+    "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e",
+    "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87",
+    "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c",
+    "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5",
+    "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20",
+    "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd",
+    "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74",
+    "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308"
   }
 }
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject c9392675917adc2edab269eea27c222b5359c63
+Subproject 6087566b3fa73bfda29702632493e938b12d19e
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index bd3a04e34ae..9c9ea114081 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,62 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[66c29b97...master](https://github.com/rust-lang/rust-clippy/compare/66c29b97...master)
+[93f0a9a9...master](https://github.com/rust-lang/rust-clippy/compare/93f0a9a9...master)
+
+## Rust 1.78
+
+Current stable, released 2024-05-02
+
+[View all 112 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-01-26T05%3A46%3A23Z..2024-03-07T16%3A25%3A52Z+base%3Amaster)
+
+### New Lints
+
+* [`assigning_clones`]
+  [#12077](https://github.com/rust-lang/rust-clippy/pull/12077)
+* [`mixed_attributes_style`]
+  [#12354](https://github.com/rust-lang/rust-clippy/pull/12354)
+* [`empty_docs`]
+  [#12342](https://github.com/rust-lang/rust-clippy/pull/12342)
+* [`unnecessary_get_then_check`]
+  [#12339](https://github.com/rust-lang/rust-clippy/pull/12339)
+* [`multiple_bound_locations`]
+  [#12259](https://github.com/rust-lang/rust-clippy/pull/12259)
+* [`unnecessary_clippy_cfg`]
+  [#12303](https://github.com/rust-lang/rust-clippy/pull/12303)
+* [`deprecated_clippy_cfg_attr`]
+  [#12292](https://github.com/rust-lang/rust-clippy/pull/12292)
+* [`manual_c_str_literals`]
+  [#11919](https://github.com/rust-lang/rust-clippy/pull/11919)
+* [`ref_as_ptr`]
+  [#12087](https://github.com/rust-lang/rust-clippy/pull/12087)
+* [`lint_groups_priority`]
+  [#11832](https://github.com/rust-lang/rust-clippy/pull/11832)
+* [`unnecessary_result_map_or_else`]
+  [#12169](https://github.com/rust-lang/rust-clippy/pull/12169)
+* [`to_string_trait_impl`]
+  [#12122](https://github.com/rust-lang/rust-clippy/pull/12122)
+* [`incompatible_msrv`]
+  [#12160](https://github.com/rust-lang/rust-clippy/pull/12160)
+
+### Enhancements
+
+* [`thread_local_initializer_can_be_made_const`]: Now checks the [`msrv`] configuration
+  [#12405](https://github.com/rust-lang/rust-clippy/pull/12405)
+* [`disallowed_macros`]: Code generated by derive macros can no longer allow this lint
+  [#12267](https://github.com/rust-lang/rust-clippy/pull/12267)
+* [`wildcard_imports`]: Add configuration [`allowed-wildcard-imports`] to allow preconfigured wildcards
+  [#11979](https://github.com/rust-lang/rust-clippy/pull/11979)
+
+### ICE Fixes
+
+* [`ptr_as_ptr`]: No longer ICEs when the cast source is a function call to a local variable
+  [#12617](https://github.com/rust-lang/rust-clippy/pull/12617)
+* [`cast_sign_loss`]: Avoids an infinite loop when casting two chained `.unwrap()` calls
+  [#12508](https://github.com/rust-lang/rust-clippy/pull/12508)
 
 ## Rust 1.77
 
-Current stable, released 2024-03-18
+Released 2024-03-18
 
 [View all 93 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-12-16T18%3A20%3A00Z..2024-01-25T18%3A15%3A56Z+base%3Amaster)
 
@@ -5891,6 +5942,7 @@ Released 2018-09-13
 [`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
 [`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
 [`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
+[`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests
 [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
 [`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
 [`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 43f20ecedc2..b48f3ab3919 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.79"
+version = "0.1.80"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -30,7 +30,7 @@ color-print = "0.3.4"
 anstream = "0.6.0"
 
 [dev-dependencies]
-ui_test = "0.22.2"
+ui_test = "0.23"
 regex = "1.5.5"
 toml = "0.7.3"
 walkdir = "2.3"
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index b80ac6370e7..415022612ca 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -299,10 +299,10 @@ This is good, because it makes writing this particular lint less complicated.
 We have to make this decision with every new Clippy lint. It boils down to using
 either [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].
 
-In short, the `LateLintPass` has access to type information while the
-`EarlyLintPass` doesn't. If you don't need access to type information, use the
-`EarlyLintPass`. The `EarlyLintPass` is also faster. However, linting speed
-hasn't really been a concern with Clippy so far.
+In short, the `EarlyLintPass` runs before type checking and
+[HIR](https://rustc-dev-guide.rust-lang.org/hir.html) lowering and the `LateLintPass`
+has access to type information. Consider using the `LateLintPass` unless you need
+something specific from the `EarlyLintPass`.
 
 Since we don't need type information for checking the function name, we used
 `--pass=early` when running the new lint automation and all the imports were
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 7cefa685264..f6af9810ca1 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -132,6 +132,16 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
 * [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
 
 
+## `allow-useless-vec-in-tests`
+Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
+
+**Default Value:** `false`
+
+---
+**Affected lints:**
+* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
+
+
 ## `allowed-dotfiles`
 Additional dotfiles (files or directories starting with a dot) to allow
 
@@ -506,13 +516,14 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large
 
 
 ## `ignore-interior-mutability`
-A list of paths to types that should be treated like `Arc`, i.e. ignored but
-for the generic parameters for determining interior mutability
+A list of paths to types that should be treated as if they do not contain interior mutability
 
 **Default Value:** `["bytes::Bytes"]`
 
 ---
 **Affected lints:**
+* [`borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const)
+* [`declare_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const)
 * [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
 * [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
 
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index 8ba2ab56625..7f7dc9d6cfb 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_config"
-version = "0.1.79"
+version = "0.1.80"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 781282213cc..5cfcbdb57d7 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -463,14 +463,17 @@ define_Conf! {
     ///
     /// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
     (allow_print_in_tests: bool = false),
+    /// Lint: USELESS_VEC.
+    ///
+    /// Whether `useless_vec` should ignore test functions or `#[cfg(test)]`
+    (allow_useless_vec_in_tests: bool = false),
     /// Lint: RESULT_LARGE_ERR.
     ///
     /// The maximum size of the `Err`-variant in a `Result` returned from a function
     (large_error_threshold: u64 = 128),
-    /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND.
+    /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND, BORROW_INTERIOR_MUTABLE_CONST, DECLARE_INTERIOR_MUTABLE_CONST.
     ///
-    /// A list of paths to types that should be treated like `Arc`, i.e. ignored but
-    /// for the generic parameters for determining interior mutability
+    /// A list of paths to types that should be treated as if they do not contain interior mutability
     (ignore_interior_mutability: Vec<String> = Vec::from(["bytes::Bytes".into()])),
     /// Lint: UNINLINED_FORMAT_ARGS.
     ///
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index 59dd5b334b8..14808440d48 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -23,7 +23,7 @@ msrv_aliases! {
     1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
     1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
-    1,63,0 { ASSIGNING_CLONES }
+    1,63,0 { CLONE_INTO }
     1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
     1,59,0 { THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST }
     1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 1d954607eee..5e3a119337c 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.79"
+version = "0.1.80"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index dc7f44af2b7..f0dafb1ae0d 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -45,7 +45,7 @@ declare_clippy_lint! {
     ///     a.clone_from(&b);
     /// }
     /// ```
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub ASSIGNING_CLONES,
     perf,
     "assigning the result of cloning may be inefficient"
@@ -153,7 +153,7 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<
 fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>, msrv: &Msrv) -> bool {
     // For calls to .to_owned we suggest using .clone_into(), which was only stablilized in 1.63.
     // If the current MSRV is below that, don't suggest the lint.
-    if !msrv.meets(msrvs::ASSIGNING_CLONES) && matches!(call.target, TargetTrait::ToOwned) {
+    if !msrv.meets(msrvs::CLONE_INTO) && matches!(call.target, TargetTrait::ToOwned) {
         return false;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index 4062212f408..8459f051d3d 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -121,9 +121,9 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
             if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
                 && let Some(sig) = expr_sig(cx, path)
                 && let Some(input) = sig.input(index)
-                && !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait()
+                && let Some(input_ty) = input.no_bound_vars()
             {
-                input.no_bound_vars().is_some()
+                input_ty == cx.typeck_results().expr_ty_adjusted(expr)
             } else {
                 false
             }
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index ca7fa4e5a41..593bc6c81ee 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -197,7 +197,7 @@ declare_clippy_lint! {
     /// pedantic = { level = "warn", priority = -1 }
     /// similar_names = "allow"
     /// ```
-    #[clippy::version = "1.76.0"]
+    #[clippy::version = "1.78.0"]
     pub LINT_GROUPS_PRIORITY,
     correctness,
     "a lint group in `Cargo.toml` at the same priority as a lint"
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 dbfa8e1ee91..7c5acd1a678 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
@@ -40,9 +40,14 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
                     get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))
                 })
             },
-            BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
+            BinOpKind::Rem => get_constant_bits(cx, right)
                 .unwrap_or(u64::MAX)
                 .min(apply_reductions(cx, nbits, left, signed)),
+            BinOpKind::BitAnd => get_constant_bits(cx, right)
+                .unwrap_or(u64::MAX)
+                .min(get_constant_bits(cx, left).unwrap_or(u64::MAX))
+                .min(apply_reductions(cx, nbits, right, signed))
+                .min(apply_reductions(cx, nbits, left, signed)),
             BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
                 .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),
             _ => nbits,
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index d14898a8196..bd2c96f01f6 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -708,7 +708,7 @@ declare_clippy_lint! {
     /// let a_ref = &1;
     /// let a_ptr = std::ptr::from_ref(a_ref);
     /// ```
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub REF_AS_PTR,
     pedantic,
     "using `as` to cast a reference to pointer"
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 6942ca53640..70856b80881 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,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
-use clippy_utils::visitors::for_each_expr_with_closures;
+use clippy_utils::visitors::{for_each_expr_with_closures, Visitable};
 use clippy_utils::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
-use rustc_hir::{Block, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
+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;
@@ -77,7 +77,7 @@ fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections:
         || is_type_lang_item(cx, ty, LangItem::String)
 }
 
-fn has_no_read_access<'tcx>(cx: &LateContext<'tcx>, id: HirId, block: &'tcx Block<'tcx>) -> bool {
+fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool {
     let mut has_access = false;
     let mut has_read_access = false;
 
@@ -109,11 +109,30 @@ fn has_no_read_access<'tcx>(cx: &LateContext<'tcx>, id: HirId, block: &'tcx Bloc
         // traits (identified as local, based on the orphan rule), pessimistically assume that they might
         // have side effects, so consider them a read.
         if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)
-            && let ExprKind::MethodCall(_, receiver, _, _) = parent.kind
+            && let ExprKind::MethodCall(_, receiver, args, _) = parent.kind
             && path_to_local_id(receiver, id)
             && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
             && !method_def_id.is_local()
         {
+            // If this "official" method takes closures,
+            // it has read access if one of the closures has read access.
+            //
+            // items.retain(|item| send_item(item).is_ok());
+            let is_read_in_closure_arg = args.iter().any(|arg| {
+                if let ExprKind::Closure(closure) = arg.kind
+                    // To keep things simple, we only check the first param to see if its read.
+                    && let Body { params: [param, ..], value } = cx.tcx.hir().body(closure.body)
+                {
+                    !has_no_read_access(cx, param.hir_id, *value)
+                } else {
+                    false
+                }
+            });
+            if is_read_in_closure_arg {
+                has_read_access = true;
+                return ControlFlow::Break(());
+            }
+
             // The method call is a statement, so the return value is not used. That's not a read access:
             //
             // id.foo(args);
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index acdcb54be27..ccf1d9d6f8c 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -1,15 +1,14 @@
 use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
 use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
-use clippy_utils::ty::{is_interior_mut_ty, needs_ordered_drop};
+use clippy_utils::ty::{needs_ordered_drop, InteriorMut};
 use clippy_utils::visitors::for_each_expr;
 use clippy_utils::{
-    capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt,
-    if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq,
+    capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence,
+    is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq,
 };
 use core::iter;
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
-use rustc_hir::def_id::DefIdSet;
 use rustc_hir::{intravisit, BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -159,40 +158,36 @@ declare_clippy_lint! {
     "`if` statement with shared code in all blocks"
 }
 
-pub struct CopyAndPaste {
+pub struct CopyAndPaste<'tcx> {
     ignore_interior_mutability: Vec<String>,
-    ignored_ty_ids: DefIdSet,
+    interior_mut: InteriorMut<'tcx>,
 }
 
-impl CopyAndPaste {
+impl CopyAndPaste<'_> {
     pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
         Self {
             ignore_interior_mutability,
-            ignored_ty_ids: DefIdSet::new(),
+            interior_mut: InteriorMut::default(),
         }
     }
 }
 
-impl_lint_pass!(CopyAndPaste => [
+impl_lint_pass!(CopyAndPaste<'_> => [
     IFS_SAME_COND,
     SAME_FUNCTIONS_IN_IF_CONDITION,
     IF_SAME_THEN_ELSE,
     BRANCHES_SHARING_CODE
 ]);
 
-impl<'tcx> LateLintPass<'tcx> for CopyAndPaste {
+impl<'tcx> LateLintPass<'tcx> for CopyAndPaste<'tcx> {
     fn check_crate(&mut self, cx: &LateContext<'tcx>) {
-        for ignored_ty in &self.ignore_interior_mutability {
-            let path: Vec<&str> = ignored_ty.split("::").collect();
-            for id in def_path_def_ids(cx, path.as_slice()) {
-                self.ignored_ty_ids.insert(id);
-            }
-        }
+        self.interior_mut = InteriorMut::new(cx, &self.ignore_interior_mutability);
     }
+
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) {
             let (conds, blocks) = if_sequence(expr);
-            lint_same_cond(cx, &conds, &self.ignored_ty_ids);
+            lint_same_cond(cx, &conds, &mut self.interior_mut);
             lint_same_fns_in_if_cond(cx, &conds);
             let all_same =
                 !is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && lint_if_same_then_else(cx, &conds, &blocks);
@@ -570,13 +565,14 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
     })
 }
 
-fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignored_ty_ids: &DefIdSet) -> bool {
+fn method_caller_is_mutable<'tcx>(
+    cx: &LateContext<'tcx>,
+    caller_expr: &Expr<'_>,
+    interior_mut: &mut InteriorMut<'tcx>,
+) -> bool {
     let caller_ty = cx.typeck_results().expr_ty(caller_expr);
-    // Check if given type has inner mutability and was not set to ignored by the configuration
-    let is_inner_mut_ty = is_interior_mut_ty(cx, caller_ty)
-        && !matches!(caller_ty.ty_adt_def(), Some(adt) if ignored_ty_ids.contains(&adt.did()));
 
-    is_inner_mut_ty
+    interior_mut.is_interior_mut_ty(cx, caller_ty)
         || caller_ty.is_mutable_ptr()
         // `find_binding_init` will return the binding iff its not mutable
         || path_to_local(caller_expr)
@@ -585,7 +581,7 @@ fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignore
 }
 
 /// Implementation of `IFS_SAME_COND`.
-fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &DefIdSet) {
+fn lint_same_cond<'tcx>(cx: &LateContext<'tcx>, conds: &[&Expr<'_>], interior_mut: &mut InteriorMut<'tcx>) {
     for (i, j) in search_same(
         conds,
         |e| hash_expr(cx, e),
@@ -593,7 +589,7 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &De
             // Ignore eq_expr side effects iff one of the expression kind is a method call
             // and the caller is not a mutable, including inner mutable type.
             if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind {
-                if method_caller_is_mutable(cx, caller, ignored_ty_ids) {
+                if method_caller_is_mutable(cx, caller, interior_mut) {
                     false
                 } else {
                     SpanlessEq::new(cx).eq_expr(lhs, rhs)
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
index e2296767431..db593726604 100644
--- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs
+++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_in_test;
 use clippy_utils::macros::{macro_backtrace, MacroCall};
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_in_cfg_test, is_in_test_function};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, HirId, Node};
+use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
@@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro {
             !in_external_macro(cx.sess(), macro_call.span) &&
             self.checked_dbg_call_site.insert(macro_call.span) &&
             // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
-            !(self.allow_dbg_in_tests && is_in_test(cx, expr.hir_id))
+            !(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
         {
             let mut applicability = Applicability::MachineApplicable;
 
@@ -129,10 +129,6 @@ impl LateLintPass<'_> for DbgMacro {
     }
 }
 
-fn is_in_test(cx: &LateContext<'_>, hir_id: HirId) -> bool {
-    is_in_test_function(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id)
-}
-
 fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {
     macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))
 }
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 89e2b344968..b936b28470b 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -9,8 +9,8 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_ty, Visitor};
 use rustc_hir::{
-    self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
-    Pat, PatKind, Path, QPath, TyKind, UnOp,
+    self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
+    PatKind, Path, QPath, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 80db617c639..003a9995c15 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::is_diag_trait_item;
 use clippy_utils::macros::{
     find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro,
-    is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage, MacroCall,
+    is_format_macro, is_panic, matching_root_macro_call, root_macro_call_first_node, FormatParamUsage, MacroCall,
 };
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
@@ -271,9 +271,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) = root_macro_call(arg_span)
-                            && self.cx.tcx.is_diagnostic_item(sym::format_args_macro, mac_call.def_id)
-                        {
+                        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,
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 7b97fc15caa..3bf8d618955 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -24,7 +24,7 @@ declare_clippy_lint! {
     ///
     /// ### Limitations
     /// This lint does not check for implied bounds transitively. Meaning that
-    /// it does't check for implied bounds from supertraits of supertraits
+    /// it doesn't check for implied bounds from supertraits of supertraits
     /// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)
     ///
     /// ### Example
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index a4c3b06046e..128461ce7bc 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -93,12 +93,9 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<Hir
     let mut slices: FxIndexMap<HirId, SliceLintInformation> = FxIndexMap::default();
     pat.walk_always(|pat| {
         // We'll just ignore mut and ref mut for simplicity sake right now
-        if let hir::PatKind::Binding(
-            hir::BindingMode(by_ref, hir::Mutability::Not),
-            value_hir_id,
-            ident,
-            sub_pat,
-        ) = pat.kind && by_ref != hir::ByRef::Yes(hir::Mutability::Mut)
+        if let hir::PatKind::Binding(hir::BindingMode(by_ref, hir::Mutability::Not), value_hir_id, ident, sub_pat) =
+            pat.kind
+            && by_ref != hir::ByRef::Yes(hir::Mutability::Mut)
         {
             // This block catches bindings with sub patterns. It would be hard to build a correct suggestion
             // for them and it's likely that the user knows what they are doing in such a case.
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
index afcb6745947..208d1bb6e68 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -1,10 +1,13 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_from_proc_macro;
+use clippy_utils::macros::macro_backtrace;
 use clippy_utils::source::snippet;
-use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
+use rustc_hir::{ArrayLen, Expr, ExprKind, Item, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, ConstKind};
 use rustc_session::impl_lint_pass;
+use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -25,20 +28,41 @@ declare_clippy_lint! {
 
 pub struct LargeStackArrays {
     maximum_allowed_size: u128,
+    prev_vec_macro_callsite: Option<Span>,
 }
 
 impl LargeStackArrays {
     #[must_use]
     pub fn new(maximum_allowed_size: u128) -> Self {
-        Self { maximum_allowed_size }
+        Self {
+            maximum_allowed_size,
+            prev_vec_macro_callsite: None,
+        }
+    }
+
+    /// Check if the given span of an expr is already in a `vec!` call.
+    fn is_from_vec_macro(&mut self, cx: &LateContext<'_>, span: Span) -> bool {
+        // First, we check if this is span is within the last encountered `vec!` macro's root callsite.
+        self.prev_vec_macro_callsite
+            .is_some_and(|vec_mac| vec_mac.contains(span))
+            || {
+                // Then, we try backtracking the macro expansions, to see if there's a `vec!` macro,
+                // and update the `prev_vec_macro_callsite`.
+                let res = macro_backtrace(span).any(|mac| cx.tcx.is_diagnostic_item(sym::vec_macro, mac.def_id));
+                if res {
+                    self.prev_vec_macro_callsite = Some(span.source_callsite());
+                }
+                res
+            }
     }
 }
 
 impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);
 
 impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
-    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
         if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind
+            && !self.is_from_vec_macro(cx, expr.span)
             && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
             && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
             && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
@@ -54,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
             })
             && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size)
         {
-            span_lint_and_help(
+            span_lint_and_then(
                 cx,
                 LARGE_STACK_ARRAYS,
                 expr.span,
@@ -62,12 +86,33 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
                     "allocating a local array larger than {} bytes",
                     self.maximum_allowed_size
                 ),
-                None,
-                format!(
-                    "consider allocating on the heap with `vec!{}.into_boxed_slice()`",
-                    snippet(cx, expr.span, "[...]")
-                ),
+                |diag| {
+                    if !might_be_expanded(cx, expr) {
+                        diag.help(format!(
+                            "consider allocating on the heap with `vec!{}.into_boxed_slice()`",
+                            snippet(cx, expr.span, "[...]")
+                        ));
+                    }
+                },
             );
         }
     }
 }
+
+/// Only giving help messages if the expr does not contains macro expanded codes.
+fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
+    /// Check if the span of `ArrayLen` of a repeat expression is within the expr's span,
+    /// if not, meaning this repeat expr is definitely from some proc-macro.
+    ///
+    /// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the
+    /// correct result.
+    fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {
+        let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else {
+            return false;
+        };
+        let len_span = cx.tcx.def_span(anon_const.def_id);
+        !expr.span.contains(len_span)
+    }
+
+    expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(cx, expr)
+}
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index e2aac58bf97..2c44c3881aa 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -535,6 +535,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         allow_print_in_tests,
         allow_private_module_inception,
         allow_unwrap_in_tests,
+        allow_useless_vec_in_tests,
         ref allowed_dotfiles,
         ref allowed_idents_below_min_chars,
         ref allowed_scripts,
@@ -754,6 +755,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
             too_large_for_stack,
             msrv: msrv(),
             span_to_lint_map: BTreeMap::new(),
+            allow_in_test: allow_useless_vec_in_tests,
         })
     });
     store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
diff --git a/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
index 31f0f1cfeba..40ccfec02be 100644
--- a/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
@@ -1,11 +1,12 @@
 use super::UNUSED_ENUMERATE_INDEX;
 use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
 use clippy_utils::source::snippet;
-use clippy_utils::{match_def_path, pat_is_wild, sugg};
+use clippy_utils::{pat_is_wild, sugg};
 use rustc_hir::def::DefKind;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
+use rustc_span::sym;
 
 /// Checks for the `UNUSED_ENUMERATE_INDEX` lint.
 ///
@@ -16,9 +17,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>, arg: &Expr<'_
         && let ty = cx.typeck_results().expr_ty(arg)
         && pat_is_wild(cx, &index.kind, body)
         && let ty::Adt(base, _) = *ty.kind()
-        && match_def_path(cx, base.did(), &clippy_utils::paths::CORE_ITER_ENUMERATE_STRUCT)
+        && cx.tcx.is_diagnostic_item(sym::Enumerate, base.did())
         && let Some((DefKind::AssocFn, call_id)) = cx.typeck_results().type_dependent_def(arg.hir_id)
-        && match_def_path(cx, call_id, &clippy_utils::paths::CORE_ITER_ENUMERATE_METHOD)
+        && cx.tcx.is_diagnostic_item(sym::enumerate_method, call_id)
     {
         span_lint_and_then(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
index 76edbe8b755..d76b94eba23 100644
--- a/src/tools/clippy/clippy_lints/src/manual_assert.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs
@@ -1,12 +1,11 @@
 use crate::rustc_lint::LintContext;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::macros::root_macro_call;
+use clippy_utils::macros::{is_panic, root_macro_call};
 use clippy_utils::{is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -42,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert {
             && !expr.span.from_expansion()
             && let then = peel_blocks_with_stmt(then)
             && let Some(macro_call) = root_macro_call(then.span)
-            && cx.tcx.item_name(macro_call.def_id) == sym::panic
+            && is_panic(cx, macro_call.def_id)
             && !cx.tcx.sess.source_map().is_multiline(cond.span)
             && let Ok(panic_snippet) = cx.sess().source_map().span_to_snippet(macro_call.span)
             && let Some(panic_snippet) = panic_snippet.strip_suffix(')')
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
index 338a299740a..6f6ba1852a6 100644
--- a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
@@ -1,15 +1,15 @@
 use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::macros::root_macro_call;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{higher, in_constant};
+use clippy_utils::{higher, in_constant, path_to_local, peel_ref_operators};
 use rustc_ast::ast::RangeLimits;
 use rustc_ast::LitKind::{Byte, Char};
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, PatKind, RangeEnd};
+use rustc_hir::{Expr, ExprKind, Node, Param, PatKind, RangeEnd};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::DefId;
 use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
@@ -97,12 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
             return;
         }
 
-        if let Some(macro_call) = root_macro_call(expr.span)
-            && is_matches_macro(cx, macro_call.def_id)
-        {
+        if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) {
             if let ExprKind::Match(recv, [arm, ..], _) = expr.kind {
                 let range = check_pat(&arm.pat.kind);
-                check_is_ascii(cx, macro_call.span, recv, &range);
+                check_is_ascii(cx, macro_call.span, recv, &range, None);
             }
         } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind
             && path.ident.name == sym!(contains)
@@ -111,42 +109,67 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
                 end: Some(end),
                 limits: RangeLimits::Closed,
             }) = higher::Range::hir(receiver)
+            && !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_))
         {
+            let arg = peel_ref_operators(cx, arg);
+            let ty_sugg = get_ty_sugg(cx, arg, start);
             let range = check_range(start, end);
-            if let ExprKind::AddrOf(BorrowKind::Ref, _, e) = arg.kind {
-                check_is_ascii(cx, expr.span, e, &range);
-            } else {
-                check_is_ascii(cx, expr.span, arg, &range);
-            }
+            check_is_ascii(cx, expr.span, arg, &range, ty_sugg);
         }
     }
 
     extract_msrv_attr!(LateContext);
 }
 
-fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &CharRange) {
-    if let Some(sugg) = match range {
-        CharRange::UpperChar => Some("is_ascii_uppercase"),
-        CharRange::LowerChar => Some("is_ascii_lowercase"),
-        CharRange::FullChar => Some("is_ascii_alphabetic"),
-        CharRange::Digit => Some("is_ascii_digit"),
-        CharRange::HexDigit => Some("is_ascii_hexdigit"),
-        CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => None,
-    } {
-        let default_snip = "..";
-        let mut app = Applicability::MachineApplicable;
-        let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par();
+fn get_ty_sugg(cx: &LateContext<'_>, arg: &Expr<'_>, bound_expr: &Expr<'_>) -> Option<(Span, &'static str)> {
+    if let ExprKind::Lit(lit) = bound_expr.kind
+        && let local_hid = path_to_local(arg)?
+        && let Node::Param(Param { ty_span, span, .. }) = cx.tcx.parent_hir_node(local_hid)
+        // `ty_span` and `span` are the same for inferred type, thus a type suggestion must be given
+        && ty_span == span
+    {
+        let ty_str = match lit.node {
+            Char(_) => "char",
+            Byte(_) => "u8",
+            _ => return None,
+        };
+        return Some((*ty_span, ty_str));
+    }
+    None
+}
 
-        span_lint_and_sugg(
-            cx,
-            MANUAL_IS_ASCII_CHECK,
-            span,
-            "manual check for common ascii range",
-            "try",
-            format!("{recv}.{sugg}()"),
-            app,
-        );
+fn check_is_ascii(
+    cx: &LateContext<'_>,
+    span: Span,
+    recv: &Expr<'_>,
+    range: &CharRange,
+    ty_sugg: Option<(Span, &'_ str)>,
+) {
+    let sugg = match range {
+        CharRange::UpperChar => "is_ascii_uppercase",
+        CharRange::LowerChar => "is_ascii_lowercase",
+        CharRange::FullChar => "is_ascii_alphabetic",
+        CharRange::Digit => "is_ascii_digit",
+        CharRange::HexDigit => "is_ascii_hexdigit",
+        CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return,
+    };
+    let default_snip = "..";
+    let mut app = Applicability::MachineApplicable;
+    let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par();
+    let mut suggestion = vec![(span, format!("{recv}.{sugg}()"))];
+    if let Some((ty_span, ty_str)) = ty_sugg {
+        suggestion.push((ty_span, format!("{recv}: {ty_str}")));
     }
+
+    span_lint_and_then(
+        cx,
+        MANUAL_IS_ASCII_CHECK,
+        span,
+        "manual check for common ascii range",
+        |diag| {
+            diag.multipart_suggestion("try", suggestion, app);
+        },
+    );
 }
 
 fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
@@ -187,11 +210,3 @@ fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {
         CharRange::Otherwise
     }
 }
-
-fn is_matches_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
-    if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {
-        return sym::matches_macro == name;
-    }
-
-    false
-}
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 6746920edc5..90cfdecc199 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -1,3 +1,4 @@
+use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLetOrMatch;
 use clippy_utils::source::snippet;
@@ -11,12 +12,12 @@ use rustc_hir::{Arm, Expr, HirId, Pat, PatKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
-use super::COLLAPSIBLE_MATCH;
+use super::{pat_contains_disallowed_or, COLLAPSIBLE_MATCH};
 
-pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
+pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: &Msrv) {
     if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) {
         for arm in arms {
-            check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body));
+            check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body), msrv);
         }
     }
 }
@@ -26,8 +27,9 @@ pub(super) fn check_if_let<'tcx>(
     pat: &'tcx Pat<'_>,
     body: &'tcx Expr<'_>,
     else_expr: Option<&'tcx Expr<'_>>,
+    msrv: &Msrv,
 ) {
-    check_arm(cx, false, pat, body, None, else_expr);
+    check_arm(cx, false, pat, body, None, else_expr, msrv);
 }
 
 fn check_arm<'tcx>(
@@ -37,6 +39,7 @@ fn check_arm<'tcx>(
     outer_then_body: &'tcx Expr<'tcx>,
     outer_guard: Option<&'tcx Expr<'tcx>>,
     outer_else_body: Option<&'tcx Expr<'tcx>>,
+    msrv: &Msrv,
 ) {
     let inner_expr = peel_blocks_with_stmt(outer_then_body);
     if let Some(inner) = IfLetOrMatch::parse(cx, inner_expr)
@@ -57,7 +60,7 @@ fn check_arm<'tcx>(
         // match expression must be a local binding
         // match <local> { .. }
         && let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee))
-        && !pat_contains_or(inner_then_pat)
+        && !pat_contains_disallowed_or(inner_then_pat, msrv)
         // the binding must come from the pattern of the containing match arm
         // ..<local>.. => match <local> { .. }
         && let (Some(binding_span), is_innermost_parent_pat_struct)
@@ -142,13 +145,3 @@ fn find_pat_binding_and_is_innermost_parent_pat_struct(pat: &Pat<'_>, hir_id: Hi
     });
     (span, is_innermost_parent_pat_struct)
 }
-
-fn pat_contains_or(pat: &Pat<'_>) -> bool {
-    let mut result = false;
-    pat.walk(|p| {
-        let is_or = matches!(p.kind, PatKind::Or(_));
-        result |= is_or;
-        !is_or
-    });
-    result
-}
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index fae2c4e4af9..ee9f48d71ad 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -27,7 +27,7 @@ mod wild_in_or_pats;
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::source::walk_span_to_context;
 use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, span_contains_cfg};
-use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat};
+use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
@@ -1040,7 +1040,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                 significant_drop_in_scrutinee::check(cx, expr, ex, arms, source);
             }
 
-            collapsible_match::check_match(cx, arms);
+            collapsible_match::check_match(cx, arms, &self.msrv);
             if !from_expansion {
                 // These don't depend on a relationship between multiple arms
                 match_wild_err_arm::check(cx, ex, arms);
@@ -1066,7 +1066,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                     needless_match::check_match(cx, ex, arms, expr);
                     match_on_vec_items::check(cx, ex);
                     match_str_case_mismatch::check(cx, ex, arms);
-                    redundant_guards::check(cx, arms);
+                    redundant_guards::check(cx, arms, &self.msrv);
 
                     if !in_constant(cx, expr.hir_id) {
                         manual_unwrap_or::check(cx, expr, ex, arms);
@@ -1083,7 +1083,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                 match_ref_pats::check(cx, ex, arms.iter().map(|el| el.pat), expr);
             }
         } else if let Some(if_let) = higher::IfLet::hir(cx, expr) {
-            collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else);
+            collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else, &self.msrv);
             if !from_expansion {
                 if let Some(else_expr) = if_let.if_else {
                     if self.msrv.meets(msrvs::MATCHES_MACRO) {
@@ -1195,3 +1195,18 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar
         Err(()) => true,
     }
 }
+
+/// Checks if `pat` contains OR patterns that cannot be nested due to a too low MSRV.
+fn pat_contains_disallowed_or(pat: &Pat<'_>, msrv: &Msrv) -> bool {
+    if msrv.meets(msrvs::OR_PATTERNS) {
+        return false;
+    }
+
+    let mut result = false;
+    pat.walk(|p| {
+        let is_or = matches!(p.kind, PatKind::Or(_));
+        result |= is_or;
+        !is_or
+    });
+    result
+}
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 50cbccc3968..a75cf37945f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -1,40 +1,32 @@
+use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::{for_each_expr, is_local_used};
 use clippy_utils::{in_constant, path_to_local};
 use rustc_ast::{BorrowKind, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, Pat, PatKind, UnOp};
+use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp};
 use rustc_lint::LateContext;
 use rustc_span::symbol::Ident;
-use rustc_span::{Span, Symbol};
+use rustc_span::{sym, Span, Symbol};
 use std::borrow::Cow;
 use std::ops::ControlFlow;
 
-use super::REDUNDANT_GUARDS;
+use super::{pat_contains_disallowed_or, REDUNDANT_GUARDS};
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: &Msrv) {
     for outer_arm in arms {
         let Some(guard) = outer_arm.guard else {
             continue;
         };
 
         // `Some(x) if matches!(x, y)`
-        if let ExprKind::Match(
-            scrutinee,
-            [
-                arm,
-                Arm {
-                    pat: Pat {
-                        kind: PatKind::Wild, ..
-                    },
-                    ..
-                },
-            ],
-            MatchSource::Normal,
-        ) = guard.kind
+        if let ExprKind::Match(scrutinee, [arm, _], MatchSource::Normal) = guard.kind
+            && matching_root_macro_call(cx, guard.span, sym::matches_macro).is_some()
             && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)
+            && !pat_contains_disallowed_or(arm.pat, msrv)
         {
             let pat_span = match (arm.pat.kind, binding.byref_ident) {
                 (PatKind::Ref(pat, _), Some(_)) => pat.span,
@@ -53,6 +45,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
         // `Some(x) if let Some(2) = x`
         else if let ExprKind::Let(let_expr) = guard.kind
             && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)
+            && !pat_contains_disallowed_or(let_expr.pat, msrv)
         {
             let pat_span = match (let_expr.pat.kind, binding.byref_ident) {
                 (PatKind::Ref(pat, _), Some(_)) => pat.span,
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 37f72528140..69791414f72 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -75,7 +75,7 @@ fn report_single_pattern(
 ) {
     let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH };
     let ctxt = expr.span.ctxt();
-    let mut app = Applicability::HasPlaceholders;
+    let mut app = Applicability::MachineApplicable;
     let els_str = els.map_or(String::new(), |els| {
         format!(" else {}", expr_block(cx, els, ctxt, "..", Some(expr.span), &mut app))
     });
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 581e3b308c3..02a11257007 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::macros::{is_panic, root_macro_call};
+use clippy_utils::macros::{is_panic, matching_root_macro_call, root_macro_call};
 use clippy_utils::source::{indent_of, reindent_multiline, snippet};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{higher, is_trait_method, path_to_local_id, peel_blocks, SpanlessEq};
@@ -247,8 +247,7 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
             } else {
                 None
             }
-        } else if let Some(macro_call) = root_macro_call(expr.span)
-            && cx.tcx.get_diagnostic_name(macro_call.def_id) == Some(sym::matches_macro)
+        } else if matching_root_macro_call(cx, expr.span, sym::matches_macro).is_some()
             // we know for a fact that the wildcard pattern is the second arm
             && let ExprKind::Match(scrutinee, [arm, _], _) = expr.kind
             && path_to_local_id(scrutinee, filter_param_id)
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
index 6d70989546a..03b4680c522 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -89,8 +89,7 @@ pub(super) fn check<'tcx>(
                 }
 
                 match it.kind {
-                    PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _)
-                    | PatKind::Ref(_, Mutability::Mut) => {
+                    PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) | PatKind::Ref(_, Mutability::Mut) => {
                         to_be_discarded = true;
                         false
                     },
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 0939c028564..63545d6c503 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -1145,11 +1145,16 @@ declare_clippy_lint! {
     /// `str` as an argument, e.g., `_.split("x")`.
     ///
     /// ### Why is this bad?
-    /// Performing these methods using a `char` is faster than
-    /// using a `str`.
+    /// While this can make a perf difference on some systems,
+    /// benchmarks have proven inconclusive. But at least using a
+    /// char literal makes it clear that we are looking at a single
+    /// character.
     ///
     /// ### Known problems
-    /// Does not catch multi-byte unicode characters.
+    /// Does not catch multi-byte unicode characters. This is by
+    /// design, on many machines, splitting by a non-ascii char is
+    /// actually slower. Please do your own measurements instead of
+    /// relying solely on the results of this lint.
     ///
     /// ### Example
     /// ```rust,ignore
@@ -1162,7 +1167,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub SINGLE_CHAR_PATTERN,
-    perf,
+    pedantic,
     "using a single-character str where a char could be used, e.g., `_.split(\"x\")`"
 }
 
@@ -3988,7 +3993,7 @@ declare_clippy_lint! {
     /// let x: Result<u32, ()> = Ok(0);
     /// let y = x.unwrap_or_else(|err| handle_error(err));
     /// ```
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub UNNECESSARY_RESULT_MAP_OR_ELSE,
     suspicious,
     "making no use of the \"map closure\" when calling `.map_or_else(|err| handle_error(err), |n| n)`"
@@ -4022,7 +4027,7 @@ declare_clippy_lint! {
     /// needs_cstr(c"Hello");
     /// unsafe { libc::puts(c"World".as_ptr()) }
     /// ```
-    #[clippy::version = "1.76.0"]
+    #[clippy::version = "1.78.0"]
     pub MANUAL_C_STR_LITERALS,
     pedantic,
     r#"creating a `CStr` through functions when `c""` literals can be used"#
diff --git a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
index 9b0180d9369..774aaec1afd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
@@ -4,7 +4,7 @@ use clippy_utils::mir::{enclosing_mir, visit_local_usage};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Node};
+use rustc_hir::{Expr, ExprKind, Node, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::mir::{Location, START_BLOCK};
 use rustc_span::sym;
@@ -25,6 +25,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver
         && is_unwrap_call(cx, unwrap_call_expr)
         && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id)
         && let Node::LetStmt(local) = parent
+        && let PatKind::Binding(.., ident, _) = local.pat.kind
+        // if the binding is prefixed with `_`, it typically means
+        // that this guard only exists to protect a section of code
+        // rather than the contained data
+        && !ident.as_str().starts_with('_')
         && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)
         && let Some((local, _)) = mir
             .local_decls
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
index 44a7ad394fa..20ec2b74d81 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_insert_string.rs
@@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR;
 /// lint for length-1 `str`s as argument for `insert_str`
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
     let mut applicability = Applicability::MachineApplicable;
-    if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) {
+    if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability, false) {
         let base_string_snippet =
             snippet_with_applicability(cx, receiver.span.source_callsite(), "_", &mut applicability);
         let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
index 363b1f2b812..982a7901c45 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
@@ -8,7 +8,7 @@ use rustc_span::symbol::Symbol;
 
 use super::SINGLE_CHAR_PATTERN;
 
-const PATTERN_METHODS: [(&str, usize); 24] = [
+const PATTERN_METHODS: [(&str, usize); 22] = [
     ("contains", 0),
     ("starts_with", 0),
     ("ends_with", 0),
@@ -27,8 +27,6 @@ const PATTERN_METHODS: [(&str, usize); 24] = [
     ("rmatches", 0),
     ("match_indices", 0),
     ("rmatch_indices", 0),
-    ("strip_prefix", 0),
-    ("strip_suffix", 0),
     ("trim_start_matches", 0),
     ("trim_end_matches", 0),
     ("replace", 0),
@@ -50,7 +48,7 @@ pub(super) fn check(
             && args.len() > pos
             && let arg = &args[pos]
             && let mut applicability = Applicability::MachineApplicable
-            && let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability)
+            && let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability, true)
         {
             span_lint_and_sugg(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
index 0698bd6a0c5..97c13825bc1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_push_string.rs
@@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR;
 /// lint for length-1 `str`s as argument for `push_str`
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
     let mut applicability = Applicability::MachineApplicable;
-    if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability) {
+    if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability, false) {
         let base_string_snippet =
             snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability);
         let sugg = format!("{base_string_snippet}.push({extension_string})");
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 e5cc898612e..8b8a965b9f0 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,7 +1,6 @@
 use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_hir_and_then};
-use clippy_utils::paths::{CORE_ITER_ENUMERATE_METHOD, CORE_ITER_ENUMERATE_STRUCT};
 use clippy_utils::source::{snippet, snippet_opt};
-use clippy_utils::{expr_or_init, is_trait_method, match_def_path, pat_is_wild};
+use clippy_utils::{expr_or_init, is_trait_method, pat_is_wild};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, FnDecl, PatKind, TyKind};
 use rustc_lint::LateContext;
@@ -42,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>,
     let recv_ty = cx.typeck_results().expr_ty(recv);
     if let Some(recv_ty_defid) = recv_ty.ty_adt_def().map(AdtDef::did)
         // If we call a method on a `std::iter::Enumerate` instance
-        && match_def_path(cx, recv_ty_defid, &CORE_ITER_ENUMERATE_STRUCT)
+        && cx.tcx.is_diagnostic_item(sym::Enumerate, recv_ty_defid)
         // If we are calling a method of the `Iterator` trait
         && is_trait_method(cx, call_expr, sym::Iterator)
         // And the map argument is a closure
@@ -75,10 +74,10 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>,
         && let ExprKind::MethodCall(_, enumerate_recv, _, enumerate_span) = recv_init_expr.kind
         && let Some(enumerate_defid) = cx.typeck_results().type_dependent_def_id(recv_init_expr.hir_id)
         // Make sure the method call is `std::iter::Iterator::enumerate`.
-        && match_def_path(cx, enumerate_defid, &CORE_ITER_ENUMERATE_METHOD)
+        && cx.tcx.is_diagnostic_item(sym::enumerate_method, enumerate_defid)
     {
         // Check if the tuple type was explicit. It may be the type system _needs_ the type of the element
-        // that would be explicited in the closure.
+        // that would be explicitly in the closure.
         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.
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index ef00c812d51..c50f24f824a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -52,11 +52,17 @@ pub(super) fn get_hint_if_single_char_arg(
     cx: &LateContext<'_>,
     arg: &Expr<'_>,
     applicability: &mut Applicability,
+    ascii_only: bool,
 ) -> Option<String> {
     if let ExprKind::Lit(lit) = &arg.kind
         && let ast::LitKind::Str(r, style) = lit.node
         && let string = r.as_str()
-        && string.chars().count() == 1
+        && let len = if ascii_only {
+            string.len()
+        } else {
+            string.chars().count()
+        }
+        && len == 1
     {
         let snip = snippet_with_applicability(cx, arg.span, string, applicability);
         let ch = if let ast::StrStyle::Raw(nhash) = style {
diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
index 191b32408ef..d608f3bf7b4 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
@@ -29,7 +29,7 @@ declare_clippy_lint! {
     ///     F: Sized + std::fmt::Debug,
     /// {}
     /// ```
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub MULTIPLE_BOUND_LOCATIONS,
     suspicious,
     "defining generic bounds in multiple locations"
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 8c2f43c97f4..2eb534da092 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_interior_mut_ty;
-use clippy_utils::{def_path_def_ids, trait_ref_of_method};
-use rustc_data_structures::fx::FxHashSet;
+use clippy_utils::trait_ref_of_method;
+use clippy_utils::ty::InteriorMut;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
@@ -23,27 +22,15 @@ declare_clippy_lint! {
     /// ### Known problems
     ///
     /// #### False Positives
-    /// It's correct to use a struct that contains interior mutability as a key, when its
+    /// It's correct to use a struct that contains interior mutability as a key when its
     /// implementation of `Hash` or `Ord` doesn't access any of the interior mutable types.
     /// However, this lint is unable to recognize this, so it will often cause false positives in
-    /// theses cases.  The `bytes` crate is a great example of this.
+    /// these cases.
     ///
     /// #### False Negatives
-    /// For custom `struct`s/`enum`s, this lint is unable to check for interior mutability behind
-    /// indirection.  For example, `struct BadKey<'a>(&'a Cell<usize>)` will be seen as immutable
-    /// and cause a false negative if its implementation of `Hash`/`Ord` accesses the `Cell`.
-    ///
-    /// This lint does check a few cases for indirection.  Firstly, using some standard library
-    /// types (`Option`, `Result`, `Box`, `Rc`, `Arc`, `Vec`, `VecDeque`, `BTreeMap` and
-    /// `BTreeSet`) directly as keys (e.g. in `HashMap<Box<Cell<usize>>, ()>`) **will** trigger the
-    /// lint, because the impls of `Hash`/`Ord` for these types directly call `Hash`/`Ord` on their
-    /// contained type.
-    ///
-    /// Secondly, the implementations of `Hash` and `Ord` for raw pointers (`*const T` or `*mut T`)
-    /// apply only to the **address** of the contained value.  Therefore, interior mutability
-    /// behind raw pointers (e.g. in `HashSet<*mut Cell<usize>>`) can't impact the value of `Hash`
-    /// or `Ord`, and therefore will not trigger this link.  For more info, see issue
-    /// [#6745](https://github.com/rust-lang/rust-clippy/issues/6745).
+    /// This lint does not follow raw pointers (`*const T` or `*mut T`) as `Hash` and `Ord`
+    /// apply only to the **address** of the contained value. This can cause false negatives for
+    /// custom collections that use raw pointers internally.
     ///
     /// ### Example
     /// ```no_run
@@ -51,13 +38,12 @@ declare_clippy_lint! {
     /// use std::collections::HashSet;
     /// use std::hash::{Hash, Hasher};
     /// use std::sync::atomic::AtomicUsize;
-    ///# #[allow(unused)]
     ///
     /// struct Bad(AtomicUsize);
     /// impl PartialEq for Bad {
     ///     fn eq(&self, rhs: &Self) -> bool {
     ///          ..
-    /// ; unimplemented!();
+    /// # ; true
     ///     }
     /// }
     ///
@@ -66,7 +52,7 @@ declare_clippy_lint! {
     /// impl Hash for Bad {
     ///     fn hash<H: Hasher>(&self, h: &mut H) {
     ///         ..
-    /// ; unimplemented!();
+    /// # ;
     ///     }
     /// }
     ///
@@ -80,25 +66,16 @@ declare_clippy_lint! {
     "Check for mutable `Map`/`Set` key type"
 }
 
-#[derive(Clone)]
-pub struct MutableKeyType {
+pub struct MutableKeyType<'tcx> {
     ignore_interior_mutability: Vec<String>,
-    ignore_mut_def_ids: FxHashSet<hir::def_id::DefId>,
+    interior_mut: InteriorMut<'tcx>,
 }
 
-impl_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]);
+impl_lint_pass!(MutableKeyType<'_> => [ MUTABLE_KEY_TYPE ]);
 
-impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
+impl<'tcx> LateLintPass<'tcx> for MutableKeyType<'tcx> {
     fn check_crate(&mut self, cx: &LateContext<'tcx>) {
-        self.ignore_mut_def_ids.clear();
-        let mut path = Vec::new();
-        for ty in &self.ignore_interior_mutability {
-            path.extend(ty.split("::"));
-            for id in def_path_def_ids(cx, &path[..]) {
-                self.ignore_mut_def_ids.insert(id);
-            }
-            path.clear();
-        }
+        self.interior_mut = InteriorMut::without_pointers(cx, &self.ignore_interior_mutability);
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
@@ -121,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
         }
     }
 
-    fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &hir::LetStmt<'tcx>) {
         if let hir::PatKind::Wild = local.pat.kind {
             return;
         }
@@ -129,15 +106,15 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
     }
 }
 
-impl MutableKeyType {
+impl<'tcx> MutableKeyType<'tcx> {
     pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
         Self {
             ignore_interior_mutability,
-            ignore_mut_def_ids: FxHashSet::default(),
+            interior_mut: InteriorMut::default(),
         }
     }
 
-    fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) {
+    fn check_sig(&mut self, cx: &LateContext<'tcx>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'tcx>) {
         let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();
         for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
             self.check_ty_(cx, hir_ty.span, *ty);
@@ -151,7 +128,7 @@ impl MutableKeyType {
 
     // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased
     // generics (because the compiler cannot ensure immutability for unknown types).
-    fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
+    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]
@@ -162,11 +139,7 @@ impl MutableKeyType {
             }
 
             let subst_ty = args.type_at(0);
-            // Determines if a type contains interior mutability which would affect its implementation of
-            // [`Hash`] or [`Ord`].
-            if is_interior_mut_ty(cx, subst_ty)
-                && !matches!(subst_ty.ty_adt_def(), Some(adt) if self.ignore_mut_def_ids.contains(&adt.did()))
-            {
+            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/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index 84a07df1bb0..630018238f4 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -1,6 +1,6 @@
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Closure, Expr, ExprKind, Stmt, StmtKind};
+use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::{sym, Span, Symbol};
@@ -35,6 +35,16 @@ declare_clippy_lint! {
     ///     println!("{}", elem);
     /// }
     /// ```
+    ///
+    /// ### Known Problems
+    /// When doing things such as:
+    /// ```ignore
+    /// let v = vec![0, 1, 2];
+    /// v.iter().for_each(|elem| unsafe {
+    ///     libc::printf(c"%d\n".as_ptr(), elem);
+    /// });
+    /// ```
+    /// This lint will not trigger.
     #[clippy::version = "1.53.0"]
     pub NEEDLESS_FOR_EACH,
     pedantic,
@@ -68,7 +78,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
             // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
             && let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind
             && let body = cx.tcx.hir().body(body)
-            && let ExprKind::Block(..) = body.value.kind
+            // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}`
+            // and suggesting `for … in … { unsafe { } }` is a little ugly.
+            && let ExprKind::Block(Block { rules: BlockCheckMode::DefaultBlock, .. }, ..) = body.value.kind
         {
             let mut ret_collector = RetCollector::default();
             ret_collector.visit_expr(body.value);
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 0c0b1a73351..6605d1fa51a 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -6,8 +6,7 @@ use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_loca
 use core::ops::ControlFlow;
 use rustc_errors::{Applicability, MultiSpan};
 use rustc_hir::{
-    BindingMode, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt,
-    StmtKind,
+    BindingMode, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 30d3e86dc4e..9e47c3ad0b7 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -83,7 +83,9 @@ fn should_skip<'tcx>(
     }
 
     if is_self(arg) {
-        return true;
+        // Interestingly enough, `self` arguments make `is_from_proc_macro` return `true`, hence why
+        // we return early here.
+        return false;
     }
 
     if let PatKind::Binding(.., name, _) = arg.pat.kind {
@@ -185,7 +187,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
         }
         // Collect variables mutably used and spans which will need dereferencings from the
         // function body.
-        let MutablyUsedVariablesCtxt { mutably_used_vars, .. } = {
+        let mutably_used_vars = {
             let mut ctx = MutablyUsedVariablesCtxt {
                 mutably_used_vars: HirIdSet::default(),
                 prev_bind: None,
@@ -217,7 +219,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                     check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures);
                 }
             }
-            ctx
+            ctx.generate_mutably_used_ids_from_aliases()
         };
         for ((&input, &_), arg) in it {
             // Only take `&mut` arguments.
@@ -309,12 +311,22 @@ struct MutablyUsedVariablesCtxt<'tcx> {
 }
 
 impl<'tcx> MutablyUsedVariablesCtxt<'tcx> {
-    fn add_mutably_used_var(&mut self, mut used_id: HirId) {
-        while let Some(id) = self.aliases.get(&used_id) {
+    fn add_mutably_used_var(&mut self, used_id: HirId) {
+        self.mutably_used_vars.insert(used_id);
+    }
+
+    // Because the alias may come after the mutable use of a variable, we need to fill the map at
+    // the end.
+    fn generate_mutably_used_ids_from_aliases(mut self) -> HirIdSet {
+        let all_ids = self.mutably_used_vars.iter().copied().collect::<Vec<_>>();
+        for mut used_id in all_ids {
+            while let Some(id) = self.aliases.get(&used_id) {
+                self.mutably_used_vars.insert(used_id);
+                used_id = *id;
+            }
             self.mutably_used_vars.insert(used_id);
-            used_id = *id;
         }
-        self.mutably_used_vars.insert(used_id);
+        self.mutably_used_vars
     }
 
     fn would_be_alias_cycle(&self, alias: HirId, mut target: HirId) -> bool {
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 53bcde68087..39d374d0d27 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
@@ -9,8 +9,8 @@ use rustc_ast::ast::Attribute;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind,
-    QPath, TyKind,
+    BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath,
+    TyKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_infer::infer::TyCtxtInferExt;
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index fd3985a5daf..932d6fe54d6 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -182,17 +182,17 @@ impl LateLintPass<'_> for NonCanonicalImpls {
 
             if block.stmts.is_empty()
                 && let Some(expr) = block.expr
-                && let ExprKind::Call(
-                        Expr {
-                            kind: ExprKind::Path(some_path),
-                            hir_id: some_hir_id,
-                            ..
-                        },
-                        [cmp_expr],
-                    ) = expr.kind
-                && is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome)
-                // Fix #11178, allow `Self::cmp(self, ..)` too
-                && self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, &mut needs_fully_qualified)
+                && expr_is_cmp(cx, &expr.kind, impl_item, &mut needs_fully_qualified)
+            {
+            }
+            // Fix #12683, allow [`needless_return`] here
+            else if block.expr.is_none()
+                && let Some(stmt) = block.stmts.first()
+                && let rustc_hir::StmtKind::Semi(Expr {
+                    kind: ExprKind::Ret(Some(Expr { kind: ret_kind, .. })),
+                    ..
+                }) = stmt.kind
+                && expr_is_cmp(cx, ret_kind, impl_item, &mut needs_fully_qualified)
             {
             } else {
                 // If `Self` and `Rhs` are not the same type, bail. This makes creating a valid
@@ -245,6 +245,30 @@ impl LateLintPass<'_> for NonCanonicalImpls {
     }
 }
 
+/// Return true if `expr_kind` is a `cmp` call.
+fn expr_is_cmp<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr_kind: &'tcx ExprKind<'tcx>,
+    impl_item: &ImplItem<'_>,
+    needs_fully_qualified: &mut bool,
+) -> bool {
+    if let ExprKind::Call(
+        Expr {
+            kind: ExprKind::Path(some_path),
+            hir_id: some_hir_id,
+            ..
+        },
+        [cmp_expr],
+    ) = expr_kind
+    {
+        is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome)
+            // Fix #11178, allow `Self::cmp(self, ..)` too
+            && self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, needs_fully_qualified)
+    } else {
+        false
+    }
+}
+
 /// Returns whether this is any of `self.cmp(..)`, `Self::cmp(self, ..)` or `Ord::cmp(self, ..)`.
 fn self_cmp_call<'tcx>(
     cx: &LateContext<'tcx>,
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 ff10a841aef..76d9cee18aa 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -5,9 +5,9 @@
 use std::ptr;
 
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::in_constant;
 use clippy_utils::macros::macro_backtrace;
-use clippy_utils::{def_path_def_ids, in_constant};
-use rustc_data_structures::fx::FxHashSet;
+use clippy_utils::ty::InteriorMut;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
@@ -52,8 +52,8 @@ declare_clippy_lint! {
     /// There're other enums plus associated constants cases that the lint cannot handle.
     ///
     /// Types that have underlying or potential interior mutability trigger the lint whether
-    /// the interior mutable field is used or not. See issues
-    /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
+    /// the interior mutable field is used or not. See issue
+    /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812)
     ///
     /// ### Example
     /// ```no_run
@@ -170,42 +170,22 @@ fn lint(cx: &LateContext<'_>, source: Source) {
     });
 }
 
-#[derive(Clone)]
-pub struct NonCopyConst {
+pub struct NonCopyConst<'tcx> {
     ignore_interior_mutability: Vec<String>,
-    ignore_mut_def_ids: FxHashSet<DefId>,
+    interior_mut: InteriorMut<'tcx>,
 }
 
-impl_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]);
+impl_lint_pass!(NonCopyConst<'_> => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]);
 
-impl NonCopyConst {
+impl<'tcx> NonCopyConst<'tcx> {
     pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
         Self {
             ignore_interior_mutability,
-            ignore_mut_def_ids: FxHashSet::default(),
+            interior_mut: InteriorMut::default(),
         }
     }
 
-    fn is_ty_ignored(&self, ty: Ty<'_>) -> bool {
-        matches!(ty.ty_adt_def(), Some(adt) if self.ignore_mut_def_ids.contains(&adt.did()))
-    }
-
-    fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
-        // Ignore types whose layout is unknown since `is_freeze` reports every generic types as `!Freeze`,
-        // making it indistinguishable from `UnsafeCell`. i.e. it isn't a tool to prove a type is
-        // 'unfrozen'. However, this code causes a false negative in which
-        // a type contains a layout-unknown type, but also an unsafe cell like `const CELL: Cell<T>`.
-        // Yet, it's better than `ty.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_PROJECTION)`
-        // since it works when a pointer indirection involves (`Cell<*const T>`).
-        // Making up a `ParamEnv` where every generic params and assoc types are `Freeze`is another option;
-        // but I'm not sure whether it's a decent way, if possible.
-        cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx, cx.param_env)
-    }
-
-    fn is_value_unfrozen_raw_inner<'tcx>(&self, cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
-        if self.is_ty_ignored(ty) {
-            return false;
-        }
+    fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
         match *ty.kind() {
             // the fact that we have to dig into every structs to search enums
             // leads us to the point checking `UnsafeCell` directly is the only option.
@@ -216,8 +196,7 @@ impl NonCopyConst {
             ty::Array(ty, _) => val
                 .unwrap_branch()
                 .iter()
-                .any(|field| self.is_value_unfrozen_raw_inner(cx, *field, ty)),
-            ty::Adt(def, _) if def.is_union() => false,
+                .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
             ty::Adt(def, args) if def.is_enum() => {
                 let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
                 let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
@@ -230,24 +209,23 @@ impl NonCopyConst {
                             .iter()
                             .map(|field| field.ty(cx.tcx, args)),
                     )
-                    .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, field, ty))
+                    .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, field, ty))
             },
             ty::Adt(def, args) => val
                 .unwrap_branch()
                 .iter()
                 .zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args)))
-                .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, *field, ty)),
+                .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
             ty::Tuple(tys) => val
                 .unwrap_branch()
                 .iter()
                 .zip(tys)
-                .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, *field, ty)),
+                .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
             _ => false,
         }
     }
 
-    fn is_value_unfrozen_raw<'tcx>(
-        &self,
+    fn is_value_unfrozen_raw(
         cx: &LateContext<'tcx>,
         result: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
         ty: Ty<'tcx>,
@@ -277,11 +255,11 @@ impl NonCopyConst {
                 // I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none).
                 matches!(err, ErrorHandled::TooGeneric(..))
             },
-            |val| val.map_or(true, |val| self.is_value_unfrozen_raw_inner(cx, val, ty)),
+            |val| val.map_or(true, |val| Self::is_value_unfrozen_raw_inner(cx, val, ty)),
         )
     }
 
-    fn is_value_unfrozen_poly<'tcx>(&self, cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
+    fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
         let def_id = body_id.hir_id.owner.to_def_id();
         let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
         let instance = ty::Instance::new(def_id, args);
@@ -291,17 +269,17 @@ impl NonCopyConst {
         };
         let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
         let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, DUMMY_SP);
-        self.is_value_unfrozen_raw(cx, result, ty)
+        Self::is_value_unfrozen_raw(cx, result, ty)
     }
 
-    fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
+    fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
         let args = cx.typeck_results().node_args(hir_id);
 
         let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), DUMMY_SP);
-        self.is_value_unfrozen_raw(cx, result, ty)
+        Self::is_value_unfrozen_raw(cx, result, ty)
     }
 
-    pub fn const_eval_resolve<'tcx>(
+    pub fn const_eval_resolve(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         ct: ty::UnevaluatedConst<'tcx>,
@@ -321,26 +299,17 @@ impl NonCopyConst {
     }
 }
 
-impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
+impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
     fn check_crate(&mut self, cx: &LateContext<'tcx>) {
-        self.ignore_mut_def_ids.clear();
-        let mut path = Vec::new();
-        for ty in &self.ignore_interior_mutability {
-            path.extend(ty.split("::"));
-            for id in def_path_def_ids(cx, &path[..]) {
-                self.ignore_mut_def_ids.insert(id);
-            }
-            path.clear();
-        }
+        self.interior_mut = InteriorMut::new(cx, &self.ignore_interior_mutability);
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
         if let ItemKind::Const(.., body_id) = it.kind {
             let ty = cx.tcx.type_of(it.owner_id).instantiate_identity();
             if !ignored_macro(cx, it)
-                && !self.is_ty_ignored(ty)
-                && Self::is_unfrozen(cx, ty)
-                && self.is_value_unfrozen_poly(cx, body_id, ty)
+                && self.interior_mut.is_interior_mut_ty(cx, ty)
+                && Self::is_value_unfrozen_poly(cx, body_id, ty)
             {
                 lint(cx, Source::Item { item: it.span });
             }
@@ -354,7 +323,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
             // Normalize assoc types because ones originated from generic params
             // bounded other traits could have their bound.
             let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
-            if !self.is_ty_ignored(ty) && Self::is_unfrozen(cx, normalized)
+            if self.interior_mut.is_interior_mut_ty(cx, normalized)
                 // When there's no default value, lint it only according to its type;
                 // in other words, lint consts whose value *could* be unfrozen, not definitely is.
                 // This feels inconsistent with how the lint treats generic types,
@@ -367,7 +336,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                 // i.e. having an enum doesn't necessary mean a type has a frozen variant.
                 // And, implementing it isn't a trivial task; it'll probably end up
                 // re-implementing the trait predicate evaluation specific to `Freeze`.
-                && body_id_opt.map_or(true, |body_id| self.is_value_unfrozen_poly(cx, body_id, normalized))
+                && body_id_opt.map_or(true, |body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized))
             {
                 lint(cx, Source::Assoc { item: trait_item.span });
             }
@@ -409,8 +378,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                             // e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
                         && let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity()
                         && let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty)
-                        && !self.is_ty_ignored(ty) && Self::is_unfrozen(cx, normalized)
-                        && self.is_value_unfrozen_poly(cx, *body_id, normalized)
+                        && self.interior_mut.is_interior_mut_ty(cx, normalized)
+                        && Self::is_value_unfrozen_poly(cx, *body_id, normalized)
                     {
                         lint(cx, Source::Assoc { item: impl_item.span });
                     }
@@ -420,9 +389,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                     // Normalize assoc types originated from generic params.
                     let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
 
-                    if !self.is_ty_ignored(ty)
-                        && Self::is_unfrozen(cx, ty)
-                        && self.is_value_unfrozen_poly(cx, *body_id, normalized)
+                    if self.interior_mut.is_interior_mut_ty(cx, normalized)
+                        && Self::is_value_unfrozen_poly(cx, *body_id, normalized)
                     {
                         lint(cx, Source::Assoc { item: impl_item.span });
                     }
@@ -517,9 +485,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                 cx.typeck_results().expr_ty(dereferenced_expr)
             };
 
-            if !self.is_ty_ignored(ty)
-                && Self::is_unfrozen(cx, ty)
-                && self.is_value_unfrozen_expr(cx, expr.hir_id, item_def_id, ty)
+            if self.interior_mut.is_interior_mut_ty(cx, ty)
+                && Self::is_value_unfrozen_expr(cx, expr.hir_id, item_def_id, ty)
             {
                 lint(cx, Source::Expr { expr: expr.span });
             }
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 96ea063aa74..7d6f26cde3e 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
@@ -7,14 +7,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
 use {rustc_ast as ast, rustc_hir as hir};
 
 const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]];
 const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"];
-const INTEGER_METHODS: &[Symbol] = &[
+const DISALLOWED_INT_METHODS: &[Symbol] = &[
     sym::saturating_div,
     sym::wrapping_div,
     sym::wrapping_rem,
@@ -27,8 +26,8 @@ pub struct ArithmeticSideEffects {
     allowed_unary: FxHashSet<String>,
     // Used to check whether expressions are constants, such as in enum discriminants and consts
     const_span: Option<Span>,
+    disallowed_int_methods: FxHashSet<Symbol>,
     expr_span: Option<Span>,
-    integer_methods: FxHashSet<Symbol>,
 }
 
 impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]);
@@ -53,8 +52,8 @@ impl ArithmeticSideEffects {
             allowed_binary,
             allowed_unary,
             const_span: None,
+            disallowed_int_methods: DISALLOWED_INT_METHODS.iter().copied().collect(),
             expr_span: None,
-            integer_methods: INTEGER_METHODS.iter().copied().collect(),
         }
     }
 
@@ -91,10 +90,10 @@ impl ArithmeticSideEffects {
     fn has_specific_allowed_type_and_operation<'tcx>(
         cx: &LateContext<'tcx>,
         lhs_ty: Ty<'tcx>,
-        op: &Spanned<hir::BinOpKind>,
+        op: hir::BinOpKind,
         rhs_ty: Ty<'tcx>,
     ) -> bool {
-        let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
+        let is_div_or_rem = matches!(op, hir::BinOpKind::Div | hir::BinOpKind::Rem);
         let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
             let tcx = cx.tcx;
 
@@ -166,13 +165,35 @@ impl ArithmeticSideEffects {
         None
     }
 
+    /// Methods like `add_assign` are send to their `BinOps` references.
+    fn manage_sugar_methods<'tcx>(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        expr: &'tcx hir::Expr<'_>,
+        lhs: &'tcx hir::Expr<'_>,
+        ps: &hir::PathSegment<'_>,
+        rhs: &'tcx hir::Expr<'_>,
+    ) {
+        if ps.ident.name == sym::add || ps.ident.name == sym::add_assign {
+            self.manage_bin_ops(cx, expr, hir::BinOpKind::Add, lhs, rhs);
+        } else if ps.ident.name == sym::div || ps.ident.name == sym::div_assign {
+            self.manage_bin_ops(cx, expr, hir::BinOpKind::Div, lhs, rhs);
+        } else if ps.ident.name == sym::mul || ps.ident.name == sym::mul_assign {
+            self.manage_bin_ops(cx, expr, hir::BinOpKind::Mul, lhs, rhs);
+        } else if ps.ident.name == sym::rem || ps.ident.name == sym::rem_assign {
+            self.manage_bin_ops(cx, expr, hir::BinOpKind::Rem, lhs, rhs);
+        } else if ps.ident.name == sym::sub || ps.ident.name == sym::sub_assign {
+            self.manage_bin_ops(cx, expr, hir::BinOpKind::Sub, lhs, rhs);
+        }
+    }
+
     /// Manages when the lint should be triggered. Operations in constant environments, hard coded
-    /// types, custom allowed types and non-constant operations that won't overflow are ignored.
+    /// types, custom allowed types and non-constant operations that don't overflow are ignored.
     fn manage_bin_ops<'tcx>(
         &mut self,
         cx: &LateContext<'tcx>,
         expr: &'tcx hir::Expr<'_>,
-        op: &Spanned<hir::BinOpKind>,
+        op: hir::BinOpKind,
         lhs: &'tcx hir::Expr<'_>,
         rhs: &'tcx hir::Expr<'_>,
     ) {
@@ -180,7 +201,7 @@ impl ArithmeticSideEffects {
             return;
         }
         if !matches!(
-            op.node,
+            op,
             hir::BinOpKind::Add
                 | hir::BinOpKind::Div
                 | hir::BinOpKind::Mul
@@ -204,7 +225,7 @@ impl ArithmeticSideEffects {
             return;
         }
         let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
-            if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node {
+            if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op {
                 // At least for integers, shifts are already handled by the CTFE
                 return;
             }
@@ -213,7 +234,7 @@ impl ArithmeticSideEffects {
                 Self::literal_integer(cx, actual_rhs),
             ) {
                 (None, None) => false,
-                (None, Some(n)) => match (&op.node, n) {
+                (None, Some(n)) => match (&op, n) {
                     // Division and module are always valid if applied to non-zero integers
                     (hir::BinOpKind::Div | hir::BinOpKind::Rem, local_n) if local_n != 0 => true,
                     // Adding or subtracting zeros is always a no-op
@@ -223,7 +244,7 @@ impl ArithmeticSideEffects {
                     => true,
                     _ => false,
                 },
-                (Some(n), None) => match (&op.node, n) {
+                (Some(n), None) => match (&op, n) {
                     // Adding or subtracting zeros is always a no-op
                     (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)
                     // Multiplication by 1 or 0 will never overflow
@@ -249,6 +270,7 @@ impl ArithmeticSideEffects {
         &mut self,
         args: &'tcx [hir::Expr<'_>],
         cx: &LateContext<'tcx>,
+        expr: &'tcx hir::Expr<'_>,
         ps: &'tcx hir::PathSegment<'_>,
         receiver: &'tcx hir::Expr<'_>,
     ) {
@@ -262,7 +284,8 @@ impl ArithmeticSideEffects {
         if !Self::is_integral(instance_ty) {
             return;
         }
-        if !self.integer_methods.contains(&ps.ident.name) {
+        self.manage_sugar_methods(cx, expr, receiver, ps, arg);
+        if !self.disallowed_int_methods.contains(&ps.ident.name) {
             return;
         }
         let (actual_arg, _) = peel_hir_expr_refs(arg);
@@ -310,10 +333,10 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
         }
         match &expr.kind {
             hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
-                self.manage_bin_ops(cx, expr, op, lhs, rhs);
+                self.manage_bin_ops(cx, expr, op.node, lhs, rhs);
             },
             hir::ExprKind::MethodCall(ps, receiver, args, _) => {
-                self.manage_method_call(args, cx, ps, receiver);
+                self.manage_method_call(args, cx, expr, ps, receiver);
             },
             hir::ExprKind::Unary(un_op, un_expr) => {
                 self.manage_unary_ops(cx, expr, un_expr, *un_op);
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index cc61ef9184c..2534e3c8468 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -11,9 +11,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::hir_id::{HirId, HirIdMap};
 use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_hir::{
-    self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg,
-    ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
-    TyKind, Unsafety,
+    self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind,
+    ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind, Unsafety,
 };
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{Obligation, ObligationCause};
@@ -687,9 +686,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
             .filter_map(|(i, arg)| {
                 let param = &body.params[arg.idx];
                 match param.pat.kind {
-                    PatKind::Binding(BindingMode::NONE, id, _, None)
-                        if !is_lint_allowed(cx, PTR_ARG, param.hir_id) =>
-                    {
+                    PatKind::Binding(BindingMode::NONE, id, _, None) if !is_lint_allowed(cx, PTR_ARG, param.hir_id) => {
                         Some((id, i))
                     },
                     _ => {
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 4ad967589a5..1f1ce147ca2 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -14,8 +14,8 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::{
-    BindingMode, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath,
-    Stmt, StmtKind,
+    BindingMode, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, Stmt,
+    StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
diff --git a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
index a358881bf80..792d8fc88f0 100644
--- a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -1,7 +1,7 @@
 use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::VecArgs;
-use clippy_utils::macros::root_macro_call;
+use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::source::snippet;
 use clippy_utils::{expr_or_init, fn_def_id, match_def_path, paths};
 use rustc_errors::Applicability;
@@ -65,8 +65,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, s
 
 /// Checks `vec![Vec::with_capacity(x); n]`
 fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) {
-    if let Some(mac_call) = root_macro_call(expr.span)
-        && cx.tcx.is_diagnostic_item(sym::vec_macro, mac_call.def_id)
+    if matching_root_macro_call(cx, expr.span, sym::vec_macro).is_some()
         && let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr)
         && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
         && !len_expr.span.from_expansion()
diff --git a/src/tools/clippy/clippy_lints/src/size_of_ref.rs b/src/tools/clippy/clippy_lints/src/size_of_ref.rs
index 14ca7a3f004..8d7f12af86e 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_ref.rs
@@ -28,7 +28,7 @@ declare_clippy_lint! {
     ///     fn size(&self) -> usize {
     ///         // Note that `&self` as an argument is a `&&Foo`: Because `self`
     ///         // is already a reference, `&self` is a double-reference.
-    ///         // The return value of `size_of_val()` therefor is the
+    ///         // The return value of `size_of_val()` therefore is the
     ///         // size of the reference-type, not the size of `self`.
     ///         std::mem::size_of_val(&self)
     ///     }
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index 28c254537ab..b0e25c02265 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::macros::root_macro_call;
+use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
     get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
@@ -145,9 +145,7 @@ impl SlowVectorInit {
         // Generally don't warn if the vec initializer comes from an expansion, except for the vec! macro.
         // This lets us still warn on `vec![]`, while ignoring other kinds of macros that may output an
         // empty vec
-        if expr.span.from_expansion()
-            && root_macro_call(expr.span).map(|m| m.def_id) != cx.tcx.get_diagnostic_item(sym::vec_macro)
-        {
+        if expr.span.from_expansion() && matching_root_macro_call(cx, expr.span, sym::vec_macro).is_none() {
             return None;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
index c1e24674e3e..4af3ee74d0e 100644
--- a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
@@ -1,13 +1,14 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::macros::macro_backtrace;
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::source::snippet;
 use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks};
 use rustc_errors::Applicability;
-use rustc_hir::{intravisit, ExprKind};
+use rustc_hir::{intravisit, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym::thread_local_macro;
+use rustc_span::sym::{self, thread_local_macro};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -69,6 +70,26 @@ fn is_thread_local_initializer(
     )
 }
 
+fn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    if let Some(macro_call) = macro_backtrace(expr.span).next()
+        && let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id)
+    {
+        return (matches!(
+            diag_name,
+            sym::core_panic_macro
+                | sym::std_panic_macro
+                | sym::core_panic_2015_macro
+                | sym::std_panic_2015_macro
+                | sym::core_panic_2021_macro
+        ) && !cx.tcx.hir().is_inside_const_context(expr.hir_id))
+            || matches!(
+                diag_name,
+                sym::unimplemented_macro | sym::todo_macro | sym::unreachable_macro | sym::unreachable_2015_macro
+            );
+    }
+    false
+}
+
 #[inline]
 fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: &Msrv) -> bool {
     // Building MIR for `fn`s with unsatisfiable preds results in ICE.
@@ -102,12 +123,17 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
             // for details on this issue, see:
             // https://github.com/rust-lang/rust-clippy/pull/12276
             && !cx.tcx.is_const_fn(defid)
-            && initializer_can_be_made_const(cx, defid, &self.msrv)
-            // we know that the function is const-qualifiable, so now
-            // we need only to get the initializer expression to span-lint it.
             && let ExprKind::Block(block, _) = body.value.kind
             && let Some(unpeeled) = block.expr
             && let ret_expr = peel_blocks(unpeeled)
+            // A common pattern around threadlocal! is to make the value unreachable
+            // to force an initialization before usage
+            // https://github.com/rust-lang/rust-clippy/issues/12637
+            // we ensure that this is reachable before we check in mir
+            && !is_unreachable(cx, ret_expr)
+            && initializer_can_be_made_const(cx, defid, &self.msrv)
+            // we know that the function is const-qualifiable, so now
+            // we need only to get the initializer expression to span-lint it.
             && let initializer_snippet = snippet(cx, ret_expr.span, "thread_local! { ... }")
             && initializer_snippet != "thread_local! { ... }"
         {
diff --git a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
index 59ae185c9de..0361836cdec 100644
--- a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
@@ -38,7 +38,7 @@ declare_clippy_lint! {
     ///   }
     /// }
     /// ```
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub TO_STRING_TRAIT_IMPL,
     style,
     "check for direct implementations of `ToString`"
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 9468d367a92..c05cd9ed593 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -237,6 +237,7 @@ impl TraitBounds {
         }
     }
 
+    #[allow(clippy::mutable_key_type)]
     fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
         struct SpanlessTy<'cx, 'tcx> {
             ty: &'tcx Ty<'tcx>,
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 0802cb2b7c7..5e45ab211ef 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -12,8 +12,8 @@ mod vec_box;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitItem,
-    TraitItemKind, TyKind,
+    Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitFn,
+    TraitItem, TraitItemKind, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -420,7 +420,13 @@ impl<'tcx> LateLintPass<'tcx> for Types {
             TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => {
                 self.check_ty(cx, ty, context);
             },
-            TraitItemKind::Fn(ref sig, _) => self.check_fn_decl(cx, sig.decl, context),
+            TraitItemKind::Fn(ref sig, trait_method) => {
+                // Check only methods without body
+                // Methods with body are covered by check_fn.
+                if let TraitFn::Required(_) = trait_method {
+                    self.check_fn_decl(cx, sig.decl, context);
+                }
+            },
             TraitItemKind::Type(..) => (),
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 7f0769452c7..4448c9ae3df 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -7,8 +7,8 @@ use rustc_ast::LitIntType;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::{
-    ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit,
-    PatKind, QPath, StmtKind, TyKind,
+    ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind,
+    QPath, StmtKind, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 27ead55bf39..9edf7579d48 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -7,7 +7,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_local_use_after_expr;
-use clippy_utils::{get_parent_expr, higher, is_trait_method};
+use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -22,6 +22,7 @@ pub struct UselessVec {
     pub too_large_for_stack: u64,
     pub msrv: Msrv,
     pub span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
+    pub allow_in_test: bool,
 }
 
 declare_clippy_lint! {
@@ -57,6 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
         let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
             return;
         };
+        if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
+            return;
+        };
         // the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
         let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
 
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index c46f0298cc8..a599415a2dd 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -6,9 +6,7 @@ use clippy_utils::{get_parent_expr, path_to_local_id};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::{
-    BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp,
-};
+use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index d2bb719a517..ab883c25338 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.79"
+version = "0.1.80"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 0395eb1449b..529d20126b2 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -446,7 +446,18 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
 pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
     use ForeignItemKind::*;
     match (l, r) {
-        (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        (
+            Static(box StaticForeignItem {
+                ty: lt,
+                mutability: lm,
+                expr: le,
+            }),
+            Static(box StaticForeignItem {
+                ty: rt,
+                mutability: rm,
+                expr: re,
+            }),
+        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 5e242aea354..a49414a058b 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -2328,10 +2328,10 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<S
 ///
 /// Given functions `eq` and `hash` such that `eq(a, b) == true`
 /// implies `hash(a) == hash(b)`
-pub fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)>
+pub fn search_same<T, Hash, Eq>(exprs: &[T], mut hash: Hash, mut eq: Eq) -> Vec<(&T, &T)>
 where
-    Hash: Fn(&T) -> u64,
-    Eq: Fn(&T, &T) -> bool,
+    Hash: FnMut(&T) -> u64,
+    Eq: FnMut(&T, &T) -> bool,
 {
     match exprs {
         [a, b] if eq(a, b) => return vec![(a, b)],
@@ -2505,8 +2505,9 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
 /// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function
 pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
     with_test_item_names(tcx, tcx.parent_module(id), |names| {
-        tcx.hir()
-            .parent_iter(id)
+        let node = tcx.hir_node(id);
+        once((id, node))
+            .chain(tcx.hir().parent_iter(id))
             // Since you can nest functions we need to collect all until we leave
             // function scope
             .any(|(_id, node)| {
@@ -2547,6 +2548,11 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
         .any(|parent_id| is_cfg_test(tcx, parent_id))
 }
 
+/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]`
+pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {
+    is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id)
+}
+
 /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
 pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     let hir = tcx.hir();
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index f166087dc3c..257dd76ab15 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -119,10 +119,20 @@ pub fn macro_backtrace(span: Span) -> impl Iterator<Item = MacroCall> {
 
 /// If the macro backtrace of `span` has a macro call at the root expansion
 /// (i.e. not a nested macro call), returns `Some` with the `MacroCall`
+///
+/// If you only want to check whether the root macro has a specific name,
+/// consider using [`matching_root_macro_call`] instead.
 pub fn root_macro_call(span: Span) -> Option<MacroCall> {
     macro_backtrace(span).last()
 }
 
+/// A combination of [`root_macro_call`] and
+/// [`is_diagnostic_item`](rustc_middle::ty::TyCtxt::is_diagnostic_item) that returns a `MacroCall`
+/// at the root expansion if only it matches the given name.
+pub fn matching_root_macro_call(cx: &LateContext<'_>, span: Span, name: Symbol) -> Option<MacroCall> {
+    root_macro_call(span).filter(|mc| cx.tcx.is_diagnostic_item(name, mc.def_id))
+}
+
 /// Like [`root_macro_call`], but only returns `Some` if `node` is the "first node"
 /// produced by the macro call, as in [`first_node_in_macro`].
 pub fn root_macro_call_first_node(cx: &LateContext<'_>, node: &impl HirNode) -> Option<MacroCall> {
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 456b8019e95..9bf068ee3cd 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -19,8 +19,6 @@ pub const BTREESET_ITER: [&str; 6] = ["alloc", "collections", "btree", "set", "B
 pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
 pub const CORE_ITER_CLONED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "cloned"];
 pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "copied"];
-pub const CORE_ITER_ENUMERATE_METHOD: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "enumerate"];
-pub const CORE_ITER_ENUMERATE_STRUCT: [&str; 5] = ["core", "iter", "adapters", "enumerate", "Enumerate"];
 pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"];
 pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"];
 pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"];
@@ -73,7 +71,6 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"];
 pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"];
 pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
 pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
-pub const SLICE_GET: [&str; 4] = ["core", "slice", "<impl [T]>", "get"];
 pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
 pub const SLICE_INTO: [&str; 4] = ["core", "slice", "<impl [T]>", "iter"];
 pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"];
@@ -81,7 +78,6 @@ pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"];
 pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
 pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
 pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"];
-pub const STR_BYTES: [&str; 4] = ["core", "str", "<impl str>", "bytes"];
 pub const STR_CHARS: [&str; 4] = ["core", "str", "<impl str>", "chars"];
 pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
 pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
@@ -108,7 +104,6 @@ pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "Vec
 pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
 pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
 pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"];
-pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
 pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"];
 pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"];
 pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"];
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index a06a82c5653..23750ed4d1b 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -29,9 +29,10 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
 use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
 use rustc_trait_selection::traits::{Obligation, ObligationCause};
 use std::assert_matches::debug_assert_matches;
+use std::collections::hash_map::Entry;
 use std::iter;
 
-use crate::{match_def_path, path_res};
+use crate::{def_path_def_ids, match_def_path, path_res};
 
 mod type_certainty;
 pub use type_certainty::expr_type_is_certain;
@@ -1198,47 +1199,88 @@ pub fn make_normalized_projection<'tcx>(
     helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?)
 }
 
-/// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`]
-/// etc.
-pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
-    match *ty.kind() {
-        ty::Ref(_, inner_ty, mutbl) => mutbl == Mutability::Mut || is_interior_mut_ty(cx, inner_ty),
-        ty::Slice(inner_ty) => is_interior_mut_ty(cx, inner_ty),
-        ty::Array(inner_ty, size) => {
-            size.try_eval_target_usize(cx.tcx, cx.param_env)
-                .map_or(true, |u| u != 0)
-                && is_interior_mut_ty(cx, inner_ty)
-        },
-        ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)),
-        ty::Adt(def, args) => {
-            // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
-            // that of their type parameters.  Note: we don't include `HashSet` and `HashMap`
-            // because they have no impl for `Hash` or `Ord`.
-            let def_id = def.did();
-            let is_std_collection = [
-                sym::Option,
-                sym::Result,
-                sym::LinkedList,
-                sym::Vec,
-                sym::VecDeque,
-                sym::BTreeMap,
-                sym::BTreeSet,
-                sym::Rc,
-                sym::Arc,
-            ]
+/// Helper to check if given type has inner mutability such as [`std::cell::Cell`] or
+/// [`std::cell::RefCell`].
+#[derive(Default, Debug)]
+pub struct InteriorMut<'tcx> {
+    ignored_def_ids: FxHashSet<DefId>,
+    ignore_pointers: bool,
+    tys: FxHashMap<Ty<'tcx>, Option<bool>>,
+}
+
+impl<'tcx> InteriorMut<'tcx> {
+    pub fn new(cx: &LateContext<'tcx>, ignore_interior_mutability: &[String]) -> Self {
+        let ignored_def_ids = ignore_interior_mutability
             .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id));
-            let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
-            if is_std_collection || is_box {
-                // The type is mutable if any of its type parameters are
-                args.types().any(|ty| is_interior_mut_ty(cx, ty))
-            } else {
-                !ty.has_escaping_bound_vars()
-                    && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
-                    && !ty.is_freeze(cx.tcx, cx.param_env)
-            }
-        },
-        _ => false,
+            .flat_map(|ignored_ty| {
+                let path: Vec<&str> = ignored_ty.split("::").collect();
+                def_path_def_ids(cx, path.as_slice())
+            })
+            .collect();
+
+        Self {
+            ignored_def_ids,
+            ..Self::default()
+        }
+    }
+
+    pub fn without_pointers(cx: &LateContext<'tcx>, ignore_interior_mutability: &[String]) -> Self {
+        Self {
+            ignore_pointers: true,
+            ..Self::new(cx, ignore_interior_mutability)
+        }
+    }
+
+    /// Check if given type has inner mutability such as [`std::cell::Cell`] or
+    /// [`std::cell::RefCell`] etc.
+    pub fn is_interior_mut_ty(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
+        match self.tys.entry(ty) {
+            Entry::Occupied(o) => return *o.get() == Some(true),
+            // Temporarily insert a `None` to break cycles
+            Entry::Vacant(v) => v.insert(None),
+        };
+
+        let interior_mut = match *ty.kind() {
+            ty::RawPtr(inner_ty, _) if !self.ignore_pointers => self.is_interior_mut_ty(cx, inner_ty),
+            ty::Ref(_, inner_ty, _) | ty::Slice(inner_ty) => self.is_interior_mut_ty(cx, inner_ty),
+            ty::Array(inner_ty, size) => {
+                size.try_eval_target_usize(cx.tcx, cx.param_env)
+                    .map_or(true, |u| u != 0)
+                    && self.is_interior_mut_ty(cx, inner_ty)
+            },
+            ty::Tuple(fields) => fields.iter().any(|ty| self.is_interior_mut_ty(cx, ty)),
+            ty::Adt(def, _) if def.is_unsafe_cell() => true,
+            ty::Adt(def, args) => {
+                let is_std_collection = matches!(
+                    cx.tcx.get_diagnostic_name(def.did()),
+                    Some(
+                        sym::LinkedList
+                            | sym::Vec
+                            | sym::VecDeque
+                            | sym::BTreeMap
+                            | sym::BTreeSet
+                            | sym::HashMap
+                            | sym::HashSet
+                            | sym::Arc
+                            | sym::Rc
+                    )
+                );
+
+                if is_std_collection || def.is_box() {
+                    // Include the types from std collections that are behind pointers internally
+                    args.types().any(|ty| self.is_interior_mut_ty(cx, ty))
+                } else if self.ignored_def_ids.contains(&def.did()) || def.is_phantom_data() {
+                    false
+                } else {
+                    def.all_fields()
+                        .any(|f| self.is_interior_mut_ty(cx, f.ty(cx.tcx, args)))
+                }
+            },
+            _ => false,
+        };
+
+        self.tys.insert(ty, Some(interior_mut));
+        interior_mut
     }
 }
 
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index 9a3a41e1d1e..c8c734c3a7c 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "declare_clippy_lint"
-version = "0.1.79"
+version = "0.1.80"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 521c0d12983..055f305eb8e 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-04-18"
+channel = "nightly-2024-05-02"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 32a31f5e082..b06a11702ec 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -4,6 +4,7 @@
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(unused_extern_crates)]
 
+use ui_test::custom_flags::rustfix::RustfixMode;
 use ui_test::spanned::Spanned;
 use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, Mode, OutputConflictHandling};
 
@@ -122,10 +123,11 @@ fn base_config(test_dir: &str) -> (Config, Args) {
         out_dir: target_dir.join("ui_test"),
         ..Config::rustc(Path::new("tests").join(test_dir))
     };
-    config.comment_defaults.base().mode = Some(Spanned::dummy(Mode::Yolo {
-        rustfix: ui_test::RustfixMode::Everything,
-    }))
-    .into();
+    config.comment_defaults.base().mode = Some(Spanned::dummy(Mode::Yolo)).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();
@@ -235,13 +237,12 @@ fn run_ui_cargo() {
         .push(("RUSTFLAGS".into(), Some("-Dwarnings".into())));
     // We need to do this while we still have a rustc in the `program` field.
     config.fill_host_and_target().unwrap();
-    config.dependencies_crate_manifest_path = None;
     config.program.program.set_file_name(if cfg!(windows) {
         "cargo-clippy.exe"
     } else {
         "cargo-clippy"
     });
-    config.comment_defaults.base().edition = Default::default();
+    config.comment_defaults.base().custom.clear();
 
     config
         .comment_defaults
diff --git a/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs
index 095e0d15448..3a8e3741e20 100644
--- a/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs
+++ b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs
@@ -44,10 +44,18 @@ impl<T> Deref for Counted<T> {
     }
 }
 
+#[derive(Hash, PartialEq, Eq)]
+struct ContainsCounted {
+    inner: Counted<String>,
+}
+
 // This is not linted because `"mut_key::Counted"` is in
 // `arc_like_types` in `clippy.toml`
 fn should_not_take_this_arg(_v: HashSet<Counted<String>>) {}
 
+fn indirect(_: HashMap<ContainsCounted, usize>) {}
+
 fn main() {
     should_not_take_this_arg(HashSet::new());
+    indirect(HashMap::new());
 }
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 24645b61fdb..722e9b3bc8d 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allow-useless-vec-in-tests
            allowed-dotfiles
            allowed-duplicate-crates
            allowed-idents-below-min-chars
@@ -91,6 +92,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allow-useless-vec-in-tests
            allowed-dotfiles
            allowed-duplicate-crates
            allowed-idents-below-min-chars
@@ -171,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allow-useless-vec-in-tests
            allowed-dotfiles
            allowed-duplicate-crates
            allowed-idents-below-min-chars
diff --git a/src/tools/clippy/tests/ui-toml/useless_vec/clippy.toml b/src/tools/clippy/tests/ui-toml/useless_vec/clippy.toml
new file mode 100644
index 00000000000..230ca2d0ab7
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/useless_vec/clippy.toml
@@ -0,0 +1 @@
+allow-useless-vec-in-tests = true
diff --git a/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.fixed b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.fixed
new file mode 100644
index 00000000000..08323a0dcc9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.fixed
@@ -0,0 +1,26 @@
+//@compile-flags: --test
+#![warn(clippy::useless_vec)]
+#![allow(clippy::unnecessary_operation, clippy::no_effect)]
+
+fn foo(_: &[u32]) {}
+
+fn main() {
+    foo(&[1_u32]);
+}
+
+#[test]
+pub fn in_test() {
+    foo(&vec![2_u32]);
+}
+
+#[cfg(test)]
+fn in_cfg_test() {
+    foo(&vec![3_u32]);
+}
+
+#[cfg(test)]
+mod mod1 {
+    fn in_cfg_test_mod() {
+        super::foo(&vec![4_u32]);
+    }
+}
diff --git a/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.rs b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.rs
new file mode 100644
index 00000000000..1f4b27c5342
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.rs
@@ -0,0 +1,26 @@
+//@compile-flags: --test
+#![warn(clippy::useless_vec)]
+#![allow(clippy::unnecessary_operation, clippy::no_effect)]
+
+fn foo(_: &[u32]) {}
+
+fn main() {
+    foo(&vec![1_u32]);
+}
+
+#[test]
+pub fn in_test() {
+    foo(&vec![2_u32]);
+}
+
+#[cfg(test)]
+fn in_cfg_test() {
+    foo(&vec![3_u32]);
+}
+
+#[cfg(test)]
+mod mod1 {
+    fn in_cfg_test_mod() {
+        super::foo(&vec![4_u32]);
+    }
+}
diff --git a/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.stderr b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.stderr
new file mode 100644
index 00000000000..633110c3c8d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/useless_vec/useless_vec.stderr
@@ -0,0 +1,11 @@
+error: useless use of `vec!`
+  --> tests/ui-toml/useless_vec/useless_vec.rs:8:9
+   |
+LL |     foo(&vec![1_u32]);
+   |         ^^^^^^^^^^^^ help: you can use a slice directly: `&[1_u32]`
+   |
+   = note: `-D clippy::useless-vec` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index fdec14a1528..66d71f337f2 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -521,4 +521,14 @@ pub fn issue_11393() {
     example_rem(x, maybe_zero);
 }
 
+pub fn issue_12318() {
+    use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
+    let mut one: i32 = 1;
+    one.add_assign(1);
+    one.div_assign(1);
+    one.mul_assign(1);
+    one.rem_assign(1);
+    one.sub_assign(1);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index 741c892a52c..8039c0bfa24 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -715,5 +715,17 @@ error: arithmetic operation that can potentially result in unexpected side-effec
 LL |         x % maybe_zero
    |         ^^^^^^^^^^^^^^
 
-error: aborting due to 119 previous errors
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:527:5
+   |
+LL |     one.add_assign(1);
+   |     ^^^^^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:531:5
+   |
+LL |     one.sub_assign(1);
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 121 previous errors
 
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
index 3303eb14567..6e6919cd295 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
@@ -9,6 +9,7 @@ use proc_macro::token_stream::IntoIter;
 use proc_macro::Delimiter::{self, Brace, Parenthesis};
 use proc_macro::Spacing::{self, Alone, Joint};
 use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT};
+use syn::spanned::Spanned;
 
 type Result<T> = core::result::Result<T, TokenStream>;
 
@@ -124,6 +125,22 @@ fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Resul
     Ok(())
 }
 
+/// Takes an array repeat expression such as `[0_u32; 2]`, and return the tokens with 10 times the
+/// original size, which turns to `[0_u32; 20]`.
+#[proc_macro]
+pub fn make_it_big(input: TokenStream) -> TokenStream {
+    let mut expr_repeat = syn::parse_macro_input!(input as syn::ExprRepeat);
+    let len_span = expr_repeat.len.span();
+    if let syn::Expr::Lit(expr_lit) = &mut *expr_repeat.len {
+        if let syn::Lit::Int(lit_int) = &expr_lit.lit {
+            let orig_val = lit_int.base10_parse::<usize>().expect("not a valid length parameter");
+            let new_val = orig_val.saturating_mul(10);
+            expr_lit.lit = syn::parse_quote_spanned!( len_span => #new_val);
+        }
+    }
+    quote::quote!(#expr_repeat).into()
+}
+
 /// Within the item this attribute is attached to, an `inline!` macro is available which expands the
 /// contained tokens as though they came from a macro expansion.
 ///
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.rs
index 4da3833cbf5..5570e7cd6d2 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.rs
@@ -158,7 +158,7 @@ trait BothOfCellAndGeneric<T> {
     const INDIRECT: Cell<*const T>;
 
     fn function() {
-        let _ = &Self::DIRECT;
+        let _ = &Self::DIRECT; //~ ERROR: interior mutability
         let _ = &Self::INDIRECT; //~ ERROR: interior mutability
     }
 }
@@ -168,7 +168,7 @@ impl<T: ConstDefault> BothOfCellAndGeneric<T> for Vec<T> {
     const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
 
     fn function() {
-        let _ = &Self::DIRECT;
+        let _ = &Self::DIRECT; //~ ERROR: interior mutability
         let _ = &Self::INDIRECT; //~ ERROR: interior mutability
     }
 }
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
index 582b744b49f..8602b46b0dc 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
@@ -76,6 +76,14 @@ LL |         let _ = &Self::WRAPPED_SELF;
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
+  --> tests/ui/borrow_interior_mutable_const/traits.rs:161:18
+   |
+LL |         let _ = &Self::DIRECT;
+   |                  ^^^^^^^^^^^^
+   |
+   = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
   --> tests/ui/borrow_interior_mutable_const/traits.rs:162:18
    |
 LL |         let _ = &Self::INDIRECT;
@@ -84,6 +92,14 @@ LL |         let _ = &Self::INDIRECT;
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
+  --> tests/ui/borrow_interior_mutable_const/traits.rs:171:18
+   |
+LL |         let _ = &Self::DIRECT;
+   |                  ^^^^^^^^^^^^
+   |
+   = help: assign this const to a local or static variable, and use the variable here
+
+error: a `const` item with interior mutability should not be borrowed
   --> tests/ui/borrow_interior_mutable_const/traits.rs:172:18
    |
 LL |         let _ = &Self::INDIRECT;
@@ -123,5 +139,5 @@ LL |     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9);
    |
    = help: assign this const to a local or static variable, and use the variable here
 
-error: aborting due to 15 previous errors
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed
index 6c2896b3aa0..1f2f57c2507 100644
--- a/src/tools/clippy/tests/ui/box_default.fixed
+++ b/src/tools/clippy/tests/ui/box_default.fixed
@@ -65,6 +65,8 @@ fn main() {
     // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563
     let mut unnameable = Box::new(Option::default());
     let _ = unnameable.insert(|| {});
+
+    let _ = Box::into_raw(Box::new(String::default()));
 }
 
 fn ret_ty_fn() -> Box<bool> {
@@ -75,6 +77,16 @@ fn call_ty_fn(_b: Box<u8>) {
     issue_9621_dyn_trait();
 }
 
+struct X<T>(T);
+
+impl<T: Default> X<T> {
+    fn x(_: Box<T>) {}
+
+    fn same_generic_param() {
+        Self::x(Box::default());
+    }
+}
+
 use std::io::{Read, Result};
 
 impl Read for ImplementsDefault {
diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs
index e19a62a9022..addfebc24f5 100644
--- a/src/tools/clippy/tests/ui/box_default.rs
+++ b/src/tools/clippy/tests/ui/box_default.rs
@@ -65,6 +65,8 @@ fn main() {
     // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563
     let mut unnameable = Box::new(Option::default());
     let _ = unnameable.insert(|| {});
+
+    let _ = Box::into_raw(Box::new(String::default()));
 }
 
 fn ret_ty_fn() -> Box<bool> {
@@ -75,6 +77,16 @@ fn call_ty_fn(_b: Box<u8>) {
     issue_9621_dyn_trait();
 }
 
+struct X<T>(T);
+
+impl<T: Default> X<T> {
+    fn x(_: Box<T>) {}
+
+    fn same_generic_param() {
+        Self::x(Box::new(T::default()));
+    }
+}
+
 use std::io::{Read, Result};
 
 impl Read for ImplementsDefault {
diff --git a/src/tools/clippy/tests/ui/box_default.stderr b/src/tools/clippy/tests/ui/box_default.stderr
index f172a875dce..39fd0d29bbf 100644
--- a/src/tools/clippy/tests/ui/box_default.stderr
+++ b/src/tools/clippy/tests/ui/box_default.stderr
@@ -55,5 +55,11 @@ error: `Box::new(_)` of default value
 LL |     call_ty_fn(Box::new(u8::default()));
    |                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
-error: aborting due to 9 previous errors
+error: `Box::new(_)` of default value
+  --> tests/ui/box_default.rs:86:17
+   |
+LL |         Self::x(Box::new(T::default()));
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index 215c008902d..453d62ce607 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -13,7 +13,8 @@
     clippy::cast_abs_to_unsigned,
     clippy::no_effect,
     clippy::unnecessary_operation,
-    clippy::unnecessary_literal_unwrap
+    clippy::unnecessary_literal_unwrap,
+    clippy::identity_op
 )]
 
 fn main() {
@@ -479,3 +480,21 @@ fn issue12506() -> usize {
     let bar: Result<Option<i64>, u32> = Ok(Some(10));
     bar.unwrap().unwrap() as usize
 }
+
+fn issue12721() {
+    fn x() -> u64 {
+        u64::MAX
+    }
+
+    // Don't lint.
+    (255 & 999999u64) as u8;
+    // Don't lint.
+    let _ = ((x() & 255) & 999999) as u8;
+    // Don't lint.
+    let _ = (999999 & (x() & 255)) as u8;
+
+    (256 & 999999u64) as u8;
+    //~^ ERROR: casting `u64` to `u8` may truncate the value
+    (255 % 999999u64) as u8;
+    //~^ ERROR: casting `u64` to `u8` may truncate the value
+}
diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr
index 8b269c47176..43c0d8f4ed7 100644
--- a/src/tools/clippy/tests/ui/cast.stderr
+++ b/src/tools/clippy/tests/ui/cast.stderr
@@ -1,5 +1,5 @@
 error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:22:5
+  --> tests/ui/cast.rs:23:5
    |
 LL |     x0 as f32;
    |     ^^^^^^^^^
@@ -8,37 +8,37 @@ LL |     x0 as f32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
 
 error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:26:5
+  --> tests/ui/cast.rs:27:5
    |
 LL |     x1 as f32;
    |     ^^^^^^^^^
 
 error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
-  --> tests/ui/cast.rs:28:5
+  --> tests/ui/cast.rs:29:5
    |
 LL |     x1 as f64;
    |     ^^^^^^^^^
 
 error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:31:5
+  --> tests/ui/cast.rs:32:5
    |
 LL |     x2 as f32;
    |     ^^^^^^^^^
 
 error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:34:5
+  --> tests/ui/cast.rs:35:5
    |
 LL |     x3 as f32;
    |     ^^^^^^^^^
 
 error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
-  --> tests/ui/cast.rs:36:5
+  --> tests/ui/cast.rs:37:5
    |
 LL |     x3 as f64;
    |     ^^^^^^^^^
 
 error: casting `f32` to `i32` may truncate the value
-  --> tests/ui/cast.rs:39:5
+  --> tests/ui/cast.rs:40:5
    |
 LL |     1f32 as i32;
    |     ^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     1f32 as i32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
 
 error: casting `f32` to `u32` may truncate the value
-  --> tests/ui/cast.rs:41:5
+  --> tests/ui/cast.rs:42:5
    |
 LL |     1f32 as u32;
    |     ^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     1f32 as u32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:41:5
+  --> tests/ui/cast.rs:42:5
    |
 LL |     1f32 as u32;
    |     ^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     1f32 as u32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]`
 
 error: casting `f64` to `f32` may truncate the value
-  --> tests/ui/cast.rs:45:5
+  --> tests/ui/cast.rs:46:5
    |
 LL |     1f64 as f32;
    |     ^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     1f64 as f32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `i32` to `i8` may truncate the value
-  --> tests/ui/cast.rs:47:5
+  --> tests/ui/cast.rs:48:5
    |
 LL |     1i32 as i8;
    |     ^^^^^^^^^^
@@ -85,7 +85,7 @@ LL |     i8::try_from(1i32);
    |     ~~~~~~~~~~~~~~~~~~
 
 error: casting `i32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:49:5
+  --> tests/ui/cast.rs:50:5
    |
 LL |     1i32 as u8;
    |     ^^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     u8::try_from(1i32);
    |     ~~~~~~~~~~~~~~~~~~
 
 error: casting `f64` to `isize` may truncate the value
-  --> tests/ui/cast.rs:51:5
+  --> tests/ui/cast.rs:52:5
    |
 LL |     1f64 as isize;
    |     ^^^^^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     1f64 as isize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `usize` may truncate the value
-  --> tests/ui/cast.rs:53:5
+  --> tests/ui/cast.rs:54:5
    |
 LL |     1f64 as usize;
    |     ^^^^^^^^^^^^^
@@ -113,13 +113,13 @@ LL |     1f64 as usize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:53:5
+  --> tests/ui/cast.rs:54:5
    |
 LL |     1f64 as usize;
    |     ^^^^^^^^^^^^^
 
 error: casting `u32` to `u16` may truncate the value
-  --> tests/ui/cast.rs:56:5
+  --> tests/ui/cast.rs:57:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     u16::try_from(1f32 as u32);
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `f32` to `u32` may truncate the value
-  --> tests/ui/cast.rs:56:5
+  --> tests/ui/cast.rs:57:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^
@@ -139,13 +139,13 @@ LL |     1f32 as u32 as u16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:56:5
+  --> tests/ui/cast.rs:57:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^
 
 error: casting `i32` to `i8` may truncate the value
-  --> tests/ui/cast.rs:61:22
+  --> tests/ui/cast.rs:62:22
    |
 LL |         let _x: i8 = 1i32 as _;
    |                      ^^^^^^^^^
@@ -157,7 +157,7 @@ LL |         let _x: i8 = 1i32.try_into();
    |                      ~~~~~~~~~~~~~~~
 
 error: casting `f32` to `i32` may truncate the value
-  --> tests/ui/cast.rs:63:9
+  --> tests/ui/cast.rs:64:9
    |
 LL |         1f32 as i32;
    |         ^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         1f32 as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `i32` may truncate the value
-  --> tests/ui/cast.rs:65:9
+  --> tests/ui/cast.rs:66:9
    |
 LL |         1f64 as i32;
    |         ^^^^^^^^^^^
@@ -173,7 +173,7 @@ LL |         1f64 as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:67:9
+  --> tests/ui/cast.rs:68:9
    |
 LL |         1f32 as u8;
    |         ^^^^^^^^^^
@@ -181,13 +181,13 @@ LL |         1f32 as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u8` may lose the sign of the value
-  --> tests/ui/cast.rs:67:9
+  --> tests/ui/cast.rs:68:9
    |
 LL |         1f32 as u8;
    |         ^^^^^^^^^^
 
 error: casting `u8` to `i8` may wrap around the value
-  --> tests/ui/cast.rs:72:5
+  --> tests/ui/cast.rs:73:5
    |
 LL |     1u8 as i8;
    |     ^^^^^^^^^
@@ -196,31 +196,31 @@ LL |     1u8 as i8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
 
 error: casting `u16` to `i16` may wrap around the value
-  --> tests/ui/cast.rs:75:5
+  --> tests/ui/cast.rs:76:5
    |
 LL |     1u16 as i16;
    |     ^^^^^^^^^^^
 
 error: casting `u32` to `i32` may wrap around the value
-  --> tests/ui/cast.rs:77:5
+  --> tests/ui/cast.rs:78:5
    |
 LL |     1u32 as i32;
    |     ^^^^^^^^^^^
 
 error: casting `u64` to `i64` may wrap around the value
-  --> tests/ui/cast.rs:79:5
+  --> tests/ui/cast.rs:80:5
    |
 LL |     1u64 as i64;
    |     ^^^^^^^^^^^
 
 error: casting `usize` to `isize` may wrap around the value
-  --> tests/ui/cast.rs:81:5
+  --> tests/ui/cast.rs:82:5
    |
 LL |     1usize as isize;
    |     ^^^^^^^^^^^^^^^
 
 error: casting `usize` to `i8` may truncate the value
-  --> tests/ui/cast.rs:84:5
+  --> tests/ui/cast.rs:85:5
    |
 LL |     1usize as i8;
    |     ^^^^^^^^^^^^
@@ -232,7 +232,7 @@ LL |     i8::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i16` may truncate the value
-  --> tests/ui/cast.rs:87:5
+  --> tests/ui/cast.rs:88:5
    |
 LL |     1usize as i16;
    |     ^^^^^^^^^^^^^
@@ -244,7 +244,7 @@ LL |     i16::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers
-  --> tests/ui/cast.rs:87:5
+  --> tests/ui/cast.rs:88:5
    |
 LL |     1usize as i16;
    |     ^^^^^^^^^^^^^
@@ -253,7 +253,7 @@ LL |     1usize as i16;
    = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
 
 error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:92:5
+  --> tests/ui/cast.rs:93:5
    |
 LL |     1usize as i32;
    |     ^^^^^^^^^^^^^
@@ -265,19 +265,19 @@ LL |     i32::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:92:5
+  --> tests/ui/cast.rs:93:5
    |
 LL |     1usize as i32;
    |     ^^^^^^^^^^^^^
 
 error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:96:5
+  --> tests/ui/cast.rs:97:5
    |
 LL |     1usize as i64;
    |     ^^^^^^^^^^^^^
 
 error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers
-  --> tests/ui/cast.rs:101:5
+  --> tests/ui/cast.rs:102:5
    |
 LL |     1u16 as isize;
    |     ^^^^^^^^^^^^^
@@ -286,13 +286,13 @@ LL |     1u16 as isize;
    = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
 
 error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:105:5
+  --> tests/ui/cast.rs:106:5
    |
 LL |     1u32 as isize;
    |     ^^^^^^^^^^^^^
 
 error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:108:5
+  --> tests/ui/cast.rs:109:5
    |
 LL |     1u64 as isize;
    |     ^^^^^^^^^^^^^
@@ -304,55 +304,55 @@ LL |     isize::try_from(1u64);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:108:5
+  --> tests/ui/cast.rs:109:5
    |
 LL |     1u64 as isize;
    |     ^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:113:5
+  --> tests/ui/cast.rs:114:5
    |
 LL |     -1i32 as u32;
    |     ^^^^^^^^^^^^
 
 error: casting `isize` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:116:5
+  --> tests/ui/cast.rs:117:5
    |
 LL |     -1isize as usize;
    |     ^^^^^^^^^^^^^^^^
 
 error: casting `i8` to `u8` may lose the sign of the value
-  --> tests/ui/cast.rs:127:5
+  --> tests/ui/cast.rs:128:5
    |
 LL |     (i8::MIN).abs() as u8;
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:131:5
+  --> tests/ui/cast.rs:132:5
    |
 LL |     (-1i64).abs() as u64;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `isize` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:132:5
+  --> tests/ui/cast.rs:133:5
    |
 LL |     (-1isize).abs() as usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:139:5
+  --> tests/ui/cast.rs:140:5
    |
 LL |     (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:154:5
+  --> tests/ui/cast.rs:155:5
    |
 LL |     (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `i8` may truncate the value
-  --> tests/ui/cast.rs:205:5
+  --> tests/ui/cast.rs:206:5
    |
 LL |     (-99999999999i64).min(1) as i8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -364,7 +364,7 @@ LL |     i8::try_from((-99999999999i64).min(1));
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u64` to `u8` may truncate the value
-  --> tests/ui/cast.rs:219:5
+  --> tests/ui/cast.rs:220:5
    |
 LL |     999999u64.clamp(0, 256) as u8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -376,7 +376,7 @@ LL |     u8::try_from(999999u64.clamp(0, 256));
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E2` to `u8` may truncate the value
-  --> tests/ui/cast.rs:242:21
+  --> tests/ui/cast.rs:243:21
    |
 LL |             let _ = self as u8;
    |                     ^^^^^^^^^^
@@ -388,7 +388,7 @@ LL |             let _ = u8::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E2::B` to `u8` will truncate the value
-  --> tests/ui/cast.rs:244:21
+  --> tests/ui/cast.rs:245:21
    |
 LL |             let _ = Self::B as u8;
    |                     ^^^^^^^^^^^^^
@@ -397,7 +397,7 @@ LL |             let _ = Self::B as u8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]`
 
 error: casting `main::E5` to `i8` may truncate the value
-  --> tests/ui/cast.rs:286:21
+  --> tests/ui/cast.rs:287:21
    |
 LL |             let _ = self as i8;
    |                     ^^^^^^^^^^
@@ -409,13 +409,13 @@ LL |             let _ = i8::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E5::A` to `i8` will truncate the value
-  --> tests/ui/cast.rs:288:21
+  --> tests/ui/cast.rs:289:21
    |
 LL |             let _ = Self::A as i8;
    |                     ^^^^^^^^^^^^^
 
 error: casting `main::E6` to `i16` may truncate the value
-  --> tests/ui/cast.rs:305:21
+  --> tests/ui/cast.rs:306:21
    |
 LL |             let _ = self as i16;
    |                     ^^^^^^^^^^^
@@ -427,7 +427,7 @@ LL |             let _ = i16::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:324:21
+  --> tests/ui/cast.rs:325:21
    |
 LL |             let _ = self as usize;
    |                     ^^^^^^^^^^^^^
@@ -439,7 +439,7 @@ LL |             let _ = usize::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E10` to `u16` may truncate the value
-  --> tests/ui/cast.rs:371:21
+  --> tests/ui/cast.rs:372:21
    |
 LL |             let _ = self as u16;
    |                     ^^^^^^^^^^^
@@ -451,7 +451,7 @@ LL |             let _ = u16::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~
 
 error: casting `u32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:382:13
+  --> tests/ui/cast.rs:383:13
    |
 LL |     let c = (q >> 16) as u8;
    |             ^^^^^^^^^^^^^^^
@@ -463,7 +463,7 @@ LL |     let c = u8::try_from(q >> 16);
    |             ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:386:13
+  --> tests/ui/cast.rs:387:13
    |
 LL |     let c = (q / 1000) as u8;
    |             ^^^^^^^^^^^^^^^^
@@ -475,85 +475,85 @@ LL |     let c = u8::try_from(q / 1000);
    |             ~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:398:9
+  --> tests/ui/cast.rs:399:9
    |
 LL |         (x * x) as u32;
    |         ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:403:32
+  --> tests/ui/cast.rs:404:32
    |
 LL |     let _a = |x: i32| -> u32 { (x * x * x * x) as u32 };
    |                                ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:405:5
+  --> tests/ui/cast.rs:406:5
    |
 LL |     (2_i32).checked_pow(3).unwrap() as u32;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:406:5
+  --> tests/ui/cast.rs:407:5
    |
 LL |     (-2_i32).pow(3) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:411:5
+  --> tests/ui/cast.rs:412:5
    |
 LL |     (-5_i32 % 2) as u32;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:413:5
+  --> tests/ui/cast.rs:414:5
    |
 LL |     (-5_i32 % -2) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:416:5
+  --> tests/ui/cast.rs:417:5
    |
 LL |     (-2_i32 >> 1) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:420:5
+  --> tests/ui/cast.rs:421:5
    |
 LL |     (x * x) as u32;
    |     ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:421:5
+  --> tests/ui/cast.rs:422:5
    |
 LL |     (x * x * x) as u32;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:425:5
+  --> tests/ui/cast.rs:426:5
    |
 LL |     (y * y * y * y * -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:427:5
+  --> tests/ui/cast.rs:428:5
    |
 LL |     (y * y * y / y * 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:428:5
+  --> tests/ui/cast.rs:429:5
    |
 LL |     (y * y / y * 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:430:5
+  --> tests/ui/cast.rs:431:5
    |
 LL |     (y / y * y * -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `/`
-  --> tests/ui/cast.rs:430:6
+  --> tests/ui/cast.rs:431:6
    |
 LL |     (y / y * y * -2) as u16;
    |      ^^^^^
@@ -561,97 +561,97 @@ LL |     (y / y * y * -2) as u16;
    = note: `#[deny(clippy::eq_op)]` on by default
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:433:5
+  --> tests/ui/cast.rs:434:5
    |
 LL |     (y + y + y + -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:435:5
+  --> tests/ui/cast.rs:436:5
    |
 LL |     (y + y + y + 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:439:5
+  --> tests/ui/cast.rs:440:5
    |
 LL |     (z + -2) as u16;
    |     ^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:441:5
+  --> tests/ui/cast.rs:442:5
    |
 LL |     (z + z + 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:444:9
+  --> tests/ui/cast.rs:445:9
    |
 LL |         (a * a * b * b * c * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:445:9
+  --> tests/ui/cast.rs:446:9
    |
 LL |         (a * b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:447:9
+  --> tests/ui/cast.rs:448:9
    |
 LL |         (a * -b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:449:9
+  --> tests/ui/cast.rs:450:9
    |
 LL |         (a * b * c * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:450:9
+  --> tests/ui/cast.rs:451:9
    |
 LL |         (a * -2) as u32;
    |         ^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:452:9
+  --> tests/ui/cast.rs:453:9
    |
 LL |         (a * b * c * -2) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:454:9
+  --> tests/ui/cast.rs:455:9
    |
 LL |         (a / b) as u32;
    |         ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:455:9
+  --> tests/ui/cast.rs:456:9
    |
 LL |         (a / b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:457:9
+  --> tests/ui/cast.rs:458:9
    |
 LL |         (a / b + b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:459:9
+  --> tests/ui/cast.rs:460:9
    |
 LL |         a.saturating_pow(3) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:461:9
+  --> tests/ui/cast.rs:462:9
    |
 LL |         (a.abs() * b.pow(2) / c.abs()) as u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:469:21
+  --> tests/ui/cast.rs:470:21
    |
 LL |             let _ = i32::MIN as u32; // cast_sign_loss
    |                     ^^^^^^^^^^^^^^^
@@ -662,7 +662,7 @@ LL |     m!();
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: casting `u32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:470:21
+  --> tests/ui/cast.rs:471:21
    |
 LL |             let _ = u32::MAX as u8; // cast_possible_truncation
    |                     ^^^^^^^^^^^^^^
@@ -678,7 +678,7 @@ LL |             let _ = u8::try_from(u32::MAX); // cast_possible_truncation
    |                     ~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `f64` to `f32` may truncate the value
-  --> tests/ui/cast.rs:471:21
+  --> tests/ui/cast.rs:472:21
    |
 LL |             let _ = std::f64::consts::PI as f32; // cast_possible_truncation
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -690,7 +690,7 @@ LL |     m!();
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:480:5
+  --> tests/ui/cast.rs:481:5
    |
 LL |     bar.unwrap().unwrap() as usize
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -702,10 +702,34 @@ LL |     usize::try_from(bar.unwrap().unwrap())
    |
 
 error: casting `i64` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:480:5
+  --> tests/ui/cast.rs:481:5
    |
 LL |     bar.unwrap().unwrap() as usize
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 90 previous errors
+error: casting `u64` to `u8` may truncate the value
+  --> tests/ui/cast.rs:496:5
+   |
+LL |     (256 & 999999u64) as u8;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+help: ... or use `try_from` and handle the error accordingly
+   |
+LL |     u8::try_from(256 & 999999u64);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: casting `u64` to `u8` may truncate the value
+  --> tests/ui/cast.rs:498:5
+   |
+LL |     (255 % 999999u64) as u8;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+help: ... or use `try_from` and handle the error accordingly
+   |
+LL |     u8::try_from(255 % 999999u64);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 92 previous errors
 
diff --git a/src/tools/clippy/tests/ui/collapsible_match.rs b/src/tools/clippy/tests/ui/collapsible_match.rs
index 7501fd2b0bd..2264b560791 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.rs
+++ b/src/tools/clippy/tests/ui/collapsible_match.rs
@@ -4,7 +4,8 @@
     clippy::needless_return,
     clippy::no_effect,
     clippy::single_match,
-    clippy::uninlined_format_args
+    clippy::uninlined_format_args,
+    clippy::let_unit_value
 )]
 
 fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {
@@ -238,13 +239,22 @@ fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u
         },
         _ => return,
     }
-    match make::<Option<E<u32>>>() {
+    #[clippy::msrv = "1.52.0"]
+    let _ = match make::<Option<E<u32>>>() {
         Some(val) => match val {
             E::A(val) | E::B(val) => foo(val),
             _ => return,
         },
         _ => return,
-    }
+    };
+    #[clippy::msrv = "1.53.0"]
+    let _ = match make::<Option<E<u32>>>() {
+        Some(val) => match val {
+            E::A(val) | E::B(val) => foo(val),
+            _ => return,
+        },
+        _ => return,
+    };
     if let Ok(val) = res_opt {
         if let Some(n) = val {
             let _ = || {
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index 46b484ab05c..01944baee79 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -1,5 +1,5 @@
 error: this `match` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:13:20
+  --> tests/ui/collapsible_match.rs:14:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -10,7 +10,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:13:12
+  --> tests/ui/collapsible_match.rs:14:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -21,7 +21,7 @@ LL |             Some(n) => foo(n),
    = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`
 
 error: this `match` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:23:20
+  --> tests/ui/collapsible_match.rs:24:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -32,7 +32,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:23:12
+  --> tests/ui/collapsible_match.rs:24:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -41,7 +41,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:33:9
+  --> tests/ui/collapsible_match.rs:34:9
    |
 LL | /         if let Some(n) = val {
 LL | |
@@ -50,7 +50,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:32:15
+  --> tests/ui/collapsible_match.rs:33:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -58,7 +58,7 @@ LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:41:9
+  --> tests/ui/collapsible_match.rs:42:9
    |
 LL | /         if let Some(n) = val {
 LL | |
@@ -69,7 +69,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:40:15
+  --> tests/ui/collapsible_match.rs:41:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -77,7 +77,7 @@ LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:53:9
+  --> tests/ui/collapsible_match.rs:54:9
    |
 LL | /         match val {
 LL | |
@@ -87,7 +87,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:52:15
+  --> tests/ui/collapsible_match.rs:53:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -96,7 +96,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:63:13
+  --> tests/ui/collapsible_match.rs:64:13
    |
 LL | /             if let Some(n) = val {
 LL | |
@@ -105,7 +105,7 @@ LL | |             }
    | |_____________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:62:12
+  --> tests/ui/collapsible_match.rs:63:12
    |
 LL |         Ok(val) => {
    |            ^^^ replace this binding
@@ -113,7 +113,7 @@ LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:73:9
+  --> tests/ui/collapsible_match.rs:74:9
    |
 LL | /         match val {
 LL | |
@@ -123,7 +123,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:72:15
+  --> tests/ui/collapsible_match.rs:73:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -132,7 +132,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:85:13
+  --> tests/ui/collapsible_match.rs:86:13
    |
 LL | /             if let Some(n) = val {
 LL | |
@@ -143,7 +143,7 @@ LL | |             }
    | |_____________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:84:12
+  --> tests/ui/collapsible_match.rs:85:12
    |
 LL |         Ok(val) => {
    |            ^^^ replace this binding
@@ -151,7 +151,7 @@ LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:97:20
+  --> tests/ui/collapsible_match.rs:98:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -162,7 +162,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:97:12
+  --> tests/ui/collapsible_match.rs:98:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -171,7 +171,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `match`
-  --> tests/ui/collapsible_match.rs:107:22
+  --> tests/ui/collapsible_match.rs:108:22
    |
 LL |           Some(val) => match val {
    |  ______________________^
@@ -182,7 +182,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:107:14
+  --> tests/ui/collapsible_match.rs:108:14
    |
 LL |         Some(val) => match val {
    |              ^^^ replace this binding
@@ -190,8 +190,26 @@ LL |
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
+error: this `match` can be collapsed into the outer `match`
+  --> tests/ui/collapsible_match.rs:252:22
+   |
+LL |           Some(val) => match val {
+   |  ______________________^
+LL | |             E::A(val) | E::B(val) => foo(val),
+LL | |             _ => return,
+LL | |         },
+   | |_________^
+   |
+help: the outer pattern can be modified to include the inner pattern
+  --> tests/ui/collapsible_match.rs:252:14
+   |
+LL |         Some(val) => match val {
+   |              ^^^ replace this binding
+LL |             E::A(val) | E::B(val) => foo(val),
+   |             ^^^^^^^^^^^^^^^^^^^^^ with this pattern
+
 error: this `if let` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:273:9
+  --> tests/ui/collapsible_match.rs:283:9
    |
 LL | /         if let Some(u) = a {
 LL | |
@@ -200,7 +218,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:272:27
+  --> tests/ui/collapsible_match.rs:282:27
    |
 LL |     if let Issue9647::A { a, .. } = x {
    |                           ^ replace this binding
@@ -208,7 +226,7 @@ LL |         if let Some(u) = a {
    |                ^^^^^^^ with this pattern, prefixed by a:
 
 error: this `if let` can be collapsed into the outer `if let`
-  --> tests/ui/collapsible_match.rs:282:9
+  --> tests/ui/collapsible_match.rs:292:9
    |
 LL | /         if let Some(u) = a {
 LL | |
@@ -217,12 +235,12 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> tests/ui/collapsible_match.rs:281:35
+  --> tests/ui/collapsible_match.rs:291:35
    |
 LL |     if let Issue9647::A { a: Some(a), .. } = x {
    |                                   ^ replace this binding
 LL |         if let Some(u) = a {
    |                ^^^^^^^ with this pattern
 
-error: aborting due to 12 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.rs b/src/tools/clippy/tests/ui/collection_is_never_read.rs
index bd281f7870c..eeb10da3402 100644
--- a/src/tools/clippy/tests/ui/collection_is_never_read.rs
+++ b/src/tools/clippy/tests/ui/collection_is_never_read.rs
@@ -222,3 +222,17 @@ fn supported_types() {
     //~^ ERROR: collection is never read
     x.push_front(1);
 }
+
+fn issue11783() {
+    struct Sender;
+    impl Sender {
+        fn send(&self, msg: String) -> Result<(), ()> {
+            // pretend to send message
+            println!("{msg}");
+            Ok(())
+        }
+    }
+
+    let mut users: Vec<Sender> = vec![];
+    users.retain(|user| user.send("hello".to_string()).is_ok());
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5238.rs b/src/tools/clippy/tests/ui/crashes/ice-5238.rs
index fe03a39ad1b..ee2ae4f1a04 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5238.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-5238.rs
@@ -3,7 +3,8 @@
 #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
 
 fn main() {
-    let _ = #[coroutine] || {
+    let _ = #[coroutine]
+    || {
         yield;
     };
 }
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs
index adc53891ef5..490073f97fb 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.rs
@@ -121,13 +121,12 @@ impl SelfType for AtomicUsize {
 // Even though a constant contains a generic type, if it also have an interior mutable type,
 // it should be linted at the definition site.
 trait BothOfCellAndGeneric<T> {
-    // this is a false negative in the current implementation.
-    const DIRECT: Cell<T>;
+    const DIRECT: Cell<T>; //~ ERROR: interior mutable
     const INDIRECT: Cell<*const T>; //~ ERROR: interior mutable
 }
 
 impl<T: ConstDefault> BothOfCellAndGeneric<T> for u64 {
-    const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
+    const DIRECT: Cell<T> = Cell::new(T::DEFAULT); //~ ERROR: interior mutable
     const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null());
 }
 
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
index 328453efa24..1d1e9e2002f 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
@@ -55,22 +55,34 @@ LL |     const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> tests/ui/declare_interior_mutable_const/traits.rs:126:5
+  --> tests/ui/declare_interior_mutable_const/traits.rs:124:5
+   |
+LL |     const DIRECT: Cell<T>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+  --> tests/ui/declare_interior_mutable_const/traits.rs:125:5
    |
 LL |     const INDIRECT: Cell<*const T>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> tests/ui/declare_interior_mutable_const/traits.rs:142:5
+  --> tests/ui/declare_interior_mutable_const/traits.rs:129:5
+   |
+LL |     const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a `const` item should never be interior mutable
+  --> tests/ui/declare_interior_mutable_const/traits.rs:141:5
    |
 LL |     const ATOMIC: AtomicUsize = AtomicUsize::new(18);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: a `const` item should never be interior mutable
-  --> tests/ui/declare_interior_mutable_const/traits.rs:148:5
+  --> tests/ui/declare_interior_mutable_const/traits.rs:147:5
    |
 LL |     const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/disallowed_names.rs b/src/tools/clippy/tests/ui/disallowed_names.rs
index 9a701a2cbcf..13c883409bf 100644
--- a/src/tools/clippy/tests/ui/disallowed_names.rs
+++ b/src/tools/clippy/tests/ui/disallowed_names.rs
@@ -71,3 +71,8 @@ mod tests {
         }
     }
 }
+
+#[test]
+fn test_with_disallowed_name() {
+    let foo = 0;
+}
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index 0649a6cb0f3..f913ae0bb50 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -54,7 +54,7 @@ help: replace the `Into` implementation with `From<ExplicitPaths>`
 LL ~ impl core::convert::From<crate::ExplicitPaths> for bool {
 LL ~     fn from(mut val: crate::ExplicitPaths) -> Self {
 LL ~         let in_closure = || val.0;
-LL | 
+LL |
 LL ~         val.0 = false;
 LL ~         val.0
    |
diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.rs b/src/tools/clippy/tests/ui/large_stack_arrays.rs
index d5c4f95f8c4..6bcaf481c9f 100644
--- a/src/tools/clippy/tests/ui/large_stack_arrays.rs
+++ b/src/tools/clippy/tests/ui/large_stack_arrays.rs
@@ -1,6 +1,9 @@
+//@aux-build:proc_macros.rs
 #![warn(clippy::large_stack_arrays)]
 #![allow(clippy::large_enum_variant)]
 
+extern crate proc_macros;
+
 #[derive(Clone, Copy)]
 struct S {
     pub data: [u64; 32],
@@ -55,3 +58,48 @@ fn main() {
         [(); 20_000_000],
     );
 }
+
+#[allow(clippy::useless_vec)]
+fn issue_12586() {
+    macro_rules! dummy {
+        ($n:expr) => {
+            $n
+        };
+        // Weird rule to test help messages.
+        ($a:expr => $b:expr) => {
+            [$a, $b, $a, $b]
+            //~^ ERROR: allocating a local array larger than 512000 bytes
+        };
+        ($id:ident; $n:literal) => {
+            dummy!(::std::vec![$id;$n])
+        };
+        ($($id:expr),+ $(,)?) => {
+            ::std::vec![$($id),*]
+        }
+    }
+    macro_rules! create_then_move {
+        ($id:ident; $n:literal) => {{
+            let _x_ = [$id; $n];
+            //~^ ERROR: allocating a local array larger than 512000 bytes
+            _x_
+        }};
+    }
+
+    let x = [0u32; 50_000];
+    let y = vec![x, x, x, x, x];
+    let y = vec![dummy![x, x, x, x, x]];
+    let y = vec![dummy![[x, x, x, x, x]]];
+    let y = dummy![x, x, x, x, x];
+    let y = [x, x, dummy!(x), x, x];
+    //~^ ERROR: allocating a local array larger than 512000 bytes
+    let y = dummy![x => x];
+    let y = dummy![x;5];
+    let y = dummy!(vec![dummy![x, x, x, x, x]]);
+    let y = dummy![[x, x, x, x, x]];
+    //~^ ERROR: allocating a local array larger than 512000 bytes
+
+    let y = proc_macros::make_it_big!([x; 1]);
+    //~^ ERROR: allocating a local array larger than 512000 bytes
+    let y = vec![proc_macros::make_it_big!([x; 10])];
+    let y = vec![create_then_move![x; 5]; 5];
+}
diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.stderr b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
index 007ca61c2de..06294ee8b8c 100644
--- a/src/tools/clippy/tests/ui/large_stack_arrays.stderr
+++ b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
@@ -1,5 +1,5 @@
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:29:14
+  --> tests/ui/large_stack_arrays.rs:32:14
    |
 LL |     let _x = [build(); 3];
    |              ^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     let _x = [build(); 3];
    = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:32:14
+  --> tests/ui/large_stack_arrays.rs:35:14
    |
 LL |     let _y = [build(), build(), build()];
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let _y = [build(), build(), build()];
    = help: consider allocating on the heap with `vec![build(), build(), build()].into_boxed_slice()`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:38:9
+  --> tests/ui/large_stack_arrays.rs:41:9
    |
 LL |         [0u32; 20_000_000],
    |         ^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |         [0u32; 20_000_000],
    = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:40:9
+  --> tests/ui/large_stack_arrays.rs:43:9
    |
 LL |         [S { data: [0; 32] }; 5000],
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |         [S { data: [0; 32] }; 5000],
    = help: consider allocating on the heap with `vec![S { data: [0; 32] }; 5000].into_boxed_slice()`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:42:9
+  --> tests/ui/large_stack_arrays.rs:45:9
    |
 LL |         [Some(""); 20_000_000],
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |         [Some(""); 20_000_000],
    = help: consider allocating on the heap with `vec![Some(""); 20_000_000].into_boxed_slice()`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:44:9
+  --> tests/ui/large_stack_arrays.rs:47:9
    |
 LL |         [E::T(0); 5000],
    |         ^^^^^^^^^^^^^^^
@@ -49,12 +49,56 @@ LL |         [E::T(0); 5000],
    = help: consider allocating on the heap with `vec![E::T(0); 5000].into_boxed_slice()`
 
 error: allocating a local array larger than 512000 bytes
-  --> tests/ui/large_stack_arrays.rs:46:9
+  --> tests/ui/large_stack_arrays.rs:49:9
    |
 LL |         [0u8; usize::MAX],
    |         ^^^^^^^^^^^^^^^^^
    |
    = help: consider allocating on the heap with `vec![0u8; usize::MAX].into_boxed_slice()`
 
-error: aborting due to 7 previous errors
+error: allocating a local array larger than 512000 bytes
+  --> tests/ui/large_stack_arrays.rs:93:13
+   |
+LL |     let y = [x, x, dummy!(x), x, x];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider allocating on the heap with `vec![x, x, dummy!(x), x, x].into_boxed_slice()`
+
+error: allocating a local array larger than 512000 bytes
+  --> tests/ui/large_stack_arrays.rs:70:13
+   |
+LL |             [$a, $b, $a, $b]
+   |             ^^^^^^^^^^^^^^^^
+...
+LL |     let y = dummy![x => x];
+   |             -------------- in this macro invocation
+   |
+   = note: this error originates in the macro `dummy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: allocating a local array larger than 512000 bytes
+  --> tests/ui/large_stack_arrays.rs:98:20
+   |
+LL |     let y = dummy![[x, x, x, x, x]];
+   |                    ^^^^^^^^^^^^^^^
+   |
+   = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()`
+
+error: allocating a local array larger than 512000 bytes
+  --> tests/ui/large_stack_arrays.rs:101:39
+   |
+LL |     let y = proc_macros::make_it_big!([x; 1]);
+   |                                       ^^^^^^
+
+error: allocating a local array larger than 512000 bytes
+  --> tests/ui/large_stack_arrays.rs:82:23
+   |
+LL |             let _x_ = [$id; $n];
+   |                       ^^^^^^^^^
+...
+LL |     let y = vec![create_then_move![x; 5]; 5];
+   |                  ----------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `create_then_move` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/let_and_return.stderr b/src/tools/clippy/tests/ui/let_and_return.stderr
index f614a5739a8..ff5962ec196 100644
--- a/src/tools/clippy/tests/ui/let_and_return.stderr
+++ b/src/tools/clippy/tests/ui/let_and_return.stderr
@@ -71,7 +71,7 @@ LL |               result
 help: return the expression directly
    |
 LL ~             
-LL | 
+LL |
 LL ~             (match self {
 LL +                 E::A(x) => x,
 LL +                 E::B(x) => x,
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
index 9c4bd335ad8..a72caa3a37e 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
@@ -55,3 +55,30 @@ fn msrv_1_47() {
     const FOO: bool = 'x'.is_ascii_digit();
     const BAR: bool = 'x'.is_ascii_hexdigit();
 }
+
+#[allow(clippy::deref_addrof, clippy::needless_borrow)]
+fn with_refs() {
+    let cool_letter = &&'g';
+    cool_letter.is_ascii_digit();
+    cool_letter.is_ascii_lowercase();
+}
+
+fn generics() {
+    fn a<U>(u: &U) -> bool
+    where
+        char: PartialOrd<U>,
+        U: PartialOrd<char> + ?Sized,
+    {
+        ('A'..='Z').contains(u)
+    }
+
+    fn take_while<Item, F>(cond: F)
+    where
+        Item: Sized,
+        F: Fn(Item) -> bool,
+    {
+    }
+    take_while(|c: char| c.is_ascii_uppercase());
+    take_while(|c: u8| c.is_ascii_uppercase());
+    take_while(|c: char| c.is_ascii_uppercase());
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
index 785943cd24d..bb6e2a317da 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
@@ -55,3 +55,30 @@ fn msrv_1_47() {
     const FOO: bool = matches!('x', '0'..='9');
     const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');
 }
+
+#[allow(clippy::deref_addrof, clippy::needless_borrow)]
+fn with_refs() {
+    let cool_letter = &&'g';
+    ('0'..='9').contains(&&cool_letter);
+    ('a'..='z').contains(*cool_letter);
+}
+
+fn generics() {
+    fn a<U>(u: &U) -> bool
+    where
+        char: PartialOrd<U>,
+        U: PartialOrd<char> + ?Sized,
+    {
+        ('A'..='Z').contains(u)
+    }
+
+    fn take_while<Item, F>(cond: F)
+    where
+        Item: Sized,
+        F: Fn(Item) -> bool,
+    {
+    }
+    take_while(|c| ('A'..='Z').contains(&c));
+    take_while(|c| (b'A'..=b'Z').contains(&c));
+    take_while(|c: char| ('A'..='Z').contains(&c));
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
index 3632077ec80..a93ccace28a 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
@@ -133,5 +133,45 @@ error: manual check for common ascii range
 LL |     const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()`
 
-error: aborting due to 22 previous errors
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:62:5
+   |
+LL |     ('0'..='9').contains(&&cool_letter);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_digit()`
+
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:63:5
+   |
+LL |     ('a'..='z').contains(*cool_letter);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_lowercase()`
+
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:81:20
+   |
+LL |     take_while(|c| ('A'..='Z').contains(&c));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL |     take_while(|c: char| c.is_ascii_uppercase());
+   |                 ~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~
+
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:82:20
+   |
+LL |     take_while(|c| (b'A'..=b'Z').contains(&c));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL |     take_while(|c: u8| c.is_ascii_uppercase());
+   |                 ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~
+
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:83:26
+   |
+LL |     take_while(|c: char| ('A'..='Z').contains(&c));
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()`
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr
index d2d4f765310..a70c988a054 100644
--- a/src/tools/clippy/tests/ui/manual_strip.stderr
+++ b/src/tools/clippy/tests/ui/manual_strip.stderr
@@ -17,7 +17,7 @@ LL ~     if let Some(<stripped>) = s.strip_prefix("ab") {
 LL ~         str::to_string(<stripped>);
 LL |
 LL ~         <stripped>.to_string();
-LL | 
+LL |
 LL ~         str::to_string(<stripped>);
 LL ~         <stripped>.to_string();
    |
@@ -39,7 +39,7 @@ LL ~     if let Some(<stripped>) = s.strip_suffix("bc") {
 LL ~         str::to_string(<stripped>);
 LL |
 LL ~         <stripped>.to_string();
-LL | 
+LL |
 LL ~         str::to_string(<stripped>);
 LL ~         <stripped>.to_string();
    |
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
index 861764a2aee..b84b3dc349e 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
@@ -32,7 +32,7 @@ fn main() {
     // testing that the suggestion actually fits in its type
     let fail30 = 127_i8; // should be i8
     let fail31 = 240_u8; // should be u8
-    let ok32 = 360_8; // doesnt fit in either, should be ignored
+    let ok32 = 360_8; // doesn't fit in either, should be ignored
     let fail33 = 0x1234_i16;
     let fail34 = 0xABCD_u16;
     let ok35 = 0x12345_16;
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
index 4a15c335fd8..a47a736067a 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
@@ -32,7 +32,7 @@ fn main() {
     // testing that the suggestion actually fits in its type
     let fail30 = 127_8; // should be i8
     let fail31 = 240_8; // should be u8
-    let ok32 = 360_8; // doesnt fit in either, should be ignored
+    let ok32 = 360_8; // doesn't fit in either, should be ignored
     let fail33 = 0x1234_16;
     let fail34 = 0xABCD_16;
     let ok35 = 0x12345_16;
diff --git a/src/tools/clippy/tests/ui/mut_key.rs b/src/tools/clippy/tests/ui/mut_key.rs
index 2d70bfd4c77..81d8732b3b2 100644
--- a/src/tools/clippy/tests/ui/mut_key.rs
+++ b/src/tools/clippy/tests/ui/mut_key.rs
@@ -5,7 +5,7 @@ use std::rc::Rc;
 use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::Relaxed;
 use std::sync::Arc;
-//@no-rustfix
+
 struct Key(AtomicUsize);
 
 impl Clone for Key {
@@ -77,8 +77,6 @@ fn main() {
     //~^ ERROR: mutable key type
     let _map = HashMap::<&mut Cell<usize>, usize>::new();
     //~^ ERROR: mutable key type
-    let _map = HashMap::<&mut usize, usize>::new();
-    //~^ ERROR: mutable key type
     // Collection types from `std` who's impl of `Hash` or `Ord` delegate their type parameters
     let _map = HashMap::<Vec<Cell<usize>>, usize>::new();
     //~^ ERROR: mutable key type
@@ -92,8 +90,6 @@ fn main() {
     //~^ ERROR: mutable key type
     let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();
     //~^ ERROR: mutable key type
-    let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
-    //~^ ERROR: mutable key type
     // Smart pointers from `std` who's impl of `Hash` or `Ord` delegate their type parameters
     let _map = HashMap::<Box<Cell<usize>>, usize>::new();
     //~^ ERROR: mutable key type
@@ -101,4 +97,8 @@ fn main() {
     //~^ ERROR: mutable key type
     let _map = HashMap::<Arc<Cell<usize>>, usize>::new();
     //~^ ERROR: mutable key type
+
+    // Not interior mutability
+    let _map = HashMap::<&mut usize, usize>::new();
+    let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
 }
diff --git a/src/tools/clippy/tests/ui/mut_key.stderr b/src/tools/clippy/tests/ui/mut_key.stderr
index e54c3075d4f..5ad9aad2d0a 100644
--- a/src/tools/clippy/tests/ui/mut_key.stderr
+++ b/src/tools/clippy/tests/ui/mut_key.stderr
@@ -38,70 +38,58 @@ LL |     let _map = HashMap::<&mut Cell<usize>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:80:5
-   |
-LL |     let _map = HashMap::<&mut usize, usize>::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: mutable key type
-  --> tests/ui/mut_key.rs:83:5
+  --> tests/ui/mut_key.rs:81:5
    |
 LL |     let _map = HashMap::<Vec<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:85:5
+  --> tests/ui/mut_key.rs:83:5
    |
 LL |     let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:87:5
+  --> tests/ui/mut_key.rs:85:5
    |
 LL |     let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:89:5
+  --> tests/ui/mut_key.rs:87:5
    |
 LL |     let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:91:5
+  --> tests/ui/mut_key.rs:89:5
    |
 LL |     let _map = HashMap::<Option<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:93:5
+  --> tests/ui/mut_key.rs:91:5
    |
 LL |     let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:95:5
-   |
-LL |     let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: mutable key type
-  --> tests/ui/mut_key.rs:98:5
+  --> tests/ui/mut_key.rs:94:5
    |
 LL |     let _map = HashMap::<Box<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:100:5
+  --> tests/ui/mut_key.rs:96:5
    |
 LL |     let _map = HashMap::<Rc<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> tests/ui/mut_key.rs:102:5
+  --> tests/ui/mut_key.rs:98:5
    |
 LL |     let _map = HashMap::<Arc<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
index 8c0e7ba7627..2362314290e 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
@@ -113,6 +113,10 @@ fn should_not_lint() {
     let _ = v.iter().for_each(|elem| {
         acc += elem;
     });
+    // `for_each` has a closure with an unsafe block.
+    v.iter().for_each(|elem| unsafe {
+        acc += elem;
+    });
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
index cdc903a636c..5b1186daa22 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
@@ -113,6 +113,10 @@ fn should_not_lint() {
     let _ = v.iter().for_each(|elem| {
         acc += elem;
     });
+    // `for_each` has a closure with an unsafe block.
+    v.iter().for_each(|elem| unsafe {
+        acc += elem;
+    });
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index a92197fb0af..3f5f55f4002 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -44,18 +44,13 @@ fn non_mut_ref(_: &Vec<u32>) {}
 struct Bar;
 
 impl Bar {
-    // Should not warn on `&mut self`.
     fn bar(&mut self) {}
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
 
     fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
         //~^ ERROR: this argument is a mutable reference, but not used mutably
         vec.len()
     }
-
-    fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
-        //~^ ERROR: this argument is a mutable reference, but not used mutably
-        vec.len()
-    }
 }
 
 trait Babar {
@@ -307,6 +302,41 @@ fn filter_copy<T: Copy>(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T)
     move |&item| predicate(item)
 }
 
+trait MutSelfTrait {
+    // Should not warn since it's a trait method.
+    fn mut_self(&mut self);
+}
+
+struct MutSelf {
+    a: u32,
+}
+
+impl MutSelf {
+    fn bar(&mut self) {}
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    async fn foo(&mut self, u: &mut i32, v: &mut u32) {
+        //~^ ERROR: this argument is a mutable reference, but not used mutably
+        //~| ERROR: this argument is a mutable reference, but not used mutably
+        async {
+            *u += 1;
+        }
+        .await;
+    }
+    async fn foo2(&mut self, u: &mut i32, v: &mut u32) {
+        //~^ ERROR: this argument is a mutable reference, but not used mutably
+        async {
+            self.a += 1;
+            *u += 1;
+        }
+        .await;
+    }
+}
+
+impl MutSelfTrait for MutSelf {
+    // Should not warn since it's a trait method.
+    fn mut_self(&mut self) {}
+}
+
 // `is_from_proc_macro` stress tests
 fn _empty_tup(x: &mut (())) {}
 fn _single_tup(x: &mut ((i32,))) {}
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index 89dad3e60b1..21ca393dcb6 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -14,73 +14,73 @@ LL | fn foo6(s: &mut Vec<u32>) {
    |            ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:50:29
+  --> tests/ui/needless_pass_by_ref_mut.rs:47:12
    |
-LL |     fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
-   |                             ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
+LL |     fn bar(&mut self) {}
+   |            ^^^^^^^^^ help: consider changing to: `&self`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:55:31
+  --> tests/ui/needless_pass_by_ref_mut.rs:50:29
    |
-LL |     fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
-   |                               ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
+LL |     fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
+   |                             ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:132:16
+  --> tests/ui/needless_pass_by_ref_mut.rs:127:16
    |
 LL | async fn a1(x: &mut i32) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:136:16
+  --> tests/ui/needless_pass_by_ref_mut.rs:131:16
    |
 LL | async fn a2(x: &mut i32, y: String) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:140:16
+  --> tests/ui/needless_pass_by_ref_mut.rs:135:16
    |
 LL | async fn a3(x: &mut i32, y: String, z: String) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:144:16
+  --> tests/ui/needless_pass_by_ref_mut.rs:139:16
    |
 LL | async fn a4(x: &mut i32, y: i32) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:148:24
+  --> tests/ui/needless_pass_by_ref_mut.rs:143:24
    |
 LL | async fn a5(x: i32, y: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:152:24
+  --> tests/ui/needless_pass_by_ref_mut.rs:147:24
    |
 LL | async fn a6(x: i32, y: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:156:32
+  --> tests/ui/needless_pass_by_ref_mut.rs:151:32
    |
 LL | async fn a7(x: i32, y: i32, z: &mut i32) {
    |                                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:160:24
+  --> tests/ui/needless_pass_by_ref_mut.rs:155:24
    |
 LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:160:45
+  --> tests/ui/needless_pass_by_ref_mut.rs:155:45
    |
 LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
    |                                             ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:194:16
+  --> tests/ui/needless_pass_by_ref_mut.rs:189:16
    |
 LL | fn cfg_warn(s: &mut u32) {}
    |                ^^^^^^^^ help: consider changing to: `&u32`
@@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {}
    = note: this is cfg-gated and may require further changes
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:200:20
+  --> tests/ui/needless_pass_by_ref_mut.rs:195:20
    |
 LL |     fn cfg_warn(s: &mut u32) {}
    |                    ^^^^^^^^ help: consider changing to: `&u32`
@@ -96,19 +96,19 @@ LL |     fn cfg_warn(s: &mut u32) {}
    = note: this is cfg-gated and may require further changes
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:214:39
+  --> tests/ui/needless_pass_by_ref_mut.rs:209:39
    |
 LL | async fn inner_async2(x: &mut i32, y: &mut u32) {
    |                                       ^^^^^^^^ help: consider changing to: `&u32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:222:26
+  --> tests/ui/needless_pass_by_ref_mut.rs:217:26
    |
 LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
    |                          ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:241:34
+  --> tests/ui/needless_pass_by_ref_mut.rs:236:34
    |
 LL | pub async fn call_in_closure1(n: &mut str) {
    |                                  ^^^^^^^^ help: consider changing to: `&str`
@@ -116,15 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:253:25
-   |
-LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
-   |                         ^^^^^^^^^^ help: consider changing to: `&usize`
-   |
-   = warning: changing this function will impact semver compatibility
-
-error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:260:20
+  --> tests/ui/needless_pass_by_ref_mut.rs:255:20
    |
 LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
    |                    ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -132,7 +124,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:271:26
+  --> tests/ui/needless_pass_by_ref_mut.rs:266:26
    |
 LL | pub async fn closure4(n: &mut usize) {
    |                          ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -140,64 +132,88 @@ LL | pub async fn closure4(n: &mut usize) {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:311:18
+  --> tests/ui/needless_pass_by_ref_mut.rs:315:12
+   |
+LL |     fn bar(&mut self) {}
+   |            ^^^^^^^^^ help: consider changing to: `&self`
+
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut.rs:317:18
+   |
+LL |     async fn foo(&mut self, u: &mut i32, v: &mut u32) {
+   |                  ^^^^^^^^^ help: consider changing to: `&self`
+
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut.rs:317:45
+   |
+LL |     async fn foo(&mut self, u: &mut i32, v: &mut u32) {
+   |                                             ^^^^^^^^ help: consider changing to: `&u32`
+
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut.rs:325:46
+   |
+LL |     async fn foo2(&mut self, u: &mut i32, v: &mut u32) {
+   |                                              ^^^^^^^^ help: consider changing to: `&u32`
+
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut.rs:341:18
    |
 LL | fn _empty_tup(x: &mut (())) {}
    |                  ^^^^^^^^^ help: consider changing to: `&()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:312:19
+  --> tests/ui/needless_pass_by_ref_mut.rs:342:19
    |
 LL | fn _single_tup(x: &mut ((i32,))) {}
    |                   ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:313:18
+  --> tests/ui/needless_pass_by_ref_mut.rs:343:18
    |
 LL | fn _multi_tup(x: &mut ((i32, u32))) {}
    |                  ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:314:11
+  --> tests/ui/needless_pass_by_ref_mut.rs:344:11
    |
 LL | fn _fn(x: &mut (fn())) {}
    |           ^^^^^^^^^^^ help: consider changing to: `&fn()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:316:23
+  --> tests/ui/needless_pass_by_ref_mut.rs:346:23
    |
 LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {}
    |                       ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:317:20
+  --> tests/ui/needless_pass_by_ref_mut.rs:347:20
    |
 LL | fn _extern_c_fn(x: &mut extern "C" fn()) {}
    |                    ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:318:18
+  --> tests/ui/needless_pass_by_ref_mut.rs:348:18
    |
 LL | fn _unsafe_fn(x: &mut unsafe fn()) {}
    |                  ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:319:25
+  --> tests/ui/needless_pass_by_ref_mut.rs:349:25
    |
 LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:320:20
+  --> tests/ui/needless_pass_by_ref_mut.rs:350:20
    |
 LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {}
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)`
 
 error: this argument is a mutable reference, but not used mutably
-  --> tests/ui/needless_pass_by_ref_mut.rs:321:20
+  --> tests/ui/needless_pass_by_ref_mut.rs:351:20
    |
 LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {}
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)`
 
-error: aborting due to 31 previous errors
+error: aborting due to 34 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.fixed b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.fixed
new file mode 100644
index 00000000000..3c2576213cd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.fixed
@@ -0,0 +1,24 @@
+// If both `inner_async3` and `inner_async4` are present, aliases are declared after
+// they're used in `inner_async4` for some reasons... This test ensures that no
+// only `v` is marked as not used mutably in `inner_async4`.
+
+#![allow(clippy::redundant_closure_call)]
+#![warn(clippy::needless_pass_by_ref_mut)]
+
+pub async fn inner_async3(x: &i32, y: &mut u32) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    async {
+        *y += 1;
+    }
+    .await;
+}
+
+pub async fn inner_async4(u: &mut i32, v: &u32) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    async {
+        *u += 1;
+    }
+    .await;
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.rs
new file mode 100644
index 00000000000..34b0b564deb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.rs
@@ -0,0 +1,24 @@
+// If both `inner_async3` and `inner_async4` are present, aliases are declared after
+// they're used in `inner_async4` for some reasons... This test ensures that no
+// only `v` is marked as not used mutably in `inner_async4`.
+
+#![allow(clippy::redundant_closure_call)]
+#![warn(clippy::needless_pass_by_ref_mut)]
+
+pub async fn inner_async3(x: &mut i32, y: &mut u32) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    async {
+        *y += 1;
+    }
+    .await;
+}
+
+pub async fn inner_async4(u: &mut i32, v: &mut u32) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    async {
+        *u += 1;
+    }
+    .await;
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.stderr
new file mode 100644
index 00000000000..c8753603225
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut2.stderr
@@ -0,0 +1,20 @@
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut2.rs:8:30
+   |
+LL | pub async fn inner_async3(x: &mut i32, y: &mut u32) {
+   |                              ^^^^^^^^ help: consider changing to: `&i32`
+   |
+   = warning: changing this function will impact semver compatibility
+   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
+
+error: this argument is a mutable reference, but not used mutably
+  --> tests/ui/needless_pass_by_ref_mut2.rs:16:43
+   |
+LL | pub async fn inner_async4(u: &mut i32, v: &mut u32) {
+   |                                           ^^^^^^^^ help: consider changing to: `&u32`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed
index db55cc094e3..d444a753697 100644
--- a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed
@@ -142,3 +142,21 @@ impl PartialOrd for H {
         Some(Ord::cmp(self, other))
     }
 }
+
+// #12683, do not lint
+
+#[derive(Eq, PartialEq)]
+struct I(u32);
+
+impl Ord for I {
+    fn cmp(&self, other: &Self) -> Ordering {
+        todo!();
+    }
+}
+
+impl PartialOrd for I {
+    #[allow(clippy::needless_return)]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        return Some(self.cmp(other));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs
index 52f4b85b917..dc6c4354604 100644
--- a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs
@@ -146,3 +146,21 @@ impl PartialOrd for H {
         Some(Ord::cmp(self, other))
     }
 }
+
+// #12683, do not lint
+
+#[derive(Eq, PartialEq)]
+struct I(u32);
+
+impl Ord for I {
+    fn cmp(&self, other: &Self) -> Ordering {
+        todo!();
+    }
+}
+
+impl PartialOrd for I {
+    #[allow(clippy::needless_return)]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        return Some(self.cmp(other));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/readonly_write_lock.fixed b/src/tools/clippy/tests/ui/readonly_write_lock.fixed
index 76f4a43ae53..4db13482ac7 100644
--- a/src/tools/clippy/tests/ui/readonly_write_lock.fixed
+++ b/src/tools/clippy/tests/ui/readonly_write_lock.fixed
@@ -43,3 +43,7 @@ fn main() {
         *writer1 = *writer2;
     }
 }
+
+fn issue12733(rw: &RwLock<()>) {
+    let _write_guard = rw.write().unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/readonly_write_lock.rs b/src/tools/clippy/tests/ui/readonly_write_lock.rs
index 3d1d3855fe1..66ba1b2d696 100644
--- a/src/tools/clippy/tests/ui/readonly_write_lock.rs
+++ b/src/tools/clippy/tests/ui/readonly_write_lock.rs
@@ -43,3 +43,7 @@ fn main() {
         *writer1 = *writer2;
     }
 }
+
+fn issue12733(rw: &RwLock<()>) {
+    let _write_guard = rw.write().unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed
index ded91e08376..ed4b1c21915 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.fixed
+++ b/src/tools/clippy/tests/ui/redundant_guards.fixed
@@ -136,6 +136,18 @@ fn f(s: Option<std::ffi::OsString>) {
     }
 }
 
+fn not_matches() {
+    match Some(42) {
+        // The pattern + guard is not equivalent to `Some(42)` because of the `panic!`
+        Some(v)
+            if match v {
+                42 => true,
+                _ => panic!(),
+            } => {},
+        _ => {},
+    }
+}
+
 struct S {
     a: usize,
 }
diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs
index 2aaa2ace398..adbc4ed16cd 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.rs
+++ b/src/tools/clippy/tests/ui/redundant_guards.rs
@@ -136,6 +136,18 @@ fn f(s: Option<std::ffi::OsString>) {
     }
 }
 
+fn not_matches() {
+    match Some(42) {
+        // The pattern + guard is not equivalent to `Some(42)` because of the `panic!`
+        Some(v)
+            if match v {
+                42 => true,
+                _ => panic!(),
+            } => {},
+        _ => {},
+    }
+}
+
 struct S {
     a: usize,
 }
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index 01ca91fcd09..fd12e083282 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -132,7 +132,7 @@ LL +         1 => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:174:28
+  --> tests/ui/redundant_guards.rs:186:28
    |
 LL |             Some(ref x) if x == &1 => {},
    |                            ^^^^^^^
@@ -144,7 +144,7 @@ LL +             Some(1) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:175:28
+  --> tests/ui/redundant_guards.rs:187:28
    |
 LL |             Some(ref x) if &1 == x => {},
    |                            ^^^^^^^
@@ -156,7 +156,7 @@ LL +             Some(1) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:176:28
+  --> tests/ui/redundant_guards.rs:188:28
    |
 LL |             Some(ref x) if let &2 = x => {},
    |                            ^^^^^^^^^^
@@ -168,7 +168,7 @@ LL +             Some(2) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:177:28
+  --> tests/ui/redundant_guards.rs:189:28
    |
 LL |             Some(ref x) if matches!(x, &3) => {},
    |                            ^^^^^^^^^^^^^^^
@@ -180,7 +180,7 @@ LL +             Some(3) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:197:32
+  --> tests/ui/redundant_guards.rs:209:32
    |
 LL |             B { ref c, .. } if c == &1 => {},
    |                                ^^^^^^^
@@ -192,7 +192,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:198:32
+  --> tests/ui/redundant_guards.rs:210:32
    |
 LL |             B { ref c, .. } if &1 == c => {},
    |                                ^^^^^^^
@@ -204,7 +204,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:199:32
+  --> tests/ui/redundant_guards.rs:211:32
    |
 LL |             B { ref c, .. } if let &1 = c => {},
    |                                ^^^^^^^^^^
@@ -216,7 +216,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:200:32
+  --> tests/ui/redundant_guards.rs:212:32
    |
 LL |             B { ref c, .. } if matches!(c, &1) => {},
    |                                ^^^^^^^^^^^^^^^
@@ -228,7 +228,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:210:26
+  --> tests/ui/redundant_guards.rs:222:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -240,7 +240,7 @@ LL +         Some(Some("")) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:221:26
+  --> tests/ui/redundant_guards.rs:233:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -252,7 +252,7 @@ LL +         Some(Some([])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:226:26
+  --> tests/ui/redundant_guards.rs:238:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -264,7 +264,7 @@ LL +         Some(Some([])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:237:26
+  --> tests/ui/redundant_guards.rs:249:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[]) => {},
    |                          ^^^^^^^^^^^^^^^^^^
@@ -276,7 +276,7 @@ LL +         Some(Some([..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:242:26
+  --> tests/ui/redundant_guards.rs:254:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[1]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^
@@ -288,7 +288,7 @@ LL +         Some(Some([1, ..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:247:26
+  --> tests/ui/redundant_guards.rs:259:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[1, 2]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^^^^
@@ -300,7 +300,7 @@ LL +         Some(Some([1, 2, ..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:252:26
+  --> tests/ui/redundant_guards.rs:264:26
    |
 LL |         Some(Some(x)) if x.ends_with(&[1, 2]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^^
@@ -312,7 +312,7 @@ LL +         Some(Some([.., 1, 2])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:274:18
+  --> tests/ui/redundant_guards.rs:286:18
    |
 LL |             y if y.is_empty() => {},
    |                  ^^^^^^^^^^^^
@@ -324,7 +324,7 @@ LL +             "" => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:293:22
+  --> tests/ui/redundant_guards.rs:305:22
    |
 LL |                 y if y.is_empty() => {},
    |                      ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs
index e9d77182a91..d21aa240b2d 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.rs
+++ b/src/tools/clippy/tests/ui/redundant_locals.rs
@@ -191,14 +191,20 @@ fn issue12225() {
         let v4 = v4;
         dbg!(&v4);
     });
-    assert_static(#[coroutine] static || {
-        let v5 = v5;
-        yield;
-    });
-    assert_static(#[coroutine] || {
-        let v6 = v6;
-        yield;
-    });
+    assert_static(
+        #[coroutine]
+        static || {
+            let v5 = v5;
+            yield;
+        },
+    );
+    assert_static(
+        #[coroutine]
+        || {
+            let v6 = v6;
+            yield;
+        },
+    );
 
     fn foo(a: &str, b: &str) {}
 
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
index fa2ac7a1b37..d69c86c70e2 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
@@ -27,7 +27,7 @@ LL | ||         do_nothing(value)
 LL | ||     });
    | ||______^- help: try: `if let Ok(value) = x.field { ... }`
    |  |______|
-   | 
+   |
 
 error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> tests/ui/result_map_unit_fn_unfixable.rs:37:5
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.fixed b/src/tools/clippy/tests/ui/single_char_pattern.fixed
index 9573fdbcfde..a18d6319f89 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.fixed
+++ b/src/tools/clippy/tests/ui/single_char_pattern.fixed
@@ -1,5 +1,5 @@
 #![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]
-
+#![warn(clippy::single_char_pattern)]
 use std::collections::HashSet;
 
 fn main() {
@@ -10,9 +10,9 @@ fn main() {
 
     let y = "x";
     x.split(y);
-    x.split('ß');
-    x.split('â„');
-    x.split('💣');
+    x.split("ß");
+    x.split("â„");
+    x.split("💣");
     // Can't use this lint for unicode code points which don't fit in a char
     x.split("â¤ï¸");
     x.split_inclusive('x');
@@ -34,8 +34,6 @@ fn main() {
     x.rmatch_indices('x');
     x.trim_start_matches('x');
     x.trim_end_matches('x');
-    x.strip_prefix('x');
-    x.strip_suffix('x');
     x.replace('x', "y");
     x.replacen('x', "y", 3);
     // Make sure we escape characters correctly.
@@ -64,4 +62,8 @@ fn main() {
     // Must escape backslash in raw strings when converting to char #8060
     x.split('\\');
     x.split('\\');
+
+    // should not warn, the char versions are actually slower in some cases
+    x.strip_prefix("x");
+    x.strip_suffix("x");
 }
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.rs b/src/tools/clippy/tests/ui/single_char_pattern.rs
index 8a04480dbc6..b52e6fb2fdf 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.rs
+++ b/src/tools/clippy/tests/ui/single_char_pattern.rs
@@ -1,5 +1,5 @@
 #![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]
-
+#![warn(clippy::single_char_pattern)]
 use std::collections::HashSet;
 
 fn main() {
@@ -34,8 +34,6 @@ fn main() {
     x.rmatch_indices("x");
     x.trim_start_matches("x");
     x.trim_end_matches("x");
-    x.strip_prefix("x");
-    x.strip_suffix("x");
     x.replace("x", "y");
     x.replacen("x", "y", 3);
     // Make sure we escape characters correctly.
@@ -64,4 +62,8 @@ fn main() {
     // Must escape backslash in raw strings when converting to char #8060
     x.split(r#"\"#);
     x.split(r"\");
+
+    // should not warn, the char versions are actually slower in some cases
+    x.strip_prefix("x");
+    x.strip_suffix("x");
 }
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.stderr b/src/tools/clippy/tests/ui/single_char_pattern.stderr
index 5a2ec6c764b..b2deed23cbd 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.stderr
+++ b/src/tools/clippy/tests/ui/single_char_pattern.stderr
@@ -8,24 +8,6 @@ LL |     x.split("x");
    = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:13:13
-   |
-LL |     x.split("ß");
-   |             ^^^ help: consider using a `char`: `'ß'`
-
-error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:14:13
-   |
-LL |     x.split("â„");
-   |             ^^^ help: consider using a `char`: `'â„'`
-
-error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:15:13
-   |
-LL |     x.split("💣");
-   |             ^^^^ help: consider using a `char`: `'💣'`
-
-error: single-character string constant used as pattern
   --> tests/ui/single_char_pattern.rs:18:23
    |
 LL |     x.split_inclusive("x");
@@ -140,106 +122,94 @@ LL |     x.trim_end_matches("x");
    |                        ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:37:20
-   |
-LL |     x.strip_prefix("x");
-   |                    ^^^ help: consider using a `char`: `'x'`
-
-error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:38:20
-   |
-LL |     x.strip_suffix("x");
-   |                    ^^^ help: consider using a `char`: `'x'`
-
-error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:39:15
+  --> tests/ui/single_char_pattern.rs:37:15
    |
 LL |     x.replace("x", "y");
    |               ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:40:16
+  --> tests/ui/single_char_pattern.rs:38:16
    |
 LL |     x.replacen("x", "y", 3);
    |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:42:13
+  --> tests/ui/single_char_pattern.rs:40:13
    |
 LL |     x.split("\n");
    |             ^^^^ help: consider using a `char`: `'\n'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:43:13
+  --> tests/ui/single_char_pattern.rs:41:13
    |
 LL |     x.split("'");
    |             ^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:44:13
+  --> tests/ui/single_char_pattern.rs:42:13
    |
 LL |     x.split("\'");
    |             ^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:46:13
+  --> tests/ui/single_char_pattern.rs:44:13
    |
 LL |     x.split("\"");
    |             ^^^^ help: consider using a `char`: `'"'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:51:31
+  --> tests/ui/single_char_pattern.rs:49:31
    |
 LL |     x.replace(';', ",").split(","); // issue #2978
    |                               ^^^ help: consider using a `char`: `','`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:52:19
+  --> tests/ui/single_char_pattern.rs:50:19
    |
 LL |     x.starts_with("\x03"); // issue #2996
    |                   ^^^^^^ help: consider using a `char`: `'\x03'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:59:13
+  --> tests/ui/single_char_pattern.rs:57:13
    |
 LL |     x.split(r"a");
    |             ^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:60:13
+  --> tests/ui/single_char_pattern.rs:58:13
    |
 LL |     x.split(r#"a"#);
    |             ^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:61:13
+  --> tests/ui/single_char_pattern.rs:59:13
    |
 LL |     x.split(r###"a"###);
    |             ^^^^^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:62:13
+  --> tests/ui/single_char_pattern.rs:60:13
    |
 LL |     x.split(r###"'"###);
    |             ^^^^^^^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:63:13
+  --> tests/ui/single_char_pattern.rs:61:13
    |
 LL |     x.split(r###"#"###);
    |             ^^^^^^^^^^ help: consider using a `char`: `'#'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:65:13
+  --> tests/ui/single_char_pattern.rs:63:13
    |
 LL |     x.split(r#"\"#);
    |             ^^^^^^ help: consider using a `char`: `'\\'`
 
 error: single-character string constant used as pattern
-  --> tests/ui/single_char_pattern.rs:66:13
+  --> tests/ui/single_char_pattern.rs:64:13
    |
 LL |     x.split(r"\");
    |             ^^^^ help: consider using a `char`: `'\\'`
 
-error: aborting due to 40 previous errors
+error: aborting due to 35 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
index b54309b44d5..f12053b1595 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
@@ -85,7 +85,7 @@ LL | |     ///! b
 help: use an inner doc comment to document the parent module or crate
    |
 LL ~     //! a
-LL | 
+LL |
 LL ~     //! b
    |
 
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
index 23d5dcd3a8d..aef6c391452 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
@@ -1,53 +1,53 @@
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:10:9
+  --> tests/ui/tabs_in_doc_comments.rs:6:5
    |
-LL |     ///     - First String:
-   |         ^^^^ help: consider using four spaces per tab
+LL | ///     - first        one
+   |     ^^^^ help: consider using four spaces per tab
    |
    = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:11:9
+  --> tests/ui/tabs_in_doc_comments.rs:6:13
    |
-LL |     ///         - needs to be inside here
-   |         ^^^^^^^^ help: consider using four spaces per tab
+LL | ///     - first        one
+   |                ^^^^^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:14:9
+  --> tests/ui/tabs_in_doc_comments.rs:7:5
    |
-LL |     ///     - Second String:
-   |         ^^^^ help: consider using four spaces per tab
+LL | ///     - second    one
+   |     ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:15:9
+  --> tests/ui/tabs_in_doc_comments.rs:7:14
    |
-LL |     ///         - needs to be inside here
-   |         ^^^^^^^^ help: consider using four spaces per tab
+LL | ///     - second    one
+   |                 ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:6:5
+  --> tests/ui/tabs_in_doc_comments.rs:10:9
    |
-LL | ///     - first        one
-   |     ^^^^ help: consider using four spaces per tab
+LL |     ///     - First String:
+   |         ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:6:13
+  --> tests/ui/tabs_in_doc_comments.rs:11:9
    |
-LL | ///     - first        one
-   |                ^^^^^^^^ help: consider using four spaces per tab
+LL |     ///         - needs to be inside here
+   |         ^^^^^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:7:5
+  --> tests/ui/tabs_in_doc_comments.rs:14:9
    |
-LL | ///     - second    one
-   |     ^^^^ help: consider using four spaces per tab
+LL |     ///     - Second String:
+   |         ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:7:14
+  --> tests/ui/tabs_in_doc_comments.rs:15:9
    |
-LL | ///     - second    one
-   |                 ^^^^ help: consider using four spaces per tab
+LL |     ///         - needs to be inside here
+   |         ^^^^^^^^ help: consider using four spaces per tab
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
index a6ed59d49c5..4c9bd0bd863 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
@@ -1,6 +1,6 @@
 #![warn(clippy::thread_local_initializer_can_be_made_const)]
 
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 
 fn main() {
     // lint and suggest const
@@ -36,6 +36,37 @@ fn main() {
     }
 }
 
+fn issue_12637() {
+    /// The set methods on LocalKey<Cell<T>> and LocalKey<RefCell<T>> are
+    /// guaranteed to bypass the thread_local's initialization expression.
+    /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for
+    /// forcing the use of set on each thread before it accesses the thread local in any other
+    /// manner.
+    thread_local! {
+        static STATE_12637_PANIC: Cell<usize> = panic!();
+    }
+    STATE_12637_PANIC.set(9);
+    println!("{}", STATE_12637_PANIC.get());
+
+    thread_local! {
+        static STATE_12637_TODO: Cell<usize> = todo!();
+    }
+    STATE_12637_TODO.set(9);
+    println!("{}", STATE_12637_TODO.get());
+
+    thread_local! {
+        static STATE_12637_UNIMPLEMENTED: Cell<usize> = unimplemented!();
+    }
+    STATE_12637_UNIMPLEMENTED.set(9);
+    println!("{}", STATE_12637_UNIMPLEMENTED.get());
+
+    thread_local! {
+        static STATE_12637_UNREACHABLE: Cell<usize> = unreachable!();
+    }
+    STATE_12637_UNREACHABLE.set(9);
+    println!("{}", STATE_12637_UNREACHABLE.get());
+}
+
 #[clippy::msrv = "1.58"]
 fn f() {
     thread_local! {
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
index 3f0159c5806..eb336f0dd19 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::thread_local_initializer_can_be_made_const)]
 
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 
 fn main() {
     // lint and suggest const
@@ -36,6 +36,37 @@ fn main() {
     }
 }
 
+fn issue_12637() {
+    /// The set methods on LocalKey<Cell<T>> and LocalKey<RefCell<T>> are
+    /// guaranteed to bypass the thread_local's initialization expression.
+    /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for
+    /// forcing the use of set on each thread before it accesses the thread local in any other
+    /// manner.
+    thread_local! {
+        static STATE_12637_PANIC: Cell<usize> = panic!();
+    }
+    STATE_12637_PANIC.set(9);
+    println!("{}", STATE_12637_PANIC.get());
+
+    thread_local! {
+        static STATE_12637_TODO: Cell<usize> = todo!();
+    }
+    STATE_12637_TODO.set(9);
+    println!("{}", STATE_12637_TODO.get());
+
+    thread_local! {
+        static STATE_12637_UNIMPLEMENTED: Cell<usize> = unimplemented!();
+    }
+    STATE_12637_UNIMPLEMENTED.set(9);
+    println!("{}", STATE_12637_UNIMPLEMENTED.get());
+
+    thread_local! {
+        static STATE_12637_UNREACHABLE: Cell<usize> = unreachable!();
+    }
+    STATE_12637_UNREACHABLE.set(9);
+    println!("{}", STATE_12637_UNREACHABLE.get());
+}
+
 #[clippy::msrv = "1.58"]
 fn f() {
     thread_local! {
diff --git a/src/tools/clippy/tests/ui/type_complexity.rs b/src/tools/clippy/tests/ui/type_complexity.rs
index b057dc4e89f..be28ee2da0c 100644
--- a/src/tools/clippy/tests/ui/type_complexity.rs
+++ b/src/tools/clippy/tests/ui/type_complexity.rs
@@ -1,5 +1,3 @@
-//@compile-flags: -Zdeduplicate-diagnostics=yes
-
 #![warn(clippy::all)]
 #![allow(unused, clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)]
 #![feature(associated_type_defaults)]
diff --git a/src/tools/clippy/tests/ui/type_complexity.stderr b/src/tools/clippy/tests/ui/type_complexity.stderr
index bfbab8647e8..9e27899e4f9 100644
--- a/src/tools/clippy/tests/ui/type_complexity.stderr
+++ b/src/tools/clippy/tests/ui/type_complexity.stderr
@@ -1,5 +1,5 @@
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:9:12
+  --> tests/ui/type_complexity.rs:7:12
    |
 LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:12:12
+  --> tests/ui/type_complexity.rs:10:12
    |
 LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:16:8
+  --> tests/ui/type_complexity.rs:14:8
    |
 LL |     f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:20:11
+  --> tests/ui/type_complexity.rs:18:11
    |
 LL | struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:24:11
+  --> tests/ui/type_complexity.rs:22:11
    |
 LL |     Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:26:17
+  --> tests/ui/type_complexity.rs:24:17
    |
 LL |     Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:31:14
+  --> tests/ui/type_complexity.rs:29:14
    |
 LL |     const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:33:30
+  --> tests/ui/type_complexity.rs:31:30
    |
 LL |     fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:38:14
+  --> tests/ui/type_complexity.rs:36:14
    |
 LL |     const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:40:14
+  --> tests/ui/type_complexity.rs:38:14
    |
 LL |     type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:42:25
+  --> tests/ui/type_complexity.rs:40:25
    |
 LL |     fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:44:29
+  --> tests/ui/type_complexity.rs:42:29
    |
 LL |     fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:57:15
+  --> tests/ui/type_complexity.rs:55:15
    |
 LL | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:62:14
+  --> tests/ui/type_complexity.rs:60:14
    |
 LL | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:66:13
+  --> tests/ui/type_complexity.rs:64:13
    |
 LL |     let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs
index f6d09834adb..67e398e604b 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs
+++ b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs
@@ -19,7 +19,7 @@ where
 impl<T> NormalTrait for T {}
 
 fn main() {
-    // (currently we don't look deeper than one level into the supertrait hierachy, but we probably
+    // (currently we don't look deeper than one level into the supertrait hierarchy, but we probably
     // could)
     let b: Box<dyn AnySubSubTrait> = Box::new(1);
     let _ = b.type_id();
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 901977da25b..4d66b728b76 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -20,7 +20,6 @@ new_pr = true
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
-    "y21",
     "matthiaskrgr",
     "giraffate",
     "Centri3",
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index f59245e556c..c63edd5bf70 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -415,7 +415,7 @@
                 let terms = searchStr.split(" ");
                 let docsLowerCase = lint.docs.toLowerCase();
                 for (index = 0; index < terms.length; index++) {
-                    // This is more likely and will therefor be checked first
+                    // This is more likely and will therefore be checked first
                     if (docsLowerCase.indexOf(terms[index]) !== -1) {
                         continue;
                     }
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 38c29b91928..52beb4c8b3d 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -21,10 +21,8 @@ regex = "1.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 rustfix = "0.8.1"
-once_cell = "1.16.0"
 walkdir = "2"
 glob = "0.3.0"
-lazycell = "1.3.0"
 anyhow = "1"
 home = "0.5.5"
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index aa69791b3b4..afbcc3e92bc 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -6,10 +6,10 @@ use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::str::FromStr;
+use std::sync::OnceLock;
 
 use crate::util::{add_dylib_path, PathBufExt};
 use build_helper::git::GitConfig;
-use lazycell::AtomicLazyCell;
 use serde::de::{Deserialize, Deserializer, Error as _};
 use std::collections::{HashMap, HashSet};
 use test::{ColorConfig, OutputFormat};
@@ -384,7 +384,7 @@ pub struct Config {
     /// Only rerun the tests that result has been modified accoring to Git status
     pub only_modified: bool,
 
-    pub target_cfgs: AtomicLazyCell<TargetCfgs>,
+    pub target_cfgs: OnceLock<TargetCfgs>,
 
     pub nocapture: bool,
 
@@ -406,13 +406,7 @@ impl Config {
     }
 
     pub fn target_cfgs(&self) -> &TargetCfgs {
-        match self.target_cfgs.borrow() {
-            Some(cfgs) => cfgs,
-            None => {
-                let _ = self.target_cfgs.fill(TargetCfgs::new(self));
-                self.target_cfgs.borrow().unwrap()
-            }
-        }
+        self.target_cfgs.get_or_init(|| TargetCfgs::new(self))
     }
 
     pub fn target_cfg(&self) -> &TargetCfg {
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index 3231f9fd3a4..c11d3da13a8 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -6,8 +6,8 @@ use std::io::prelude::*;
 use std::io::BufReader;
 use std::path::Path;
 use std::str::FromStr;
+use std::sync::OnceLock;
 
-use once_cell::sync::Lazy;
 use regex::Regex;
 use tracing::*;
 
@@ -117,10 +117,11 @@ fn parse_expected(
     //     //~^^^^^
     //     //[rev1]~
     //     //[rev1,rev2]~^^
-    static RE: Lazy<Regex> =
-        Lazy::new(|| Regex::new(r"//(?:\[(?P<revs>[\w\-,]+)])?~(?P<adjust>\||\^*)").unwrap());
+    static RE: OnceLock<Regex> = OnceLock::new();
 
-    let captures = RE.captures(line)?;
+    let captures = RE
+        .get_or_init(|| Regex::new(r"//(?:\[(?P<revs>[\w\-,]+)])?~(?P<adjust>\||\^*)").unwrap())
+        .captures(line)?;
 
     match (test_revision, captures.name("revs")) {
         // Only error messages that contain our revision between the square brackets apply to us.
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 8aafbb3e399..34e65c7d61f 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -5,8 +5,8 @@ use std::io::prelude::*;
 use std::io::BufReader;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::sync::OnceLock;
 
-use once_cell::sync::Lazy;
 use regex::Regex;
 use tracing::*;
 
@@ -1021,8 +1021,9 @@ fn iter_header(
     let mut line_number = 0;
 
     // Match on error annotations like `//~ERROR`.
-    static REVISION_MAGIC_COMMENT_RE: Lazy<Regex> =
-        Lazy::new(|| Regex::new("//(\\[.*\\])?~.*").unwrap());
+    static REVISION_MAGIC_COMMENT_RE: OnceLock<Regex> = OnceLock::new();
+    let revision_magic_comment_re =
+        REVISION_MAGIC_COMMENT_RE.get_or_init(|| Regex::new("//(\\[.*\\])?~.*").unwrap());
 
     loop {
         line_number += 1;
@@ -1087,7 +1088,7 @@ fn iter_header(
             });
         // Then we try to check for legacy-style candidates, which are not the magic ~ERROR family
         // error annotations.
-        } else if !REVISION_MAGIC_COMMENT_RE.is_match(ln) {
+        } else if !revision_magic_comment_re.is_match(ln) {
             let Some((_, rest)) = line_directive("//", ln) else {
                 continue;
             };
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index db154932d5b..7bc7e4b8680 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -120,16 +120,6 @@ pub(super) fn handle_needs(
             ignore_reason: "ignored on targets without Rust's LLDB",
         },
         Need {
-            name: "needs-i686-dlltool",
-            condition: cache.i686_dlltool,
-            ignore_reason: "ignored when dlltool for i686 is not present",
-        },
-        Need {
-            name: "needs-x86_64-dlltool",
-            condition: cache.x86_64_dlltool,
-            ignore_reason: "ignored when dlltool for x86_64 is not present",
-        },
-        Need {
             name: "needs-dlltool",
             condition: cache.dlltool,
             ignore_reason: "ignored when dlltool for the current architecture is not present",
@@ -218,27 +208,11 @@ pub(super) struct CachedNeedsConditions {
     profiler_support: bool,
     xray: bool,
     rust_lld: bool,
-    i686_dlltool: bool,
-    x86_64_dlltool: bool,
     dlltool: bool,
 }
 
 impl CachedNeedsConditions {
     pub(super) fn load(config: &Config) -> Self {
-        let path = std::env::var_os("PATH").expect("missing PATH environment variable");
-        let path = std::env::split_paths(&path).collect::<Vec<_>>();
-
-        // On Windows, dlltool.exe is used for all architectures.
-        #[cfg(windows)]
-        let dlltool = path.iter().any(|dir| dir.join("dlltool.exe").is_file());
-
-        // For non-Windows, there are architecture specific dlltool binaries.
-        #[cfg(not(windows))]
-        let i686_dlltool = path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file());
-        #[cfg(not(windows))]
-        let x86_64_dlltool =
-            path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file());
-
         let target = &&*config.target;
         let sanitizers = &config.target_cfg().sanitizers;
         Self {
@@ -278,26 +252,30 @@ impl CachedNeedsConditions {
                 .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
                 .exists(),
 
-            #[cfg(windows)]
-            i686_dlltool: dlltool,
-            #[cfg(windows)]
-            x86_64_dlltool: dlltool,
-            #[cfg(windows)]
-            dlltool,
-
-            // For non-Windows, there are architecture specific dlltool binaries.
-            #[cfg(not(windows))]
-            i686_dlltool,
-            #[cfg(not(windows))]
-            x86_64_dlltool,
-            #[cfg(not(windows))]
-            dlltool: if config.matches_arch("x86") {
-                i686_dlltool
-            } else if config.matches_arch("x86_64") {
-                x86_64_dlltool
-            } else {
-                false
-            },
+            dlltool: find_dlltool(&config),
         }
     }
 }
+
+fn find_dlltool(config: &Config) -> bool {
+    let path = std::env::var_os("PATH").expect("missing PATH environment variable");
+    let path = std::env::split_paths(&path).collect::<Vec<_>>();
+
+    // dlltool is used ony by GNU based `*-*-windows-gnu`
+    if !(config.matches_os("windows") && config.matches_env("gnu") && config.matches_abi("")) {
+        return false;
+    }
+
+    // On Windows, dlltool.exe is used for all architectures.
+    // For non-Windows, there are architecture specific dlltool binaries.
+    let dlltool_found = if cfg!(windows) {
+        path.iter().any(|dir| dir.join("dlltool.exe").is_file())
+    } else if config.matches_arch("i686") {
+        path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file())
+    } else if config.matches_arch("x86_64") {
+        path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file())
+    } else {
+        false
+    };
+    dlltool_found
+}
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index c8a8b79921e..2e45caec46c 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -24,13 +24,13 @@ use crate::util::logv;
 use build_helper::git::{get_git_modified_files, get_git_untracked_files};
 use core::panic;
 use getopts::Options;
-use lazycell::AtomicLazyCell;
 use std::collections::HashSet;
 use std::ffi::OsString;
 use std::fs;
 use std::io::{self, ErrorKind};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
+use std::sync::{Arc, OnceLock};
 use std::time::SystemTime;
 use std::{env, vec};
 use test::ColorConfig;
@@ -39,7 +39,6 @@ use walkdir::WalkDir;
 
 use self::header::{make_test_description, EarlyProps};
 use crate::header::HeadersCache;
-use std::sync::Arc;
 
 pub fn parse_config(args: Vec<String>) -> Config {
     let mut opts = Options::new();
@@ -320,7 +319,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
         force_rerun: matches.opt_present("force-rerun"),
 
-        target_cfgs: AtomicLazyCell::new(),
+        target_cfgs: OnceLock::new(),
 
         nocapture: matches.opt_present("nocapture"),
 
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index a4235381beb..218bea68a21 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -4,7 +4,7 @@
 /// on the number of cores available.
 ///
 /// This fixes issue #7772.
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "visionos"))]
+#[cfg(target_vendor = "apple")]
 #[allow(non_camel_case_types)]
 pub unsafe fn raise_fd_limit() {
     use std::cmp;
@@ -50,5 +50,5 @@ pub unsafe fn raise_fd_limit() {
     }
 }
 
-#[cfg(not(any(target_os = "macos", target_os = "ios")))]
+#[cfg(not(target_vendor = "apple"))]
 pub unsafe fn raise_fd_limit() {}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 1dd639a8918..0a861d62c37 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -36,7 +36,6 @@ use std::sync::Arc;
 
 use anyhow::Context;
 use glob::glob;
-use once_cell::sync::Lazy;
 use tracing::*;
 
 use crate::extract_gdb_version;
@@ -48,6 +47,13 @@ use debugger::DebuggerCommands;
 #[cfg(test)]
 mod tests;
 
+macro_rules! static_regex {
+    ($re:literal) => {{
+        static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new();
+        RE.get_or_init(|| ::regex::Regex::new($re).unwrap())
+    }};
+}
+
 const FAKE_SRC_BASE: &str = "fake-test-src-base";
 
 #[cfg(windows)]
@@ -765,28 +771,23 @@ impl<'test> TestCx<'test> {
         // `  100|` => `   LL|`
         // `  | 1000|`    => `  |   LL|`
         // `  |  | 1000|` => `  |  |   LL|`
-        static LINE_NUMBER_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?:  \|)*) *[0-9]+\|").unwrap());
-        let coverage = LINE_NUMBER_RE.replace_all(&coverage, "${prefix}   LL|");
+        let coverage = static_regex!(r"(?m:^)(?<prefix>(?:  \|)*) *[0-9]+\|")
+            .replace_all(&coverage, "${prefix}   LL|");
 
         // `  |  Branch (1:`     => `  |  Branch (LL:`
         // `  |  |  Branch (10:` => `  |  |  Branch (LL:`
-        static BRANCH_LINE_NUMBER_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new(r"(?m:^)(?<prefix>(?:  \|)+  Branch \()[0-9]+:").unwrap());
-        let coverage = BRANCH_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:");
+        let coverage = static_regex!(r"(?m:^)(?<prefix>(?:  \|)+  Branch \()[0-9]+:")
+            .replace_all(&coverage, "${prefix}LL:");
 
         // `  |---> MC/DC Decision Region (1:30) to (2:`     => `  |---> MC/DC Decision Region (LL:30) to (LL:`
-        static MCDC_DECISION_LINE_NUMBER_RE: Lazy<Regex> = Lazy::new(|| {
-            Regex::new(r"(?m:^)(?<prefix>(?:  \|)+---> MC/DC Decision Region \()[0-9]+:(?<middle>[0-9]+\) to \()[0-9]+:").unwrap()
-        });
         let coverage =
-            MCDC_DECISION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:${middle}LL:");
+            static_regex!(r"(?m:^)(?<prefix>(?:  \|)+---> MC/DC Decision Region \()[0-9]+:(?<middle>[0-9]+\) to \()[0-9]+:")
+            .replace_all(&coverage, "${prefix}LL:${middle}LL:");
 
         // `  |     Condition C1 --> (1:`     => `  |     Condition C1 --> (LL:`
-        static MCDC_CONDITION_LINE_NUMBER_RE: Lazy<Regex> = Lazy::new(|| {
-            Regex::new(r"(?m:^)(?<prefix>(?:  \|)+     Condition C[0-9]+ --> \()[0-9]+:").unwrap()
-        });
-        let coverage = MCDC_CONDITION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:");
+        let coverage =
+            static_regex!(r"(?m:^)(?<prefix>(?:  \|)+     Condition C[0-9]+ --> \()[0-9]+:")
+                .replace_all(&coverage, "${prefix}LL:");
 
         coverage.into_owned()
     }
@@ -2139,6 +2140,7 @@ impl<'test> TestCx<'test> {
 
         if !self.props.aux_bins.is_empty() {
             let aux_bin_dir = self.aux_bin_output_dir_name();
+            remove_and_create_dir_all(&aux_dir);
             remove_and_create_dir_all(&aux_bin_dir);
         }
 
@@ -3471,13 +3473,12 @@ impl<'test> TestCx<'test> {
         // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>,
         // remove all crate-disambiguators.
         fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String {
-            static RE: Lazy<Regex> = Lazy::new(|| {
-                Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
-                    .unwrap()
-            });
-
-            let captures =
-                RE.captures(cgu).unwrap_or_else(|| panic!("invalid cgu name encountered: {}", cgu));
+            let Some(captures) =
+                static_regex!(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
+                    .captures(cgu)
+            else {
+                panic!("invalid cgu name encountered: {cgu}");
+            };
 
             let mut new_name = cgu.to_owned();
 
@@ -3824,6 +3825,7 @@ impl<'test> TestCx<'test> {
             .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
             .arg("--extern")
             .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
+            .arg("--edition=2021")
             .arg(&self.testpaths.file.join("rmake.rs"))
             .env("TARGET", &self.config.target)
             .env("PYTHON", &self.config.python)
@@ -4073,18 +4075,16 @@ impl<'test> TestCx<'test> {
                 // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
                 // is printed to stdout by the client and then captured in the ProcRes,
                 // so it needs to be removed when comparing the run-pass test execution output.
-                static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| {
-                    Regex::new(
-                        "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n"
-                    )
-                    .unwrap()
-                });
-                normalized_stdout = REMOTE_TEST_RE.replace(&normalized_stdout, "").to_string();
+                normalized_stdout = static_regex!(
+                    "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n"
+                )
+                .replace(&normalized_stdout, "")
+                .to_string();
                 // When there is a panic, the remote-test-client also prints "died due to signal";
                 // that needs to be removed as well.
-                static SIGNAL_DIED_RE: Lazy<Regex> =
-                    Lazy::new(|| Regex::new("^died due to signal [0-9]+\n").unwrap());
-                normalized_stdout = SIGNAL_DIED_RE.replace(&normalized_stdout, "").to_string();
+                normalized_stdout = static_regex!("^died due to signal [0-9]+\n")
+                    .replace(&normalized_stdout, "")
+                    .to_string();
                 // FIXME: it would be much nicer if we could just tell the remote-test-client to not
                 // print these things.
             }
@@ -4556,10 +4556,9 @@ impl<'test> TestCx<'test> {
         // with placeholders as we do not want tests needing updated when compiler source code
         // changes.
         // eg. $SRC_DIR/libcore/mem.rs:323:14 becomes $SRC_DIR/libcore/mem.rs:LL:COL
-        static SRC_DIR_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap());
-
-        normalized = SRC_DIR_RE.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned();
+        normalized = static_regex!("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?")
+            .replace_all(&normalized, "SRC_DIR$1:LL:COL")
+            .into_owned();
 
         normalized = Self::normalize_platform_differences(&normalized);
         normalized = normalized.replace("\t", "\\t"); // makes tabs visible
@@ -4568,34 +4567,29 @@ impl<'test> TestCx<'test> {
         // since they duplicate actual errors and make the output hard to read.
         // This mirrors the regex in src/tools/tidy/src/style.rs, please update
         // both if either are changed.
-        static ANNOTATION_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new("\\s*//(\\[.*\\])?~.*").unwrap());
-
-        normalized = ANNOTATION_RE.replace_all(&normalized, "").into_owned();
+        normalized =
+            static_regex!("\\s*//(\\[.*\\])?~.*").replace_all(&normalized, "").into_owned();
 
         // This code normalizes various hashes in v0 symbol mangling that is
         // emitted in the ui and mir-opt tests.
-        static V0_CRATE_HASH_PREFIX_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap());
-        static V0_CRATE_HASH_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap());
+        let v0_crate_hash_prefix_re = static_regex!(r"_R.*?Cs[0-9a-zA-Z]+_");
+        let v0_crate_hash_re = static_regex!(r"Cs[0-9a-zA-Z]+_");
 
         const V0_CRATE_HASH_PLACEHOLDER: &str = r"CsCRATE_HASH_";
-        if V0_CRATE_HASH_PREFIX_RE.is_match(&normalized) {
+        if v0_crate_hash_prefix_re.is_match(&normalized) {
             // Normalize crate hash
             normalized =
-                V0_CRATE_HASH_RE.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned();
+                v0_crate_hash_re.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned();
         }
 
-        static V0_BACK_REF_PREFIX_RE: Lazy<Regex> =
-            Lazy::new(|| Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap());
-        static V0_BACK_REF_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"B[0-9a-zA-Z]_").unwrap());
+        let v0_back_ref_prefix_re = static_regex!(r"\(_R.*?B[0-9a-zA-Z]_");
+        let v0_back_ref_re = static_regex!(r"B[0-9a-zA-Z]_");
 
         const V0_BACK_REF_PLACEHOLDER: &str = r"B<REF>_";
-        if V0_BACK_REF_PREFIX_RE.is_match(&normalized) {
+        if v0_back_ref_prefix_re.is_match(&normalized) {
             // Normalize back references (see RFC 2603)
             normalized =
-                V0_BACK_REF_RE.replace_all(&normalized, V0_BACK_REF_PLACEHOLDER).into_owned();
+                v0_back_ref_re.replace_all(&normalized, V0_BACK_REF_PLACEHOLDER).into_owned();
         }
 
         // AllocId are numbered globally in a compilation session. This can lead to changes
@@ -4608,26 +4602,22 @@ impl<'test> TestCx<'test> {
             let mut seen_allocs = indexmap::IndexSet::new();
 
             // The alloc-id appears in pretty-printed allocations.
-            static ALLOC_ID_PP_RE: Lazy<Regex> = Lazy::new(|| {
-                Regex::new(r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?(<imm>)?( \([0-9]+ ptr bytes\))?─*╼")
-                    .unwrap()
-            });
-            normalized = ALLOC_ID_PP_RE
-                .replace_all(&normalized, |caps: &Captures<'_>| {
-                    // Renumber the captured index.
-                    let index = caps.get(2).unwrap().as_str().to_string();
-                    let (index, _) = seen_allocs.insert_full(index);
-                    let offset = caps.get(3).map_or("", |c| c.as_str());
-                    let imm = caps.get(4).map_or("", |c| c.as_str());
-                    // Do not bother keeping it pretty, just make it deterministic.
-                    format!("╾ALLOC{index}{offset}{imm}╼")
-                })
-                .into_owned();
+            normalized = static_regex!(
+                r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?(<imm>)?( \([0-9]+ ptr bytes\))?─*╼"
+            )
+            .replace_all(&normalized, |caps: &Captures<'_>| {
+                // Renumber the captured index.
+                let index = caps.get(2).unwrap().as_str().to_string();
+                let (index, _) = seen_allocs.insert_full(index);
+                let offset = caps.get(3).map_or("", |c| c.as_str());
+                let imm = caps.get(4).map_or("", |c| c.as_str());
+                // Do not bother keeping it pretty, just make it deterministic.
+                format!("╾ALLOC{index}{offset}{imm}╼")
+            })
+            .into_owned();
 
             // The alloc-id appears in a sentence.
-            static ALLOC_ID_RE: Lazy<Regex> =
-                Lazy::new(|| Regex::new(r"\balloc([0-9]+)\b").unwrap());
-            normalized = ALLOC_ID_RE
+            normalized = static_regex!(r"\balloc([0-9]+)\b")
                 .replace_all(&normalized, |caps: &Captures<'_>| {
                     let index = caps.get(1).unwrap().as_str().to_string();
                     let (index, _) = seen_allocs.insert_full(index);
@@ -4650,12 +4640,13 @@ impl<'test> TestCx<'test> {
     /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings
     /// with LF.
     fn normalize_platform_differences(output: &str) -> String {
-        /// Used to find Windows paths.
-        ///
-        /// It's not possible to detect paths in the error messages generally, but this is a
-        /// decent enough heuristic.
-        static PATH_BACKSLASH_RE: Lazy<Regex> = Lazy::new(|| {
-            Regex::new(
+        let output = output.replace(r"\\", r"\");
+
+        // Used to find Windows paths.
+        //
+        // It's not possible to detect paths in the error messages generally, but this is a
+        // decent enough heuristic.
+        static_regex!(
                 r#"(?x)
                 (?:
                   # Match paths that don't include spaces.
@@ -4663,14 +4654,8 @@ impl<'test> TestCx<'test> {
                 |
                   # If the path starts with a well-known root, then allow spaces and no file extension.
                   \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_'\ ]+)+
-                )"#,
+                )"#
             )
-            .unwrap()
-        });
-
-        let output = output.replace(r"\\", r"\");
-
-        PATH_BACKSLASH_RE
             .replace_all(&output, |caps: &Captures<'_>| {
                 println!("{}", &caps[0]);
                 caps[0].replace(r"\", "/")
diff --git a/src/tools/expand-yaml-anchors/Cargo.toml b/src/tools/expand-yaml-anchors/Cargo.toml
deleted file mode 100644
index 9a25b6c1f1c..00000000000
--- a/src/tools/expand-yaml-anchors/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "expand-yaml-anchors"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-yaml-rust = "0.4.3"
-yaml-merge-keys = "0.4.0"
diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs
deleted file mode 100644
index 60651734b9e..00000000000
--- a/src/tools/expand-yaml-anchors/src/main.rs
+++ /dev/null
@@ -1,198 +0,0 @@
-use std::error::Error;
-use std::path::{Path, PathBuf};
-use yaml_rust::{Yaml, YamlEmitter, YamlLoader};
-
-/// List of files to expand. The first tuple element is the source
-/// file, while the second tuple element is the destination file.
-#[rustfmt::skip]
-static TO_EXPAND: &[(&str, &str)] = &[
-    ("src/ci/github-actions/ci.yml", ".github/workflows/ci.yml"),
-];
-
-/// Name of a special key that will be removed from all the maps in expanded configuration files.
-/// This key can then be used to contain shared anchors.
-static REMOVE_MAP_KEY: &str = "x--expand-yaml-anchors--remove";
-
-/// Message that will be included at the top of all the expanded files. {source} will be replaced
-/// with the source filename relative to the base path.
-static HEADER_MESSAGE: &str = "\
-#############################################################
-#   WARNING: automatically generated file, DO NOT CHANGE!   #
-#############################################################
-
-# This file was automatically generated by the expand-yaml-anchors tool. The
-# source file that generated this one is:
-#
-#   {source}
-#
-# Once you make changes to that file you need to run:
-#
-#   ./x.py run src/tools/expand-yaml-anchors/
-#
-# The CI build will fail if the tool is not run after changes to this file.
-
-";
-
-enum Mode {
-    Check,
-    Generate,
-}
-
-struct App {
-    mode: Mode,
-    base: PathBuf,
-}
-
-impl App {
-    fn from_args() -> Result<Self, Box<dyn Error>> {
-        // Parse CLI arguments
-        let args = std::env::args().skip(1).collect::<Vec<_>>();
-        let (mode, base) = match args.iter().map(|s| s.as_str()).collect::<Vec<_>>().as_slice() {
-            ["generate", ref base] => (Mode::Generate, PathBuf::from(base)),
-            ["check", ref base] => (Mode::Check, PathBuf::from(base)),
-            _ => {
-                eprintln!("usage: expand-yaml-anchors <generate|check> <base-dir>");
-                std::process::exit(1);
-            }
-        };
-
-        Ok(App { mode, base })
-    }
-
-    fn run(&self) -> Result<(), Box<dyn Error>> {
-        for (source, dest) in TO_EXPAND {
-            let source = self.base.join(source);
-            let dest_path = self.base.join(dest);
-
-            self.expand(&source, &dest_path).with_context(|| match self.mode {
-                Mode::Generate => format!(
-                    "failed to expand {} into {}",
-                    self.path(&source),
-                    self.path(&dest_path)
-                ),
-                Mode::Check => format!(
-                    "{} is not up to date; please run \
-                        `x.py run src/tools/expand-yaml-anchors`.",
-                    self.path(&dest_path)
-                ),
-            })?;
-        }
-        Ok(())
-    }
-
-    fn expand(&self, source: &Path, dest: &Path) -> Result<(), Box<dyn Error>> {
-        let content = std::fs::read_to_string(source)
-            .with_context(|| format!("failed to read {}", self.path(source)))?;
-
-        let mut buf =
-            HEADER_MESSAGE.replace("{source}", &self.path(source).to_string().replace("\\", "/"));
-
-        let documents = YamlLoader::load_from_str(&content)
-            .with_context(|| format!("failed to parse {}", self.path(source)))?;
-        for mut document in documents.into_iter() {
-            document = yaml_merge_keys::merge_keys(document)
-                .with_context(|| format!("failed to expand {}", self.path(source)))?;
-            document = filter_document(document);
-
-            YamlEmitter::new(&mut buf).dump(&document).map_err(|err| WithContext {
-                context: "failed to serialize the expanded yaml".into(),
-                source: Box::new(err),
-            })?;
-            buf.push('\n');
-        }
-
-        match self.mode {
-            Mode::Check => {
-                let old = std::fs::read_to_string(dest)
-                    .with_context(|| format!("failed to read {}", self.path(dest)))?;
-                if old != buf {
-                    return Err(Box::new(StrError(format!(
-                        "{} and {} are different",
-                        self.path(source),
-                        self.path(dest),
-                    ))));
-                }
-            }
-            Mode::Generate => {
-                std::fs::write(dest, buf.as_bytes())
-                    .with_context(|| format!("failed to write to {}", self.path(dest)))?;
-            }
-        }
-        Ok(())
-    }
-
-    fn path<'a>(&self, path: &'a Path) -> impl std::fmt::Display + 'a {
-        path.strip_prefix(&self.base).unwrap_or(path).display()
-    }
-}
-
-fn filter_document(document: Yaml) -> Yaml {
-    match document {
-        Yaml::Hash(map) => Yaml::Hash(
-            map.into_iter()
-                .filter(|(key, _)| {
-                    if let Yaml::String(string) = &key { string != REMOVE_MAP_KEY } else { true }
-                })
-                .map(|(key, value)| (filter_document(key), filter_document(value)))
-                .collect(),
-        ),
-        Yaml::Array(vec) => Yaml::Array(vec.into_iter().map(filter_document).collect()),
-        other => other,
-    }
-}
-
-fn main() {
-    if let Err(err) = App::from_args().and_then(|app| app.run()) {
-        eprintln!("error: {}", err);
-
-        let mut source = err.as_ref() as &dyn Error;
-        while let Some(err) = source.source() {
-            eprintln!("caused by: {}", err);
-            source = err;
-        }
-
-        std::process::exit(1);
-    }
-}
-
-#[derive(Debug)]
-struct StrError(String);
-
-impl Error for StrError {}
-
-impl std::fmt::Display for StrError {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.0, f)
-    }
-}
-
-#[derive(Debug)]
-struct WithContext {
-    context: String,
-    source: Box<dyn Error>,
-}
-
-impl std::fmt::Display for WithContext {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.context)
-    }
-}
-
-impl Error for WithContext {
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Some(self.source.as_ref())
-    }
-}
-
-pub(crate) trait ResultExt<T> {
-    fn with_context<F: FnOnce() -> String>(self, f: F) -> Result<T, Box<dyn Error>>;
-}
-
-impl<T, E: Into<Box<dyn Error>>> ResultExt<T> for Result<T, E> {
-    fn with_context<F: FnOnce() -> String>(self, f: F) -> Result<T, Box<dyn Error>> {
-        match self {
-            Ok(ok) => Ok(ok),
-            Err(err) => Err(WithContext { source: err.into(), context: f() }.into()),
-        }
-    }
-}
diff --git a/src/tools/jsondocck/Cargo.toml b/src/tools/jsondocck/Cargo.toml
index 6326a9b1e79..e1eb6d05665 100644
--- a/src/tools/jsondocck/Cargo.toml
+++ b/src/tools/jsondocck/Cargo.toml
@@ -10,4 +10,3 @@ regex = "1.4"
 shlex = "1.0"
 serde_json = "1.0"
 fs-err = "2.5.0"
-once_cell = "1.0"
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index e3d05ec8315..688b403bf0e 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -1,8 +1,8 @@
 use jsonpath_lib::select;
-use once_cell::sync::Lazy;
 use regex::{Regex, RegexBuilder};
 use serde_json::Value;
 use std::borrow::Cow;
+use std::sync::OnceLock;
 use std::{env, fmt, fs};
 
 mod cache;
@@ -95,7 +95,8 @@ impl fmt::Display for CommandKind {
     }
 }
 
-static LINE_PATTERN: Lazy<Regex> = Lazy::new(|| {
+static LINE_PATTERN: OnceLock<Regex> = OnceLock::new();
+fn line_pattern() -> Regex {
     RegexBuilder::new(
         r#"
         \s(?P<invalid>!?)@(?P<negated>!?)
@@ -107,7 +108,7 @@ static LINE_PATTERN: Lazy<Regex> = Lazy::new(|| {
     .unicode(true)
     .build()
     .unwrap()
-});
+}
 
 fn print_err(msg: &str, lineno: usize) {
     eprintln!("Invalid command: {} on line {}", msg, lineno)
@@ -123,7 +124,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
     for (lineno, line) in file.split('\n').enumerate() {
         let lineno = lineno + 1;
 
-        let cap = match LINE_PATTERN.captures(line) {
+        let cap = match LINE_PATTERN.get_or_init(line_pattern).captures(line) {
             Some(c) => c,
             None => continue,
         };
diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml
index 318a69ab835..05049aabc7d 100644
--- a/src/tools/linkchecker/Cargo.toml
+++ b/src/tools/linkchecker/Cargo.toml
@@ -9,5 +9,4 @@ path = "main.rs"
 
 [dependencies]
 regex = "1"
-once_cell = "1"
 html5ever = "0.26.0"
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index f49c6e79f13..32f935de730 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -18,8 +18,6 @@ use html5ever::tendril::ByteTendril;
 use html5ever::tokenizer::{
     BufferQueue, TagToken, Token, TokenSink, TokenSinkResult, Tokenizer, TokenizerOpts,
 };
-use once_cell::sync::Lazy;
-use regex::Regex;
 use std::cell::RefCell;
 use std::collections::{HashMap, HashSet};
 use std::env;
@@ -69,8 +67,12 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[
 
 ];
 
-static BROKEN_INTRA_DOC_LINK: Lazy<Regex> =
-    Lazy::new(|| Regex::new(r#"\[<code>(.*)</code>\]"#).unwrap());
+macro_rules! static_regex {
+    ($re:literal) => {{
+        static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new();
+        RE.get_or_init(|| ::regex::Regex::new($re).unwrap())
+    }};
+}
 
 macro_rules! t {
     ($e:expr) => {
@@ -373,7 +375,7 @@ impl Checker {
         // Search for intra-doc links that rustdoc didn't warn about
         // NOTE: only looks at one line at a time; in practice this should find most links
         for (i, line) in source.lines().enumerate() {
-            for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
+            for broken_link in static_regex!(r#"\[<code>(.*)</code>\]"#).captures_iter(line) {
                 if is_intra_doc_exception(file, &broken_link[1]) {
                     report.intra_doc_exceptions += 1;
                 } else {
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 3a282e89312..6960c1661c5 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -553,7 +553,6 @@ dependencies = [
  "directories",
  "getrandom",
  "jemalloc-sys",
- "lazy_static",
  "libc",
  "libffi",
  "libloading",
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index de7a6de9e3e..976bd080867 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -47,7 +47,6 @@ colored = "2"
 ui_test = "0.21.1"
 rustc_version = "0.4"
 regex = "1.5.5"
-lazy_static = "1.4.0"
 tempfile = "3"
 
 [package.metadata.rust-analyzer]
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index a45ecda15c4..dcd7b0698a6 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-6acb9e75ebc936df737381a9d0b7a7bccd6f0b2f
+79734f1db8dbe322192dea32c0f6b80ab14c4c1d
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 44727e01ea2..f47c84842b1 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -89,8 +89,10 @@ mod shims;
 // Establish a "crate-wide prelude": we often import `crate::*`.
 
 // Make all those symbols available in the same place as our own.
+#[doc(no_inline)]
 pub use rustc_const_eval::interpret::*;
 // Resolve ambiguity.
+#[doc(no_inline)]
 pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};
 
 pub use crate::shims::env::{EnvVars, EvalContextExt as _};
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 8b286871774..4dacb6db8da 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -380,7 +380,7 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
         let mut_raw_ptr = Ty::new_mut_ptr(tcx, tcx.types.unit);
         let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit);
         Ok(Self {
-            unit: layout_cx.layout_of(Ty::new_unit(tcx))?,
+            unit: layout_cx.layout_of(tcx.types.unit)?,
             i8: layout_cx.layout_of(tcx.types.i8)?,
             i16: layout_cx.layout_of(tcx.types.i16)?,
             i32: layout_cx.layout_of(tcx.types.i32)?,
diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs
index ace0da01253..efeefbe29fb 100644
--- a/src/tools/miri/tests/ui.rs
+++ b/src/tools/miri/tests/ui.rs
@@ -1,6 +1,7 @@
 use std::ffi::OsString;
 use std::num::NonZeroUsize;
 use std::path::{Path, PathBuf};
+use std::sync::OnceLock;
 use std::{env, process::Command};
 
 use colored::*;
@@ -67,8 +68,8 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
 
     let mut config = Config {
         target: Some(target.to_owned()),
-        stderr_filters: STDERR.clone(),
-        stdout_filters: STDOUT.clone(),
+        stderr_filters: stderr_filters().into(),
+        stdout_filters: stdout_filters().into(),
         mode,
         program,
         out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap()).join("ui"),
@@ -174,15 +175,18 @@ fn run_tests(
 }
 
 macro_rules! regexes {
-    ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! {
-        static ref $name: Vec<(Match, &'static [u8])> = vec![
-            $((Regex::new($regex).unwrap().into(), $replacement.as_bytes()),)*
-        ];
-    }};
+    ($name:ident: $($regex:expr => $replacement:expr,)*) => {
+        fn $name() -> &'static [(Match, &'static [u8])] {
+            static S: OnceLock<Vec<(Match, &'static [u8])>> = OnceLock::new();
+            S.get_or_init(|| vec![
+                $((Regex::new($regex).unwrap().into(), $replacement.as_bytes()),)*
+            ])
+        }
+    };
 }
 
 regexes! {
-    STDOUT:
+    stdout_filters:
     // Windows file paths
     r"\\"                           => "/",
     // erase borrow tags
@@ -191,7 +195,7 @@ regexes! {
 }
 
 regexes! {
-    STDERR:
+    stderr_filters:
     // erase line and column info
     r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC",
     // erase alloc ids
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 61a24c97e77..cf4ae4b16cd 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -8,3 +8,4 @@ object = "0.34.0"
 similar = "2.5.0"
 wasmparser = "0.118.2"
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
+gimli = "0.28.1"
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
index a2d51902652..4082639f618 100644
--- a/src/tools/run-make-support/src/cc.rs
+++ b/src/tools/run-make-support/src/cc.rs
@@ -71,6 +71,11 @@ impl Cc {
 
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
 
 /// `EXTRACFLAGS`
@@ -161,8 +166,9 @@ pub fn extra_cxx_flags() -> Vec<&'static str> {
     if is_windows() {
         if is_msvc() { vec![] } else { vec!["-lstdc++"] }
     } else {
-        match uname() {
-            n if n.contains("Darwin") => vec!["-lc++"],
+        match &uname()[..] {
+            "Darwin" => vec!["-lc++"],
+            "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
             _ => vec!["-lstdc++"],
         }
     }
diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs
index ed9f8383dc3..c30ba29ed76 100644
--- a/src/tools/run-make-support/src/clang.rs
+++ b/src/tools/run-make-support/src/clang.rs
@@ -70,4 +70,9 @@ impl Clang {
         self.cmd.arg(format!("-fuse-ld={ld}"));
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs
index 54532c6e35b..332126939c0 100644
--- a/src/tools/run-make-support/src/diff/mod.rs
+++ b/src/tools/run-make-support/src/diff/mod.rs
@@ -1,3 +1,4 @@
+use regex::Regex;
 use similar::TextDiff;
 use std::path::Path;
 
@@ -14,12 +15,19 @@ pub struct Diff {
     expected_name: Option<String>,
     actual: Option<String>,
     actual_name: Option<String>,
+    normalizers: Vec<(String, String)>,
 }
 
 impl Diff {
     /// Construct a bare `diff` invocation.
     pub fn new() -> Self {
-        Self { expected: None, expected_name: None, actual: None, actual_name: None }
+        Self {
+            expected: None,
+            expected_name: None,
+            actual: None,
+            actual_name: None,
+            normalizers: Vec::new(),
+        }
     }
 
     /// Specify the expected output for the diff from a file.
@@ -58,15 +66,29 @@ impl Diff {
         self
     }
 
+    /// Specify a regex that should replace text in the "actual" text that will be compared.
+    pub fn normalize<R: Into<String>, I: Into<String>>(
+        &mut self,
+        regex: R,
+        replacement: I,
+    ) -> &mut Self {
+        self.normalizers.push((regex.into(), replacement.into()));
+        self
+    }
+
     /// Executes the diff process, prints any differences to the standard error.
     #[track_caller]
     pub fn run(&self) {
         let expected = self.expected.as_ref().expect("expected text not set");
-        let actual = self.actual.as_ref().expect("actual text not set");
+        let mut actual = self.actual.as_ref().expect("actual text not set").to_string();
         let expected_name = self.expected_name.as_ref().unwrap();
         let actual_name = self.actual_name.as_ref().unwrap();
+        for (regex, replacement) in &self.normalizers {
+            let re = Regex::new(regex).expect("bad regex in custom normalization rule");
+            actual = re.replace_all(&actual, replacement).into_owned();
+        }
 
-        let output = TextDiff::from_lines(expected, actual)
+        let output = TextDiff::from_lines(expected, &actual)
             .unified_diff()
             .header(expected_name, actual_name)
             .to_string();
diff --git a/src/tools/run-make-support/src/diff/tests.rs b/src/tools/run-make-support/src/diff/tests.rs
index e6d72544b7e..286548bef61 100644
--- a/src/tools/run-make-support/src/diff/tests.rs
+++ b/src/tools/run-make-support/src/diff/tests.rs
@@ -36,4 +36,26 @@ test failed: `EXPECTED_TEXT` is different from `ACTUAL_TEXT`
 
         assert_eq!(output.downcast_ref::<String>().unwrap(), expected_output);
     }
+
+    #[test]
+    fn test_normalize() {
+        let expected = "
+running 2 tests
+..
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+";
+        let actual = "
+running 2 tests
+..
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
+";
+
+        diff()
+            .expected_text("EXPECTED_TEXT", expected)
+            .actual_text("ACTUAL_TEXT", actual)
+            .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME")
+            .run();
+    }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 76e8838d27c..239f90b23c9 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -15,6 +15,7 @@ use std::env;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output};
 
+pub use gimli;
 pub use object;
 pub use regex;
 pub use wasmparser;
@@ -143,7 +144,7 @@ pub fn set_host_rpath(cmd: &mut Command) {
 }
 
 /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
-/// containing a `cmd: Command` field. The provided helpers are:
+/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
 ///
 /// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
 ///    to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
@@ -159,7 +160,12 @@ pub fn set_host_rpath(cmd: &mut Command) {
 /// Example usage:
 ///
 /// ```ignore (illustrative)
-/// struct CommandWrapper { cmd: Command }
+/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
+///
+/// impl CommandWrapper {
+///     /// Get the [`Output`][::std::process::Output] of the finished process.
+///     pub fn output(&mut self) -> Output { /* ... */ } // <- required `output()` method
+/// }
 ///
 /// crate::impl_common_helpers!(CommandWrapper);
 ///
@@ -230,18 +236,13 @@ macro_rules! impl_common_helpers {
                 self
             }
 
-            /// Get the [`Output`][::std::process::Output] of the finished process.
-            pub fn output(&mut self) -> ::std::process::Output {
-                self.cmd.output().expect("failed to get output of finished process")
-            }
-
             /// Run the constructed command and assert that it is successfully run.
             #[track_caller]
             pub fn run(&mut self) -> ::std::process::Output {
                 let caller_location = ::std::panic::Location::caller();
                 let caller_line_number = caller_location.line();
 
-                let output = self.cmd.output().unwrap();
+                let output = self.output();
                 if !output.status.success() {
                     handle_failed_output(&self.cmd, output, caller_line_number);
                 }
@@ -254,7 +255,7 @@ macro_rules! impl_common_helpers {
                 let caller_location = ::std::panic::Location::caller();
                 let caller_line_number = caller_location.line();
 
-                let output = self.cmd.output().unwrap();
+                let output = self.output();
                 if output.status.success() {
                     handle_failed_output(&self.cmd, output, caller_line_number);
                 }
diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs
index 32ea07e932e..4e1f2b002f3 100644
--- a/src/tools/run-make-support/src/llvm_readobj.rs
+++ b/src/tools/run-make-support/src/llvm_readobj.rs
@@ -41,4 +41,10 @@ impl LlvmReadobj {
         self.cmd.arg("--file-header");
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index ddaae3236c2..37539528ab3 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -1,7 +1,8 @@
 use std::env;
 use std::ffi::OsString;
+use std::io::Write;
 use std::path::Path;
-use std::process::{Command, Output};
+use std::process::{Command, Output, Stdio};
 
 use crate::{handle_failed_output, set_host_rpath, tmp_dir};
 
@@ -19,6 +20,7 @@ pub fn aux_build() -> Rustc {
 #[derive(Debug)]
 pub struct Rustc {
     cmd: Command,
+    stdin: Option<Box<[u8]>>,
 }
 
 crate::impl_common_helpers!(Rustc);
@@ -37,14 +39,14 @@ impl Rustc {
     /// Construct a new `rustc` invocation.
     pub fn new() -> Self {
         let cmd = setup_common();
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
     pub fn new_aux_build() -> Self {
         let mut cmd = setup_common();
         cmd.arg("--crate-type=lib");
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     // Argument provider methods
@@ -161,12 +163,40 @@ impl Rustc {
         self
     }
 
+    /// Specify a stdin input
+    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
+        self
+    }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        // let's make sure we piped all the input and outputs
+        self.cmd.stdin(Stdio::piped());
+        self.cmd.stdout(Stdio::piped());
+        self.cmd.stderr(Stdio::piped());
+
+        if let Some(input) = &self.stdin {
+            let mut child = self.cmd.spawn().unwrap();
+
+            {
+                let mut stdin = child.stdin.take().unwrap();
+                stdin.write_all(input.as_ref()).unwrap();
+            }
+
+            child.wait_with_output().expect("failed to get output of finished process")
+        } else {
+            self.cmd.output().expect("failed to get output of finished process")
+        }
+    }
+
     #[track_caller]
     pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
         let caller_location = std::panic::Location::caller();
         let caller_line_number = caller_location.line();
 
-        let output = self.cmd.output().unwrap();
+        let output = self.output();
         if output.status.code().unwrap() != code {
             handle_failed_output(&self.cmd, output, caller_line_number);
         }
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
index 1054ac83c10..c2c4f2e68e2 100644
--- a/src/tools/run-make-support/src/rustdoc.rs
+++ b/src/tools/run-make-support/src/rustdoc.rs
@@ -1,6 +1,7 @@
 use std::env;
+use std::io::Write;
 use std::path::Path;
-use std::process::{Command, Output};
+use std::process::{Command, Output, Stdio};
 
 use crate::{handle_failed_output, set_host_rpath};
 
@@ -17,6 +18,7 @@ pub fn rustdoc() -> Rustdoc {
 #[derive(Debug)]
 pub struct Rustdoc {
     cmd: Command,
+    stdin: Option<Box<[u8]>>,
 }
 
 crate::impl_common_helpers!(Rustdoc);
@@ -32,7 +34,7 @@ impl Rustdoc {
     /// Construct a bare `rustdoc` invocation.
     pub fn bare() -> Self {
         let cmd = setup_common();
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
@@ -40,7 +42,7 @@ impl Rustdoc {
         let mut cmd = setup_common();
         let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
         cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Specify path to the input file.
@@ -62,12 +64,41 @@ impl Rustdoc {
         self
     }
 
+    /// Specify a stdin input
+    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.cmd.stdin(Stdio::piped());
+        self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
+        self
+    }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        // let's make sure we piped all the input and outputs
+        self.cmd.stdin(Stdio::piped());
+        self.cmd.stdout(Stdio::piped());
+        self.cmd.stderr(Stdio::piped());
+
+        if let Some(input) = &self.stdin {
+            let mut child = self.cmd.spawn().unwrap();
+
+            {
+                let mut stdin = child.stdin.take().unwrap();
+                stdin.write_all(input.as_ref()).unwrap();
+            }
+
+            child.wait_with_output().expect("failed to get output of finished process")
+        } else {
+            self.cmd.output().expect("failed to get output of finished process")
+        }
+    }
+
     #[track_caller]
     pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
         let caller_location = std::panic::Location::caller();
         let caller_line_number = caller_location.line();
 
-        let output = self.cmd.output().unwrap();
+        let output = self.output();
         if output.status.code().unwrap() != code {
             handle_failed_output(&self.cmd, output, caller_line_number);
         }
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index f6f51fbd8ea..e196d1817f3 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -3325,11 +3325,11 @@ impl Rewrite for ast::ForeignItem {
                     .map(|(s, _, _)| format!("{};", s))
                 }
             }
-            ast::ForeignItemKind::Static(ref ty, mutability, _) => {
+            ast::ForeignItemKind::Static(ref static_foreign_item) => {
                 // FIXME(#21): we're dropping potential comments in between the
                 // function kw here.
                 let vis = format_visibility(context, &self.vis);
-                let mut_str = format_mutability(mutability);
+                let mut_str = format_mutability(static_foreign_item.mutability);
                 let prefix = format!(
                     "{}static {}{}:",
                     vis,
@@ -3340,7 +3340,7 @@ impl Rewrite for ast::ForeignItem {
                 rewrite_assign_rhs(
                     context,
                     prefix,
-                    &**ty,
+                    &static_foreign_item.ty,
                     &RhsAssignKind::Ty,
                     shape.sub_width(1)?,
                 )
diff --git a/src/tools/suggest-tests/Cargo.toml b/src/tools/suggest-tests/Cargo.toml
index f4f4d548bb7..7c048d53a50 100644
--- a/src/tools/suggest-tests/Cargo.toml
+++ b/src/tools/suggest-tests/Cargo.toml
@@ -6,4 +6,3 @@ edition = "2021"
 [dependencies]
 glob = "0.3.0"
 build_helper = { version = "0.1.0", path = "../build_helper" }
-once_cell = "1.17.1"
diff --git a/src/tools/suggest-tests/src/lib.rs b/src/tools/suggest-tests/src/lib.rs
index 1c1d9d0333d..8932403ac9f 100644
--- a/src/tools/suggest-tests/src/lib.rs
+++ b/src/tools/suggest-tests/src/lib.rs
@@ -5,7 +5,7 @@ use std::{
 
 use dynamic_suggestions::DYNAMIC_SUGGESTIONS;
 use glob::Pattern;
-use static_suggestions::STATIC_SUGGESTIONS;
+use static_suggestions::static_suggestions;
 
 mod dynamic_suggestions;
 mod static_suggestions;
@@ -33,7 +33,7 @@ pub fn get_suggestions<T: AsRef<str>>(modified_files: &[T]) -> Vec<Suggestion> {
     let mut suggestions = Vec::new();
 
     // static suggestions
-    for (globs, sugs) in STATIC_SUGGESTIONS.iter() {
+    for (globs, sugs) in static_suggestions().iter() {
         let globs = globs
             .iter()
             .map(|glob| Pattern::new(glob).expect("Found invalid glob pattern!"))
diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs
index fbd265ea42a..a34a4b16ec1 100644
--- a/src/tools/suggest-tests/src/static_suggestions.rs
+++ b/src/tools/suggest-tests/src/static_suggestions.rs
@@ -1,10 +1,14 @@
 use crate::{sug, Suggestion};
+use std::sync::OnceLock;
 
 // FIXME: perhaps this could use `std::lazy` when it is stablizied
 macro_rules! static_suggestions {
     ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => {
-        pub(crate) const STATIC_SUGGESTIONS: ::once_cell::unsync::Lazy<Vec<(Vec<&'static str>, Vec<Suggestion>)>>
-            = ::once_cell::unsync::Lazy::new(|| vec![ $( (vec![ $($glob),* ], vec![ $($suggestion),* ]) ),*]);
+        pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec<Suggestion>)]
+        {
+            static S: OnceLock<Vec<(Vec<&'static str>, Vec<Suggestion>)>> = OnceLock::new();
+            S.get_or_init(|| vec![ $( (vec![ $($glob),* ], vec![ $($suggestion),* ]) ),*])
+        }
     }
 }
 
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 96866e74248..63963b0bd1c 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -8,7 +8,6 @@ autobins = false
 cargo_metadata = "0.15"
 regex = "1"
 miropt-test-tools = { path = "../miropt-test-tools" }
-lazy_static = "1"
 walkdir = "2"
 ignore = "0.4.18"
 semver = "1.0"
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 9b3c0d0f1a5..4b79b910ec3 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -219,8 +219,6 @@ run-make/prefer-rlib/Makefile
 run-make/pretty-print-to-file/Makefile
 run-make/pretty-print-with-dep-file/Makefile
 run-make/print-calling-conventions/Makefile
-run-make/print-cfg/Makefile
-run-make/print-native-static-libs/Makefile
 run-make/print-target-list/Makefile
 run-make/profile/Makefile
 run-make/prune-link-args/Makefile
@@ -237,7 +235,6 @@ run-make/relocation-model/Makefile
 run-make/relro-levels/Makefile
 run-make/remap-path-prefix-dwarf/Makefile
 run-make/remap-path-prefix/Makefile
-run-make/repr128-dwarf/Makefile
 run-make/reproducible-build-2/Makefile
 run-make/reproducible-build/Makefile
 run-make/resolve-rename/Makefile
@@ -291,7 +288,6 @@ run-make/static-unwinding/Makefile
 run-make/staticlib-blank-lib/Makefile
 run-make/staticlib-dylib-linkage/Makefile
 run-make/std-core-cycle/Makefile
-run-make/stdin-non-utf8/Makefile
 run-make/suspicious-library/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/symbol-visibility/Makefile
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index d673ce7a736..3e84bf3c34b 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -17,8 +17,6 @@ use std::fs;
 use std::num::NonZeroU32;
 use std::path::{Path, PathBuf};
 
-use regex::Regex;
-
 #[cfg(test)]
 mod tests;
 
@@ -251,16 +249,10 @@ fn format_features<'a>(
 }
 
 fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
-    lazy_static::lazy_static! {
-        static ref ISSUE: Regex = Regex::new(r#"issue\s*=\s*"([^"]*)""#).unwrap();
-        static ref FEATURE: Regex = Regex::new(r#"feature\s*=\s*"([^"]*)""#).unwrap();
-        static ref SINCE: Regex = Regex::new(r#"since\s*=\s*"([^"]*)""#).unwrap();
-    }
-
     let r = match attr {
-        "issue" => &*ISSUE,
-        "feature" => &*FEATURE,
-        "since" => &*SINCE,
+        "issue" => static_regex!(r#"issue\s*=\s*"([^"]*)""#),
+        "feature" => static_regex!(r#"feature\s*=\s*"([^"]*)""#),
+        "since" => static_regex!(r#"since\s*=\s*"([^"]*)""#),
         _ => unimplemented!("{attr} not handled"),
     };
 
@@ -528,11 +520,8 @@ fn map_lib_features(
                     }};
                 }
 
-                lazy_static::lazy_static! {
-                    static ref COMMENT_LINE: Regex = Regex::new(r"^\s*//").unwrap();
-                }
                 // exclude commented out lines
-                if COMMENT_LINE.is_match(line) {
+                if static_regex!(r"^\s*//").is_match(line) {
                     continue;
                 }
 
diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs
index 9803b6eab2d..a85367984de 100644
--- a/src/tools/tidy/src/fluent_alphabetical.rs
+++ b/src/tools/tidy/src/fluent_alphabetical.rs
@@ -6,8 +6,8 @@ use std::{fs::OpenOptions, io::Write, path::Path};
 
 use regex::Regex;
 
-lazy_static::lazy_static! {
-    static ref MESSAGE: Regex = Regex::new(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#).unwrap();
+fn message() -> &'static Regex {
+    static_regex!(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#)
 }
 
 fn filter_fluent(path: &Path) -> bool {
@@ -20,7 +20,7 @@ fn check_alphabetic(
     bad: &mut bool,
     all_defined_msgs: &mut HashMap<String, String>,
 ) {
-    let mut matches = MESSAGE.captures_iter(fluent).peekable();
+    let mut matches = message().captures_iter(fluent).peekable();
     while let Some(m) = matches.next() {
         let name = m.get(1).unwrap();
         if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) {
@@ -60,7 +60,7 @@ fn sort_messages(
     let mut chunks = vec![];
     let mut cur = String::new();
     for line in fluent.lines() {
-        if let Some(name) = MESSAGE.find(line) {
+        if let Some(name) = message().find(line) {
             if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) {
                 tidy_error!(
                     bad,
diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs
index b73e79cb38d..8b6c6c18813 100644
--- a/src/tools/tidy/src/fluent_used.rs
+++ b/src/tools/tidy/src/fluent_used.rs
@@ -1,14 +1,9 @@
 //! Checks that all Fluent messages appear at least twice
 
 use crate::walk::{filter_dirs, walk};
-use regex::Regex;
 use std::collections::HashMap;
 use std::path::Path;
 
-lazy_static::lazy_static! {
-    static ref WORD: Regex = Regex::new(r"\w+").unwrap();
-}
-
 fn filter_used_messages(
     contents: &str,
     msgs_not_appeared_yet: &mut HashMap<String, String>,
@@ -17,7 +12,7 @@ fn filter_used_messages(
     // we don't just check messages never appear in Rust files,
     // because messages can be used as parts of other fluent messages in Fluent files,
     // so we do checking messages appear only once in all Rust and Fluent files.
-    let mut matches = WORD.find_iter(contents);
+    let mut matches = static_regex!(r"\w+").find_iter(contents);
     while let Some(name) = matches.next() {
         if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) {
             // if one msg appears for the first time,
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index dff15265fae..4f02a61f7bc 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -439,7 +439,6 @@ ui/closures/issue-11873.rs
 ui/closures/issue-1460.rs
 ui/closures/issue-22864-1.rs
 ui/closures/issue-22864-2.rs
-ui/closures/issue-23012-supertrait-signature-inference.rs
 ui/closures/issue-25439.rs
 ui/closures/issue-41366.rs
 ui/closures/issue-42463.rs
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 23f303276aa..c15081a56d1 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -5,6 +5,13 @@
 
 use termcolor::WriteColor;
 
+macro_rules! static_regex {
+    ($re:literal) => {{
+        static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new();
+        RE.get_or_init(|| ::regex::Regex::new($re).unwrap())
+    }};
+}
+
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
 /// * The expression that failed
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index a1445ce5896..9cabab582d0 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -18,7 +18,7 @@
 // ignore-tidy-dbg
 
 use crate::walk::{filter_dirs, walk};
-use regex::{Regex, RegexSet};
+use regex::RegexSet;
 use rustc_hash::FxHashMap;
 use std::{ffi::OsStr, path::Path};
 
@@ -178,20 +178,14 @@ fn should_ignore(line: &str) -> bool {
     // Matches test annotations like `//~ ERROR text`.
     // This mirrors the regex in src/tools/compiletest/src/runtest.rs, please
     // update both if either are changed.
-    lazy_static::lazy_static! {
-        static ref ANNOTATION_RE: Regex = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap();
-    }
+    static_regex!("\\s*//(\\[.*\\])?~.*").is_match(line)
+        || ANNOTATIONS_TO_IGNORE.iter().any(|a| line.contains(a))
+
     // For `ui_test`-style UI test directives, also ignore
     // - `//@[rev] compile-flags`
     // - `//@[rev] normalize-stderr-test`
-    lazy_static::lazy_static! {
-        static ref UI_TEST_LONG_DIRECTIVES_RE: Regex =
-        Regex::new("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*")
-            .unwrap();
-    }
-    ANNOTATION_RE.is_match(line)
-        || ANNOTATIONS_TO_IGNORE.iter().any(|a| line.contains(a))
-        || UI_TEST_LONG_DIRECTIVES_RE.is_match(line)
+        || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*")
+            .is_match(line)
 }
 
 /// Returns `true` if `line` is allowed to be longer than the normal limit.
@@ -226,6 +220,7 @@ fn contains_ignore_directive(can_contain: bool, contents: &str, check: &str) ->
     if contents.contains(&format!("// ignore-tidy-{check}"))
         || contents.contains(&format!("# ignore-tidy-{check}"))
         || contents.contains(&format!("/* ignore-tidy-{check} */"))
+        || contents.contains(&format!("<!-- ignore-tidy-{check} -->"))
     {
         Directive::Ignore(false)
     } else {
@@ -352,7 +347,8 @@ pub fn check(path: &Path, bad: &mut bool) {
 
         let can_contain = contents.contains("// ignore-tidy-")
             || contents.contains("# ignore-tidy-")
-            || contents.contains("/* ignore-tidy-");
+            || contents.contains("/* ignore-tidy-")
+            || contents.contains("<!-- ignore-tidy-");
         // Enable testing ICE's that require specific (untidy)
         // file formats easily eg. `issue-1234-ignore-tidy.rs`
         if filename.contains("ignore-tidy") {
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index f9985a75703..94a0eee154d 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -2,8 +2,6 @@
 //! - the number of entries in each directory must be less than `ENTRY_LIMIT`
 //! - there are no stray `.stderr` files
 use ignore::Walk;
-use lazy_static::lazy_static;
-use regex::Regex;
 use std::collections::{BTreeSet, HashMap};
 use std::ffi::OsStr;
 use std::fs;
@@ -182,12 +180,8 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) {
             }
 
             if ext == "rs" {
-                lazy_static! {
-                    static ref ISSUE_NAME_REGEX: Regex =
-                        Regex::new(r"^issues?[-_]?(\d{3,})").unwrap();
-                }
-
-                if let Some(test_name) = ISSUE_NAME_REGEX.captures(testname) {
+                if let Some(test_name) = static_regex!(r"^issues?[-_]?(\d{3,})").captures(testname)
+                {
                     // these paths are always relative to the passed `path` and always UTF8
                     let stripped_path = file_path
                         .strip_prefix(path)
diff --git a/src/version b/src/version
index b3a8c61e6a8..aaceec04e04 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.79.0
+1.80.0
diff --git a/tests/assembly/manual-eq-efficient.rs b/tests/assembly/manual-eq-efficient.rs
new file mode 100644
index 00000000000..817ce94f476
--- /dev/null
+++ b/tests/assembly/manual-eq-efficient.rs
@@ -0,0 +1,22 @@
+// Regression test for #106269
+//@ assembly-output: emit-asm
+//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
+//@ only-x86_64
+//@ ignore-sgx
+
+pub struct S {
+    a: u8,
+    b: u8,
+    c: u8,
+    d: u8,
+}
+
+// CHECK-LABEL: manual_eq:
+#[no_mangle]
+pub fn manual_eq(s1: &S, s2: &S) -> bool {
+    // CHECK: mov [[REG:[a-z0-9]+]], dword ptr [{{[a-z0-9]+}}]
+    // CHECK-NEXT: cmp [[REG]], dword ptr [{{[a-z0-9]+}}]
+    // CHECK-NEXT: sete al
+    // CHECK: ret
+    s1.a == s2.a && s1.b == s2.b && s1.c == s2.c && s1.d == s2.d
+}
diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs
index 763401755fa..72c3f6376e8 100644
--- a/tests/assembly/simd-intrinsic-mask-reduce.rs
+++ b/tests/assembly/simd-intrinsic-mask-reduce.rs
@@ -1,6 +1,8 @@
 // verify that simd mask reductions do not introduce additional bit shift operations
 //@ revisions: x86 aarch64
 //@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
+// Set the base cpu explicitly, in case the default has been changed.
+//@ [x86] compile-flags: -C target-cpu=x86-64
 //@ [x86] needs-llvm-components: x86
 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu
 //@ [aarch64] needs-llvm-components: aarch64
diff --git a/tests/assembly/x86_64-floating-point-clamp.rs b/tests/assembly/x86_64-floating-point-clamp.rs
index 4a72a7f44fa..c05afadff64 100644
--- a/tests/assembly/x86_64-floating-point-clamp.rs
+++ b/tests/assembly/x86_64-floating-point-clamp.rs
@@ -2,7 +2,8 @@
 // so check to make sure that's what it's actually emitting.
 
 //@ assembly-output: emit-asm
-//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
+// Set the base cpu explicitly, in case the default has been changed.
+//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel -C target-cpu=x86-64
 //@ only-x86_64
 //@ ignore-sgx
 
diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs
index f1c40f6695b..ced26c0a434 100644
--- a/tests/codegen/enum/enum-match.rs
+++ b/tests/codegen/enum/enum-match.rs
@@ -11,7 +11,7 @@ pub enum Enum0 {
     B,
 }
 
-// CHECK: define noundef i8 @match0{{.*}}
+// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match0{{.*}}
 // CHECK-NEXT: start:
 // CHECK-NEXT: %1 = icmp eq i8 %0, 2
 // CHECK-NEXT: %2 = and i8 %0, 1
@@ -32,7 +32,7 @@ pub enum Enum1 {
     C,
 }
 
-// CHECK: define noundef i8 @match1{{.*}}
+// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match1{{.*}}
 // CHECK-NEXT: start:
 // CHECK-NEXT: %1 = add i8 %0, -2
 // CHECK-NEXT: %2 = zext i8 %1 to i64
@@ -91,7 +91,7 @@ pub enum Enum2 {
     E,
 }
 
-// CHECK: define noundef i8 @match2{{.*}}
+// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match2{{.*}}
 // CHECK-NEXT: start:
 // CHECK-NEXT: %1 = add i8 %0, 2
 // CHECK-NEXT: %2 = zext i8 %1 to i64
diff --git a/tests/codegen/ptr-read-metadata.rs b/tests/codegen/ptr-read-metadata.rs
index 4c623dee5e1..e3565c962f7 100644
--- a/tests/codegen/ptr-read-metadata.rs
+++ b/tests/codegen/ptr-read-metadata.rs
@@ -47,7 +47,7 @@ pub unsafe fn read_byte_assume_init(p: &MaybeUninit<u8>) -> u8 {
     p.assume_init_read()
 }
 
-// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @copy_char(
+// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @copy_char(
 #[no_mangle]
 pub unsafe fn copy_char(p: *const char) -> char {
     // CHECK-NOT: load
@@ -58,7 +58,7 @@ pub unsafe fn copy_char(p: *const char) -> char {
     *p
 }
 
-// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @read_char(
+// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @read_char(
 #[no_mangle]
 pub unsafe fn read_char(p: *const char) -> char {
     // CHECK-NOT: load
@@ -80,7 +80,7 @@ pub unsafe fn read_char_maybe_uninit(p: *const MaybeUninit<char>) -> MaybeUninit
     p.read()
 }
 
-// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @read_char_assume_init(
+// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @read_char_assume_init(
 #[no_mangle]
 pub unsafe fn read_char_assume_init(p: &MaybeUninit<char>) -> char {
     // CHECK-NOT: load
diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs
index 88bd413a870..d973bd93e31 100644
--- a/tests/codegen/target-feature-inline-closure.rs
+++ b/tests/codegen/target-feature-inline-closure.rs
@@ -1,5 +1,6 @@
 //@ only-x86_64
-//@ compile-flags: -Copt-level=3
+// Set the base cpu explicitly, in case the default has been changed.
+//@ compile-flags: -Copt-level=3 -Ctarget-cpu=x86-64
 
 #![crate_type = "lib"]
 #![feature(target_feature_11)]
diff --git a/tests/coverage/mcdc_nested_if.cov-map b/tests/coverage/mcdc_nested_if.cov-map
new file mode 100644
index 00000000000..2f35ffad8a9
--- /dev/null
+++ b/tests/coverage/mcdc_nested_if.cov-map
@@ -0,0 +1,201 @@
+Function name: mcdc_nested_if::doubly_nested_if_in_condition
+Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 0f, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 01, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 00, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 14
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 3 operands: lhs = Expression(9, Sub), rhs = Counter(6)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 5 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 6 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 7 operands: lhs = Counter(7), rhs = Expression(8, Sub)
+- expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(6)
+- expression 9 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 10 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 20
+- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
+- MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
+- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78)
+    true  = c3
+    false = c2
+- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
+- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 54)
+- MCDCBranch { true: Counter(4), false: Expression(9, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+    true  = c4
+    false = (c1 - c4)
+- MCDCBranch { true: Counter(5), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54)
+    true  = c5
+    false = c8
+- Code(Expression(9, Sub)) at (prev + 0, 24) to (start + 0, 25)
+    = (c1 - c4)
+- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 24) to (start + 0, 30)
+- MCDCBranch { true: Counter(6), false: Expression(8, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25)
+    true  = c6
+    false = ((c1 - c4) - c6)
+- Code(Counter(6)) at (prev + 0, 29) to (start + 0, 30)
+- MCDCBranch { true: Expression(6, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30)
+    true  = (c6 - c7)
+    false = c7
+- Code(Expression(6, Sub)) at (prev + 0, 33) to (start + 0, 37)
+    = (c6 - c7)
+- Code(Expression(7, Add)) at (prev + 0, 47) to (start + 0, 52)
+    = (c7 + ((c1 - c4) - c6))
+- Code(Expression(10, Add)) at (prev + 0, 57) to (start + 0, 62)
+    = (c4 + c5)
+- Code(Counter(8)) at (prev + 0, 72) to (start + 0, 76)
+- Code(Counter(3)) at (prev + 0, 79) to (start + 2, 6)
+- Code(Expression(13, Add)) at (prev + 2, 12) to (start + 2, 6)
+    = (c2 + (c0 - c1))
+- Code(Expression(12, Add)) at (prev + 3, 1) to (start + 0, 2)
+    = (c3 + (c2 + (c0 - c1)))
+
+Function name: mcdc_nested_if::nested_if_in_condition
+Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 07, 01, 01, 09, 28, 01, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 11
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(5)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 5 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(5)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 8 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+- expression 9 operands: lhs = Counter(3), rhs = Expression(10, Add)
+- expression 10 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 14
+- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
+- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
+- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46)
+    true  = c3
+    false = c2
+- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
+- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22)
+- MCDCBranch { true: Counter(4), false: Expression(7, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+    true  = c4
+    false = (c1 - c4)
+- Code(Expression(7, Sub)) at (prev + 0, 21) to (start + 0, 22)
+    = (c1 - c4)
+- MCDCBranch { true: Counter(5), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
+    true  = c5
+    false = ((c1 - c4) - c5)
+- Code(Expression(5, Add)) at (prev + 0, 25) to (start + 0, 29)
+    = (c4 + c5)
+- Code(Expression(6, Sub)) at (prev + 0, 39) to (start + 0, 44)
+    = ((c1 - c4) - c5)
+- Code(Counter(3)) at (prev + 0, 47) to (start + 2, 6)
+- Code(Expression(10, Add)) at (prev + 2, 12) to (start + 2, 6)
+    = (c2 + (c0 - c1))
+- Code(Expression(9, Add)) at (prev + 3, 1) to (start + 0, 2)
+    = (c3 + (c2 + (c0 - c1)))
+
+Function name: mcdc_nested_if::nested_in_then_block_in_condition
+Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 22, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 01, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 18
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 3 operands: lhs = Expression(14, Sub), rhs = Counter(5)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 5 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(6)
+- expression 7 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 8 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 10 operands: lhs = Counter(7), rhs = Expression(11, Sub)
+- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(6)
+- expression 12 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 13 operands: lhs = Expression(14, Sub), rhs = Counter(5)
+- expression 14 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 15 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+- expression 16 operands: lhs = Counter(3), rhs = Expression(17, Add)
+- expression 17 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 20
+- Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9)
+- MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
+- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75)
+    true  = c3
+    false = c2
+- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
+- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22)
+- MCDCBranch { true: Counter(4), false: Expression(14, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+    true  = c4
+    false = (c1 - c4)
+- Code(Expression(14, Sub)) at (prev + 0, 21) to (start + 0, 22)
+    = (c1 - c4)
+- MCDCBranch { true: Counter(5), false: Expression(13, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
+    true  = c5
+    false = ((c1 - c4) - c5)
+- Code(Expression(12, Add)) at (prev + 0, 28) to (start + 0, 29)
+    = (c4 + c5)
+- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 0, 28) to (start + 0, 34)
+- MCDCBranch { true: Counter(6), false: Expression(11, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29)
+    true  = c6
+    false = ((c4 + c5) - c6)
+- Code(Counter(6)) at (prev + 0, 33) to (start + 0, 34)
+- MCDCBranch { true: Expression(9, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34)
+    true  = (c6 - c7)
+    false = c7
+- Code(Expression(9, Sub)) at (prev + 0, 37) to (start + 0, 41)
+    = (c6 - c7)
+- Code(Expression(10, Add)) at (prev + 0, 51) to (start + 0, 56)
+    = (c7 + ((c4 + c5) - c6))
+- Code(Expression(13, Sub)) at (prev + 0, 68) to (start + 0, 73)
+    = ((c1 - c4) - c5)
+- Code(Counter(3)) at (prev + 0, 76) to (start + 2, 6)
+- Code(Expression(17, Add)) at (prev + 2, 12) to (start + 2, 6)
+    = (c2 + (c0 - c1))
+- Code(Expression(16, Add)) at (prev + 3, 1) to (start + 0, 2)
+    = (c3 + (c2 + (c0 - c1)))
+
+Function name: mcdc_nested_if::nested_single_condition_decision
+Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 17, 01, 04, 09, 28, 00, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 6
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+- expression 4 operands: lhs = Counter(3), rhs = Expression(5, Add)
+- expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 11
+- Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9)
+- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
+- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41)
+    true  = c3
+    false = c2
+- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
+- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 16) to (start + 0, 17)
+    true  = c4
+    false = (c1 - c4)
+- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 25)
+- Code(Expression(2, Sub)) at (prev + 0, 35) to (start + 0, 39)
+    = (c1 - c4)
+- Code(Counter(3)) at (prev + 0, 42) to (start + 2, 6)
+- Code(Expression(5, Add)) at (prev + 2, 12) to (start + 2, 6)
+    = (c2 + (c0 - c1))
+- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2)
+    = (c3 + (c2 + (c0 - c1)))
+
diff --git a/tests/coverage/mcdc_nested_if.coverage b/tests/coverage/mcdc_nested_if.coverage
new file mode 100644
index 00000000000..19529cd6aa4
--- /dev/null
+++ b/tests/coverage/mcdc_nested_if.coverage
@@ -0,0 +1,235 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |//@ edition: 2021
+   LL|       |//@ min-llvm-version: 18
+   LL|       |//@ compile-flags: -Zcoverage-options=mcdc
+   LL|       |//@ llvm-cov-flags: --show-mcdc
+   LL|       |
+   LL|      4|fn nested_if_in_condition(a: bool, b: bool, c: bool) {
+   LL|      4|    if a && if b || c { true } else { false } {
+                             ^3   ^2  ^2            ^1
+  ------------------
+  |---> MC/DC Decision Region (LL:8) to (LL:46)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:8)
+  |     Condition C2 --> (LL:13)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  F  = F      }
+  |  3 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,3)
+  |  C2-Pair: covered: (2,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  |---> MC/DC Decision Region (LL:16) to (LL:22)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:16)
+  |     Condition C2 --> (LL:21)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  F  = F      }
+  |  2 { T,  -  = T      }
+  |  3 { F,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,2)
+  |  C2-Pair: covered: (1,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  ------------------
+   LL|      2|        say("yes");
+   LL|      2|    } else {
+   LL|      2|        say("no");
+   LL|      2|    }
+   LL|      4|}
+   LL|       |
+   LL|      4|fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) {
+   LL|      4|    if a && if b || if c && d { true } else { false } { false } else { true } {
+                             ^3      ^2   ^1  ^1            ^1        ^2             ^1
+  ------------------
+  |---> MC/DC Decision Region (LL:8) to (LL:78)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:8)
+  |     Condition C2 --> (LL:13)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  F  = F      }
+  |  3 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,3)
+  |  C2-Pair: covered: (2,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  |---> MC/DC Decision Region (LL:16) to (LL:54)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:16)
+  |     Condition C2 --> (LL:21)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  F  = F      }
+  |  2 { T,  -  = T      }
+  |  3 { F,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,2)
+  |  C2-Pair: covered: (1,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  |---> MC/DC Decision Region (LL:24) to (LL:30)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:24)
+  |     Condition C2 --> (LL:29)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,2)
+  |  C2-Pair: not covered
+  |  MC/DC Coverage for Decision: 50.00%
+  |
+  ------------------
+   LL|      1|        say("yes");
+   LL|      3|    } else {
+   LL|      3|        say("no");
+   LL|      3|    }
+   LL|      4|}
+   LL|       |
+   LL|      3|fn nested_single_condition_decision(a: bool, b: bool) {
+   LL|      3|    // Decision with only 1 decision should not be instrumented by MCDC because
+   LL|      3|    // branch-coverage is equivalent to MCDC coverage in this case, and we don't
+   LL|      3|    // want to waste bitmap space for this.
+   LL|      3|    if a && if b { false } else { true } {
+                             ^2  ^1             ^1
+  ------------------
+  |---> MC/DC Decision Region (LL:8) to (LL:41)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:8)
+  |     Condition C2 --> (LL:13)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  F  = F      }
+  |  3 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,3)
+  |  C2-Pair: covered: (2,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  ------------------
+   LL|      1|        say("yes");
+   LL|      2|    } else {
+   LL|      2|        say("no");
+   LL|      2|    }
+   LL|      3|}
+   LL|       |
+   LL|      7|fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) {
+   LL|      7|    if a && if b || c { if d && e { true } else { false } } else { false } {
+                             ^6   ^5     ^5   ^2  ^1            ^4               ^1
+  ------------------
+  |---> MC/DC Decision Region (LL:8) to (LL:75)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:8)
+  |     Condition C2 --> (LL:13)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  F  = F      }
+  |  3 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,3)
+  |  C2-Pair: covered: (2,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  |---> MC/DC Decision Region (LL:16) to (LL:22)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:16)
+  |     Condition C2 --> (LL:21)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  F  = F      }
+  |  2 { T,  -  = T      }
+  |  3 { F,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,2)
+  |  C2-Pair: covered: (1,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  |---> MC/DC Decision Region (LL:28) to (LL:34)
+  |
+  |  Number of Conditions: 2
+  |     Condition C1 --> (LL:28)
+  |     Condition C2 --> (LL:33)
+  |
+  |  Executed MC/DC Test Vectors:
+  |
+  |     C1, C2    Result
+  |  1 { F,  -  = F      }
+  |  2 { T,  F  = F      }
+  |  3 { T,  T  = T      }
+  |
+  |  C1-Pair: covered: (1,3)
+  |  C2-Pair: covered: (2,3)
+  |  MC/DC Coverage for Decision: 100.00%
+  |
+  ------------------
+   LL|      1|        say("yes");
+   LL|      6|    } else {
+   LL|      6|        say("no");
+   LL|      6|    }
+   LL|      7|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    nested_if_in_condition(true, false, false);
+   LL|       |    nested_if_in_condition(true, true, true);
+   LL|       |    nested_if_in_condition(true, false, true);
+   LL|       |    nested_if_in_condition(false, true, true);
+   LL|       |
+   LL|       |    doubly_nested_if_in_condition(true, false, false, true);
+   LL|       |    doubly_nested_if_in_condition(true, true, true, true);
+   LL|       |    doubly_nested_if_in_condition(true, false, true, true);
+   LL|       |    doubly_nested_if_in_condition(false, true, true, true);
+   LL|       |
+   LL|       |    nested_single_condition_decision(true, true);
+   LL|       |    nested_single_condition_decision(true, false);
+   LL|       |    nested_single_condition_decision(false, false);
+   LL|       |
+   LL|       |    nested_in_then_block_in_condition(false, false, false, false, false);
+   LL|       |    nested_in_then_block_in_condition(true, false, false, false, false);
+   LL|       |    nested_in_then_block_in_condition(true, true, false, false, false);
+   LL|       |    nested_in_then_block_in_condition(true, false, true, false, false);
+   LL|       |    nested_in_then_block_in_condition(true, false, true, true, false);
+   LL|       |    nested_in_then_block_in_condition(true, false, true, false, true);
+   LL|       |    nested_in_then_block_in_condition(true, false, true, true, true);
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn say(message: &str) {
+   LL|       |    core::hint::black_box(message);
+   LL|       |}
+
diff --git a/tests/coverage/mcdc_nested_if.rs b/tests/coverage/mcdc_nested_if.rs
new file mode 100644
index 00000000000..3d869771f75
--- /dev/null
+++ b/tests/coverage/mcdc_nested_if.rs
@@ -0,0 +1,70 @@
+#![feature(coverage_attribute)]
+//@ edition: 2021
+//@ min-llvm-version: 18
+//@ compile-flags: -Zcoverage-options=mcdc
+//@ llvm-cov-flags: --show-mcdc
+
+fn nested_if_in_condition(a: bool, b: bool, c: bool) {
+    if a && if b || c { true } else { false } {
+        say("yes");
+    } else {
+        say("no");
+    }
+}
+
+fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) {
+    if a && if b || if c && d { true } else { false } { false } else { true } {
+        say("yes");
+    } else {
+        say("no");
+    }
+}
+
+fn nested_single_condition_decision(a: bool, b: bool) {
+    // Decision with only 1 decision should not be instrumented by MCDC because
+    // branch-coverage is equivalent to MCDC coverage in this case, and we don't
+    // want to waste bitmap space for this.
+    if a && if b { false } else { true } {
+        say("yes");
+    } else {
+        say("no");
+    }
+}
+
+fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) {
+    if a && if b || c { if d && e { true } else { false } } else { false } {
+        say("yes");
+    } else {
+        say("no");
+    }
+}
+
+#[coverage(off)]
+fn main() {
+    nested_if_in_condition(true, false, false);
+    nested_if_in_condition(true, true, true);
+    nested_if_in_condition(true, false, true);
+    nested_if_in_condition(false, true, true);
+
+    doubly_nested_if_in_condition(true, false, false, true);
+    doubly_nested_if_in_condition(true, true, true, true);
+    doubly_nested_if_in_condition(true, false, true, true);
+    doubly_nested_if_in_condition(false, true, true, true);
+
+    nested_single_condition_decision(true, true);
+    nested_single_condition_decision(true, false);
+    nested_single_condition_decision(false, false);
+
+    nested_in_then_block_in_condition(false, false, false, false, false);
+    nested_in_then_block_in_condition(true, false, false, false, false);
+    nested_in_then_block_in_condition(true, true, false, false, false);
+    nested_in_then_block_in_condition(true, false, true, false, false);
+    nested_in_then_block_in_condition(true, false, true, true, false);
+    nested_in_then_block_in_condition(true, false, true, false, true);
+    nested_in_then_block_in_condition(true, false, true, true, true);
+}
+
+#[coverage(off)]
+fn say(message: &str) {
+    core::hint::black_box(message);
+}
diff --git a/tests/crashes/109812.rs b/tests/crashes/109812.rs
new file mode 100644
index 00000000000..c29b8746521
--- /dev/null
+++ b/tests/crashes/109812.rs
@@ -0,0 +1,22 @@
+//@ known-bug: #109812
+
+#![warn(rust_2021_incompatible_closure_captures)]
+
+enum Either {
+    One(X),
+    Two(X),
+}
+
+struct X(Y);
+
+struct Y;
+
+fn move_into_fnmut() {
+    let x = X(Y);
+
+    consume_fnmut(|| {
+        let Either::Two(ref mut _t) = x;
+
+        let X(mut _t) = x;
+    });
+}
diff --git a/tests/crashes/123710.rs b/tests/crashes/123710.rs
deleted file mode 100644
index f171fa7cebb..00000000000
--- a/tests/crashes/123710.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #123710
-
-#[repr(packed)]
-#[repr(u32)]
-enum E {
-    A,
-    B,
-    C,
-}
-
-fn main() {
-    union InvalidTag {
-        int: u32,
-        e: E,
-    }
-    let _invalid_tag = InvalidTag { int: 4 };
-}
diff --git a/tests/crashes/123863.rs b/tests/crashes/123863.rs
deleted file mode 100644
index e0f3ac9dcd7..00000000000
--- a/tests/crashes/123863.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #123863
-const fn concat_strs<const A: &'static str>() -> &'static str {
-    struct Inner<const A: &'static str>;
-    Inner::concat_strs::<"a">::A
-}
-pub fn main() {}
diff --git a/tests/crashes/124262.rs b/tests/crashes/124262.rs
new file mode 100644
index 00000000000..b9dac5eca22
--- /dev/null
+++ b/tests/crashes/124262.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #124262
+//@ edition:2021
+
+struct Foo(<&[fn()] as ::core::ops::Deref>::Target);
+const _: *const Foo = 0 as _;
diff --git a/tests/crashes/124340.rs b/tests/crashes/124340.rs
new file mode 100644
index 00000000000..cdf24fa0395
--- /dev/null
+++ b/tests/crashes/124340.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #124340
+#![feature(anonymous_lifetime_in_impl_trait)]
+
+trait Producer {
+    type Output;
+    fn produce(self) -> Self::Output;
+}
+
+trait SomeTrait<'a> {}
+
+fn force_same_lifetime<'a>(_x: &'a i32, _y: impl SomeTrait<'a>) {
+    unimplemented!()
+}
+
+fn foo<'a>(s: &'a i32, producer: impl Producer<Output: SomeTrait<'_>>) {
+    force_same_lifetime(s, producer.produce());
+}
diff --git a/tests/crashes/124342.rs b/tests/crashes/124342.rs
new file mode 100644
index 00000000000..ae51b3db96f
--- /dev/null
+++ b/tests/crashes/124342.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #124342
+trait Trait2 : Trait {
+   reuse <() as Trait>::async {
+        (async || {}).await;
+    };
+}
diff --git a/tests/crashes/124347.rs b/tests/crashes/124347.rs
new file mode 100644
index 00000000000..d2bc555fe1c
--- /dev/null
+++ b/tests/crashes/124347.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #124347
+trait Trait: ToReuse {
+    reuse Trait::lolno { &self.0 };
+}
diff --git a/tests/crashes/124348.rs b/tests/crashes/124348.rs
new file mode 100644
index 00000000000..554f383026c
--- /dev/null
+++ b/tests/crashes/124348.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #124348
+enum Eek {
+    TheConst,
+    UnusedByTheConst(Sum),
+}
+
+const EEK_ZERO: &[Eek] = &[];
diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs
new file mode 100644
index 00000000000..d6038f280cf
--- /dev/null
+++ b/tests/crashes/124350.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #124350
+
+struct Node<const D: usize> {}
+
+impl Node<D>
+where
+    SmallVec<{ D * 2 }>:,
+{
+    fn new() -> Self {
+        let mut node = Node::new();
+        (&a, 0)();
+
+        node
+    }
+}
+
+struct SmallVec<T1, T2> {}
diff --git a/tests/crashes/124352.rs b/tests/crashes/124352.rs
new file mode 100644
index 00000000000..e9eb4419e6a
--- /dev/null
+++ b/tests/crashes/124352.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #124352
+#![rustc_never_type_options(: Unsize<U> = "hi")]
+
+fn main() {}
diff --git a/tests/crashes/124375.rs b/tests/crashes/124375.rs
new file mode 100644
index 00000000000..7165655178d
--- /dev/null
+++ b/tests/crashes/124375.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #124375
+//@ compile-flags: -Zmir-opt-level=0
+//@ only-x86_64
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+#[naked]
+pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
+    asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
+}
diff --git a/tests/crashes/92470.rs b/tests/crashes/92470.rs
new file mode 100644
index 00000000000..a3c518f5ec6
--- /dev/null
+++ b/tests/crashes/92470.rs
@@ -0,0 +1,31 @@
+//@ known-bug: #92470
+fn main() {
+    encode(&mut EncoderImpl);
+}
+
+pub trait Encoder {
+    type W;
+
+    fn writer(&self) -> Self::W;
+}
+
+fn encode<E: Encoder>(mut encoder: E) {
+    encoder.writer();
+    encode(&mut encoder);
+}
+
+struct EncoderImpl;
+
+impl Encoder for EncoderImpl {
+    type W = ();
+
+    fn writer(&self) {}
+}
+
+impl<'a, T: Encoder> Encoder for &'a mut T {
+    type W = T::W;
+
+    fn writer(&self) -> Self::W {
+        panic!()
+    }
+}
diff --git a/tests/incremental/slice-pattern-const-ice-83085.rs b/tests/incremental/slice-pattern-const-ice-83085.rs
new file mode 100644
index 00000000000..4d318fd7ec1
--- /dev/null
+++ b/tests/incremental/slice-pattern-const-ice-83085.rs
@@ -0,0 +1,39 @@
+//@ compile-flags: -Zincremental-verify-ich=yes
+// issue: rust-lang/rust#83085 incremental ICE: forcing query with already existing `DepNode`
+// this used to fail to build straight away without needing any kind of
+// stage1/2 builds but tidy demands it
+//@ revisions:rpass1 rpass2
+
+fn main() {
+    const BOO: &[u8; 0] = &[];
+    match &[] {
+        BOO => (),
+        b"" => (),
+        _ => (),
+    }
+}
+
+#[derive(PartialEq, Eq)]
+struct Id<'a> {
+    ns: &'a str,
+}
+fn visit_struct() {
+    let id = Id { ns: "random1" };
+    const FLAG: Id<'static> = Id {
+        ns: "needs_to_be_the_same",
+    };
+    match id {
+        FLAG => {}
+        _ => {}
+    }
+}
+fn visit_struct2() {
+    let id = Id { ns: "random2" };
+    const FLAG: Id<'static> = Id {
+        ns: "needs_to_be_the_same",
+    };
+    match id {
+        FLAG => {}
+        _ => {}
+    }
+}
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff
index 5d94797905d..77a2c5bcccc 100644
--- a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff
@@ -4,33 +4,26 @@
   fn concrete() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
-      let mut _10: usize;
-      let mut _12: usize;
-      let mut _14: usize;
       scope 1 {
           debug x => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug y => _3;
-              let _5: usize;
+              debug y => _2;
+              let _3: usize;
               scope 3 {
-                  debug z0 => _5;
-                  let _7: usize;
+                  debug z0 => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug z1 => _7;
-                      let _9: usize;
+                      debug z1 => _4;
+                      let _5: usize;
                       scope 5 {
-                          debug eA0 => _9;
-                          let _11: usize;
+                          debug eA0 => _5;
+                          let _6: usize;
                           scope 6 {
-                              debug eA1 => _11;
-                              let _13: usize;
+                              debug eA1 => _6;
+                              let _7: usize;
                               scope 7 {
-                                  debug eC => _13;
+                                  debug eC => _7;
                               }
                           }
                       }
@@ -41,82 +34,33 @@
   
       bb0: {
           StorageLive(_1);
+-         _1 = OffsetOf(Alpha, [(0, 0)]);
++         _1 = const 4_usize;
           StorageLive(_2);
--         _2 = OffsetOf(Alpha, [(0, 0)]);
--         _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
-+         _2 = const 4_usize;
-+         _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+-         _2 = OffsetOf(Alpha, [(0, 1)]);
++         _2 = const 0_usize;
           StorageLive(_3);
+-         _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
++         _3 = const 2_usize;
           StorageLive(_4);
--         _4 = OffsetOf(Alpha, [(0, 1)]);
--         _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
-+         _4 = const 0_usize;
-+         _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          StorageDead(_4);
+-         _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
++         _4 = const 3_usize;
           StorageLive(_5);
+-         _5 = OffsetOf(Epsilon, [(0, 0)]);
++         _5 = const 1_usize;
           StorageLive(_6);
--         _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
+-         _6 = OffsetOf(Epsilon, [(0, 1)]);
 +         _6 = const 2_usize;
-+         _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_6);
           StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
-+         _8 = const 3_usize;
-+         _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          StorageLive(_9);
-          StorageLive(_10);
--         _10 = OffsetOf(Epsilon, [(0, 0)]);
--         _9 = must_use::<usize>(move _10) -> [return: bb5, unwind unreachable];
-+         _10 = const 1_usize;
-+         _9 = must_use::<usize>(const 1_usize) -> [return: bb5, unwind unreachable];
-      }
-  
-      bb5: {
-          StorageDead(_10);
-          StorageLive(_11);
-          StorageLive(_12);
--         _12 = OffsetOf(Epsilon, [(0, 1)]);
--         _11 = must_use::<usize>(move _12) -> [return: bb6, unwind unreachable];
-+         _12 = const 2_usize;
-+         _11 = must_use::<usize>(const 2_usize) -> [return: bb6, unwind unreachable];
-      }
-  
-      bb6: {
-          StorageDead(_12);
-          StorageLive(_13);
-          StorageLive(_14);
--         _14 = OffsetOf(Epsilon, [(2, 0)]);
--         _13 = must_use::<usize>(move _14) -> [return: bb7, unwind unreachable];
-+         _14 = const 4_usize;
-+         _13 = must_use::<usize>(const 4_usize) -> [return: bb7, unwind unreachable];
-      }
-  
-      bb7: {
-          StorageDead(_14);
+-         _7 = OffsetOf(Epsilon, [(2, 0)]);
++         _7 = const 4_usize;
           _0 = const ();
-          StorageDead(_13);
-          StorageDead(_11);
-          StorageDead(_9);
           StorageDead(_7);
+          StorageDead(_6);
           StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff
index 4d890742ee9..77a2c5bcccc 100644
--- a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff
@@ -4,33 +4,26 @@
   fn concrete() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
-      let mut _10: usize;
-      let mut _12: usize;
-      let mut _14: usize;
       scope 1 {
           debug x => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug y => _3;
-              let _5: usize;
+              debug y => _2;
+              let _3: usize;
               scope 3 {
-                  debug z0 => _5;
-                  let _7: usize;
+                  debug z0 => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug z1 => _7;
-                      let _9: usize;
+                      debug z1 => _4;
+                      let _5: usize;
                       scope 5 {
-                          debug eA0 => _9;
-                          let _11: usize;
+                          debug eA0 => _5;
+                          let _6: usize;
                           scope 6 {
-                              debug eA1 => _11;
-                              let _13: usize;
+                              debug eA1 => _6;
+                              let _7: usize;
                               scope 7 {
-                                  debug eC => _13;
+                                  debug eC => _7;
                               }
                           }
                       }
@@ -41,82 +34,33 @@
   
       bb0: {
           StorageLive(_1);
+-         _1 = OffsetOf(Alpha, [(0, 0)]);
++         _1 = const 4_usize;
           StorageLive(_2);
--         _2 = OffsetOf(Alpha, [(0, 0)]);
--         _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
-+         _2 = const 4_usize;
-+         _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind continue];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+-         _2 = OffsetOf(Alpha, [(0, 1)]);
++         _2 = const 0_usize;
           StorageLive(_3);
+-         _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
++         _3 = const 2_usize;
           StorageLive(_4);
--         _4 = OffsetOf(Alpha, [(0, 1)]);
--         _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
-+         _4 = const 0_usize;
-+         _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind continue];
-      }
-  
-      bb2: {
-          StorageDead(_4);
+-         _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
++         _4 = const 3_usize;
           StorageLive(_5);
+-         _5 = OffsetOf(Epsilon, [(0, 0)]);
++         _5 = const 1_usize;
           StorageLive(_6);
--         _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
+-         _6 = OffsetOf(Epsilon, [(0, 1)]);
 +         _6 = const 2_usize;
-+         _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind continue];
-      }
-  
-      bb3: {
-          StorageDead(_6);
           StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
-+         _8 = const 3_usize;
-+         _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind continue];
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          StorageLive(_9);
-          StorageLive(_10);
--         _10 = OffsetOf(Epsilon, [(0, 0)]);
--         _9 = must_use::<usize>(move _10) -> [return: bb5, unwind continue];
-+         _10 = const 1_usize;
-+         _9 = must_use::<usize>(const 1_usize) -> [return: bb5, unwind continue];
-      }
-  
-      bb5: {
-          StorageDead(_10);
-          StorageLive(_11);
-          StorageLive(_12);
--         _12 = OffsetOf(Epsilon, [(0, 1)]);
--         _11 = must_use::<usize>(move _12) -> [return: bb6, unwind continue];
-+         _12 = const 2_usize;
-+         _11 = must_use::<usize>(const 2_usize) -> [return: bb6, unwind continue];
-      }
-  
-      bb6: {
-          StorageDead(_12);
-          StorageLive(_13);
-          StorageLive(_14);
--         _14 = OffsetOf(Epsilon, [(2, 0)]);
--         _13 = must_use::<usize>(move _14) -> [return: bb7, unwind continue];
-+         _14 = const 4_usize;
-+         _13 = must_use::<usize>(const 4_usize) -> [return: bb7, unwind continue];
-      }
-  
-      bb7: {
-          StorageDead(_14);
+-         _7 = OffsetOf(Epsilon, [(2, 0)]);
++         _7 = const 4_usize;
           _0 = const ();
-          StorageDead(_13);
-          StorageDead(_11);
-          StorageDead(_9);
           StorageDead(_7);
+          StorageDead(_6);
           StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff
index 025241dd1bf..130c31eff8c 100644
--- a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff
@@ -4,33 +4,26 @@
   fn generic() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
-      let mut _10: usize;
-      let mut _12: usize;
-      let mut _14: usize;
       scope 1 {
           debug gx => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug gy => _3;
-              let _5: usize;
+              debug gy => _2;
+              let _3: usize;
               scope 3 {
-                  debug dx => _5;
-                  let _7: usize;
+                  debug dx => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug dy => _7;
-                      let _9: usize;
+                      debug dy => _4;
+                      let _5: usize;
                       scope 5 {
-                          debug zA0 => _9;
-                          let _11: usize;
+                          debug zA0 => _5;
+                          let _6: usize;
                           scope 6 {
-                              debug zA1 => _11;
-                              let _13: usize;
+                              debug zA1 => _6;
+                              let _7: usize;
                               scope 7 {
-                                  debug zB => _13;
+                                  debug zB => _7;
                               }
                           }
                       }
@@ -41,72 +34,28 @@
   
       bb0: {
           StorageLive(_1);
+          _1 = OffsetOf(Gamma<T>, [(0, 0)]);
           StorageLive(_2);
-          _2 = OffsetOf(Gamma<T>, [(0, 0)]);
-          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+          _2 = OffsetOf(Gamma<T>, [(0, 1)]);
           StorageLive(_3);
+-         _3 = OffsetOf(Delta<T>, [(0, 1)]);
++         _3 = const 0_usize;
           StorageLive(_4);
-          _4 = OffsetOf(Gamma<T>, [(0, 1)]);
-          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          StorageDead(_4);
+-         _4 = OffsetOf(Delta<T>, [(0, 2)]);
++         _4 = const 2_usize;
           StorageLive(_5);
+          _5 = OffsetOf(Zeta<T>, [(0, 0)]);
           StorageLive(_6);
--         _6 = OffsetOf(Delta<T>, [(0, 1)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
-+         _6 = const 0_usize;
-+         _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_6);
+          _6 = OffsetOf(Zeta<T>, [(0, 1)]);
           StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Delta<T>, [(0, 2)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
-+         _8 = const 2_usize;
-+         _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = OffsetOf(Zeta<T>, [(0, 0)]);
-          _9 = must_use::<usize>(move _10) -> [return: bb5, unwind unreachable];
-      }
-  
-      bb5: {
-          StorageDead(_10);
-          StorageLive(_11);
-          StorageLive(_12);
-          _12 = OffsetOf(Zeta<T>, [(0, 1)]);
-          _11 = must_use::<usize>(move _12) -> [return: bb6, unwind unreachable];
-      }
-  
-      bb6: {
-          StorageDead(_12);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = OffsetOf(Zeta<T>, [(1, 0)]);
-          _13 = must_use::<usize>(move _14) -> [return: bb7, unwind unreachable];
-      }
-  
-      bb7: {
-          StorageDead(_14);
+          _7 = OffsetOf(Zeta<T>, [(1, 0)]);
           _0 = const ();
-          StorageDead(_13);
-          StorageDead(_11);
-          StorageDead(_9);
           StorageDead(_7);
+          StorageDead(_6);
           StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff
index 27f2b2f7355..130c31eff8c 100644
--- a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff
@@ -4,33 +4,26 @@
   fn generic() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
-      let mut _10: usize;
-      let mut _12: usize;
-      let mut _14: usize;
       scope 1 {
           debug gx => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug gy => _3;
-              let _5: usize;
+              debug gy => _2;
+              let _3: usize;
               scope 3 {
-                  debug dx => _5;
-                  let _7: usize;
+                  debug dx => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug dy => _7;
-                      let _9: usize;
+                      debug dy => _4;
+                      let _5: usize;
                       scope 5 {
-                          debug zA0 => _9;
-                          let _11: usize;
+                          debug zA0 => _5;
+                          let _6: usize;
                           scope 6 {
-                              debug zA1 => _11;
-                              let _13: usize;
+                              debug zA1 => _6;
+                              let _7: usize;
                               scope 7 {
-                                  debug zB => _13;
+                                  debug zB => _7;
                               }
                           }
                       }
@@ -41,72 +34,28 @@
   
       bb0: {
           StorageLive(_1);
+          _1 = OffsetOf(Gamma<T>, [(0, 0)]);
           StorageLive(_2);
-          _2 = OffsetOf(Gamma<T>, [(0, 0)]);
-          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+          _2 = OffsetOf(Gamma<T>, [(0, 1)]);
           StorageLive(_3);
+-         _3 = OffsetOf(Delta<T>, [(0, 1)]);
++         _3 = const 0_usize;
           StorageLive(_4);
-          _4 = OffsetOf(Gamma<T>, [(0, 1)]);
-          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
-      }
-  
-      bb2: {
-          StorageDead(_4);
+-         _4 = OffsetOf(Delta<T>, [(0, 2)]);
++         _4 = const 2_usize;
           StorageLive(_5);
+          _5 = OffsetOf(Zeta<T>, [(0, 0)]);
           StorageLive(_6);
--         _6 = OffsetOf(Delta<T>, [(0, 1)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
-+         _6 = const 0_usize;
-+         _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind continue];
-      }
-  
-      bb3: {
-          StorageDead(_6);
+          _6 = OffsetOf(Zeta<T>, [(0, 1)]);
           StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Delta<T>, [(0, 2)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
-+         _8 = const 2_usize;
-+         _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind continue];
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = OffsetOf(Zeta<T>, [(0, 0)]);
-          _9 = must_use::<usize>(move _10) -> [return: bb5, unwind continue];
-      }
-  
-      bb5: {
-          StorageDead(_10);
-          StorageLive(_11);
-          StorageLive(_12);
-          _12 = OffsetOf(Zeta<T>, [(0, 1)]);
-          _11 = must_use::<usize>(move _12) -> [return: bb6, unwind continue];
-      }
-  
-      bb6: {
-          StorageDead(_12);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = OffsetOf(Zeta<T>, [(1, 0)]);
-          _13 = must_use::<usize>(move _14) -> [return: bb7, unwind continue];
-      }
-  
-      bb7: {
-          StorageDead(_14);
+          _7 = OffsetOf(Zeta<T>, [(1, 0)]);
           _0 = const ();
-          StorageDead(_13);
-          StorageDead(_11);
-          StorageDead(_9);
           StorageDead(_7);
+          StorageDead(_6);
           StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff
index f8f89175033..92691d0f807 100644
--- a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff
@@ -4,21 +4,17 @@
   fn concrete() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
       scope 1 {
           debug x => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug y => _3;
-              let _5: usize;
+              debug y => _2;
+              let _3: usize;
               scope 3 {
-                  debug z0 => _5;
-                  let _7: usize;
+                  debug z0 => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug z1 => _7;
+                      debug z1 => _4;
                   }
               }
           }
@@ -26,49 +22,21 @@
   
       bb0: {
           StorageLive(_1);
+-         _1 = OffsetOf(Alpha, [(0, 0)]);
++         _1 = const 4_usize;
           StorageLive(_2);
--         _2 = OffsetOf(Alpha, [(0, 0)]);
--         _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
-+         _2 = const 4_usize;
-+         _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+-         _2 = OffsetOf(Alpha, [(0, 1)]);
++         _2 = const 0_usize;
           StorageLive(_3);
+-         _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
++         _3 = const 2_usize;
           StorageLive(_4);
--         _4 = OffsetOf(Alpha, [(0, 1)]);
--         _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
-+         _4 = const 0_usize;
-+         _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          StorageDead(_4);
-          StorageLive(_5);
-          StorageLive(_6);
--         _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
-+         _6 = const 2_usize;
-+         _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_6);
-          StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
-+         _8 = const 3_usize;
-+         _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_8);
+-         _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
++         _4 = const 3_usize;
           _0 = const ();
-          StorageDead(_7);
-          StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff
index d4f8cb66704..92691d0f807 100644
--- a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff
@@ -4,21 +4,17 @@
   fn concrete() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
       scope 1 {
           debug x => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug y => _3;
-              let _5: usize;
+              debug y => _2;
+              let _3: usize;
               scope 3 {
-                  debug z0 => _5;
-                  let _7: usize;
+                  debug z0 => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug z1 => _7;
+                      debug z1 => _4;
                   }
               }
           }
@@ -26,49 +22,21 @@
   
       bb0: {
           StorageLive(_1);
+-         _1 = OffsetOf(Alpha, [(0, 0)]);
++         _1 = const 4_usize;
           StorageLive(_2);
--         _2 = OffsetOf(Alpha, [(0, 0)]);
--         _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
-+         _2 = const 4_usize;
-+         _1 = must_use::<usize>(const 4_usize) -> [return: bb1, unwind continue];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+-         _2 = OffsetOf(Alpha, [(0, 1)]);
++         _2 = const 0_usize;
           StorageLive(_3);
+-         _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
++         _3 = const 2_usize;
           StorageLive(_4);
--         _4 = OffsetOf(Alpha, [(0, 1)]);
--         _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
-+         _4 = const 0_usize;
-+         _3 = must_use::<usize>(const 0_usize) -> [return: bb2, unwind continue];
-      }
-  
-      bb2: {
-          StorageDead(_4);
-          StorageLive(_5);
-          StorageLive(_6);
--         _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
-+         _6 = const 2_usize;
-+         _5 = must_use::<usize>(const 2_usize) -> [return: bb3, unwind continue];
-      }
-  
-      bb3: {
-          StorageDead(_6);
-          StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
-+         _8 = const 3_usize;
-+         _7 = must_use::<usize>(const 3_usize) -> [return: bb4, unwind continue];
-      }
-  
-      bb4: {
-          StorageDead(_8);
+-         _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]);
++         _4 = const 3_usize;
           _0 = const ();
-          StorageDead(_7);
-          StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff
index 7f166e4fa35..c6908166def 100644
--- a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff
@@ -4,21 +4,17 @@
   fn generic() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
       scope 1 {
           debug gx => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug gy => _3;
-              let _5: usize;
+              debug gy => _2;
+              let _3: usize;
               scope 3 {
-                  debug dx => _5;
-                  let _7: usize;
+                  debug dx => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug dy => _7;
+                      debug dy => _4;
                   }
               }
           }
@@ -26,45 +22,19 @@
   
       bb0: {
           StorageLive(_1);
+          _1 = OffsetOf(Gamma<T>, [(0, 0)]);
           StorageLive(_2);
-          _2 = OffsetOf(Gamma<T>, [(0, 0)]);
-          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+          _2 = OffsetOf(Gamma<T>, [(0, 1)]);
           StorageLive(_3);
+-         _3 = OffsetOf(Delta<T>, [(0, 1)]);
++         _3 = const 0_usize;
           StorageLive(_4);
-          _4 = OffsetOf(Gamma<T>, [(0, 1)]);
-          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          StorageDead(_4);
-          StorageLive(_5);
-          StorageLive(_6);
--         _6 = OffsetOf(Delta<T>, [(0, 1)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind unreachable];
-+         _6 = const 0_usize;
-+         _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_6);
-          StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Delta<T>, [(0, 2)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind unreachable];
-+         _8 = const 2_usize;
-+         _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_8);
+-         _4 = OffsetOf(Delta<T>, [(0, 2)]);
++         _4 = const 2_usize;
           _0 = const ();
-          StorageDead(_7);
-          StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff
index 38ad6f79801..c6908166def 100644
--- a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff
@@ -4,21 +4,17 @@
   fn generic() -> () {
       let mut _0: ();
       let _1: usize;
-      let mut _2: usize;
-      let mut _4: usize;
-      let mut _6: usize;
-      let mut _8: usize;
       scope 1 {
           debug gx => _1;
-          let _3: usize;
+          let _2: usize;
           scope 2 {
-              debug gy => _3;
-              let _5: usize;
+              debug gy => _2;
+              let _3: usize;
               scope 3 {
-                  debug dx => _5;
-                  let _7: usize;
+                  debug dx => _3;
+                  let _4: usize;
                   scope 4 {
-                      debug dy => _7;
+                      debug dy => _4;
                   }
               }
           }
@@ -26,45 +22,19 @@
   
       bb0: {
           StorageLive(_1);
+          _1 = OffsetOf(Gamma<T>, [(0, 0)]);
           StorageLive(_2);
-          _2 = OffsetOf(Gamma<T>, [(0, 0)]);
-          _1 = must_use::<usize>(move _2) -> [return: bb1, unwind continue];
-      }
-  
-      bb1: {
-          StorageDead(_2);
+          _2 = OffsetOf(Gamma<T>, [(0, 1)]);
           StorageLive(_3);
+-         _3 = OffsetOf(Delta<T>, [(0, 1)]);
++         _3 = const 0_usize;
           StorageLive(_4);
-          _4 = OffsetOf(Gamma<T>, [(0, 1)]);
-          _3 = must_use::<usize>(move _4) -> [return: bb2, unwind continue];
-      }
-  
-      bb2: {
-          StorageDead(_4);
-          StorageLive(_5);
-          StorageLive(_6);
--         _6 = OffsetOf(Delta<T>, [(0, 1)]);
--         _5 = must_use::<usize>(move _6) -> [return: bb3, unwind continue];
-+         _6 = const 0_usize;
-+         _5 = must_use::<usize>(const 0_usize) -> [return: bb3, unwind continue];
-      }
-  
-      bb3: {
-          StorageDead(_6);
-          StorageLive(_7);
-          StorageLive(_8);
--         _8 = OffsetOf(Delta<T>, [(0, 2)]);
--         _7 = must_use::<usize>(move _8) -> [return: bb4, unwind continue];
-+         _8 = const 2_usize;
-+         _7 = must_use::<usize>(const 2_usize) -> [return: bb4, unwind continue];
-      }
-  
-      bb4: {
-          StorageDead(_8);
+-         _4 = OffsetOf(Delta<T>, [(0, 2)]);
++         _4 = const 2_usize;
           _0 = const ();
-          StorageDead(_7);
-          StorageDead(_5);
+          StorageDead(_4);
           StorageDead(_3);
+          StorageDead(_2);
           StorageDead(_1);
           return;
       }
diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs
index cd4e1f6990d..12396b31ed0 100644
--- a/tests/mir-opt/dataflow-const-prop/offset_of.rs
+++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs
@@ -36,16 +36,16 @@ fn concrete() {
     // CHECK: debug z0 => [[z0:_.*]];
     // CHECK: debug z1 => [[z1:_.*]];
 
-    // CHECK: [[x]] = must_use::<usize>(const 4_usize) -> {{.*}}
+    // CHECK: [[x]] = const 4_usize
     let x = offset_of!(Alpha, x);
 
-    // CHECK: [[y]] = must_use::<usize>(const 0_usize) -> {{.*}}
+    // CHECK: [[y]] = const 0_usize
     let y = offset_of!(Alpha, y);
 
-    // CHECK: [[z0]] = must_use::<usize>(const 2_usize) -> {{.*}}
+    // CHECK: [[z0]] = const 2_usize
     let z0 = offset_of!(Alpha, z.0);
 
-    // CHECK: [[z1]] = must_use::<usize>(const 3_usize) -> {{.*}}
+    // CHECK: [[z1]] = const 3_usize
     let z1 = offset_of!(Alpha, z.1);
 }
 
@@ -58,16 +58,16 @@ fn generic<T>() {
     // CHECK: debug dx => [[dx:_.*]];
     // CHECK: debug dy => [[dy:_.*]];
 
-    // CHECK: [[gx]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
+    // CHECK: [[gx]] = OffsetOf(Gamma<T>, [(0, 0)]);
     let gx = offset_of!(Gamma<T>, x);
 
-    // CHECK: [[gy]] = must_use::<usize>(move {{_.*}}) -> {{.*}}
+    // CHECK: [[gy]] = OffsetOf(Gamma<T>, [(0, 1)]);
     let gy = offset_of!(Gamma<T>, y);
 
-    // CHECK: [[dx]] = must_use::<usize>(const 0_usize) -> {{.*}}
+    // CHECK: [[dx]] = const 0_usize
     let dx = offset_of!(Delta<T>, x);
 
-    // CHECK: [[dy]] = must_use::<usize>(const 2_usize) -> {{.*}}
+    // CHECK: [[dy]] = const 2_usize
     let dy = offset_of!(Delta<T>, y);
 }
 
diff --git a/tests/pretty/postfix-match/precedence.pp b/tests/pretty/postfix-match/precedence.pp
new file mode 100644
index 00000000000..967aa7bc39e
--- /dev/null
+++ b/tests/pretty/postfix-match/precedence.pp
@@ -0,0 +1,34 @@
+#![feature(prelude_import)]
+#![no_std]
+#![feature(postfix_match)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+use std::ops::Add;
+
+//@ pretty-mode:expanded
+//@ pp-exact:precedence.pp
+
+macro_rules! repro { ($e:expr) => { $e.match { _ => {} } }; }
+
+struct Struct {}
+
+impl Add<Struct> for usize {
+    type Output = ();
+    fn add(self, _: Struct) -> () { () }
+}
+pub fn main() {
+    let a;
+    (
+        { 1 } + 1).match {
+        _ => {}
+    };
+    (4 as usize).match { _ => {} };
+    (return).match { _ => {} };
+    (a = 42).match { _ => {} };
+    (|| {}).match { _ => {} };
+    (42..101).match { _ => {} };
+    (1 + Struct {}).match { _ => {} };
+}
diff --git a/tests/pretty/postfix-match/precedence.rs b/tests/pretty/postfix-match/precedence.rs
new file mode 100644
index 00000000000..ee947e161dd
--- /dev/null
+++ b/tests/pretty/postfix-match/precedence.rs
@@ -0,0 +1,34 @@
+#![feature(postfix_match)]
+
+use std::ops::Add;
+
+//@ pretty-mode:expanded
+//@ pp-exact:precedence.pp
+
+macro_rules! repro {
+    ($e:expr) => {
+        $e.match {
+            _ => {}
+        }
+    };
+}
+
+struct Struct {}
+
+impl Add<Struct> for usize {
+    type Output = ();
+    fn add(self, _: Struct) -> () {
+        ()
+    }
+}
+pub fn main() {
+    let a;
+
+    repro!({ 1 } + 1);
+    repro!(4 as usize);
+    repro!(return);
+    repro!(a = 42);
+    repro!(|| {});
+    repro!(42..101);
+    repro!(1 + Struct {});
+}
diff --git a/tests/pretty/postfix-match.rs b/tests/pretty/postfix-match/simple-matches.rs
index 5bb54e15275..5bb54e15275 100644
--- a/tests/pretty/postfix-match.rs
+++ b/tests/pretty/postfix-match/simple-matches.rs
diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
index 1204260a2f4..4b7ce4e57d5 100644
--- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
+++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
@@ -3,11 +3,9 @@
 // Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current
 // `rustc` version and the `since` property in feature stability gating is properly respected.
 
-extern crate run_make_support;
-
 use std::path::PathBuf;
 
-use run_make_support::{rustc, aux_build};
+use run_make_support::{aux_build, rustc};
 
 fn main() {
     aux_build().input("stable.rs").emit("metadata").run();
@@ -15,11 +13,7 @@ fn main() {
     let mut stable_path = PathBuf::from(env!("TMPDIR"));
     stable_path.push("libstable.rmeta");
 
-    let output = rustc()
-        .input("main.rs")
-        .emit("metadata")
-        .extern_("stable", &stable_path)
-        .output();
+    let output = rustc().input("main.rs").emit("metadata").extern_("stable", &stable_path).output();
 
     let stderr = String::from_utf8_lossy(&output.stderr);
     let version = include_str!(concat!(env!("S"), "/src/version"));
diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs
index ffc1b2000b9..ee6d655bc76 100644
--- a/tests/run-make/a-b-a-linker-guard/rmake.rs
+++ b/tests/run-make/a-b-a-linker-guard/rmake.rs
@@ -3,8 +3,6 @@
 // Test that if we build `b` against a version of `a` that has one set of types, it will not run
 // with a dylib that has a different set of types.
 
-extern crate run_make_support;
-
 use run_make_support::{run, run_fail, rustc};
 
 fn main() {
diff --git a/tests/run-make/arguments-non-c-like-enum/rmake.rs b/tests/run-make/arguments-non-c-like-enum/rmake.rs
index 624a7fb2251..13230206ca8 100644
--- a/tests/run-make/arguments-non-c-like-enum/rmake.rs
+++ b/tests/run-make/arguments-non-c-like-enum/rmake.rs
@@ -1,8 +1,6 @@
 //! Check that non-trivial `repr(C)` enum in Rust has valid C layout.
 //@ ignore-cross-compile
 
-extern crate run_make_support;
-
 use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib};
 
 pub fn main() {
diff --git a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs
index de55de2a1ee..6613698ae1d 100644
--- a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs
+++ b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs
@@ -5,8 +5,6 @@
 //
 // Fixes: rust-lang/rust#123234
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 
 fn main() {
diff --git a/tests/run-make/artifact-incr-cache/rmake.rs b/tests/run-make/artifact-incr-cache/rmake.rs
index bb651368081..106f363eb8d 100644
--- a/tests/run-make/artifact-incr-cache/rmake.rs
+++ b/tests/run-make/artifact-incr-cache/rmake.rs
@@ -7,8 +7,6 @@
 // Also see discussion at
 // <https://internals.rust-lang.org/t/interaction-between-incremental-compilation-and-emit/20551>
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 
 fn main() {
diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
index 97ff12877f1..f5da50ebb04 100644
--- a/tests/run-make/compiler-builtins/rmake.rs
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -14,8 +14,6 @@
 
 #![deny(warnings)]
 
-extern crate run_make_support;
-
 use run_make_support::object;
 use run_make_support::object::read::archive::ArchiveFile;
 use run_make_support::object::read::Object;
@@ -51,22 +49,22 @@ fn main() {
     let bootstrap_cargo = std::env::var("BOOTSTRAP_CARGO").unwrap();
     let mut cmd = std::process::Command::new(bootstrap_cargo);
     cmd.args([
-            "build",
-            "--manifest-path",
-            manifest_path.to_str().unwrap(),
-            "-Zbuild-std=core",
-            "--target",
-            &target,
-        ])
-        .env_clear()
-        .env("PATH", path)
-        .env("RUSTC", rustc)
-        .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
-        .env("CARGO_TARGET_DIR", &target_dir)
-        .env("RUSTC_BOOTSTRAP", "1")
-        // Visual Studio 2022 requires that the LIB env var be set so it can
-        // find the Windows SDK.
-        .env("LIB", std::env::var("LIB").unwrap_or_default());
+        "build",
+        "--manifest-path",
+        manifest_path.to_str().unwrap(),
+        "-Zbuild-std=core",
+        "--target",
+        &target,
+    ])
+    .env_clear()
+    .env("PATH", path)
+    .env("RUSTC", rustc)
+    .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
+    .env("CARGO_TARGET_DIR", &target_dir)
+    .env("RUSTC_BOOTSTRAP", "1")
+    // Visual Studio 2022 requires that the LIB env var be set so it can
+    // find the Windows SDK.
+    .env("LIB", std::env::var("LIB").unwrap_or_default());
     set_host_rpath(&mut cmd);
 
     let status = cmd.status().unwrap();
diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
index 2748d4359c3..e3484888ca5 100644
--- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs
+++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
@@ -1,8 +1,6 @@
 // This test checks that the core library of Rust can be compiled without enabling
 // support for formatting and parsing floating-point numbers.
 
-extern crate run_make_support;
-
 use run_make_support::rustc;
 use std::path::PathBuf;
 
diff --git a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
index b534a99f8cf..61f32762d8b 100644
--- a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
+++ b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
@@ -2,7 +2,6 @@
 //! which requires extra `target-abi` metadata to be emitted.
 //@ needs-matching-clang
 //@ needs-llvm-components riscv
-extern crate run_make_support;
 
 use run_make_support::{bin_name, clang, llvm_readobj, rustc, tmp_dir};
 use std::{
diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs
index f387626287e..b1143153d0a 100644
--- a/tests/run-make/exit-code/rmake.rs
+++ b/tests/run-make/exit-code/rmake.rs
@@ -1,21 +1,13 @@
 // Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, rustdoc, tmp_dir};
 
 fn main() {
-    rustc()
-        .arg("success.rs")
-        .run();
+    rustc().arg("success.rs").run();
 
-    rustc()
-        .arg("--invalid-arg-foo")
-        .run_fail_assert_exit_code(1);
+    rustc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1);
 
-    rustc()
-        .arg("compile-error.rs")
-        .run_fail_assert_exit_code(1);
+    rustc().arg("compile-error.rs").run_fail_assert_exit_code(1);
 
     rustc()
         .env("RUSTC_ICE", "0")
@@ -23,21 +15,11 @@ fn main() {
         .arg("compile-error.rs")
         .run_fail_assert_exit_code(101);
 
-    rustdoc()
-        .arg("success.rs")
-        .arg("-o")
-        .arg(tmp_dir().join("exit-code"))
-        .run();
+    rustdoc().arg("success.rs").arg("-o").arg(tmp_dir().join("exit-code")).run();
 
-    rustdoc()
-        .arg("--invalid-arg-foo")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1);
 
-    rustdoc()
-        .arg("compile-error.rs")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("compile-error.rs").run_fail_assert_exit_code(1);
 
-    rustdoc()
-        .arg("lint-failure.rs")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("lint-failure.rs").run_fail_assert_exit_code(1);
 }
diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs
index 40deabe15b7..db25e9b033c 100644
--- a/tests/run-make/issue-107495-archive-permissions/rmake.rs
+++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs
@@ -2,7 +2,6 @@
 
 #[cfg(unix)]
 extern crate libc;
-extern crate run_make_support;
 
 use run_make_support::{aux_build, tmp_dir};
 use std::fs;
diff --git a/tests/run-make/no-input-file/rmake.rs b/tests/run-make/no-input-file/rmake.rs
index 26df7e80dfb..15e582311f0 100644
--- a/tests/run-make/no-input-file/rmake.rs
+++ b/tests/run-make/no-input-file/rmake.rs
@@ -1,5 +1,3 @@
-extern crate run_make_support;
-
 use run_make_support::{diff, rustc};
 
 fn main() {
diff --git a/tests/run-make/non-unicode-env/rmake.rs b/tests/run-make/non-unicode-env/rmake.rs
index ba4aa1609b5..a4843a52efd 100644
--- a/tests/run-make/non-unicode-env/rmake.rs
+++ b/tests/run-make/non-unicode-env/rmake.rs
@@ -1,5 +1,3 @@
-extern crate run_make_support;
-
 use run_make_support::rustc;
 
 fn main() {
diff --git a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs
index 129e424f27a..40152e0411d 100644
--- a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs
+++ b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs
@@ -1,5 +1,3 @@
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 
 fn main() {
diff --git a/tests/run-make/print-cfg/Makefile b/tests/run-make/print-cfg/Makefile
deleted file mode 100644
index 6b153e5b54e..00000000000
--- a/tests/run-make/print-cfg/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-# needs-llvm-components: x86 arm
-
-include ../tools.mk
-
-all: default output_to_file
-	$(RUSTC) --target x86_64-pc-windows-gnu --print cfg | $(CGREP) windows
-	$(RUSTC) --target x86_64-pc-windows-gnu --print cfg | $(CGREP) x86_64
-	$(RUSTC) --target i686-pc-windows-msvc --print cfg | $(CGREP) msvc
-	$(RUSTC) --target i686-apple-darwin --print cfg | $(CGREP) macos
-	$(RUSTC) --target i686-unknown-linux-gnu --print cfg | $(CGREP) gnu
-	$(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) target_abi=
-	$(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) eabihf
-
-output_to_file:
-	# Backend-independent, printed by rustc_driver_impl/src/lib.rs
-	$(RUSTC) --target x86_64-pc-windows-gnu --print cfg=$(TMPDIR)/cfg.txt
-	$(CGREP) windows < $(TMPDIR)/cfg.txt
-
-	# Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs
-	$(RUSTC) --print relocation-models=$(TMPDIR)/relocation-models.txt
-	$(CGREP) dynamic-no-pic < $(TMPDIR)/relocation-models.txt
-
-	# Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs
-	$(RUSTC) --target wasm32-unknown-unknown --print target-features=$(TMPDIR)/target-features.txt
-	$(CGREP) reference-types < $(TMPDIR)/target-features.txt
-
-	# Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp
-	$(RUSTC) --target wasm32-unknown-unknown --print target-cpus=$(TMPDIR)/target-cpus.txt
-	$(CGREP) generic < $(TMPDIR)/target-cpus.txt
-
-ifdef IS_WINDOWS
-default:
-	$(RUSTC) --print cfg | $(CGREP) windows
-else
-default:
-	$(RUSTC) --print cfg | $(CGREP) unix
-endif
diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs
new file mode 100644
index 00000000000..6e72c16f1f9
--- /dev/null
+++ b/tests/run-make/print-cfg/rmake.rs
@@ -0,0 +1,104 @@
+//! This checks the output of `--print=cfg`
+//!
+//! Specifically it checks that output is correctly formatted
+//! (ie. no duplicated cfgs, values are between "", names are not).
+//!
+//! It also checks that some targets have the correct set cfgs.
+
+use std::collections::HashSet;
+use std::ffi::OsString;
+use std::io::BufRead;
+use std::iter::FromIterator;
+
+use run_make_support::{rustc, tmp_dir};
+
+struct PrintCfg {
+    target: &'static str,
+    includes: &'static [&'static str],
+    disallow: &'static [&'static str],
+}
+
+fn main() {
+    check(PrintCfg {
+        target: "x86_64-pc-windows-gnu",
+        includes: &["windows", "target_arch=\"x86_64\""],
+        disallow: &["unix"],
+    });
+    check(PrintCfg {
+        target: "i686-pc-windows-msvc",
+        includes: &["windows", "target_env=\"msvc\""],
+        disallow: &["unix"],
+    });
+    check(PrintCfg {
+        target: "i686-apple-darwin",
+        includes: &["unix", "target_os=\"macos\"", "target_vendor=\"apple\""],
+        disallow: &["windows"],
+    });
+    check(PrintCfg {
+        target: "i686-unknown-linux-gnu",
+        includes: &["unix", "target_env=\"gnu\""],
+        disallow: &["windows"],
+    });
+    check(PrintCfg {
+        target: "arm-unknown-linux-gnueabihf",
+        includes: &["unix", "target_abi=\"eabihf\""],
+        disallow: &["windows"],
+    });
+}
+
+fn check(PrintCfg { target, includes, disallow }: PrintCfg) {
+    fn check_(output: &str, includes: &[&str], disallow: &[&str]) {
+        let mut found = HashSet::<String>::new();
+        let mut recorded = HashSet::<String>::new();
+
+        for l in output.lines() {
+            assert!(l == l.trim());
+            if let Some((left, right)) = l.split_once('=') {
+                assert!(right.starts_with("\""));
+                assert!(right.ends_with("\""));
+                assert!(!left.contains("\""));
+            } else {
+                assert!(!l.contains("\""));
+            }
+
+            assert!(recorded.insert(l.to_string()), "duplicated: {}", &l);
+            assert!(!disallow.contains(&l), "found disallowed: {}", &l);
+            if includes.contains(&l) {
+                assert!(found.insert(l.to_string()), "duplicated (includes): {}", &l);
+            }
+        }
+
+        let should_found = HashSet::<String>::from_iter(includes.iter().map(|s| s.to_string()));
+        let diff: Vec<_> = should_found.difference(&found).collect();
+
+        assert!(
+            diff.is_empty(),
+            "expected: {:?}, found: {:?} (~ {:?})",
+            &should_found,
+            &found,
+            &diff
+        );
+    }
+
+    // --print=cfg
+    {
+        let output = rustc().target(target).print("cfg").run();
+
+        let stdout = String::from_utf8(output.stdout).unwrap();
+
+        check_(&stdout, includes, disallow);
+    }
+
+    // --print=cfg=PATH
+    {
+        let tmp_path = tmp_dir().join(format!("{target}.cfg"));
+        let mut print_arg = OsString::from("--print=cfg=");
+        print_arg.push(tmp_path.as_os_str());
+
+        let output = rustc().target(target).arg(print_arg).run();
+
+        let output = std::fs::read_to_string(&tmp_path).unwrap();
+
+        check_(&output, includes, disallow);
+    }
+}
diff --git a/tests/run-make/print-native-static-libs/Makefile b/tests/run-make/print-native-static-libs/Makefile
deleted file mode 100644
index a16c8b0f2a4..00000000000
--- a/tests/run-make/print-native-static-libs/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-include ../tools.mk
-
-# ignore-cross-compile
-# ignore-wasm
-
-all:
-	$(RUSTC) --crate-type rlib -lbar_cli bar.rs
-	$(RUSTC) foo.rs -lfoo_cli -lfoo_cli --crate-type staticlib --print native-static-libs 2>&1 \
-		| grep 'note: native-static-libs: ' \
-		| sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt
-
-	cat $(TMPDIR)/libs.txt | grep -F "glib-2.0" # in bar.rs
-	cat $(TMPDIR)/libs.txt | grep -F "systemd" # in foo.rs
-	cat $(TMPDIR)/libs.txt | grep -F "bar_cli"
-	cat $(TMPDIR)/libs.txt | grep -F "foo_cli"
-
-    # make sure that foo_cli and glib-2.0 are not consecutively present
-	cat $(TMPDIR)/libs.txt | grep -Fv "foo_cli -lfoo_cli"
-	cat $(TMPDIR)/libs.txt | grep -Fv "glib-2.0 -lglib-2.0"
diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs
new file mode 100644
index 00000000000..edb85d568c6
--- /dev/null
+++ b/tests/run-make/print-native-static-libs/rmake.rs
@@ -0,0 +1,72 @@
+//! This checks the output of `--print=native-static-libs`
+//!
+//! Specifically, this test makes sure that one and only one
+//! note is emitted with the text "native-static-libs:" as prefix
+//! that the note contains the link args given in the source code
+//! and cli of the current crate and downstream crates.
+//!
+//! It also checks that there aren't any duplicated consecutive
+//! args, as they are useless and suboptimal for debugability.
+//! See https://github.com/rust-lang/rust/issues/113209.
+
+//@ ignore-cross-compile
+//@ ignore-wasm
+
+use std::io::BufRead;
+
+use run_make_support::{is_msvc, rustc};
+
+fn main() {
+    // build supporting crate
+    rustc().input("bar.rs").crate_type("rlib").arg("-lbar_cli").run();
+
+    // build main crate as staticlib
+    let output = rustc()
+        .input("foo.rs")
+        .crate_type("staticlib")
+        .arg("-lfoo_cli")
+        .arg("-lfoo_cli") // 2nd time
+        .print("native-static-libs")
+        .run();
+
+    let mut found_note = false;
+    for l in output.stderr.lines() {
+        let l = l.expect("utf-8 string");
+
+        let Some(args) = l.strip_prefix("note: native-static-libs:") else {
+            continue;
+        };
+        assert!(!found_note);
+        found_note = true;
+
+        let args: Vec<&str> = args.trim().split_ascii_whitespace().collect();
+
+        macro_rules! assert_contains_lib {
+            ($lib:literal in $args:ident) => {{
+                let lib = format!(
+                    "{}{}{}",
+                    if !is_msvc() { "-l" } else { "" },
+                    $lib,
+                    if !is_msvc() { "" } else { ".lib" },
+                );
+                let found = $args.contains(&&*lib);
+                assert!(found, "unable to find lib `{}` in those linker args: {:?}", lib, $args);
+            }};
+        }
+
+        assert_contains_lib!("glib-2.0" in args); // in bar.rs
+        assert_contains_lib!("systemd" in args); // in foo.rs
+        assert_contains_lib!("bar_cli" in args);
+        assert_contains_lib!("foo_cli" in args);
+
+        // make sure that no args are consecutively present
+        let dedup_args: Vec<&str> = {
+            let mut args = args.clone();
+            args.dedup();
+            args
+        };
+        assert_eq!(args, dedup_args);
+    }
+
+    assert!(found_note);
+}
diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs
new file mode 100644
index 00000000000..1763cd378d2
--- /dev/null
+++ b/tests/run-make/print-to-output/rmake.rs
@@ -0,0 +1,62 @@
+//! This checks the output of some `--print` options when
+//! output to a file (instead of stdout)
+
+use std::ffi::OsString;
+
+use run_make_support::{rustc, target, tmp_dir};
+
+struct Option<'a> {
+    target: &'a str,
+    option: &'static str,
+    includes: &'static [&'static str],
+}
+
+fn main() {
+    // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs
+    check(Option { target: &target(), option: "relocation-models", includes: &["dynamic-no-pic"] });
+
+    // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs
+    check(Option {
+        target: "wasm32-unknown-unknown",
+        option: "target-features",
+        includes: &["reference-types"],
+    });
+
+    // Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp
+    check(Option {
+        target: "wasm32-unknown-unknown",
+        option: "target-cpus",
+        includes: &["generic"],
+    });
+}
+
+fn check(args: Option) {
+    fn check_(output: &str, includes: &[&str]) {
+        for i in includes {
+            assert!(output.contains(i), "output doesn't contains: {}", i);
+        }
+    }
+
+    // --print={option}
+    let stdout = {
+        let output = rustc().target(args.target).print(args.option).run();
+
+        String::from_utf8(output.stdout).unwrap()
+    };
+
+    // --print={option}=PATH
+    let output = {
+        let tmp_path = tmp_dir().join(format!("{}.txt", args.option));
+        let mut print_arg = OsString::from(format!("--print={}=", args.option));
+        print_arg.push(tmp_path.as_os_str());
+
+        let _output = rustc().target(args.target).arg(print_arg).run();
+
+        std::fs::read_to_string(&tmp_path).unwrap()
+    };
+
+    check_(&stdout, args.includes);
+    check_(&output, args.includes);
+
+    assert_eq!(&stdout, &output);
+}
diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile
index a8f97edd689..2524f8500e1 100644
--- a/tests/run-make/raw-dylib-cross-compilation/Makefile
+++ b/tests/run-make/raw-dylib-cross-compilation/Makefile
@@ -1,8 +1,6 @@
 # Tests that raw-dylib cross compilation works correctly
 
-# only-gnu
-# needs-i686-dlltool
-# needs-x86_64-dlltool
+# needs-dlltool
 
 # i686 dlltool.exe can't product x64 binaries.
 # ignore-i686-pc-windows-gnu
diff --git a/tests/run-make/repr128-dwarf/Makefile b/tests/run-make/repr128-dwarf/Makefile
deleted file mode 100644
index 3f933042724..00000000000
--- a/tests/run-make/repr128-dwarf/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# ignore-windows
-# This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit
-# enums.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )"
diff --git a/tests/run-make/repr128-dwarf/lib.rs b/tests/run-make/repr128-dwarf/main.rs
index 63675441d4b..57923a8386d 100644
--- a/tests/run-make/repr128-dwarf/lib.rs
+++ b/tests/run-make/repr128-dwarf/main.rs
@@ -1,4 +1,3 @@
-#![crate_type = "lib"]
 #![feature(repr128)]
 
 // Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian
@@ -21,3 +20,7 @@ pub enum I128Enum {
 }
 
 pub fn f(_: U128Enum, _: I128Enum) {}
+
+fn main() {
+    f(U128Enum::U128A, I128Enum::I128A);
+}
diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs
new file mode 100644
index 00000000000..d734b2add79
--- /dev/null
+++ b/tests/run-make/repr128-dwarf/rmake.rs
@@ -0,0 +1,73 @@
+//@ ignore-windows
+// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums.
+
+use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian};
+use object::{Object, ObjectSection};
+use run_make_support::{gimli, object, rustc, tmp_dir};
+use std::borrow::Cow;
+use std::collections::HashMap;
+use std::rc::Rc;
+
+fn main() {
+    let output = tmp_dir().join("repr128");
+    rustc().input("main.rs").arg("-o").arg(&output).arg("-Cdebuginfo=2").run();
+    // Mach-O uses packed debug info
+    let dsym_location = output
+        .with_extension("dSYM")
+        .join("Contents")
+        .join("Resources")
+        .join("DWARF")
+        .join("repr128");
+    let output =
+        std::fs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output })
+            .unwrap();
+    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 iter = dwarf.units();
+    let mut still_to_find = HashMap::from([
+        ("U128A", 0_u128),
+        ("U128B", 1_u128),
+        ("U128C", u64::MAX as u128 + 1),
+        ("U128D", u128::MAX),
+        ("I128A", 0_i128 as u128),
+        ("I128B", (-1_i128) as u128),
+        ("I128C", i128::MIN as u128),
+        ("I128D", i128::MAX as u128),
+    ]);
+    while let Some(header) = iter.next().unwrap() {
+        let unit = dwarf.unit(header).unwrap();
+        let mut cursor = unit.entries();
+        while let Some((_, entry)) = cursor.next_dfs().unwrap() {
+            if entry.tag() == gimli::constants::DW_TAG_enumerator {
+                let name = dwarf
+                    .attr_string(
+                        &unit,
+                        entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(),
+                    )
+                    .unwrap();
+                let name = name.to_string().unwrap();
+                if let Some(expected) = still_to_find.remove(name.as_ref()) {
+                    match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value()
+                    {
+                        AttributeValue::Block(value) => {
+                            assert_eq!(
+                                value.to_slice().unwrap(),
+                                expected.to_le_bytes().as_slice(),
+                                "{name}"
+                            );
+                        }
+                        value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"),
+                    }
+                }
+            }
+        }
+    }
+    if !still_to_find.is_empty() {
+        panic!("Didn't find debug entries for {still_to_find:?}");
+    }
+}
diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs
index b5341725e36..9bdb69f47d8 100644
--- a/tests/run-make/rust-lld-custom-target/rmake.rs
+++ b/tests/run-make/rust-lld-custom-target/rmake.rs
@@ -8,8 +8,6 @@
 //@ needs-rust-lld
 //@ only-x86_64-unknown-linux-gnu
 
-extern crate run_make_support;
-
 use run_make_support::regex::Regex;
 use run_make_support::rustc;
 use std::process::Output;
diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs
index acb6d74aaa8..feeb82e709e 100644
--- a/tests/run-make/rust-lld/rmake.rs
+++ b/tests/run-make/rust-lld/rmake.rs
@@ -5,8 +5,6 @@
 //@ ignore-msvc
 //@ ignore-s390x lld does not yet support s390x as target
 
-extern crate run_make_support;
-
 use run_make_support::regex::Regex;
 use run_make_support::rustc;
 use std::process::Output;
diff --git a/tests/run-make/rustdoc-test-args/rmake.rs b/tests/run-make/rustdoc-test-args/rmake.rs
index c8edfb6370e..66f3f7cf131 100644
--- a/tests/run-make/rustdoc-test-args/rmake.rs
+++ b/tests/run-make/rustdoc-test-args/rmake.rs
@@ -1,5 +1,3 @@
-extern crate run_make_support;
-
 use run_make_support::{rustdoc, tmp_dir};
 use std::path::Path;
 use std::{fs, iter};
diff --git a/tests/run-make/stdin-non-utf8/Makefile b/tests/run-make/stdin-non-utf8/Makefile
deleted file mode 100644
index 709d4cf1408..00000000000
--- a/tests/run-make/stdin-non-utf8/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-include ../tools.mk
-
-all:
-	cp non-utf8 $(TMPDIR)/non-utf.rs
-	cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \
-		| $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8"
diff --git a/tests/run-make/stdin-non-utf8/non-utf8 b/tests/run-make/stdin-non-utf8/non-utf8
deleted file mode 100644
index bc87051a852..00000000000
--- a/tests/run-make/stdin-non-utf8/non-utf8
+++ /dev/null
@@ -1 +0,0 @@

diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs
new file mode 100644
index 00000000000..c07a6df4d84
--- /dev/null
+++ b/tests/run-make/stdin-rustc/rmake.rs
@@ -0,0 +1,26 @@
+//! This test checks rustc `-` (stdin) support
+
+use run_make_support::{is_windows, rustc, tmp_dir};
+
+const HELLO_WORLD: &str = r#"
+fn main() {
+    println!("Hello world!");
+}
+"#;
+
+const NOT_UTF8: &[u8] = &[0xff, 0xff, 0xff];
+
+fn main() {
+    let out_dir = tmp_dir();
+
+    // echo $HELLO_WORLD | rustc -
+    rustc().arg("-").stdin(HELLO_WORLD).run();
+    assert!(
+        out_dir.join(if !is_windows() { "rust_out" } else { "rust_out.exe" }).try_exists().unwrap()
+    );
+
+    // echo $NOT_UTF8 | rustc -
+    let output = rustc().arg("-").stdin(NOT_UTF8).run_fail();
+    let stderr = String::from_utf8(output.stderr).unwrap();
+    assert!(stderr.contains("error: couldn't read from stdin, as it did not contain valid UTF-8"));
+}
diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs
index d83332f6e03..a2dcafbbe0f 100644
--- a/tests/run-make/wasm-abi/rmake.rs
+++ b/tests/run-make/wasm-abi/rmake.rs
@@ -1,8 +1,6 @@
 //@ only-wasm32-wasip1
 //@ needs-wasmtime
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 use std::path::Path;
 use std::process::Command;
diff --git a/tests/run-make/wasm-custom-section/rmake.rs b/tests/run-make/wasm-custom-section/rmake.rs
index 825fcf71514..0303ca05ca6 100644
--- a/tests/run-make/wasm-custom-section/rmake.rs
+++ b/tests/run-make/wasm-custom-section/rmake.rs
@@ -1,5 +1,4 @@
 //@ only-wasm32-wasip1
-extern crate run_make_support;
 
 use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs
index 634683adc22..50916b1bf81 100644
--- a/tests/run-make/wasm-custom-sections-opt/rmake.rs
+++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs
@@ -1,7 +1,6 @@
 //@ only-wasm32-wasip1
-extern crate run_make_support;
 
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use std::path::Path;
 
diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs
index 400d6db5651..f4c51bc4ab4 100644
--- a/tests/run-make/wasm-export-all-symbols/rmake.rs
+++ b/tests/run-make/wasm-export-all-symbols/rmake.rs
@@ -1,8 +1,6 @@
 //@ only-wasm32-wasip1
 
-extern crate run_make_support;
-
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use std::path::Path;
 use wasmparser::ExternalKind::*;
diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs
index 1b814e9ccce..6eed229e907 100644
--- a/tests/run-make/wasm-import-module/rmake.rs
+++ b/tests/run-make/wasm-import-module/rmake.rs
@@ -1,19 +1,12 @@
 //@ only-wasm32-wasip1
 
-extern crate run_make_support;
-
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use wasmparser::TypeRef::Func;
 
 fn main() {
     rustc().input("foo.rs").target("wasm32-wasip1").run();
-    rustc()
-        .input("bar.rs")
-        .target("wasm32-wasip1")
-        .arg("-Clto")
-        .opt()
-        .run();
+    rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
 
     let file = std::fs::read(&tmp_dir().join("bar.wasm")).unwrap();
 
diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs
index bffa311d93a..373b966401c 100644
--- a/tests/run-make/wasm-panic-small/rmake.rs
+++ b/tests/run-make/wasm-panic-small/rmake.rs
@@ -1,8 +1,6 @@
 //@ only-wasm32-wasip1
 #![deny(warnings)]
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 
 fn main() {
diff --git a/tests/run-make/wasm-spurious-import/rmake.rs b/tests/run-make/wasm-spurious-import/rmake.rs
index 8f716061d28..458c7bfccb7 100644
--- a/tests/run-make/wasm-spurious-import/rmake.rs
+++ b/tests/run-make/wasm-spurious-import/rmake.rs
@@ -1,7 +1,5 @@
 //@ only-wasm32-wasip1
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 
diff --git a/tests/run-make/wasm-stringify-ints-small/rmake.rs b/tests/run-make/wasm-stringify-ints-small/rmake.rs
index 5efbfee8d38..9fac0c0c215 100644
--- a/tests/run-make/wasm-stringify-ints-small/rmake.rs
+++ b/tests/run-make/wasm-stringify-ints-small/rmake.rs
@@ -1,8 +1,6 @@
 //@ only-wasm32-wasip1
 #![deny(warnings)]
 
-extern crate run_make_support;
-
 use run_make_support::{rustc, tmp_dir};
 
 fn main() {
diff --git a/tests/run-make/wasm-symbols-different-module/rmake.rs b/tests/run-make/wasm-symbols-different-module/rmake.rs
index 88bd16a404c..521d2c31ee6 100644
--- a/tests/run-make/wasm-symbols-different-module/rmake.rs
+++ b/tests/run-make/wasm-symbols-different-module/rmake.rs
@@ -1,5 +1,4 @@
 //@ only-wasm32-wasip1
-extern crate run_make_support;
 
 use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::{HashMap, HashSet};
diff --git a/tests/run-make/wasm-symbols-not-exported/rmake.rs b/tests/run-make/wasm-symbols-not-exported/rmake.rs
index c9207f70ae5..1b020b67a38 100644
--- a/tests/run-make/wasm-symbols-not-exported/rmake.rs
+++ b/tests/run-make/wasm-symbols-not-exported/rmake.rs
@@ -1,5 +1,4 @@
 //@ only-wasm32-wasip1
-extern crate run_make_support;
 
 use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::path::Path;
diff --git a/tests/run-make/wasm-symbols-not-imported/rmake.rs b/tests/run-make/wasm-symbols-not-imported/rmake.rs
index 4d41dc7c0aa..a653ab61b2c 100644
--- a/tests/run-make/wasm-symbols-not-imported/rmake.rs
+++ b/tests/run-make/wasm-symbols-not-imported/rmake.rs
@@ -1,5 +1,4 @@
 //@ only-wasm32-wasip1
-extern crate run_make_support;
 
 use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::path::Path;
diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs
new file mode 100644
index 00000000000..aa166c343b2
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/non_local_defs.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+//@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options
+//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
+
+//! ```
+//! #[macro_export]
+//! macro_rules! a_macro { () => {} }
+//! ```
diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr
new file mode 100644
index 00000000000..39a25de1aae
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr
@@ -0,0 +1,14 @@
+warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_defs.rs:9:1
+   |
+LL | macro_rules! a_macro { () => {} }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }`
+   = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
+   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
+   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
+   = note: `#[warn(non_local_definitions)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout
new file mode 100644
index 00000000000..bee195fcdd7
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout
@@ -0,0 +1,6 @@
+
+running 1 test
+test $DIR/non_local_defs.rs - (line 7) ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc/resolve-ice-124363.rs b/tests/rustdoc/resolve-ice-124363.rs
new file mode 100644
index 00000000000..111916cc590
--- /dev/null
+++ b/tests/rustdoc/resolve-ice-124363.rs
@@ -0,0 +1,7 @@
+/**
+*/
+pub mod A {
+    #![doc = "{
+         Foo { },
+     }"]
+}
diff --git a/tests/ui/asm/x86_64/target-feature-attr.rs b/tests/ui/asm/x86_64/target-feature-attr.rs
index 820be132ef7..6bb277ac165 100644
--- a/tests/ui/asm/x86_64/target-feature-attr.rs
+++ b/tests/ui/asm/x86_64/target-feature-attr.rs
@@ -1,4 +1,6 @@
 //@ only-x86_64
+// Set the base cpu explicitly, in case the default has been changed.
+//@ compile-flags: -C target-cpu=x86-64
 
 #![feature(avx512_target_feature)]
 
diff --git a/tests/ui/asm/x86_64/target-feature-attr.stderr b/tests/ui/asm/x86_64/target-feature-attr.stderr
index c852726ee7f..0cd571ac8cc 100644
--- a/tests/ui/asm/x86_64/target-feature-attr.stderr
+++ b/tests/ui/asm/x86_64/target-feature-attr.stderr
@@ -1,23 +1,23 @@
 error: register class `ymm_reg` requires the `avx` target feature
-  --> $DIR/target-feature-attr.rs:18:40
+  --> $DIR/target-feature-attr.rs:20:40
    |
 LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
    |                                        ^^^^^^^^^^^^^
 
 error: register class `ymm_reg` requires the `avx` target feature
-  --> $DIR/target-feature-attr.rs:18:55
+  --> $DIR/target-feature-attr.rs:20:55
    |
 LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
    |                                                       ^^^^^^^^^^^^^
 
 error: register class `ymm_reg` requires the `avx` target feature
-  --> $DIR/target-feature-attr.rs:18:70
+  --> $DIR/target-feature-attr.rs:20:70
    |
 LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
    |                                                                      ^^^^^^^^^^^^^^^^^^
 
 error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f
-  --> $DIR/target-feature-attr.rs:33:23
+  --> $DIR/target-feature-attr.rs:35:23
    |
 LL |     asm!("/* {0} */", in(kreg) x);
    |                       ^^^^^^^^^^
diff --git a/tests/ui/async-await/inference_var_self_argument.rs b/tests/ui/async-await/inference_var_self_argument.rs
index f4bb8884b05..4d5ac4abb19 100644
--- a/tests/ui/async-await/inference_var_self_argument.rs
+++ b/tests/ui/async-await/inference_var_self_argument.rs
@@ -4,7 +4,7 @@
 trait Foo {
     async fn foo(self: &dyn Foo) {
         //~^ ERROR: `Foo` cannot be made into an object
-        //~| ERROR invalid `self` parameter type: &dyn Foo
+        //~| ERROR invalid `self` parameter type: `&dyn Foo`
         todo!()
     }
 }
diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr
index 8a8c1ea03f1..f94ae2a27c3 100644
--- a/tests/ui/async-await/inference_var_self_argument.stderr
+++ b/tests/ui/async-await/inference_var_self_argument.stderr
@@ -13,7 +13,7 @@ LL |     async fn foo(self: &dyn Foo) {
    |              ^^^ ...because method `foo` is `async`
    = help: consider moving `foo` to another trait
 
-error[E0307]: invalid `self` parameter type: &dyn Foo
+error[E0307]: invalid `self` parameter type: `&dyn Foo`
   --> $DIR/inference_var_self_argument.rs:5:24
    |
 LL |     async fn foo(self: &dyn Foo) {
diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr
index 2875af8a97e..702e0b375e5 100644
--- a/tests/ui/async-await/issue-66312.stderr
+++ b/tests/ui/async-await/issue-66312.stderr
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
 LL |     if x.is_some() {
    |        ^^^^^^^^^^^ expected `bool`, found `()`
 
-error[E0307]: invalid `self` parameter type: T
+error[E0307]: invalid `self` parameter type: `T`
   --> $DIR/issue-66312.rs:4:22
    |
 LL |     fn is_some(self: T);
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
index 694fa460e9b..3e63349edb7 100644
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
@@ -8,7 +8,7 @@
 
 extern crate libc;
 
-// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec:ing child
+// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec'ing child
 // processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See
 // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384
 #[unix_sigpipe = "sig_dfl"]
diff --git a/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs b/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs
new file mode 100644
index 00000000000..9885d381d24
--- /dev/null
+++ b/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs
@@ -0,0 +1,11 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+trait Foo {
+    fn test() -> impl Fn(u32) -> u32 {
+        |x| x.count_ones()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs b/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs
new file mode 100644
index 00000000000..3185a431f0b
--- /dev/null
+++ b/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs
@@ -0,0 +1,9 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+fn foo() -> impl FnOnce(u32) -> u32 {
+    |x| x.leading_zeros()
+}
+
+fn main() {}
diff --git a/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs b/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs
new file mode 100644
index 00000000000..d9ab0149087
--- /dev/null
+++ b/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs
@@ -0,0 +1,20 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+
+trait Foo {}
+fn needs_foo<T>(_: T)
+where
+    Wrap<T>: Foo,
+{
+}
+
+struct Wrap<T>(T);
+impl<T> Foo for Wrap<T> where T: for<'a> Fn(&'a i32) {}
+
+fn main() {
+    needs_foo(|x| {
+        x.to_string();
+    });
+}
diff --git a/tests/ui/closures/infer-signature-from-impl.rs b/tests/ui/closures/deduce-signature/infer-signature-from-impl.rs
index fa455c15ec7..20802ce37ee 100644
--- a/tests/ui/closures/infer-signature-from-impl.rs
+++ b/tests/ui/closures/deduce-signature/infer-signature-from-impl.rs
@@ -1,8 +1,7 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
-//@[next] known-bug: trait-system-refactor-initiative#71
-//@[current] check-pass
+//@ check-pass
 
 trait Foo {}
 fn needs_foo<T>(_: T)
diff --git a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr
new file mode 100644
index 00000000000..eaa0d32e75d
--- /dev/null
+++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr
@@ -0,0 +1,15 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/obligation-with-leaking-placeholders.rs:18:5
+   |
+LL | /     needs_foo(|x| {
+LL | |
+LL | |
+LL | |         x.to_string();
+LL | |     });
+   | |______^ implementation of `Foo` is not general enough
+   |
+   = note: `Wrap<{closure@$DIR/obligation-with-leaking-placeholders.rs:18:15: 18:18}>` must implement `Foo<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/closures/infer-signature-from-impl.next.stderr b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr
index 332917eaaff..3d667f12371 100644
--- a/tests/ui/closures/infer-signature-from-impl.next.stderr
+++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr
@@ -1,8 +1,9 @@
 error[E0282]: type annotations needed
-  --> $DIR/infer-signature-from-impl.rs:18:16
+  --> $DIR/obligation-with-leaking-placeholders.rs:18:16
    |
 LL |     needs_foo(|x| {
    |                ^
+...
 LL |         x.to_string();
    |         - type must be known at this point
    |
diff --git a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs
new file mode 100644
index 00000000000..deb888ec286
--- /dev/null
+++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs
@@ -0,0 +1,23 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// See #124385 for more details.
+
+trait Foo<'a> {}
+fn needs_foo<T>(_: T)
+where
+    for<'a> Wrap<T>: Foo<'a>,
+{
+}
+
+struct Wrap<T>(T);
+impl<'a, T> Foo<'a> for Wrap<T> where T: Fn(&'a i32) {}
+
+fn main() {
+    needs_foo(|x| {
+        //[current]~^ implementation of `Foo` is not general enough
+        //[next]~^^ ERROR type annotations needed
+        x.to_string();
+    });
+}
diff --git a/tests/ui/closures/issue-23012-supertrait-signature-inference.rs b/tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs
index 732f687309c..16890b28acd 100644
--- a/tests/ui/closures/issue-23012-supertrait-signature-inference.rs
+++ b/tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs
@@ -1,3 +1,6 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
 //@ check-pass
 // Checks that we can infer a closure signature even if the `FnOnce` bound is
 // a supertrait of the obligations we have currently registered for the Ty var.
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.svg b/tests/ui/codemap_tests/huge_multispan_highlight.svg
index f1e96583ff0..7b6dbb17c6f 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.svg
@@ -27,11 +27,11 @@
 </tspan>
     <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>       let _ = match true {</tspan>
 </tspan>
-    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>              </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
 </tspan>
     <tspan x="10px" y="118px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
 </tspan>
     <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>             // last line shown in multispan header</tspan>
 </tspan>
@@ -41,11 +41,11 @@
 </tspan>
     <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
+    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
 </tspan>
     <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
+    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
 </tspan>
     <tspan x="10px" y="280px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
@@ -53,7 +53,7 @@
 </tspan>
     <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
+    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
 </tspan>
     <tspan x="10px" y="352px">
 </tspan>
@@ -65,11 +65,11 @@
 </tspan>
     <tspan x="10px" y="424px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>       let _ = match true {</tspan>
 </tspan>
-    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>              </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
 </tspan>
     <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
+    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
 </tspan>
     <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -81,11 +81,11 @@
 </tspan>
     <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         ),</tspan>
 </tspan>
-    <tspan x="10px" y="586px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
+    <tspan x="10px" y="586px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|_________-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
 </tspan>
     <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
+    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
 </tspan>
     <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
@@ -99,7 +99,7 @@
 </tspan>
     <tspan x="10px" y="730px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan><tspan>         ",</tspan>
 </tspan>
-    <tspan x="10px" y="748px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
+    <tspan x="10px" y="748px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|_________^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
 </tspan>
     <tspan x="10px" y="766px">
 </tspan>
diff --git a/tests/ui/coherence/auxiliary/parametrized-trait.rs b/tests/ui/coherence/auxiliary/parametrized-trait.rs
new file mode 100644
index 00000000000..88a3d5cd52d
--- /dev/null
+++ b/tests/ui/coherence/auxiliary/parametrized-trait.rs
@@ -0,0 +1,2 @@
+pub trait Trait0<T, U, V> {}
+pub trait Trait1<T, U> {}
diff --git a/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs b/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs
new file mode 100644
index 00000000000..d49538de580
--- /dev/null
+++ b/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs
@@ -0,0 +1,3 @@
+pub trait Trait {
+    type Assoc;
+}
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr
new file mode 100644
index 00000000000..2ffb6000ec8
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr
@@ -0,0 +1,19 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
+  --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1
+   |
+LL | / impl<T> Trait for T
+LL | | where
+LL | |     T: 'static,
+LL | |     for<'a> T: WithAssoc<'a>,
+LL | |     for<'a> <T as WithAssoc<'a>>::Assoc: WhereBound,
+   | |____________________________________________________- first implementation here
+...
+LL |   impl<T> Trait for Box<T> {}
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
+   = note: downstream crates may implement trait `WhereBound` for type `<std::boxed::Box<_> as WithAssoc<'a>>::Assoc`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr
new file mode 100644
index 00000000000..99abdf65abd
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr
@@ -0,0 +1,18 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
+  --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1
+   |
+LL | / impl<T> Trait for T
+LL | | where
+LL | |     T: 'static,
+LL | |     for<'a> T: WithAssoc<'a>,
+LL | |     for<'a> <T as WithAssoc<'a>>::Assoc: WhereBound,
+   | |____________________________________________________- first implementation here
+...
+LL |   impl<T> Trait for Box<T> {}
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs
new file mode 100644
index 00000000000..b8b6d8846ef
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs
@@ -0,0 +1,42 @@
+// Regression test for soundness issue #114061:
+// "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could"
+#![crate_type = "lib"]
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+trait WhereBound {}
+impl WhereBound for () {}
+
+
+pub trait WithAssoc<'a> {
+    type Assoc;
+}
+
+// These two impls of `Trait` overlap:
+
+pub trait Trait {}
+impl<T> Trait for T
+where
+    T: 'static,
+    for<'a> T: WithAssoc<'a>,
+    for<'a> <T as WithAssoc<'a>>::Assoc: WhereBound,
+{
+}
+
+impl<T> Trait for Box<T> {} //~ ERROR conflicting implementations of trait `Trait` for type `Box<_>`
+
+// A downstream crate could write:
+//
+//     use upstream::*;
+//
+//     struct Local;
+//     impl WithAssoc<'_> for Box<Local> {
+//         type Assoc = ();
+//     }
+//
+//     fn impls_trait<T: Trait>() {}
+//
+//     fn main() {
+//         impls_trait::<Box<Local>>();
+//     }
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr
new file mode 100644
index 00000000000..49b236f9d2a
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr
@@ -0,0 +1,19 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
+  --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1
+   |
+LL | / impl<T> Trait for T
+LL | | where
+LL | |     T: 'static,
+LL | |     for<'a> T: WithAssoc<'a>,
+LL | |     for<'a> Box<<T as WithAssoc<'a>>::Assoc>: WhereBound,
+   | |_________________________________________________________- first implementation here
+...
+LL |   impl<T> Trait for Box<T> {}
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
+   = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr
new file mode 100644
index 00000000000..49b236f9d2a
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr
@@ -0,0 +1,19 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
+  --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1
+   |
+LL | / impl<T> Trait for T
+LL | | where
+LL | |     T: 'static,
+LL | |     for<'a> T: WithAssoc<'a>,
+LL | |     for<'a> Box<<T as WithAssoc<'a>>::Assoc>: WhereBound,
+   | |_________________________________________________________- first implementation here
+...
+LL |   impl<T> Trait for Box<T> {}
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
+   = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs
new file mode 100644
index 00000000000..8eeadb3dc75
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs
@@ -0,0 +1,44 @@
+// Regression test for soundness issue #114061:
+// "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could"
+#![crate_type = "lib"]
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+pub trait WhereBound {}
+impl WhereBound for () {}
+
+pub trait WithAssoc<'a> {
+    type Assoc;
+}
+
+// These two impls of `Trait` overlap:
+
+pub trait Trait {}
+impl<T> Trait for T
+where
+    T: 'static,
+    for<'a> T: WithAssoc<'a>,
+    for<'a> Box<<T as WithAssoc<'a>>::Assoc>: WhereBound,
+{
+}
+
+impl<T> Trait for Box<T> {} //~ ERROR conflicting implementations of trait `Trait` for type `Box<_>`
+
+// A downstream crate could write:
+//
+//
+//     use upstream::*;
+//
+//     struct Local;
+//     impl WithAssoc<'_> for Box<Local> {
+//         type Assoc = Local;
+//     }
+//
+//     impl WhereBound for Box<Local> {}
+//
+//     fn impls_trait<T: Trait>() {}
+//
+//     fn main() {
+//         impls_trait::<Box<Local>>();
+//     }
diff --git a/tests/ui/coherence/orphan-check-projections-covering.rs b/tests/ui/coherence/orphan-check-projections-covering.rs
new file mode 100644
index 00000000000..ae1917ec161
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-covering.rs
@@ -0,0 +1,25 @@
+// Projections cover type parameters if they normalize to a (local) type that covers them.
+// This ensures that we don't perform an overly strict check on
+// projections like in closed PR #100555 which did a syntactic
+// check for type parameters in projections without normalizing
+// first which would've lead to real-word regressions.
+
+//@ check-pass
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+trait Project { type Output; }
+
+impl<T> Project for Wrapper<T> {
+    type Output = Local;
+}
+
+struct Wrapper<T>(T);
+struct Local;
+
+impl<T> foreign::Trait1<Local, T> for <Wrapper<T> as Project>::Output {}
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-projections-nested.rs b/tests/ui/coherence/orphan-check-projections-nested.rs
new file mode 100644
index 00000000000..ec244a8005b
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-nested.rs
@@ -0,0 +1,23 @@
+// This used to ICE in an earlier iteration of #117164. Minimized from crate `proqnt`.
+
+//@ check-pass
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+//@ aux-crate:dep=trait-with-assoc-ty.rs
+//@ edition: 2021
+
+pub(crate) trait Trait<T> {
+    type Assoc;
+}
+
+pub(crate) struct Type<T, U, V>(T, U, V);
+
+impl<T, U> dep::Trait for Type<T, <<T as dep::Trait>::Assoc as Trait<U>>::Assoc, U>
+where
+    T: dep::Trait,
+    <T as dep::Trait>::Assoc: Trait<U>,
+{
+    type Assoc = U;
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr
new file mode 100644
index 00000000000..d83a56c0bd0
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr
@@ -0,0 +1,15 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering-ambiguity.rs:25:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for <T as Project>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning: 1 warning emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr
new file mode 100644
index 00000000000..d83a56c0bd0
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr
@@ -0,0 +1,15 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering-ambiguity.rs:25:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for <T as Project>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning: 1 warning emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs
new file mode 100644
index 00000000000..227d8535232
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs
@@ -0,0 +1,29 @@
+// This test demonstrates a limitation of the trait solver.
+// Basically, one might think that `T` was covered by the projection since the
+// latter appears to normalize to a local type. However, since we instantiate the
+// constituent types of the self type of impls with fresh infer vars and try to
+// normalize them during orphan checking, we wind up trying to normalize a
+// projection whose self type is an infer var which unconditionally fails due to
+// ambiguity.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+trait Project { type Output; }
+
+impl<T> Project for T {
+    type Output = Local;
+}
+
+struct Local;
+
+impl<T> foreign::Trait1<Local, T> for <T as Project>::Output {}
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr
new file mode 100644
index 00000000000..8964fefedd4
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr
@@ -0,0 +1,26 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:6
+   |
+LL | impl<T, U> foreign::Trait0<LocalTy, T, U> for <() as Trait<T, U>>::Assoc {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning[E0210]: type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:9
+   |
+LL | impl<T, U> foreign::Trait0<LocalTy, T, U> for <() as Trait<T, U>>::Assoc {}
+   |         ^ type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning: 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr
new file mode 100644
index 00000000000..8964fefedd4
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr
@@ -0,0 +1,26 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:6
+   |
+LL | impl<T, U> foreign::Trait0<LocalTy, T, U> for <() as Trait<T, U>>::Assoc {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning[E0210]: type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:9
+   |
+LL | impl<T, U> foreign::Trait0<LocalTy, T, U> for <() as Trait<T, U>>::Assoc {}
+   |         ^ type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning: 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs
new file mode 100644
index 00000000000..c5340e85405
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs
@@ -0,0 +1,24 @@
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+trait Trait<T, U> { type Assoc; }
+
+impl<T, U> Trait<T, U> for () {
+    type Assoc = LocalTy;
+}
+
+struct LocalTy;
+
+impl<T, U> foreign::Trait0<LocalTy, T, U> for <() as Trait<T, U>>::Assoc {}
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+//~| WARNING type parameter `U` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr
new file mode 100644
index 00000000000..28b8c3f4a94
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr
@@ -0,0 +1,37 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:22:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for <T as Identity>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:27:6
+   |
+LL | impl<T> foreign::Trait0<<T as Identity>::Output, Local, T> for Option<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:40:6
+   |
+LL | impl<T: Deferred> foreign::Trait1<Local, T> for <T as Deferred>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning: 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr
new file mode 100644
index 00000000000..28b8c3f4a94
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr
@@ -0,0 +1,37 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:22:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for <T as Identity>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:27:6
+   |
+LL | impl<T> foreign::Trait0<<T as Identity>::Output, Local, T> for Option<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-projections-not-covering.rs:40:6
+   |
+LL | impl<T: Deferred> foreign::Trait1<Local, T> for <T as Deferred>::Output {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+warning: 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.rs b/tests/ui/coherence/orphan-check-projections-not-covering.rs
new file mode 100644
index 00000000000..8c2a9a17e2b
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-not-covering.rs
@@ -0,0 +1,42 @@
+// Regression test for issue #99554.
+// Projections might not cover type parameters.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+trait Identity {
+    type Output;
+}
+
+impl<T> Identity for T {
+    type Output = T;
+}
+
+struct Local;
+
+impl<T> foreign::Trait0<Local, T, ()> for <T as Identity>::Output {}
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+
+
+impl<T> foreign::Trait0<<T as Identity>::Output, Local, T> for Option<T> {}
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+
+pub trait Deferred {
+    type Output;
+}
+
+// A downstream user could implement
+//
+//     impl<T> Deferred for Type<T> { type Output = T; }
+//     struct Type<T>(T);
+//
+impl<T: Deferred> foreign::Trait1<Local, T> for <T as Deferred>::Output {}
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr b/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr
new file mode 100644
index 00000000000..0346a9d665c
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr
@@ -0,0 +1,15 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-unsat-bounds.rs:28:6
+   |
+LL | impl<T> foreign::Trait1<LocalTy, T> for <Wrapper<T> as Discard>::Output
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning: 1 warning emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr b/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr
new file mode 100644
index 00000000000..0346a9d665c
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr
@@ -0,0 +1,15 @@
+warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+  --> $DIR/orphan-check-projections-unsat-bounds.rs:28:6
+   |
+LL | impl<T> foreign::Trait1<LocalTy, T> for <Wrapper<T> as Discard>::Output
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`)
+   |
+   = 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+   = note: `#[warn(uncovered_param_in_projection)]` on by default
+
+warning: 1 warning emitted
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs b/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs
new file mode 100644
index 00000000000..bc52673a016
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs
@@ -0,0 +1,35 @@
+// This used to ICE in an earlier iteration of #117164.
+// The normalization performed during orphan checking happens inside an empty ParamEnv and
+// with type parameters mapped to fresh infer vars. Therefore it may fail for example due to
+// unsatisfied bounds while normalization outside of orphan checking succeeds.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ check-pass
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+struct Wrapper<T>(T);
+
+trait Bound {}
+
+trait Discard { type Output; }
+
+impl<T> Discard for Wrapper<T>
+where
+    Wrapper<T>: Bound
+{
+    type Output = LocalTy;
+}
+
+struct LocalTy;
+
+impl<T> foreign::Trait1<LocalTy, T> for <Wrapper<T> as Discard>::Output
+//~^ WARNING type parameter `T` must be covered by another type
+//~| WARNING this was previously accepted by the compiler
+where
+    Wrapper<T>: Bound
+{}
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-covering.rs
new file mode 100644
index 00000000000..a8b9e905c70
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-weak-aliases-covering.rs
@@ -0,0 +1,20 @@
+// Weak aliases cover type parameters if they normalize to a (local) type that covers them.
+
+//@ check-pass
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+type Alias<T> = LocalWrapper<T>;
+
+struct Local;
+struct LocalWrapper<T>(T);
+
+impl<T> foreign::Trait1<Local, T> for Alias<T> {}
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr
new file mode 100644
index 00000000000..276833fa171
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr
new file mode 100644
index 00000000000..276833fa171
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs
new file mode 100644
index 00000000000..9ebc45a8829
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs
@@ -0,0 +1,19 @@
+// Weak aliases might not cover type parameters.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+#![feature(lazy_type_alias)]
+#![allow(incomplete_features)]
+
+type Identity<T> = T;
+
+struct Local;
+
+impl<T> foreign::Trait1<Local, T> for Identity<T> {}
+//~^ ERROR type parameter `T` must be covered by another type
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs
new file mode 100644
index 00000000000..05bd0d91168
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs
@@ -0,0 +1,13 @@
+//@ edition:2021
+// issues rust-lang/rust#111911
+// test for ICE opaque type with non-universal region substs
+
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+pub async fn foo<const X: &'static str>() {}
+//~^ ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+//~| ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+fn bar<const N: &'static u8>() -> impl Sized {}
+
+pub fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr
new file mode 100644
index 00000000000..1bdb9cd9501
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr
@@ -0,0 +1,16 @@
+error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43
+   |
+LL | pub async fn foo<const X: &'static str>() {}
+   |                                           ^^
+
+error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+  --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43
+   |
+LL | pub async fn foo<const X: &'static str>() {}
+   |                                           ^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
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
new file mode 100644
index 00000000000..68b8b489816
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
@@ -0,0 +1,32 @@
+// ICE Inconsistent rustc_transmute::is_transmutable(...) result, got Yes
+// issue: rust-lang/rust#110969
+#![feature(adt_const_params, generic_const_exprs, transmutability)]
+#![allow(incomplete_features, unstable_features)]
+
+mod assert {
+    use std::mem::BikeshedIntrinsicFrom;
+
+    pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
+        //~^ ERROR trait takes at most 2 generic arguments but 3 generic arguments were supplied
+    {
+    }
+}
+
+fn via_associated_const() {
+    struct Context;
+    #[repr(C)]
+    struct Src;
+    #[repr(C)]
+    struct Dst;
+
+    trait Trait {
+        const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
+        //~^ ERROR mismatched types
+        //~| ERROR `Src` cannot be safely transmuted into `Dst`
+        //~| ERROR mismatched types
+    }
+}
+
+pub fn main() {}
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
new file mode 100644
index 00000000000..1dbacaee3c2
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
@@ -0,0 +1,39 @@
+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 this generic argument
+   |              |
+   |              expected at most 2 generic arguments
+
+error[E0308]: mismatched types
+  --> $DIR/transmutable-ice-110969.rs:25:74
+   |
+LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
+   |                                                                          ^^ expected `Assume`, found `()`
+
+error[E0277]: `Src` cannot be safely transmuted into `Dst`
+  --> $DIR/transmutable-ice-110969.rs:25:60
+   |
+LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
+   |                                                            ^^^ `Dst` may carry safety invariants
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/transmutable-ice-110969.rs:11:14
+   |
+LL |     pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error[E0308]: mismatched types
+  --> $DIR/transmutable-ice-110969.rs:25:29
+   |
+LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0107, E0277, E0308.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs
new file mode 100644
index 00000000000..4bea3ad87f5
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs
@@ -0,0 +1,23 @@
+// issue: rust-lang/rust#113776
+// ice: expected type of closure body to be a closure or coroutine
+//@ edition: 2021
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+use core::ops::SubAssign;
+
+fn f<T>(
+    data: &[(); {
+         let f: F = async { 1 };
+         //~^ ERROR cannot find type `F` in this scope
+
+         1
+     }],
+) -> impl Iterator<Item = SubAssign> {
+//~^ ERROR the type parameter `Rhs` must be explicitly specified
+//~| ERROR `()` is not an iterator
+//~| ERROR trait objects must include the `dyn` keyword
+//~| ERROR the type parameter `Rhs` must be explicitly specified [E0393]
+}
+
+pub fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
new file mode 100644
index 00000000000..be79450a3ce
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
@@ -0,0 +1,68 @@
+error[E0412]: cannot find type `F` in this scope
+  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:11:17
+   |
+LL |          let f: F = async { 1 };
+   |                 ^
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+   = note: similarly named trait `Fn` defined here
+   |
+help: a trait with a similar name exists
+   |
+LL |          let f: Fn = async { 1 };
+   |                 ~~
+help: you might be missing a type parameter
+   |
+LL | fn f<T, F>(
+   |       +++
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
+   |
+LL | ) -> impl Iterator<Item = SubAssign> {
+   |                           ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign<Rhs>`
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+   |
+   = note: type parameter `Rhs` must be specified for this
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
+   |
+LL | ) -> impl Iterator<Item = SubAssign> {
+   |                           ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign<Rhs>`
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+   |
+   = note: type parameter `Rhs` must be specified for this
+   |
+   = note: because of the default `Self` reference, type parameters must be specified on object types
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: `()` is not an iterator
+  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:6
+   |
+LL | ) -> impl Iterator<Item = SubAssign> {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `()`
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27
+   |
+LL | ) -> impl Iterator<Item = SubAssign> {
+   |                           ^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | ) -> impl Iterator<Item = dyn SubAssign> {
+   |                           +++
+help: you might have meant to write a bound here
+   |
+LL | ) -> impl Iterator<Item: SubAssign> {
+   |                        ~
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0393, E0412, E0782.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs b/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs
new file mode 100644
index 00000000000..c547b54e16b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs
@@ -0,0 +1,18 @@
+// issue rust-lang/rust#111667
+// ICE failed to resolve instance for <[f32; 2] as CrossProduct ..
+//@ check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait CrossProduct<'a, T, R> {
+    fn cross(&'a self, t: &'a T) -> R;
+}
+
+impl<'a, T, U, const N: usize> CrossProduct<'a, [U; N], [(&'a T, &'a U); N * N]> for [T; N] {
+    fn cross(&'a self, us: &'a [U; N]) -> [(&'a T, &'a U); N * N] {
+        std::array::from_fn(|i| (&self[i / N], &us[i % N]))
+    }
+}
+
+pub fn main() {}
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 b56b68a5795..ee669abb51e 100644
--- a/tests/ui/consts/const-eval/const_fn_target_feature.rs
+++ b/tests/ui/consts/const-eval/const_fn_target_feature.rs
@@ -1,5 +1,6 @@
 //@ only-x86_64
-//@ compile-flags:-C target-feature=+ssse3
+// Set the base cpu explicitly, in case the default has been changed.
+//@ compile-flags: -C target-cpu=x86-64 -C target-feature=+ssse3
 
 #![crate_type = "lib"]
 
diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.stderr b/tests/ui/consts/const-eval/const_fn_target_feature.stderr
index 0c7c69b794a..d3a00b57ebb 100644
--- a/tests/ui/consts/const-eval/const_fn_target_feature.stderr
+++ b/tests/ui/consts/const-eval/const_fn_target_feature.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_fn_target_feature.rs:10:24
+  --> $DIR/const_fn_target_feature.rs:11:24
    |
 LL | const B: () = unsafe { avx2_fn() };
    |                        ^^^^^^^^^ calling a function that requires unavailable target features: avx2
diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs
new file mode 100644
index 00000000000..a92b99976e2
--- /dev/null
+++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs
@@ -0,0 +1,18 @@
+type Foo = impl Send;
+//~^ ERROR `impl Trait` in type aliases is unstable
+
+struct A;
+
+const VALUE: Foo = value();
+//~^ ERROR cannot find function `value` in this scope
+
+fn test() {
+    match VALUE {
+        0 | 0 => {}
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
+        _ => (),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr
new file mode 100644
index 00000000000..daf0ccaa776
--- /dev/null
+++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr
@@ -0,0 +1,58 @@
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/ice-unhandled-type-122191.rs:1:12
+   |
+LL | type Foo = impl Send;
+   |            ^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` 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[E0425]: cannot find function `value` in this scope
+  --> $DIR/ice-unhandled-type-122191.rs:6:20
+   |
+LL | const VALUE: Foo = value();
+   |                    ^^^^^ not found in this scope
+
+error[E0308]: mismatched types
+  --> $DIR/ice-unhandled-type-122191.rs:11:9
+   |
+LL | type Foo = impl Send;
+   |            --------- the expected opaque type
+...
+LL |     match VALUE {
+   |           ----- this expression has type `Foo`
+LL |         0 | 0 => {}
+   |         ^ expected opaque type, found integer
+   |
+   = note: expected opaque type `Foo`
+                     found type `{integer}`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/ice-unhandled-type-122191.rs:9:4
+   |
+LL | fn test() {
+   |    ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/ice-unhandled-type-122191.rs:11:13
+   |
+LL | type Foo = impl Send;
+   |            --------- the expected opaque type
+...
+LL |     match VALUE {
+   |           ----- this expression has type `Foo`
+LL |         0 | 0 => {}
+   |             ^ expected opaque type, found integer
+   |
+   = note: expected opaque type `Foo`
+                     found type `{integer}`
+note: this item must have the opaque type in its signature in order to be able to register hidden types
+  --> $DIR/ice-unhandled-type-122191.rs:9:4
+   |
+LL | fn test() {
+   |    ^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0425, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/mono-reachable-invalid-const.rs b/tests/ui/consts/mono-reachable-invalid-const.rs
new file mode 100644
index 00000000000..aabdb071bc9
--- /dev/null
+++ b/tests/ui/consts/mono-reachable-invalid-const.rs
@@ -0,0 +1,23 @@
+//@ build-fail
+
+struct Bar<const BITS: usize>;
+
+impl<const BITS: usize> Bar<BITS> {
+    const ASSERT: bool = {
+        let b = std::convert::identity(1);
+        ["oops"][b]; //~ ERROR evaluation of `Bar::<0>::ASSERT` failed
+        true
+    };
+
+    fn assert() {
+        let val = Self::ASSERT;
+        if val {
+            std::convert::identity(val);
+        }
+    }
+}
+
+
+fn main() {
+    Bar::<0>::assert();
+}
diff --git a/tests/ui/consts/mono-reachable-invalid-const.stderr b/tests/ui/consts/mono-reachable-invalid-const.stderr
new file mode 100644
index 00000000000..6b7b25b59b8
--- /dev/null
+++ b/tests/ui/consts/mono-reachable-invalid-const.stderr
@@ -0,0 +1,29 @@
+error[E0080]: evaluation of `Bar::<0>::ASSERT` failed
+  --> $DIR/mono-reachable-invalid-const.rs:8:9
+   |
+LL |         ["oops"][b];
+   |         ^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+note: erroneous constant encountered
+  --> $DIR/mono-reachable-invalid-const.rs:13:19
+   |
+LL |         let val = Self::ASSERT;
+   |                   ^^^^^^^^^^^^
+
+note: erroneous constant encountered
+  --> $DIR/mono-reachable-invalid-const.rs:13:19
+   |
+LL |         let val = Self::ASSERT;
+   |                   ^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn Bar::<0>::assert`
+  --> $DIR/mono-reachable-invalid-const.rs:22:5
+   |
+LL |     Bar::<0>::assert();
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg
index 1d82a97888a..be92c00c19b 100644
--- a/tests/ui/error-emitter/highlighting.svg
+++ b/tests/ui/error-emitter/highlighting.svg
@@ -29,11 +29,11 @@
 </tspan>
     <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     query(wrapped_fn);</tspan>
 </tspan>
-    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-012 bold">-----</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">^^^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">one type is more general than the other</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">-----</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">^^^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">one type is more general than the other</tspan>
 </tspan>
-    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-012 bold">arguments to this function are incorrect</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">arguments to this function are incorrect</tspan>
 </tspan>
     <tspan x="10px" y="154px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -49,13 +49,13 @@
 </tspan>
     <tspan x="10px" y="262px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>   fn query(_: fn(Box&lt;(dyn Any + Send + '_)&gt;) -&gt; Pin&lt;Box&lt;(</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-012 bold">_-</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-012 bold">_-</tspan>
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     dyn Future&lt;Output = Result&lt;Box&lt;(dyn Any + 'static)&gt;, String&gt;&gt; + Send + 'static</tspan>
 </tspan>
     <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> )&gt;&gt;) {}</tspan>
 </tspan>
-    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan class="fg-ansi256-012 bold">|___-</tspan>
+    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|___-</tspan>
 </tspan>
     <tspan x="10px" y="352px">
 </tspan>
diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg
index 88143f725a5..152245da9dd 100644
--- a/tests/ui/error-emitter/highlighting.windows.svg
+++ b/tests/ui/error-emitter/highlighting.windows.svg
@@ -30,11 +30,11 @@
 </tspan>
     <tspan x="10px" y="82px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     query(wrapped_fn);</tspan>
 </tspan>
-    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-014 bold">-----</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">^^^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">one type is more general than the other</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-014 bold">-----</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">^^^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">one type is more general than the other</tspan>
 </tspan>
-    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
-    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>    </tspan><tspan class="fg-ansi256-014 bold">arguments to this function are incorrect</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     </tspan><tspan class="fg-ansi256-014 bold">arguments to this function are incorrect</tspan>
 </tspan>
     <tspan x="10px" y="154px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -50,13 +50,13 @@
 </tspan>
     <tspan x="10px" y="262px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>   fn query(_: fn(Box&lt;(dyn Any + Send + '_)&gt;) -&gt; Pin&lt;Box&lt;(</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-014 bold">_-</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-014 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-014 bold">_-</tspan>
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     dyn Future&lt;Output = Result&lt;Box&lt;(dyn Any + 'static)&gt;, String&gt;&gt; + Send + 'static</tspan>
 </tspan>
     <tspan x="10px" y="316px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> )&gt;&gt;) {}</tspan>
 </tspan>
-    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan class="fg-ansi256-014 bold">|___-</tspan>
+    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|___-</tspan>
 </tspan>
     <tspan x="10px" y="352px">
 </tspan>
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
index 26210fade74..c0fb98555ad 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
@@ -29,7 +29,7 @@
 </tspan>
     <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> fn short(foo_bar: &amp;Vec&lt;&amp;i32&gt;) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>                  </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>                   </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -53,13 +53,13 @@
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     foo_bar: &amp;Vec&lt;&amp;i32&gt;,</tspan>
 </tspan>
-    <tspan x="10px" y="316px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>             </tspan><tspan class="fg-ansi256-012 bold">----------</tspan>
+    <tspan x="10px" y="316px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>              </tspan><tspan class="fg-ansi256-012 bold">----------</tspan>
 </tspan>
     <tspan x="10px" y="334px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
 </tspan>
     <tspan x="10px" y="352px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> ) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="370px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="370px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>      </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="388px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -73,7 +73,7 @@
 </tspan>
     <tspan x="10px" y="478px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~ </tspan><tspan>    foo_bar: &amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>Vec&lt;&amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>i32&gt;,</tspan>
 </tspan>
-    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>    something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
+    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
 </tspan>
     <tspan x="10px" y="514px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~ </tspan><tspan>) -&gt; &amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>i32 {</tspan>
 </tspan>
@@ -89,7 +89,7 @@
 </tspan>
     <tspan x="10px" y="622px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     foo_bar: &amp;Vec&lt;&amp;i32&gt;) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="640px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">| </tspan><tspan>             </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="640px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>              </tspan><tspan class="fg-ansi256-012 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="658px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
index 3fa9cc18f0d..61b544001f0 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
@@ -29,7 +29,7 @@
 </tspan>
     <tspan x="10px" y="82px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> fn short(foo_bar: &amp;Vec&lt;&amp;i32&gt;) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>                  </tspan><tspan class="fg-ansi256-014 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>                   </tspan><tspan class="fg-ansi256-014 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -53,13 +53,13 @@
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     foo_bar: &amp;Vec&lt;&amp;i32&gt;,</tspan>
 </tspan>
-    <tspan x="10px" y="316px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>             </tspan><tspan class="fg-ansi256-014 bold">----------</tspan>
+    <tspan x="10px" y="316px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>              </tspan><tspan class="fg-ansi256-014 bold">----------</tspan>
 </tspan>
     <tspan x="10px" y="334px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
 </tspan>
     <tspan x="10px" y="352px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> ) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="370px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="370px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>      </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="388px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
@@ -73,7 +73,7 @@
 </tspan>
     <tspan x="10px" y="478px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~ </tspan><tspan>    foo_bar: &amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>Vec&lt;&amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>i32&gt;,</tspan>
 </tspan>
-    <tspan x="10px" y="496px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>    something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
+    <tspan x="10px" y="496px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     something_very_long_so_that_the_line_will_wrap_around__________: i32,</tspan>
 </tspan>
     <tspan x="10px" y="514px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-010">~ </tspan><tspan>) -&gt; &amp;</tspan><tspan class="fg-ansi256-010">'a </tspan><tspan>i32 {</tspan>
 </tspan>
@@ -89,7 +89,7 @@
 </tspan>
     <tspan x="10px" y="622px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     foo_bar: &amp;Vec&lt;&amp;i32&gt;) -&gt; &amp;i32 {</tspan>
 </tspan>
-    <tspan x="10px" y="640px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">| </tspan><tspan>             </tspan><tspan class="fg-ansi256-014 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
+    <tspan x="10px" y="640px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>              </tspan><tspan class="fg-ansi256-014 bold">----------</tspan><tspan>     </tspan><tspan class="fg-ansi256-009 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected named lifetime parameter</tspan>
 </tspan>
     <tspan x="10px" y="658px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs
index 83366ea02b0..eea6a21ce27 100644
--- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs
+++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs
@@ -3,7 +3,7 @@
 use std::cell::Cell;
 
 trait Trait{
-    fn cell(self: Cell<&Self>); //~ ERROR invalid `self` parameter type: Cell<&Self>
+    fn cell(self: Cell<&Self>); //~ ERROR invalid `self` parameter type: `Cell<&Self>`
 }
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
index e727b69ffce..2150effc3b7 100644
--- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
+++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
@@ -1,4 +1,4 @@
-error[E0307]: invalid `self` parameter type: Cell<&Self>
+error[E0307]: invalid `self` parameter type: `Cell<&Self>`
   --> $DIR/feature-gate-dispatch-from-dyn-cell.rs:6:19
    |
 LL |     fn cell(self: Cell<&Self>);
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
index 815013733a9..9bab366f7fe 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:7:1
+  --> $DIR/feature-gate-optimize_attribute.rs:4:1
    |
 LL | #[optimize(size)]
    | ^^^^^^^^^^^^^^^^^
@@ -9,30 +9,30 @@ LL | #[optimize(size)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:10:1
+  --> $DIR/feature-gate-optimize_attribute.rs:7:1
    |
-LL | #[optimize(speed)]
-   | ^^^^^^^^^^^^^^^^^^
+LL | #[optimize(size)]
+   | ^^^^^^^^^^^^^^^^^
    |
    = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
    = help: add `#![feature(optimize_attribute)]` 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]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:13:1
+  --> $DIR/feature-gate-optimize_attribute.rs:10:1
    |
-LL | #[optimize(banana)]
-   | ^^^^^^^^^^^^^^^^^^^
+LL | #[optimize(speed)]
+   | ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
    = help: add `#![feature(optimize_attribute)]` 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]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:4:1
+  --> $DIR/feature-gate-optimize_attribute.rs:13:1
    |
-LL | #[optimize(size)]
-   | ^^^^^^^^^^^^^^^^^
+LL | #[optimize(banana)]
+   | ^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr b/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr
index 677fef3a926..e4cc088e2cd 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr
@@ -1,4 +1,10 @@
 error[E0734]: stability attributes may not be used outside of the standard library
+  --> $DIR/issue-43106-gating-of-stable.rs:10:1
+   |
+LL | #[stable()]
+   | ^^^^^^^^^^^
+
+error[E0734]: stability attributes may not be used outside of the standard library
   --> $DIR/issue-43106-gating-of-stable.rs:14:9
    |
 LL |         #![stable()]
@@ -29,12 +35,6 @@ LL |     #[stable()]
    |     ^^^^^^^^^^^
 
 error[E0734]: stability attributes may not be used outside of the standard library
-  --> $DIR/issue-43106-gating-of-stable.rs:10:1
-   |
-LL | #[stable()]
-   | ^^^^^^^^^^^
-
-error[E0734]: stability attributes may not be used outside of the standard library
   --> $DIR/issue-43106-gating-of-stable.rs:7:1
    |
 LL | #![stable()]
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr b/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr
index a2f361878c6..f7c6e631cd1 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr
@@ -1,4 +1,10 @@
 error[E0734]: stability attributes may not be used outside of the standard library
+  --> $DIR/issue-43106-gating-of-unstable.rs:10:1
+   |
+LL | #[unstable()]
+   | ^^^^^^^^^^^^^
+
+error[E0734]: stability attributes may not be used outside of the standard library
   --> $DIR/issue-43106-gating-of-unstable.rs:14:9
    |
 LL |         #![unstable()]
@@ -29,12 +35,6 @@ LL |     #[unstable()]
    |     ^^^^^^^^^^^^^
 
 error[E0734]: stability attributes may not be used outside of the standard library
-  --> $DIR/issue-43106-gating-of-unstable.rs:10:1
-   |
-LL | #[unstable()]
-   | ^^^^^^^^^^^^^
-
-error[E0734]: stability attributes may not be used outside of the standard library
   --> $DIR/issue-43106-gating-of-unstable.rs:7:1
    |
 LL | #![unstable()]
diff --git a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs
new file mode 100644
index 00000000000..dc4dc9e220d
--- /dev/null
+++ b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs
@@ -0,0 +1,29 @@
+// issue: rust-lang/rust#112347
+// ICE future has no bound vars
+//@ edition:2021
+//@ check-pass
+
+#![feature(type_alias_impl_trait)]
+
+use std::future::Future;
+
+type Fut<'a> = impl Future<Output = ()> + 'a;
+
+fn foo<'a>(_: &()) -> Fut<'_> {
+    async {}
+}
+
+trait Test {
+    fn hello();
+}
+
+impl Test for ()
+where
+    for<'a> Fut<'a>: Future<Output = ()>,
+{
+    fn hello() {}
+}
+
+fn main() {
+    <()>::hello();
+}
diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr
index fe58eb97b8d..293c2a60d80 100644
--- a/tests/ui/imports/issue-59764.stderr
+++ b/tests/ui/imports/issue-59764.stderr
@@ -208,9 +208,9 @@ LL |                 makro as foobar}
 help: a macro with this name exists at the root of the crate
    |
 LL ~         issue_59764::{makro as foobar, 
-LL | 
+LL |
  ...
-LL | 
+LL |
 LL ~             foo::{baz}
    |
 
diff --git a/tests/ui/instrument-coverage/coverage-options.bad.stderr b/tests/ui/instrument-coverage/coverage-options.bad.stderr
index f6e5421f878..9e2c19e90d5 100644
--- a/tests/ui/instrument-coverage/coverage-options.bad.stderr
+++ b/tests/ui/instrument-coverage/coverage-options.bad.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `bad` for unstable option `coverage-options` - either  `no-branch`, `branch` or `mcdc` was expected
+error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `mcdc` was expected
 
diff --git a/tests/ui/instrument-coverage/coverage-options.rs b/tests/ui/instrument-coverage/coverage-options.rs
index 50c01ed29b5..332da32e435 100644
--- a/tests/ui/instrument-coverage/coverage-options.rs
+++ b/tests/ui/instrument-coverage/coverage-options.rs
@@ -1,20 +1,17 @@
 //@ needs-profiler-support
-//@ revisions: branch no-branch bad
+//@ revisions: block branch bad
 //@ compile-flags -Cinstrument-coverage
 
+//@ [block] check-pass
+//@ [block] compile-flags: -Zcoverage-options=block
+
 //@ [branch] check-pass
 //@ [branch] compile-flags: -Zcoverage-options=branch
 
-//@ [no-branch] check-pass
-//@ [no-branch] compile-flags: -Zcoverage-options=no-branch
-
 //@ [mcdc] check-pass
 //@ [mcdc] compile-flags: -Zcoverage-options=mcdc
 
 //@ [bad] check-fail
 //@ [bad] compile-flags: -Zcoverage-options=bad
 
-//@ [conflict] check-fail
-//@ [conflict] compile-flags: -Zcoverage-options=no-branch,mcdc
-
 fn main() {}
diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/issues/issue-22644.stderr
index 0799e9ef11b..7d8a0ff170a 100644
--- a/tests/ui/issues/issue-22644.stderr
+++ b/tests/ui/issues/issue-22644.stderr
@@ -63,9 +63,9 @@ LL |                    5);
 help: try comparing the cast value
    |
 LL ~     println!("{}", (a
-LL | 
+LL |
  ...
-LL | 
+LL |
 LL ~                    usize)
    |
 
diff --git a/tests/ui/issues/issue-43250.stderr b/tests/ui/issues/issue-43250.stderr
index f729c5cf10c..e74342b85ad 100644
--- a/tests/ui/issues/issue-43250.stderr
+++ b/tests/ui/issues/issue-43250.stderr
@@ -3,12 +3,16 @@ error: arbitrary expressions aren't allowed in patterns
    |
 LL |     m!(y);
    |        ^
+   |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
 
 error: arbitrary expressions aren't allowed in patterns
   --> $DIR/issue-43250.rs:11:8
    |
 LL |     m!(C);
    |        ^
+   |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/issues/issue-56806.stderr
index f3d4c2fef94..ec50d863758 100644
--- a/tests/ui/issues/issue-56806.stderr
+++ b/tests/ui/issues/issue-56806.stderr
@@ -1,4 +1,4 @@
-error[E0307]: invalid `self` parameter type: Box<(dyn Trait + 'static)>
+error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>`
   --> $DIR/issue-56806.rs:2:34
    |
 LL |     fn dyn_instead_of_self(self: Box<dyn Trait>);
diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs
new file mode 100644
index 00000000000..2b93d0f8a60
--- /dev/null
+++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs
@@ -0,0 +1,22 @@
+// Regression test for issue 123710.
+// Tests that the we do not ICE in KnownPanicsLint
+// when a union contains an enum with an repr(packed),
+// which is a repr not supported for enums
+
+#[repr(packed)]
+//~^ ERROR attribute should be applied to a struct or union
+#[repr(u32)]
+enum E {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    union InvalidTag {
+        int: u32,
+        e: E,
+//~^ ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+    }
+    let _invalid_tag = InvalidTag { int: 4 };
+}
diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr
new file mode 100644
index 00000000000..44dde6120e8
--- /dev/null
+++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr
@@ -0,0 +1,29 @@
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:6:8
+   |
+LL |   #[repr(packed)]
+   |          ^^^^^^
+...
+LL | / enum E {
+LL | |     A,
+LL | |     B,
+LL | |     C,
+LL | | }
+   | |_- not a struct or union
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:18:9
+   |
+LL |         e: E,
+   |         ^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |         e: std::mem::ManuallyDrop<E>,
+   |            +++++++++++++++++++++++ +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0517, E0740.
+For more information about an error, try `rustc --explain E0517`.
diff --git a/tests/ui/lint/non-local-defs/module_as_local.rs b/tests/ui/lint/non-local-defs/module_as_local.rs
new file mode 100644
index 00000000000..bb215026c7d
--- /dev/null
+++ b/tests/ui/lint/non-local-defs/module_as_local.rs
@@ -0,0 +1,38 @@
+//! This test checks that module are treated as if they were local
+//!
+//! https://github.com/rust-lang/rust/issues/124396
+
+//@ check-pass
+
+trait JoinTo {}
+
+fn simple_one() {
+    mod posts {
+        #[allow(non_camel_case_types)]
+        pub struct table {}
+    }
+
+    impl JoinTo for posts::table {}
+}
+
+fn simple_two() {
+    mod posts {
+        pub mod posts {
+            #[allow(non_camel_case_types)]
+            pub struct table {}
+        }
+    }
+
+    impl JoinTo for posts::posts::table {}
+}
+
+struct Global;
+fn trait_() {
+    mod posts {
+        pub trait AdjecentTo {}
+    }
+
+    impl posts::AdjecentTo for Global {}
+}
+
+fn main() {}
diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr
index 16fb1682d4a..acc36550642 100644
--- a/tests/ui/lint/use_suggestion_json.stderr
+++ b/tests/ui/lint/use_suggestion_json.stderr
@@ -384,7 +384,7 @@ mod foo {
 \u001b[0m  \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m
 \u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
 \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m    let x: Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m           \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m
+\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m            \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m
 \u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
 \u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these items\u001b[0m
 \u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.rs b/tests/ui/lowering/expr-in-pat-issue-99380.rs
new file mode 100644
index 00000000000..1d4a047f717
--- /dev/null
+++ b/tests/ui/lowering/expr-in-pat-issue-99380.rs
@@ -0,0 +1,11 @@
+macro_rules! foo {
+    ($p:expr) => {
+        if let $p = Some(42) {
+            return;
+        }
+    };
+}
+
+fn main() {
+    foo!(Some(3)); //~ ERROR arbitrary expressions aren't allowed in patterns
+}
diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.stderr b/tests/ui/lowering/expr-in-pat-issue-99380.stderr
new file mode 100644
index 00000000000..29438c9b063
--- /dev/null
+++ b/tests/ui/lowering/expr-in-pat-issue-99380.stderr
@@ -0,0 +1,10 @@
+error: arbitrary expressions aren't allowed in patterns
+  --> $DIR/expr-in-pat-issue-99380.rs:10:10
+   |
+LL |     foo!(Some(3));
+   |          ^^^^^^^
+   |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/macros/issue-118048.stderr b/tests/ui/macros/issue-118048.stderr
index 6acf78f63b2..4dc5ef71fec 100644
--- a/tests/ui/macros/issue-118048.stderr
+++ b/tests/ui/macros/issue-118048.stderr
@@ -12,7 +12,7 @@ help: use type parameters instead
 LL ~         fn foo<T>(_: $ty, _: $ty) {}
 LL |     }
 LL | }
-LL | 
+LL |
 LL ~ foo!(T);
    |
 
diff --git a/tests/ui/macros/vec-macro-in-pattern.stderr b/tests/ui/macros/vec-macro-in-pattern.stderr
index 447f5dcf864..1a446b8c3ed 100644
--- a/tests/ui/macros/vec-macro-in-pattern.stderr
+++ b/tests/ui/macros/vec-macro-in-pattern.stderr
@@ -4,6 +4,7 @@ error: arbitrary expressions aren't allowed in patterns
 LL |         Some(vec![43]) => {}
    |              ^^^^^^^^
    |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr
index 57a2d2b26cf..1657c51545c 100644
--- a/tests/ui/match/expr_before_ident_pat.stderr
+++ b/tests/ui/match/expr_before_ident_pat.stderr
@@ -9,6 +9,8 @@ error: arbitrary expressions aren't allowed in patterns
    |
 LL |     funny!(a, a);
    |            ^
+   |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index 7d9b38fb29b..5a76449e9f9 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -55,7 +55,7 @@ LL | /     y.zero()
 LL | |      .take()
    | |      -^^^^ `Foo` is not an iterator
    | |______|
-   | 
+   |
    |
    = note: the following trait bounds were not satisfied:
            `Foo: Iterator`
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs
new file mode 100644
index 00000000000..0ae498c134f
--- /dev/null
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs
@@ -0,0 +1,141 @@
+//@ check-pass
+use std::{marker, mem, ptr};
+
+fn main() {}
+
+fn _zero() {
+    if false {
+        unsafe { mem::zeroed() }
+        //~^ warn: never type fallback affects this call to an `unsafe` function
+    } else {
+        return;
+    };
+
+    // no ; -> type is inferred without fallback
+    if true { unsafe { mem::zeroed() } } else { return }
+}
+
+fn _trans() {
+    if false {
+        unsafe {
+            struct Zst;
+            core::mem::transmute(Zst)
+            //~^ warn: never type fallback affects this call to an `unsafe` function
+        }
+    } else {
+        return;
+    };
+}
+
+fn _union() {
+    if false {
+        union Union<T: Copy> {
+            a: (),
+            b: T,
+        }
+
+        unsafe { Union { a: () }.b }
+        //~^ warn: never type fallback affects this union access
+    } else {
+        return;
+    };
+}
+
+fn _deref() {
+    if false {
+        unsafe { *ptr::from_ref(&()).cast() }
+        //~^ warn: never type fallback affects this raw pointer dereference
+    } else {
+        return;
+    };
+}
+
+fn _only_generics() {
+    if false {
+        unsafe fn internally_create<T>(_: Option<T>) {
+            let _ = mem::zeroed::<T>();
+        }
+
+        // We need the option (and unwrap later) to call a function in a way,
+        // which makes it affected by the fallback, but without having it return anything
+        let x = None;
+
+        unsafe { internally_create(x) }
+        //~^ warn: never type fallback affects this call to an `unsafe` function
+
+        x.unwrap()
+    } else {
+        return;
+    };
+}
+
+fn _stored_function() {
+    if false {
+        let zeroed = mem::zeroed;
+        //~^ warn: never type fallback affects this `unsafe` function
+
+        unsafe { zeroed() }
+        //~^ warn: never type fallback affects this call to an `unsafe` function
+    } else {
+        return;
+    };
+}
+
+fn _only_generics_stored_function() {
+    if false {
+        unsafe fn internally_create<T>(_: Option<T>) {
+            let _ = mem::zeroed::<T>();
+        }
+
+        let x = None;
+        let f = internally_create;
+        //~^ warn: never type fallback affects this `unsafe` function
+
+        unsafe { f(x) }
+
+        x.unwrap()
+    } else {
+        return;
+    };
+}
+
+fn _method() {
+    struct S<T>(marker::PhantomData<T>);
+
+    impl<T> S<T> {
+        #[allow(unused)] // FIXME: the unused lint is probably incorrect here
+        unsafe fn create_out_of_thin_air(&self) -> T {
+            todo!()
+        }
+    }
+
+    if false {
+        unsafe {
+            S(marker::PhantomData).create_out_of_thin_air()
+            //~^ warn: never type fallback affects this call to an `unsafe` method
+        }
+    } else {
+        return;
+    };
+}
+
+// Minimization of the famous `objc` crate issue
+fn _objc() {
+    pub unsafe fn send_message<R>() -> Result<R, ()> {
+        Ok(unsafe { core::mem::zeroed() })
+    }
+
+    macro_rules! msg_send {
+        () => {
+            match send_message::<_ /* ?0 */>() {
+                //~^ warn: never type fallback affects this call to an `unsafe` function
+                Ok(x) => x,
+                Err(_) => loop {},
+            }
+        };
+    }
+
+    unsafe {
+        msg_send!();
+    }
+}
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr
new file mode 100644
index 00000000000..84c9385fd13
--- /dev/null
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr
@@ -0,0 +1,87 @@
+warning: never type fallback affects this call to an `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:8:18
+   |
+LL |         unsafe { mem::zeroed() }
+   |                  ^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+   = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
+
+warning: never type fallback affects this call to an `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:22:13
+   |
+LL |             core::mem::transmute(Zst)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this union access
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:37:18
+   |
+LL |         unsafe { Union { a: () }.b }
+   |                  ^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this raw pointer dereference
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18
+   |
+LL |         unsafe { *ptr::from_ref(&()).cast() }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this call to an `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:63:18
+   |
+LL |         unsafe { internally_create(x) }
+   |                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this call to an `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:77:18
+   |
+LL |         unsafe { zeroed() }
+   |                  ^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:74:22
+   |
+LL |         let zeroed = mem::zeroed;
+   |                      ^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:17
+   |
+LL |         let f = internally_create;
+   |                 ^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this call to an `unsafe` method
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:13
+   |
+LL |             S(marker::PhantomData).create_out_of_thin_air()
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: specify the type explicitly
+
+warning: never type fallback affects this call to an `unsafe` function
+  --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:130:19
+   |
+LL |             match send_message::<_ /* ?0 */>() {
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |         msg_send!();
+   |         ----------- in this macro invocation
+   |
+   = help: specify the type explicitly
+   = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 10 warnings emitted
+
diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr
index 753ba809e7d..adfd16c6f2b 100644
--- a/tests/ui/offset-of/offset-of-dst-field.stderr
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -34,20 +34,6 @@ LL |     offset_of!((u8, dyn Trait), 1);
    = help: the trait `Sized` is not implemented for `dyn Trait`
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/offset-of-dst-field.rs:44:5
-   |
-LL |     offset_of!(Delta<Alpha>, z);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]`, which is required by `Alpha: Sized`
-note: required because it appears within the type `Alpha`
-  --> $DIR/offset-of-dst-field.rs:5:8
-   |
-LL | struct Alpha {
-   |        ^^^^^
-   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error[E0277]: the size for values of type `Extern` cannot be known at compilation time
   --> $DIR/offset-of-dst-field.rs:45:5
    |
@@ -66,6 +52,20 @@ LL |     offset_of!(Delta<dyn Trait>, z);
    = help: the trait `Sized` is not implemented for `dyn Trait`
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:44:5
+   |
+LL |     offset_of!(Delta<Alpha>, z);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]`, which is required by `Alpha: Sized`
+note: required because it appears within the type `Alpha`
+  --> $DIR/offset-of-dst-field.rs:5:8
+   |
+LL | struct Alpha {
+   |        ^^^^^
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/offset-of-dst-field.rs:50:5
    |
diff --git a/tests/ui/offset-of/offset-of-must-use.rs b/tests/ui/offset-of/offset-of-must-use.rs
index f0c242891d8..87918b8ff95 100644
--- a/tests/ui/offset-of/offset-of-must-use.rs
+++ b/tests/ui/offset-of/offset-of-must-use.rs
@@ -4,5 +4,5 @@
 
 fn main() {
     core::mem::offset_of!((String,), 0);
-    //~^ WARN unused return value of `must_use` that must be used
+    //~^ WARN unused `offset_of` call that must be used
 }
diff --git a/tests/ui/offset-of/offset-of-must-use.stderr b/tests/ui/offset-of/offset-of-must-use.stderr
index b6d88e098d0..9f0e37a59f4 100644
--- a/tests/ui/offset-of/offset-of-must-use.stderr
+++ b/tests/ui/offset-of/offset-of-must-use.stderr
@@ -1,8 +1,8 @@
-warning: unused return value of `must_use` that must be used
+warning: unused `offset_of` call that must be used
   --> $DIR/offset-of-must-use.rs:6:5
    |
 LL |     core::mem::offset_of!((String,), 0);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `offset_of` call produces a value
    |
 note: the lint level is defined here
   --> $DIR/offset-of-must-use.rs:3:9
diff --git a/tests/ui/offset-of/offset-of-temporaries.rs b/tests/ui/offset-of/offset-of-temporaries.rs
new file mode 100644
index 00000000000..951a8ee2b50
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-temporaries.rs
@@ -0,0 +1,23 @@
+//@ build-pass
+
+//! Regression test #124478.
+
+use std::mem::offset_of;
+
+struct S {
+    v: u8,
+    w: u16,
+}
+
+impl S {
+    fn return_static_slice() -> &'static [usize] {
+        &[offset_of!(Self, v), offset_of!(Self, w)]
+    }
+    fn use_reference() -> usize {
+        let r = &offset_of!(Self, v);
+        *r * 6
+    }
+}
+
+fn main() {
+}
diff --git a/tests/ui/parser/issues/issue-32505.stderr b/tests/ui/parser/issues/issue-32505.stderr
index 27ad2c3e5be..0eaa5efd525 100644
--- a/tests/ui/parser/issues/issue-32505.stderr
+++ b/tests/ui/parser/issues/issue-32505.stderr
@@ -9,7 +9,7 @@ LL |     foo(|_|)
 help: you might have meant to open the body of the closure
    |
 LL |     foo(|_| {})
-   |            ++
+   |             ++
 
 error[E0425]: cannot find function `foo` in this scope
   --> $DIR/issue-32505.rs:2:5
diff --git a/tests/ui/pattern/issue-92074-macro-ice.stderr b/tests/ui/pattern/issue-92074-macro-ice.stderr
index b340afff010..025592116e5 100644
--- a/tests/ui/pattern/issue-92074-macro-ice.stderr
+++ b/tests/ui/pattern/issue-92074-macro-ice.stderr
@@ -7,6 +7,7 @@ LL |     () => { force_expr!(Vec::new()) }
 LL |     assert!(matches!(x, En::A(make_vec!())));
    |                               ----------- in this macro invocation
    |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
    = note: this error originates in the macro `make_vec` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: arbitrary expressions aren't allowed in patterns
@@ -18,6 +19,7 @@ LL |     () => { force_pat!(get_usize(), get_usize()) }
 LL |     assert!(matches!(5, make_pat!()));
    |                         ----------- in this macro invocation
    |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
    = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: arbitrary expressions aren't allowed in patterns
@@ -29,6 +31,7 @@ LL |     () => { force_pat!(get_usize(), get_usize()) }
 LL |     assert!(matches!(5, make_pat!()));
    |                         ----------- in this macro invocation
    |
+   = note: the `expr` fragment specifier forces the metavariable's content to be an expression
    = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs
index c73b8d7e4d2..de002ef71d7 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs
@@ -1,4 +1,6 @@
 //@ only-x86_64
+// Set the base cpu explicitly, in case the default has been changed.
+//@ compile-flags: -C target-cpu=x86-64
 
 #![feature(target_feature_11)]
 
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
index d9d7e297f8e..aa660db3867 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:25:5
+  --> $DIR/safe-calls.rs:27:5
    |
 LL |     sse2();
    |     ^^^^^^ call to function with `#[target_feature]`
@@ -8,7 +8,7 @@ LL |     sse2();
    = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
 
 error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:27:5
+  --> $DIR/safe-calls.rs:29:5
    |
 LL |     avx_bmi2();
    |     ^^^^^^^^^^ call to function with `#[target_feature]`
@@ -16,7 +16,7 @@ LL |     avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
 
 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:29:5
+  --> $DIR/safe-calls.rs:31:5
    |
 LL |     Quux.avx_bmi2();
    |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@@ -24,7 +24,7 @@ LL |     Quux.avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
 
 error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:35:5
+  --> $DIR/safe-calls.rs:37:5
    |
 LL |     avx_bmi2();
    |     ^^^^^^^^^^ call to function with `#[target_feature]`
@@ -32,7 +32,7 @@ LL |     avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
 
 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:37:5
+  --> $DIR/safe-calls.rs:39:5
    |
 LL |     Quux.avx_bmi2();
    |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@@ -40,7 +40,7 @@ LL |     Quux.avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
 
 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:43:5
+  --> $DIR/safe-calls.rs:45:5
    |
 LL |     sse2();
    |     ^^^^^^ call to function with `#[target_feature]`
@@ -49,7 +49,7 @@ LL |     sse2();
    = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
 
 error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:45:5
+  --> $DIR/safe-calls.rs:47:5
    |
 LL |     avx_bmi2();
    |     ^^^^^^^^^^ call to function with `#[target_feature]`
@@ -57,7 +57,7 @@ LL |     avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
 
 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:47:5
+  --> $DIR/safe-calls.rs:49:5
    |
 LL |     Quux.avx_bmi2();
    |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@@ -65,7 +65,7 @@ LL |     Quux.avx_bmi2();
    = help: in order for the call to be safe, the context requires the following additional target feature: bmi2
 
 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:54:5
+  --> $DIR/safe-calls.rs:56:5
    |
 LL |     sse2();
    |     ^^^^^^ call to function with `#[target_feature]`
@@ -74,7 +74,7 @@ LL |     sse2();
    = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
 
 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:58:15
+  --> $DIR/safe-calls.rs:60:15
    |
 LL | const _: () = sse2();
    |               ^^^^^^ call to function with `#[target_feature]`
@@ -83,7 +83,7 @@ LL | const _: () = sse2();
    = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
 
 error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
-  --> $DIR/safe-calls.rs:61:15
+  --> $DIR/safe-calls.rs:63:15
    |
 LL | const _: () = sse2_and_fxsr();
    |               ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
@@ -92,7 +92,7 @@ LL | const _: () = sse2_and_fxsr();
    = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
 
 error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
-  --> $DIR/safe-calls.rs:68:5
+  --> $DIR/safe-calls.rs:70:5
    |
 LL |     sse2();
    |     ^^^^^^ call to function with `#[target_feature]`
@@ -101,12 +101,12 @@ LL |     sse2();
    = help: in order for the call to be safe, the context requires the following additional target feature: sse2
    = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
 note: an unsafe function restricts its caller, but its body is safe by default
-  --> $DIR/safe-calls.rs:67:1
+  --> $DIR/safe-calls.rs:69:1
    |
 LL | unsafe fn needs_unsafe_block() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the lint level is defined here
-  --> $DIR/safe-calls.rs:64:8
+  --> $DIR/safe-calls.rs:66:8
    |
 LL | #[deny(unsafe_op_in_unsafe_fn)]
    |        ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
index 5ff3cd25e67..402efaf5027 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
@@ -1,7 +1,5 @@
 // Tests that dlltool failing to generate an import library will raise an error.
 
-//@ only-gnu
-//@ only-windows
 //@ needs-dlltool
 //@ compile-flags: --crate-type lib --emit link
 //@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL"
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
index ac6a2998a47..bcf6dda7a44 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
@@ -1,7 +1,6 @@
 // Tests that failing to run dlltool will raise an error.
 
-//@ only-gnu
-//@ only-windows
+//@ needs-dlltool
 //@ compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe
 #[link(name = "foo", kind = "raw-dylib")]
 extern "C" {
diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs
index 99357dde3e1..3331b037b05 100644
--- a/tests/ui/self/arbitrary-self-opaque.rs
+++ b/tests/ui/self/arbitrary-self-opaque.rs
@@ -6,7 +6,7 @@ type Bar = impl Sized;
 
 impl Foo {
     fn foo(self: Bar) {}
-    //~^ ERROR: invalid `self` parameter type: Bar
+    //~^ ERROR: invalid `self` parameter type: `Bar`
 }
 
 fn main() {}
diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr
index 6b5db8d8493..0cbe22afac3 100644
--- a/tests/ui/self/arbitrary-self-opaque.stderr
+++ b/tests/ui/self/arbitrary-self-opaque.stderr
@@ -6,7 +6,7 @@ LL | type Bar = impl Sized;
    |
    = note: `Bar` must be used in combination with a concrete type within the same module
 
-error[E0307]: invalid `self` parameter type: Bar
+error[E0307]: invalid `self` parameter type: `Bar`
   --> $DIR/arbitrary-self-opaque.rs:8:18
    |
 LL |     fn foo(self: Bar) {}
diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr
index c2de1562841..c57a100bbe2 100644
--- a/tests/ui/span/issue-27522.stderr
+++ b/tests/ui/span/issue-27522.stderr
@@ -1,4 +1,4 @@
-error[E0307]: invalid `self` parameter type: &SomeType
+error[E0307]: invalid `self` parameter type: `&SomeType`
   --> $DIR/issue-27522.rs:6:22
    |
 LL |     fn handler(self: &SomeType);
diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr
index 708c0817fd9..a69826fa96b 100644
--- a/tests/ui/specialization/specialization-overlap-projection.stderr
+++ b/tests/ui/specialization/specialization-overlap-projection.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/specialization-overlap-projection.rs:7:12
+  --> $DIR/specialization-overlap-projection.rs:10:12
    |
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr
new file mode 100644
index 00000000000..ab040193fa4
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-projection.next.stderr
@@ -0,0 +1,49 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/specialization-overlap-projection.rs:10:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:28:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+LL | impl Foo for <u8 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:30:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+...
+LL | impl Foo for <u16 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error[E0282]: type annotations needed
+  --> $DIR/specialization-overlap-projection.rs:17:27
+   |
+LL |     default type Output = bool;
+   |                           ^^^^ cannot infer type for associated type `<T as Assoc>::Output`
+
+error[E0282]: type annotations needed
+  --> $DIR/specialization-overlap-projection.rs:21:35
+   |
+LL | impl Assoc for u8 { type Output = u8; }
+   |                                   ^^ cannot infer type for associated type `<u8 as Assoc>::Output`
+
+error[E0282]: type annotations needed
+  --> $DIR/specialization-overlap-projection.rs:23:36
+   |
+LL | impl Assoc for u16 { type Output = u16; }
+   |                                    ^^^ cannot infer type for associated type `<u16 as Assoc>::Output`
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0119, E0282.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs
index 66951b9d50c..78e75f623c4 100644
--- a/tests/ui/specialization/specialization-overlap-projection.rs
+++ b/tests/ui/specialization/specialization-overlap-projection.rs
@@ -1,4 +1,7 @@
-//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@[current] check-pass
 
 // Test that impls on projected self types can resolve overlap, even when the
 // projections involve specialization, so long as the associated type is
@@ -12,14 +15,19 @@ trait Assoc {
 
 impl<T> Assoc for T {
     default type Output = bool;
+    //[next]~^ ERROR type annotations needed
 }
 
 impl Assoc for u8 { type Output = u8; }
+//[next]~^ ERROR type annotations needed
 impl Assoc for u16 { type Output = u16; }
+//[next]~^ ERROR type annotations needed
 
 trait Foo {}
 impl Foo for u32 {}
 impl Foo for <u8 as Assoc>::Output {}
+//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32`
 impl Foo for <u16 as Assoc>::Output {}
+//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32`
 
 fn main() {}
diff --git a/tests/ui/sse2.rs b/tests/ui/sse2.rs
index fa6d79713b4..60570c566de 100644
--- a/tests/ui/sse2.rs
+++ b/tests/ui/sse2.rs
@@ -19,7 +19,7 @@ fn main() {
         assert!(cfg!(target_feature = "sse2"),
                 "SSE2 was not detected as available on an x86 platform");
     }
-    // check a negative case too -- allowed on x86, but not enabled by default
-    assert!(cfg!(not(target_feature = "avx2")),
-            "AVX2 shouldn't be detected as available by default on any platform");
+    // check a negative case too -- certainly not enabled by default
+    assert!(cfg!(not(target_feature = "ferris_wheel")),
+            "🎡 shouldn't be detected as available by default on any platform");
 }
diff --git a/tests/ui/statics/nested_struct.rs b/tests/ui/statics/nested_struct.rs
index f5819f50789..6745e102962 100644
--- a/tests/ui/statics/nested_struct.rs
+++ b/tests/ui/statics/nested_struct.rs
@@ -9,7 +9,7 @@ pub struct Lint {
     pub name: &'static str,
     pub desc: &'static str,
     pub report_in_external_macro: bool,
-    pub is_loaded: bool,
+    pub is_externally_loaded: bool,
     pub crate_level_only: bool,
 }
 
@@ -17,7 +17,7 @@ static FOO: &Lint = &Lint {
     name: &"foo",
     desc: "desc",
     report_in_external_macro: false,
-    is_loaded: true,
+    is_externally_loaded: true,
     crate_level_only: false,
 };
 
diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr
index dc24833c267..1a67c943844 100644
--- a/tests/ui/stats/hir-stats.stderr
+++ b/tests/ui/stats/hir-stats.stderr
@@ -11,15 +11,15 @@ ast-stats-1 Attribute                 64 ( 1.0%)             2            32
 ast-stats-1 - Normal                    32 ( 0.5%)             1
 ast-stats-1 - DocComment                32 ( 0.5%)             1
 ast-stats-1 Local                     80 ( 1.2%)             1            80
-ast-stats-1 Arm                       96 ( 1.4%)             2            48
-ast-stats-1 ForeignItem               96 ( 1.4%)             1            96
-ast-stats-1 - Fn                        96 ( 1.4%)             1
+ast-stats-1 ForeignItem               88 ( 1.3%)             1            88
+ast-stats-1 - Fn                        88 ( 1.3%)             1
+ast-stats-1 Arm                       96 ( 1.5%)             2            48
 ast-stats-1 FnDecl                   120 ( 1.8%)             5            24
 ast-stats-1 FieldDef                 160 ( 2.4%)             2            80
 ast-stats-1 Stmt                     160 ( 2.4%)             5            32
 ast-stats-1 - Let                       32 ( 0.5%)             1
 ast-stats-1 - MacCall                   32 ( 0.5%)             1
-ast-stats-1 - Expr                      96 ( 1.4%)             3
+ast-stats-1 - Expr                      96 ( 1.5%)             3
 ast-stats-1 Param                    160 ( 2.4%)             4            40
 ast-stats-1 Block                    192 ( 2.9%)             6            32
 ast-stats-1 Variant                  208 ( 3.1%)             2           104
@@ -28,7 +28,7 @@ ast-stats-1 - Trait                    352 ( 5.3%)             4
 ast-stats-1 AssocItem                352 ( 5.3%)             4            88
 ast-stats-1 - Type                     176 ( 2.7%)             2
 ast-stats-1 - Fn                       176 ( 2.7%)             2
-ast-stats-1 GenericParam             480 ( 7.2%)             5            96
+ast-stats-1 GenericParam             480 ( 7.3%)             5            96
 ast-stats-1 Pat                      504 ( 7.6%)             7            72
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Wild                      72 ( 1.1%)             1
@@ -53,7 +53,7 @@ ast-stats-1 - Impl                     136 ( 2.1%)             1
 ast-stats-1 - Fn                       272 ( 4.1%)             2
 ast-stats-1 - Use                      408 ( 6.2%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_624
+ast-stats-1 Total                  6_616
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -65,9 +65,9 @@ ast-stats-2 ExprField                 48 ( 0.7%)             1            48
 ast-stats-2 WherePredicate            56 ( 0.8%)             1            56
 ast-stats-2 - BoundPredicate            56 ( 0.8%)             1
 ast-stats-2 Local                     80 ( 1.1%)             1            80
+ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
+ast-stats-2 - Fn                        88 ( 1.2%)             1
 ast-stats-2 Arm                       96 ( 1.3%)             2            48
-ast-stats-2 ForeignItem               96 ( 1.3%)             1            96
-ast-stats-2 - Fn                        96 ( 1.3%)             1
 ast-stats-2 InlineAsm                120 ( 1.7%)             1           120
 ast-stats-2 FnDecl                   120 ( 1.7%)             5            24
 ast-stats-2 Attribute                128 ( 1.8%)             4            32
@@ -86,7 +86,7 @@ ast-stats-2 - Trait                    352 ( 4.9%)             4
 ast-stats-2 AssocItem                352 ( 4.9%)             4            88
 ast-stats-2 - Type                     176 ( 2.4%)             2
 ast-stats-2 - Fn                       176 ( 2.4%)             2
-ast-stats-2 GenericParam             480 ( 6.6%)             5            96
+ast-stats-2 GenericParam             480 ( 6.7%)             5            96
 ast-stats-2 Pat                      504 ( 7.0%)             7            72
 ast-stats-2 - Struct                    72 ( 1.0%)             1
 ast-stats-2 - Wild                      72 ( 1.0%)             1
@@ -113,7 +113,7 @@ ast-stats-2 - Impl                     136 ( 1.9%)             1
 ast-stats-2 - Fn                       272 ( 3.8%)             2
 ast-stats-2 - Use                      544 ( 7.5%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_224
+ast-stats-2 Total                  7_216
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/tests/ui/str/str-escape.stderr b/tests/ui/str/str-escape.stderr
index 00fe5444e1a..c4aee2a110a 100644
--- a/tests/ui/str/str-escape.stderr
+++ b/tests/ui/str/str-escape.stderr
@@ -15,7 +15,7 @@ LL |       let s = c"foo\
 LL | |              bar
    | |   ^ whitespace symbol '\u{a0}' is not skipped
    | |___|
-   | 
+   |
 
 warning: whitespace symbol '\u{c}' is not skipped
   --> $DIR/str-escape.rs:26:16
@@ -25,7 +25,7 @@ LL |       let s = b"a\
 LL | |     b";
    | |    ^- whitespace symbol '\u{c}' is not skipped
    | |____|
-   | 
+   |
 
 warning: 3 warnings emitted
 
diff --git a/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr
index cdf51632acd..e818409366d 100644
--- a/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr
@@ -11,7 +11,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~ struct Baz { q: Option<Box<Foo>> }
 LL |
-LL | 
+LL |
 LL ~ struct Foo { q: Option<Box<Baz>> }
    |
 
diff --git a/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr b/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr
index 881bc281936..afe523939ac 100644
--- a/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr
+++ b/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr
@@ -16,7 +16,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~     y: Box<B<T>>,
 LL | }
-LL | 
+LL |
 LL | struct B<T> {
 LL ~     z: Box<A<T>>
    |
@@ -39,7 +39,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~     y: Option<Option<Box<D<T>>>>,
 LL | }
-LL | 
+LL |
 LL | struct D<T> {
 LL ~     z: Option<Option<Box<C<T>>>>,
    |
diff --git a/tests/ui/suggestions/issue-99240-2.stderr b/tests/ui/suggestions/issue-99240-2.stderr
index 00bffee6529..5b86bc9880f 100644
--- a/tests/ui/suggestions/issue-99240-2.stderr
+++ b/tests/ui/suggestions/issue-99240-2.stderr
@@ -8,7 +8,7 @@ LL | //     Alias::
 LL | ||     Unit();
    | ||________^_- call expression requires function
    |  |________|
-   | 
+   |
    |
 help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed
    |
diff --git a/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
index c0dc71df06e..abbf56cfac8 100644
--- a/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
+++ b/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr
@@ -26,7 +26,7 @@ help: consider changing method `bar`'s `self` parameter to be `&self`
 LL |     fn bar(self: &Self) {}
    |                  ~~~~~
 
-error[E0307]: invalid `self` parameter type: ()
+error[E0307]: invalid `self` parameter type: `()`
   --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18
    |
 LL |     fn bar(self: ()) {}
diff --git a/tests/ui/traits/dyn-any-prefer-vtable.rs b/tests/ui/traits/dyn-any-prefer-vtable.rs
new file mode 100644
index 00000000000..ca9d655239d
--- /dev/null
+++ b/tests/ui/traits/dyn-any-prefer-vtable.rs
@@ -0,0 +1,9 @@
+//@ run-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+fn main() {
+    let x: &dyn std::any::Any = &1i32;
+    assert_eq!(x.type_id(), std::any::TypeId::of::<i32>());
+}
diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs
index 143325c097c..b97835bbc57 100644
--- a/tests/ui/traits/issue-78372.rs
+++ b/tests/ui/traits/issue-78372.rs
@@ -6,7 +6,7 @@ impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U`
 //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
 trait Foo: X<u32> {}
 trait X<T> {
-    fn foo(self: Smaht<Self, T>); //~ ERROR: invalid `self`
+    fn foo(self: Smaht<Self, T>); //~ ERROR: invalid `self` parameter type
 }
 trait Marker {}
 impl Marker for dyn Foo {}
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index edb07957c44..58a4c229e5e 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -79,7 +79,7 @@ LL | trait X<T> {
 LL |     fn foo(self: Smaht<Self, T>);
    |                  ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
 
-error[E0307]: invalid `self` parameter type: Smaht<Self, T>
+error[E0307]: invalid `self` parameter type: `Smaht<Self, T>`
   --> $DIR/issue-78372.rs:9:18
    |
 LL |     fn foo(self: Smaht<Self, T>);
diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs
deleted file mode 100644
index a0fe7f0d0a5..00000000000
--- a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ compile-flags: -Znext-solver
-// FIXME(-Znext-solver): This test is currently broken because the `deduce_closure_signature`
-// is unable to look at nested obligations.
-trait Foo {
-    fn test() -> impl Fn(u32) -> u32 {
-        |x| x.count_ones()
-        //~^ ERROR type annotations needed
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr
deleted file mode 100644
index 3d7cd1af467..00000000000
--- a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed
-  --> $DIR/deduce-closure-signature-after-normalization.rs:6:10
-   |
-LL |         |x| x.count_ones()
-   |          ^  - type must be known at this point
-   |
-help: consider giving this closure parameter an explicit type
-   |
-LL |         |x: /* Type */| x.count_ones()
-   |           ++++++++++++
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr
index 4462b70f782..266a532a1db 100644
--- a/tests/ui/type-alias-impl-trait/coherence.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.stderr
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
    | |                                    |
-   | |                                    `AliasOfForeignType<()>` is not defined in the current crate
+   | |                                    type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
diff --git a/tests/ui/typeck/ice-unexpected-region-123863.rs b/tests/ui/typeck/ice-unexpected-region-123863.rs
new file mode 100644
index 00000000000..d0242df5fd2
--- /dev/null
+++ b/tests/ui/typeck/ice-unexpected-region-123863.rs
@@ -0,0 +1,9 @@
+const fn concat_strs<const A: &'static str>() -> &'static str {
+//~^ ERROR &'static str` is forbidden as the type of a const generic parameter
+    struct Inner<const A: &'static str>;
+//~^ ERROR &'static str` is forbidden as the type of a const generic parameter
+    Inner::concat_strs::<"a">::A
+//~^ ERROR ambiguous associated type
+}
+
+pub fn main() {}
diff --git a/tests/ui/typeck/ice-unexpected-region-123863.stderr b/tests/ui/typeck/ice-unexpected-region-123863.stderr
new file mode 100644
index 00000000000..08f1ede95b4
--- /dev/null
+++ b/tests/ui/typeck/ice-unexpected-region-123863.stderr
@@ -0,0 +1,38 @@
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/ice-unexpected-region-123863.rs:1:31
+   |
+LL | const fn concat_strs<const A: &'static str>() -> &'static str {
+   |                               ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/ice-unexpected-region-123863.rs:3:27
+   |
+LL |     struct Inner<const A: &'static str>;
+   |                           ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ice-unexpected-region-123863.rs:5:5
+   |
+LL |     Inner::concat_strs::<"a">::A
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `concat_strs` implemented for `Inner<_>`, you could use the fully-qualified path
+   |
+LL |     <Inner<_> as Example>::concat_strs::A
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/typeck/issue-100285.stderr b/tests/ui/typeck/issue-100285.stderr
index 9c8685a7712..c0deb63af59 100644
--- a/tests/ui/typeck/issue-100285.stderr
+++ b/tests/ui/typeck/issue-100285.stderr
@@ -49,7 +49,7 @@ LL ~           return Some(4);
 LL |         } else {
 LL ~           return Some(5);
 LL |         }
-LL | 
+LL |
 LL ~     }
 LL ~     None
    |
diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr
index 0983147a5f0..9598bc61352 100644
--- a/tests/ui/typeck/issue-31173.stderr
+++ b/tests/ui/typeck/issue-31173.stderr
@@ -34,7 +34,7 @@ LL | |         .cloned()
 LL | |         .collect();
    | |         -^^^^^^^ method cannot be called due to unsatisfied trait bounds
    | |_________|
-   | 
+   |
    |
    = note: the following trait bounds were not satisfied:
            `<TakeWhile<&mut std::vec::IntoIter<u8>, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_`
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index 7c250775475..c48d094daea 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -15,7 +15,7 @@ LL |     fn dummy2(&self);
    = note: expected signature `fn(&&'a Bar<_>)`
               found signature `fn(&Bar<_>)`
 
-error[E0307]: invalid `self` parameter type: isize
+error[E0307]: invalid `self` parameter type: `isize`
   --> $DIR/ufcs-explicit-self-bad.rs:8:18
    |
 LL |     fn foo(self: isize, x: isize) -> isize {
@@ -24,7 +24,7 @@ LL |     fn foo(self: isize, x: isize) -> isize {
    = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid `self` parameter type: Bar<isize>
+error[E0307]: invalid `self` parameter type: `Bar<isize>`
   --> $DIR/ufcs-explicit-self-bad.rs:19:18
    |
 LL |     fn foo(self: Bar<isize>, x: isize) -> isize {
@@ -33,7 +33,7 @@ LL |     fn foo(self: Bar<isize>, x: isize) -> isize {
    = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid `self` parameter type: &Bar<usize>
+error[E0307]: invalid `self` parameter type: `&Bar<usize>`
   --> $DIR/ufcs-explicit-self-bad.rs:23:18
    |
 LL |     fn bar(self: &Bar<usize>, x: isize) -> isize {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
index b7e9e1baa7b..c0fce5c2aaa 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
@@ -15,7 +15,7 @@ help: consider introducing a named lifetime parameter
 LL ~ fn main<'a>() {
 LL |     eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>,
  ...
-LL | 
+LL |
 LL ~     let _: dyn Foo(&'a isize, &'a usize) -> &'a usize;
    |
 
diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.rs b/tests/ui/unpretty/staged-api-invalid-path-108697.rs
new file mode 100644
index 00000000000..1b6ef249191
--- /dev/null
+++ b/tests/ui/unpretty/staged-api-invalid-path-108697.rs
@@ -0,0 +1,9 @@
+// issue: rust-lang/rust#108697
+// ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir
+// on invalid module path with staged_api
+//@ compile-flags: -Zunpretty=mir
+//@ normalize-stderr-test: "The system cannot find the file specified." -> "No such file or directory"
+#![feature(staged_api)]
+#[path = "lol"]
+mod foo;
+//~^ ERROR couldn't read
diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.stderr b/tests/ui/unpretty/staged-api-invalid-path-108697.stderr
new file mode 100644
index 00000000000..9c6d1a042d7
--- /dev/null
+++ b/tests/ui/unpretty/staged-api-invalid-path-108697.stderr
@@ -0,0 +1,8 @@
+error: couldn't read $DIR/lol: No such file or directory (os error 2)
+  --> $DIR/staged-api-invalid-path-108697.rs:8:1
+   |
+LL | mod foo;
+   | ^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/variance/variance-regions-unused-indirect.stderr b/tests/ui/variance/variance-regions-unused-indirect.stderr
index ec4d480baab..8cdbb3c0f5e 100644
--- a/tests/ui/variance/variance-regions-unused-indirect.stderr
+++ b/tests/ui/variance/variance-regions-unused-indirect.stderr
@@ -16,7 +16,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~     Foo1(Box<Bar<'a>>)
 LL | }
-LL | 
+LL |
 LL | enum Bar<'a> {
 LL ~     Bar1(Box<Foo<'a>>)
    |
diff --git a/triagebot.toml b/triagebot.toml
index 903569bf445..499ba6e470c 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -529,6 +529,10 @@ cc = ["@compiler-errors", "@lcnr"]
 message = "changes to the core type system"
 cc = ["@compiler-errors", "@lcnr"]
 
+[mentions."compiler/rustc_hir_analysis/src/fn_ctxt/inspect_obligations.rs"]
+message = "changes to `inspect_obligations.rs`"
+cc = ["@compiler-errors", "@lcnr"]
+
 [mentions."compiler/rustc_middle/src/mir/interpret"]
 message = "Some changes occurred to the CTFE / Miri engine"
 cc = ["@rust-lang/miri"]