about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/dependencies.yml2
-rw-r--r--Cargo.lock3
-rw-r--r--compiler/rustc_ast/src/util/classify.rs98
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs70
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/fixup.rs57
-rw-r--r--compiler/rustc_const_eval/src/const_eval/dummy_machine.rs5
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs3
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs6
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs2
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs1
-rw-r--r--compiler/rustc_const_eval/src/util/caller_location.rs1
-rw-r--r--compiler/rustc_const_eval/src/util/check_validity_requirement.rs1
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0457.md2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/entry.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/test.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs1
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs8
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl4
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs1351
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs774
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude2021.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs50
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/rvalue_scopes.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs18
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs1
-rw-r--r--compiler/rustc_infer/src/infer/at.rs1
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs1
-rw-r--r--compiler/rustc_infer/src/infer/canonical/instantiate.rs1
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs1
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs1
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs1
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs1
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs1
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs1
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs1
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs1
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs1
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs1
-rw-r--r--compiler/rustc_infer/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/unused.rs27
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs38
-rw-r--r--compiler/rustc_metadata/src/creader.rs1
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs1
-rw-r--r--compiler/rustc_metadata/src/lib.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs38
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs19
-rw-r--r--compiler/rustc_mir_build/Cargo.toml1
-rw-r--r--compiler/rustc_mir_build/messages.ftl2
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs1
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs1
-rw-r--r--compiler/rustc_mir_build/src/errors.rs27
-rw-r--r--compiler/rustc_mir_build/src/lib.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs12
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs91
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs1
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs1
-rw-r--r--compiler/rustc_mir_transform/src/check_packed_ref.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs1
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs1
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs1
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs1
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs1
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs1
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs1
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs1
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs1
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs1
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs1
-rw-r--r--compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs1
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs1
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs1
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs1
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_enum_branching.rs1
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs1
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs34
-rw-r--r--compiler/rustc_query_impl/src/lib.rs5
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs5
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/alias_relate.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs27
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/build.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs23
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.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.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs1
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs1
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs1
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs1
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs1
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs1
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs1
-rw-r--r--compiler/rustc_ty_utils/src/layout_sanity_check.rs1
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs2
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs1
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs1
-rw-r--r--compiler/rustc_ty_utils/src/representability.rs1
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs1
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs1
-rw-r--r--config.example.toml6
-rw-r--r--library/alloc/src/fmt.rs4
-rw-r--r--library/core/src/primitive_docs.rs3
-rw-r--r--library/std/src/io/mod.rs6
-rw-r--r--library/std/src/sys/pal/unix/alloc.rs2
-rw-r--r--src/bootstrap/bootstrap.py38
-rw-r--r--src/bootstrap/src/core/config/config.rs38
-rw-r--r--src/bootstrap/src/core/download.rs8
-rw-r--r--src/doc/rustdoc/src/command-line-arguments.md2
-rw-r--r--src/stage0447
-rw-r--r--src/stage0.json456
-rw-r--r--src/tools/build_helper/src/lib.rs1
-rw-r--r--src/tools/build_helper/src/stage0_parser.rs76
-rw-r--r--src/tools/bump-stage0/Cargo.toml2
-rw-r--r--src/tools/bump-stage0/src/main.rs143
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs14
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs13
-rw-r--r--src/tools/run-make-support/src/lib.rs9
-rw-r--r--src/tools/run-make-support/src/rustc.rs9
-rw-r--r--src/tools/run-make-support/src/rustdoc.rs30
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/codegen-units/partitioning/extern-drop-glue.rs5
-rw-r--r--tests/codegen-units/partitioning/extern-generic.rs4
-rw-r--r--tests/codegen-units/partitioning/incremental-merging.rs3
-rw-r--r--tests/codegen-units/partitioning/inlining-from-extern-crate.rs4
-rw-r--r--tests/codegen-units/partitioning/local-drop-glue.rs4
-rw-r--r--tests/codegen-units/partitioning/local-generic.rs3
-rw-r--r--tests/codegen-units/partitioning/local-inlining-but-not-all.rs4
-rw-r--r--tests/codegen-units/partitioning/local-inlining.rs4
-rw-r--r--tests/codegen-units/partitioning/local-transitive-inlining.rs4
-rw-r--r--tests/codegen-units/partitioning/methods-are-with-self-type.rs4
-rw-r--r--tests/codegen-units/partitioning/regular-modules.rs3
-rw-r--r--tests/codegen-units/partitioning/shared-generics.rs1
-rw-r--r--tests/codegen-units/partitioning/statics.rs3
-rw-r--r--tests/codegen-units/partitioning/vtable-through-const.rs5
-rw-r--r--tests/crashes/123901.rs8
-rw-r--r--tests/run-make/rustdoc-scrape-examples-ordering/Makefile5
-rw-r--r--tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs55
-rw-r--r--tests/ui/async-await/async-closures/ambiguous-arg.rs15
-rw-r--r--tests/ui/async-await/async-closures/ambiguous-arg.stderr13
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.fixed31
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.rs31
-rw-r--r--tests/ui/lint/lint-unnecessary-parens.stderr74
-rw-r--r--tests/ui/macros/stringify.rs45
-rw-r--r--tests/ui/parser/else-no-if.rs30
-rw-r--r--tests/ui/parser/else-no-if.stderr56
-rw-r--r--tests/ui/parser/macro/statement-boundaries.rs104
-rw-r--r--tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs12
-rw-r--r--tests/ui/pattern/match_ergonomics_2024.fixed57
-rw-r--r--tests/ui/pattern/match_ergonomics_2024.rs57
-rw-r--r--tests/ui/pattern/match_ergonomics_2024.stderr97
-rw-r--r--tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs16
-rw-r--r--tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr31
-rw-r--r--tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs19
-rw-r--r--tests/ui/unpretty/let-else-hir.rs (renamed from tests/ui/unpretty/pretty-let-else.rs)0
-rw-r--r--tests/ui/unpretty/let-else-hir.stdout (renamed from tests/ui/unpretty/pretty-let-else.stdout)0
-rw-r--r--tests/ui/unpretty/let-else.rs11
-rw-r--r--tests/ui/unpretty/let-else.stdout15
-rw-r--r--tests/ui/write-fmt-errors.rs29
-rw-r--r--triagebot.toml6
303 files changed, 3314 insertions, 2094 deletions
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index f4e409e0d49..03584aed08d 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -56,7 +56,7 @@ jobs:
       - name: install the bootstrap toolchain
         run: |
           # Extract the stage0 version
-          TOOLCHAIN=$(jq -r '.compiler | {version,date} | join("-")' -- src/stage0.json)
+          TOOLCHAIN=$(awk -F= '{a[$1]=$2} END {print(a["compiler_version"] "-" a["compiler_date"])}' src/stage0)
           # Install and set as default
           rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN
           rustup default $TOOLCHAIN
diff --git a/Cargo.lock b/Cargo.lock
index 2aed7ebacd5..df4e4f32613 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -381,10 +381,10 @@ name = "bump-stage0"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "build_helper",
  "curl",
  "indexmap",
  "serde",
- "serde_json",
  "toml 0.5.11",
 ]
 
@@ -4369,6 +4369,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_infer",
+ "rustc_lint",
  "rustc_macros",
  "rustc_middle",
  "rustc_pattern_analysis",
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index f21a9cabb81..f6e9e1a87c4 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -1,34 +1,88 @@
-//! Routines the parser uses to classify AST nodes
-
-// Predicates on exprs and stmts that the pretty-printer and parser use
+//! Routines the parser and pretty-printer use to classify AST nodes.
 
+use crate::ast::ExprKind::*;
 use crate::{ast, token::Delimiter};
 
-/// Does this expression require a semicolon to be treated
-/// as a statement? The negation of this: 'can this expression
-/// be used as a statement without a semicolon' -- is used
-/// as an early-bail-out in the parser so that, for instance,
-///     if true {...} else {...}
-///      |x| 5
-/// isn't parsed as (if true {...} else {...} | x) | 5
-pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
-    !matches!(
+/// This classification determines whether various syntactic positions break out
+/// of parsing the current expression (true) or continue parsing more of the
+/// same expression (false).
+///
+/// For example, it's relevant in the parsing of match arms:
+///
+/// ```ignore (illustrative)
+/// match ... {
+///     // Is this calling $e as a function, or is it the start of a new arm
+///     // with a tuple pattern?
+///     _ => $e (
+///             ^                                                          )
+///
+///     // Is this an Index operation, or new arm with a slice pattern?
+///     _ => $e [
+///             ^                                                          ]
+///
+///     // Is this a binary operator, or leading vert in a new arm? Same for
+///     // other punctuation which can either be a binary operator in
+///     // expression or unary operator in pattern, such as `&` and `-`.
+///     _ => $e |
+///             ^
+/// }
+/// ```
+///
+/// If $e is something like `{}` or `if … {}`, then terminate the current
+/// arm and parse a new arm.
+///
+/// If $e is something like `path::to` or `(…)`, continue parsing the same
+/// arm.
+///
+/// *Almost* the same classification is used as an early bail-out for parsing
+/// statements. See `expr_requires_semi_to_be_stmt`.
+pub fn expr_is_complete(e: &ast::Expr) -> bool {
+    matches!(
         e.kind,
-        ast::ExprKind::If(..)
-            | ast::ExprKind::Match(..)
-            | ast::ExprKind::Block(..)
-            | ast::ExprKind::While(..)
-            | ast::ExprKind::Loop(..)
-            | ast::ExprKind::ForLoop { .. }
-            | ast::ExprKind::TryBlock(..)
-            | ast::ExprKind::ConstBlock(..)
+        If(..)
+            | Match(..)
+            | Block(..)
+            | While(..)
+            | Loop(..)
+            | ForLoop { .. }
+            | TryBlock(..)
+            | ConstBlock(..)
     )
 }
 
+/// Does this expression require a semicolon to be treated as a statement?
+///
+/// The negation of this: "can this expression be used as a statement without a
+/// semicolon" -- is used as an early bail-out when parsing statements so that,
+/// for instance,
+///
+/// ```ignore (illustrative)
+/// if true {...} else {...}
+/// |x| 5
+/// ```
+///
+/// isn't parsed as `(if true {...} else {...} | x) | 5`.
+///
+/// Surprising special case: even though braced macro calls like `m! {}`
+/// normally do not introduce a boundary when found at the head of a match arm,
+/// they do terminate the parsing of a statement.
+///
+/// ```ignore (illustrative)
+/// match ... {
+///     _ => m! {} (),  // macro that expands to a function, which is then called
+/// }
+///
+/// let _ = { m! {} () };  // macro call followed by unit
+/// ```
+pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
+    match &e.kind {
+        MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace,
+        _ => !expr_is_complete(e),
+    }
+}
+
 /// If an expression ends with `}`, returns the innermost expression ending in the `}`
 pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
-    use ast::ExprKind::*;
-
     loop {
         match &expr.kind {
             AddrOf(_, _, e)
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 2c176828c84..c41c7a3dfa4 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -55,8 +55,8 @@ impl PpAnn for NoAnn {}
 
 pub struct Comments<'a> {
     sm: &'a SourceMap,
-    comments: Vec<Comment>,
-    current: usize,
+    // Stored in reverse order so we can consume them by popping.
+    reversed_comments: Vec<Comment>,
 }
 
 /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char.
@@ -182,21 +182,25 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment>
 
 impl<'a> Comments<'a> {
     pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> {
-        let comments = gather_comments(sm, filename, input);
-        Comments { sm, comments, current: 0 }
+        let mut comments = gather_comments(sm, filename, input);
+        comments.reverse();
+        Comments { sm, reversed_comments: comments }
     }
 
-    // FIXME: This shouldn't probably clone lmao
-    fn next(&self) -> Option<Comment> {
-        self.comments.get(self.current).cloned()
+    fn peek(&self) -> Option<&Comment> {
+        self.reversed_comments.last()
+    }
+
+    fn next(&mut self) -> Option<Comment> {
+        self.reversed_comments.pop()
     }
 
     fn trailing_comment(
-        &self,
+        &mut self,
         span: rustc_span::Span,
         next_pos: Option<BytePos>,
     ) -> Option<Comment> {
-        if let Some(cmnt) = self.next() {
+        if let Some(cmnt) = self.peek() {
             if cmnt.style != CommentStyle::Trailing {
                 return None;
             }
@@ -204,7 +208,7 @@ impl<'a> Comments<'a> {
             let comment_line = self.sm.lookup_char_pos(cmnt.pos);
             let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1));
             if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line {
-                return Some(cmnt);
+                return Some(self.next().unwrap());
             }
         }
 
@@ -400,7 +404,8 @@ impl std::ops::DerefMut for State<'_> {
 
 /// This trait is used for both AST and HIR pretty-printing.
 pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut {
-    fn comments(&mut self) -> &mut Option<Comments<'a>>;
+    fn comments(&self) -> Option<&Comments<'a>>;
+    fn comments_mut(&mut self) -> Option<&mut Comments<'a>>;
     fn ann_post(&mut self, ident: Ident);
     fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
 
@@ -442,18 +447,18 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
 
     fn maybe_print_comment(&mut self, pos: BytePos) -> bool {
         let mut has_comment = false;
-        while let Some(cmnt) = self.next_comment() {
-            if cmnt.pos < pos {
-                has_comment = true;
-                self.print_comment(&cmnt);
-            } else {
+        while let Some(cmnt) = self.peek_comment() {
+            if cmnt.pos >= pos {
                 break;
             }
+            has_comment = true;
+            let cmnt = self.next_comment().unwrap();
+            self.print_comment(cmnt);
         }
         has_comment
     }
 
-    fn print_comment(&mut self, cmnt: &Comment) {
+    fn print_comment(&mut self, cmnt: Comment) {
         match cmnt.style {
             CommentStyle::Mixed => {
                 if !self.is_beginning_of_line() {
@@ -517,19 +522,20 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                 self.hardbreak();
             }
         }
-        if let Some(cmnts) = self.comments() {
-            cmnts.current += 1;
-        }
+    }
+
+    fn peek_comment<'b>(&'b self) -> Option<&'b Comment> where 'a: 'b {
+        self.comments().and_then(|c| c.peek())
     }
 
     fn next_comment(&mut self) -> Option<Comment> {
-        self.comments().as_mut().and_then(|c| c.next())
+        self.comments_mut().and_then(|c| c.next())
     }
 
     fn maybe_print_trailing_comment(&mut self, span: rustc_span::Span, next_pos: Option<BytePos>) {
-        if let Some(cmnts) = self.comments() {
+        if let Some(cmnts) = self.comments_mut() {
             if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) {
-                self.print_comment(&cmnt);
+                self.print_comment(cmnt);
             }
         }
     }
@@ -537,11 +543,11 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
     fn print_remaining_comments(&mut self) {
         // If there aren't any remaining comments, then we need to manually
         // make sure there is a line break at the end.
-        if self.next_comment().is_none() {
+        if self.peek_comment().is_none() {
             self.hardbreak();
         }
         while let Some(cmnt) = self.next_comment() {
-            self.print_comment(&cmnt)
+            self.print_comment(cmnt)
         }
     }
 
@@ -994,8 +1000,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
 }
 
 impl<'a> PrintState<'a> for State<'a> {
-    fn comments(&mut self) -> &mut Option<Comments<'a>> {
-        &mut self.comments
+    fn comments(&self) -> Option<&Comments<'a>> {
+        self.comments.as_ref()
+    }
+
+    fn comments_mut(&mut self) -> Option<&mut Comments<'a>> {
+        self.comments.as_mut()
     }
 
     fn ann_post(&mut self, ident: Ident) {
@@ -1238,7 +1248,11 @@ impl<'a> State<'a> {
                 if let Some((init, els)) = loc.kind.init_else_opt() {
                     self.nbsp();
                     self.word_space("=");
-                    self.print_expr(init, FixupContext::default());
+                    self.print_expr_cond_paren(
+                        init,
+                        els.is_some() && classify::expr_trailing_brace(init).is_some(),
+                        FixupContext::default(),
+                    );
                     if let Some(els) = els {
                         self.cbox(INDENT_UNIT);
                         self.ibox(INDENT_UNIT);
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 93400c67949..1e117c46b6e 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -780,7 +780,7 @@ impl<'a> State<'a> {
                 }
                 _ => {
                     self.end(); // Close the ibox for the pattern.
-                    self.print_expr(body, FixupContext::new_stmt());
+                    self.print_expr(body, FixupContext::new_match_arm());
                     self.word(",");
                 }
             }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
index d21cb82f83b..86d4796e9ce 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
@@ -49,6 +49,38 @@ pub(crate) struct FixupContext {
     ///     No parentheses required.
     leftmost_subexpression_in_stmt: bool,
 
+    /// Print expression such that it can be parsed as a match arm.
+    ///
+    /// This is almost equivalent to `stmt`, but the grammar diverges a tiny bit
+    /// between statements and match arms when it comes to braced macro calls.
+    /// Macro calls with brace delimiter terminate a statement without a
+    /// semicolon, but do not terminate a match-arm without comma.
+    ///
+    /// ```ignore (illustrative)
+    /// m! {} - 1;  // two statements: a macro call followed by -1 literal
+    ///
+    /// match () {
+    ///     _ => m! {} - 1,  // binary subtraction operator
+    /// }
+    /// ```
+    match_arm: bool,
+
+    /// This is almost equivalent to `leftmost_subexpression_in_stmt`, other
+    /// than for braced macro calls.
+    ///
+    /// If we have `m! {} - 1` as an expression, the leftmost subexpression
+    /// `m! {}` will need to be parenthesized in the statement case but not the
+    /// match-arm case.
+    ///
+    /// ```ignore (illustrative)
+    /// (m! {}) - 1;  // subexpression needs parens
+    ///
+    /// match () {
+    ///     _ => m! {} - 1,  // no parens
+    /// }
+    /// ```
+    leftmost_subexpression_in_match_arm: bool,
+
     /// This is the difference between:
     ///
     /// ```ignore (illustrative)
@@ -68,6 +100,8 @@ impl Default for FixupContext {
         FixupContext {
             stmt: false,
             leftmost_subexpression_in_stmt: false,
+            match_arm: false,
+            leftmost_subexpression_in_match_arm: false,
             parenthesize_exterior_struct_lit: false,
         }
     }
@@ -76,13 +110,16 @@ impl Default for FixupContext {
 impl FixupContext {
     /// Create the initial fixup for printing an expression in statement
     /// position.
-    ///
-    /// This is currently also used for printing an expression as a match-arm,
-    /// but this is incorrect and leads to over-parenthesizing.
     pub fn new_stmt() -> Self {
         FixupContext { stmt: true, ..FixupContext::default() }
     }
 
+    /// Create the initial fixup for printing an expression as the right-hand
+    /// side of a match arm.
+    pub fn new_match_arm() -> Self {
+        FixupContext { match_arm: true, ..FixupContext::default() }
+    }
+
     /// Create the initial fixup for printing an expression as the "condition"
     /// of an `if` or `while`. There are a few other positions which are
     /// grammatically equivalent and also use this, such as the iterator
@@ -106,6 +143,9 @@ impl FixupContext {
         FixupContext {
             stmt: false,
             leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
+            match_arm: false,
+            leftmost_subexpression_in_match_arm: self.match_arm
+                || self.leftmost_subexpression_in_match_arm,
             ..self
         }
     }
@@ -119,7 +159,13 @@ impl FixupContext {
     /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
     /// `$a.f($b)`.
     pub fn subsequent_subexpression(self) -> Self {
-        FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..self }
+        FixupContext {
+            stmt: false,
+            leftmost_subexpression_in_stmt: false,
+            match_arm: false,
+            leftmost_subexpression_in_match_arm: false,
+            ..self
+        }
     }
 
     /// Determine whether parentheses are needed around the given expression to
@@ -128,7 +174,8 @@ impl FixupContext {
     /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
     /// examples.
     pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
-        self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr)
+        (self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr))
+            || (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr))
     }
 
     /// Determine whether parentheses are needed around the given `let`
diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
index afc60d33647..94c9f056b30 100644
--- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
@@ -1,9 +1,12 @@
-use crate::interpret::{self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic};
+use crate::interpret::{
+    self, throw_machine_stop, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic,
+};
 use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult};
 use rustc_middle::mir::*;
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
 
 /// Macro for machine-specific `InterpError` without allocation.
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 2c9eb393e4a..08c9609eacf 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -11,6 +11,7 @@ use rustc_span::{Span, Symbol};
 
 use super::CompileTimeInterpreter;
 use crate::errors::{self, FrameNote, ReportErrorExt};
+use crate::interpret::{err_inval, err_machine_stop};
 use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType};
 
 /// The CTFE machine has some custom error kinds.
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index d9f329c8b0e..6a9a21bbd8e 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -3,6 +3,7 @@ use std::sync::atomic::Ordering::Relaxed;
 use either::{Left, Right};
 
 use rustc_hir::def::DefKind;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
 use rustc_middle::mir::{self, ConstAlloc, ConstValue};
 use rustc_middle::query::TyCtxtAt;
@@ -24,7 +25,7 @@ use crate::interpret::{
     InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
     StackPopCleanup,
 };
-use crate::interpret::{eval_nullary_intrinsic, InternResult};
+use crate::interpret::{eval_nullary_intrinsic, throw_exhaust, InternResult};
 use crate::CTRL_C_RECEIVED;
 
 // Returns a pointer to where the result lives
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 6e6fa70107b..836e548ae2b 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -10,6 +10,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::LangItem;
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::AssertMessage;
 use rustc_middle::query::TyCtxtAt;
@@ -24,8 +25,9 @@ use rustc_target::spec::abi::Abi as CallAbi;
 use crate::errors::{LongRunning, LongRunningWarn};
 use crate::fluent_generated as fluent;
 use crate::interpret::{
-    self, compile_time_machine, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal,
-    Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar,
+    self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom,
+    throw_unsup_format, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, Frame,
+    ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar,
 };
 
 use super::error::*;
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 8efc67bcb0c..a5c8c0bb82a 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -1,5 +1,6 @@
 // Not in interpret to make sure we do not use private implementation details
 
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::InterpErrorInfo;
 use rustc_middle::query::{Key, TyCtxtAt};
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index dcfce4e35e0..fbf2ca5ab0a 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 76e59ea9055..799e12f9ac9 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -7,11 +7,13 @@ use rustc_middle::mir::CastKind;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, Ty};
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::Integer;
 use rustc_type_ir::TyKind::*;
 
 use super::{
-    util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy,
+    err_inval, throw_ub, throw_ub_custom, util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate,
+    InterpCx, Machine, OpTy, PlaceTy,
 };
 
 use crate::fluent_generated as fluent;
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index caacc6f57d3..8ddc741de23 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -1,12 +1,15 @@
 //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines).
 
 use rustc_middle::mir;
+use rustc_middle::span_bug;
 use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt};
 use rustc_middle::ty::{self, ScalarInt, Ty};
 use rustc_target::abi::{self, TagEncoding};
 use rustc_target::abi::{VariantIdx, Variants};
 
-use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable};
+use super::{
+    err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable,
+};
 
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Writes the discriminant of the given variant.
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 126d64329f8..344bb7cd98b 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -17,15 +17,17 @@ use rustc_middle::ty::layout::{
     TyAndLayout,
 };
 use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance};
+use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_session::Limit;
 use rustc_span::Span;
 use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout};
 
 use super::{
-    GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta,
-    Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable,
-    Provenance, Scalar, StackPopJump,
+    err_inval, throw_inval, throw_ub, throw_ub_custom, throw_unsup, GlobalId, Immediate,
+    InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind,
+    OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, Provenance, Scalar,
+    StackPopJump,
 };
 use crate::errors;
 use crate::util;
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index d4168273f29..3565b4fb516 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -24,7 +24,7 @@ use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::sym;
 
-use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
+use super::{err_ub, AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
 use crate::const_eval;
 use crate::errors::NestedStaticInThreadLocal;
 
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 52c31629d54..dce4d56f7e0 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -8,6 +8,7 @@ use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_middle::{
+    bug,
     mir::{self, BinOp, ConstValue, NonDivergingIntrinsic},
     ty::layout::TyAndLayout,
 };
@@ -15,9 +16,10 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_target::abi::Size;
 
 use super::{
-    memory::MemoryKind, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg,
-    ConstAllocation, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer,
-    PointerArithmetic, Scalar,
+    err_inval, err_ub_custom, err_unsup_format, memory::MemoryKind, throw_inval, throw_ub_custom,
+    throw_ub_format, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, ConstAllocation,
+    GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, PointerArithmetic,
+    Scalar,
 };
 
 use crate::fluent_generated as fluent;
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 8405d0746df..2eaebc1924b 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -18,9 +18,9 @@ use rustc_target::abi::{Align, Size};
 use rustc_target::spec::abi::Abi as CallAbi;
 
 use super::{
-    AllocBytes, AllocId, AllocKind, AllocRange, Allocation, ConstAllocation, CtfeProvenance, FnArg,
-    Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, Misalignment, OpTy, PlaceTy,
-    Pointer, Provenance,
+    throw_unsup, throw_unsup_format, AllocBytes, AllocId, AllocKind, AllocRange, Allocation,
+    ConstAllocation, CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy,
+    MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance,
 };
 
 /// Data returned by Machine::stack_pop,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 594e3b3212f..350fd480fba 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -16,6 +16,7 @@ use std::ptr;
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_hir::def::DefKind;
+use rustc_middle::bug;
 use rustc_middle::mir::display_allocation;
 use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_target::abi::{Align, HasDataLayout, Size};
@@ -23,9 +24,10 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
 use crate::fluent_generated as fluent;
 
 use super::{
-    alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg,
-    CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak,
-    Misalignment, Pointer, PointerArithmetic, Provenance, Scalar,
+    alloc_range, err_ub, err_ub_custom, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
+    AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, CheckInAllocMsg,
+    CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer,
+    PointerArithmetic, Provenance, Scalar,
 };
 
 #[derive(Debug, PartialEq, Copy, Clone)]
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 718c91b2f76..bad9732f483 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -10,13 +10,14 @@ use rustc_middle::mir::interpret::ScalarSizeMismatch;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
 use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_middle::{mir, ty};
 use rustc_target::abi::{self, Abi, HasDataLayout, Size};
 
 use super::{
-    alloc_range, from_known_layout, mir_assign_valid_types, CtfeProvenance, InterpCx, InterpResult,
-    MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, Pointer, Projectable,
-    Provenance, Scalar,
+    alloc_range, err_ub, from_known_layout, mir_assign_valid_types, throw_ub, CtfeProvenance,
+    InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy,
+    Pointer, Projectable, Provenance, Scalar,
 };
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 2d5dbbd58b3..5f59e3d887e 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -3,10 +3,11 @@ use rustc_middle::mir;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
 use rustc_target::abi::Abi;
 
-use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
+use super::{err_ub, throw_ub, throw_ub_custom, ImmTy, Immediate, InterpCx, Machine, PlaceTy};
 
 use crate::fluent_generated as fluent;
 
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 809aca18990..9ced825853b 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -11,12 +11,14 @@ use rustc_middle::mir;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::Ty;
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::{Abi, Align, HasDataLayout, Size};
 
 use super::{
-    alloc_range, mir_assign_valid_types, AllocRef, AllocRefMut, CheckAlignMsg, CtfeProvenance,
-    ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy,
-    Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, Scalar,
+    alloc_range, mir_assign_valid_types, throw_ub, AllocRef, AllocRefMut, CheckAlignMsg,
+    CtfeProvenance, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment,
+    OffsetMode, OpTy, Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable,
+    Scalar,
 };
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 5ff78f7b8c9..0a2fedb4840 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -14,10 +14,14 @@ use rustc_middle::mir;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::Ty;
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::Size;
 use rustc_target::abi::{self, VariantIdx};
 
-use super::{InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Provenance, Scalar};
+use super::{
+    throw_ub, throw_unsup_format, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
+    Provenance, Scalar,
+};
 
 /// Describes the constraints placed on offset-projections.
 #[derive(Copy, Clone, Debug)]
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index b29034e991e..ee415c380de 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -7,6 +7,7 @@ use either::Either;
 use rustc_index::IndexSlice;
 use rustc_middle::mir;
 use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
 
 use super::{
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index b474003087b..b82c1857858 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -2,6 +2,7 @@ use std::borrow::Cow;
 
 use either::Either;
 
+use rustc_middle::span_bug;
 use rustc_middle::{
     mir,
     ty::{
@@ -19,8 +20,9 @@ use rustc_target::abi::{
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy,
-    Projectable, Provenance, Scalar, StackPopCleanup,
+    throw_ub, throw_ub_custom, throw_unsup_format, CtfeProvenance, FnVal, ImmTy, InterpCx,
+    InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, Projectable, Provenance, Scalar,
+    StackPopCleanup,
 };
 use crate::fluent_generated as fluent;
 
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index c83ef14c03f..e304d1e1cc5 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -1,5 +1,4 @@
 use crate::const_eval::{CompileTimeEvalContext, CompileTimeInterpreter, InterpretationResult};
-use crate::interpret::{MemPlaceMeta, MemoryKind};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
@@ -9,7 +8,7 @@ use rustc_middle::ty::{
 };
 use std::ops::ControlFlow;
 
-use super::{InterpCx, MPlaceTy};
+use super::{throw_inval, InterpCx, MPlaceTy, MemPlaceMeta, MemoryKind};
 
 /// Checks whether a type contains generic parameters which must be instantiated.
 ///
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 14566719ccd..2bd4d9dc07a 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -13,6 +13,7 @@ use hir::def::DefKind;
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{
     ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, Provenance,
     ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*,
@@ -27,9 +28,9 @@ use rustc_target::abi::{
 use std::hash::Hash;
 
 use super::{
-    format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy,
-    Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable,
-    Scalar, ValueVisitor,
+    err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, CheckInAllocMsg,
+    GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
+    Pointer, Projectable, Scalar, ValueVisitor,
 };
 
 // for the validation errors
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 84557b8e2d6..59bcc5174cb 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -9,7 +9,7 @@ use rustc_target::abi::{FieldsShape, VariantIdx, Variants};
 
 use std::num::NonZero;
 
-use super::{InterpCx, MPlaceTy, Machine, Projectable};
+use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable};
 
 /// How to traverse a value and what to do when we are at the leaves.
 pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index d27d42737cd..a525b838afa 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -22,8 +22,6 @@ Rust MIR: a lowered representation of Rust.
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 pub mod const_eval;
 mod errors;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 46cc9f69373..5edf5bb39dd 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -8,6 +8,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
 use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt};
 use rustc_mir_dataflow::Analysis;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index 12e7ec15e32..308b90cd470 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -8,6 +8,7 @@ use rustc_attr as attr;
 use rustc_errors::DiagCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::ty::{self, PolyFnSig, TyCtxt};
 use rustc_span::Symbol;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 247a2889dc5..8775685e8c7 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -8,6 +8,7 @@ use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir::{self, CallSource};
+use rustc_middle::span_bug;
 use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
 use rustc_middle::ty::{
     self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 1847847d9d2..eae0e2f27db 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -5,6 +5,7 @@
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::LangItem;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::*;
 use rustc_middle::traits::BuiltinImplSource;
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index c95166d84e9..fdc7f6a69cb 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -9,6 +9,7 @@ use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance};
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::{Size, FIRST_VARIANT};
 use rustc_target::spec::abi::Abi;
 
diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs
index af9a4a4271d..403bc1eca13 100644
--- a/compiler/rustc_const_eval/src/util/caller_location.rs
+++ b/compiler/rustc_const_eval/src/util/caller_location.rs
@@ -1,4 +1,5 @@
 use rustc_hir::LangItem;
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::layout::LayoutOf;
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 36597507f47..68fb122a765 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -1,3 +1,4 @@
+use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement};
 use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
 use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index e474b952938..01e517250f7 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -1,6 +1,7 @@
 use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::DisambiguatedDefPathData;
+use rustc_middle::bug;
 use rustc_middle::ty::{
     self,
     print::{PrettyPrinter, Print, PrintError, Printer},
diff --git a/compiler/rustc_error_codes/src/error_codes/E0457.md b/compiler/rustc_error_codes/src/error_codes/E0457.md
index e2dbf53a0f8..47bff4bc49f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0457.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0457.md
@@ -1,4 +1,4 @@
-#### Note: this error code is no longer emitted by the compiler`
+#### Note: this error code is no longer emitted by the compiler
 
 Plugin `..` only found in rlib format, but must be available in dylib format.
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index fb9d97ba08b..652c1885073 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -14,6 +14,7 @@ use rustc_infer::traits::Obligation;
 use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
 use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
 use rustc_middle::middle::stability::EvalResult;
+use rustc_middle::span_bug;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
 use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index db223f9d80f..8352d1d7a90 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -19,6 +19,7 @@ use rustc_middle::ty::{
     self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
 use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index a2a20082bb0..ca08eeea227 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -3,6 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
 use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
+use rustc_middle::span_bug;
 use rustc_middle::traits::{ObligationCause, Reveal};
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs
index d5908cf2851..e44e8e67da3 100644
--- a/compiler/rustc_hir_analysis/src/check/entry.rs
+++ b/compiler/rustc_hir_analysis/src/check/entry.rs
@@ -1,6 +1,7 @@
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::config::EntryFnType;
 use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index eb1fa1baecc..00ff470a0a7 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -9,6 +9,7 @@ use crate::errors::{
 
 use rustc_errors::{codes::*, struct_span_code_err, DiagMessage};
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 45ccd0fa2e0..b09de1a4a09 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -1,6 +1,7 @@
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
 use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index eb0ffc19d45..9c5c0a766b4 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -90,6 +90,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP};
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index d2ea51f65f9..4540310937d 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt};
 use rustc_index::Idx;
+use rustc_middle::bug;
 use rustc_middle::middle::region::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map;
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index e50af9605fd..b918a8c32d8 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -24,6 +24,7 @@ use rustc_middle::ty::{
     TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 use rustc_middle::ty::{GenericArgKind, GenericArgs};
+use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, DUMMY_SP};
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index 4a85e9983f4..e2d3ff558cf 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -10,6 +10,7 @@
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::bug;
 use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
 use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
 use rustc_span::symbol::sym;
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 8e1b2e8e65c..bdac0d9b0b4 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -10,6 +10,7 @@ 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_middle::{bug, span_bug};
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams};
 use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode};
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 566f818f899..0b9f7fd41fb 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -30,6 +30,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
 use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::FieldIdx;
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 02291cc603e..3c89c2b23fc 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -5,6 +5,7 @@ use rustc_hir as hir;
 use rustc_infer::traits::util;
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 7e82571d172..8e79b36060c 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -10,6 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 3ef132a3e8c..5c7733065c6 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -15,11 +15,11 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node};
 use rustc_macros::extension;
-use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 24a5349858a..1475e53c47c 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -7,6 +7,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index b5765913cb8..1bec8c496ad 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -3,6 +3,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem};
+use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 3b8bb0731fb..b50c11aaa9a 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::bug;
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index de12475678c..6786c9afd0d 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -5,6 +5,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::bug;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
 use rustc_span::symbol::Ident;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 38dfa8d57d3..211da237f8a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -16,6 +16,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
+use rustc_middle::bug;
 use rustc_middle::query::Key;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::GenericParamDefKind;
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 591d554d335..d16648b9e8f 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -44,6 +44,7 @@ use rustc_middle::ty::{
     self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
     TypeVisitableExt,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index 37d4d4ec355..b8d4ee58e2e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -6,6 +6,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
+use rustc_middle::span_bug;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable};
 use rustc_middle::ty::{DynKind, ToPredicate};
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index d6ba5fa9b5b..10101aa046e 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -4,6 +4,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{ForeignItem, ForeignItemKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ObligationCause, WellFormedLoc};
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index e75740837f8..654ef4baeb3 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -75,9 +75,6 @@ This API is completely unstable and subject to change.
 #[macro_use]
 extern crate tracing;
 
-#[macro_use]
-extern crate rustc_middle;
-
 // These are used by Clippy.
 pub mod check;
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs
index 60cd8c39fa0..e9b6c679bd5 100644
--- a/compiler/rustc_hir_analysis/src/outlives/test.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/test.rs
@@ -1,3 +1,4 @@
+use rustc_middle::bug;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::sym, ErrorGuaranteed};
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index d3bb22d715d..95290bbecf2 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
 use rustc_middle::ty::{self, Region, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArg, GenericArgKind};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 use smallvec::smallvec;
 
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index eeb8b028505..730e989edae 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -8,6 +8,7 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 
 use super::terms::VarianceTerm::*;
 use super::terms::*;
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 27fdea01c2b..c7e2050453d 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -8,6 +8,7 @@ use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
 use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
 
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 4f5fbd024a9..a47e6af0bf2 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -139,8 +139,12 @@ impl std::ops::DerefMut for State<'_> {
 }
 
 impl<'a> PrintState<'a> for State<'a> {
-    fn comments(&mut self) -> &mut Option<Comments<'a>> {
-        &mut self.comments
+    fn comments(&self) -> Option<&Comments<'a>> {
+        self.comments.as_ref()
+    }
+
+    fn comments_mut(&mut self) -> Option<&mut Comments<'a>> {
+        self.comments.as_mut()
     }
 
     fn ann_post(&mut self, ident: Ident) {
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 0560d0d902a..72b95a9603d 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -46,10 +46,6 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
 
 hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
 
-hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding
-    .label = `mut` dereferences the type of this binding
-    .help = this will change in edition 2024
-
 hir_typeck_expected_default_return_type = expected `()` because of default return type
 
 hir_typeck_expected_return_type = expected `{$expected}` because of return type
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index defb557867b..1347e850d6f 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -19,6 +19,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 92f74281ab9..316a2bf08cb 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -36,6 +36,7 @@ use hir::ExprKind;
 use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_macros::{TypeFoldable, TypeVisitable};
+use rustc_middle::bug;
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::cast::{CastKind, CastTy};
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index f52f95db6d3..2ff46689d4a 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -10,6 +10,7 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes};
 use rustc_infer::infer::{InferOk, InferResult};
 use rustc_infer::traits::ObligationCauseCode;
 use rustc_macros::{TypeFoldable, TypeVisitable};
+use rustc_middle::span_bug;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 88ba937e4b5..8d93f402f10 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -45,6 +45,7 @@ use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
 use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause};
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::span_bug;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index b2112491733..706f6f875bf 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -5,6 +5,7 @@ use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::Visitor;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
+use rustc_middle::bug;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index ba8f246fd8d..f250b909596 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -651,10 +651,3 @@ pub enum SuggestBoxingForReturnImplTrait {
         ends: Vec<Span>,
     },
 }
-#[derive(LintDiagnostic)]
-#[diag(hir_typeck_dereferencing_mut_binding)]
-pub struct DereferencingMutBinding {
-    #[label]
-    #[help]
-    pub span: Span,
-}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index cdf17f3a113..f283c013805 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -45,6 +45,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
 use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index cc42e69f538..1864c7e6ef8 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -2,26 +2,34 @@
 //! normal visitor, which just walks the entire body in one shot, the
 //! `ExprUseVisitor` determines how expressions are being used.
 
+use std::cell::{Ref, RefCell};
+use std::ops::Deref;
 use std::slice::from_ref;
 
 use hir::def::DefKind;
+use hir::pat_util::EnumerateAndAdjustIterator as _;
 use hir::Expr;
+use rustc_lint::LateContext;
 // Export these here so that Clippy can use them.
 pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
 
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{CtorOf, Res};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{HirId, PatKind};
-use rustc_infer::infer::InferCtxt;
+use rustc_middle::{bug, span_bug};
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt};
-use rustc_target::abi::FIRST_VARIANT;
+use rustc_middle::ty::{
+    self, adjustment, AdtKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _,
+};
+use rustc_span::{ErrorGuaranteed, Span};
+use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
+use rustc_trait_selection::infer::InferCtxtExt;
 use ty::BorrowKind::ImmBorrow;
 
-use crate::mem_categorization as mc;
+use crate::fn_ctxt::FnCtxt;
 
 /// This trait defines the callbacks you can expect to receive when
 /// employing the ExprUseVisitor.
@@ -80,191 +88,322 @@ pub trait Delegate<'tcx> {
     );
 }
 
-#[derive(Copy, Clone, PartialEq, Debug)]
-enum ConsumeMode {
-    /// reference to x where x has a type that copies
-    Copy,
-    /// reference to x where x has a type that moves
-    Move,
+impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D {
+    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
+        (**self).consume(place_with_id, diag_expr_id)
+    }
+
+    fn borrow(
+        &mut self,
+        place_with_id: &PlaceWithHirId<'tcx>,
+        diag_expr_id: HirId,
+        bk: ty::BorrowKind,
+    ) {
+        (**self).borrow(place_with_id, diag_expr_id, bk)
+    }
+
+    fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
+        (**self).copy(place_with_id, diag_expr_id)
+    }
+
+    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
+        (**self).mutate(assignee_place, diag_expr_id)
+    }
+
+    fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
+        (**self).bind(binding_place, diag_expr_id)
+    }
+
+    fn fake_read(
+        &mut self,
+        place_with_id: &PlaceWithHirId<'tcx>,
+        cause: FakeReadCause,
+        diag_expr_id: HirId,
+    ) {
+        (**self).fake_read(place_with_id, cause, diag_expr_id)
+    }
+}
+
+pub trait TypeInformationCtxt<'tcx> {
+    type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
+    where
+        Self: 'a;
+
+    type Error;
+
+    fn typeck_results(&self) -> Self::TypeckResults<'_>;
+
+    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
+
+    fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
+
+    fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error;
+
+    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>;
+
+    fn tainted_by_errors(&self) -> Result<(), Self::Error>;
+
+    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
+
+    fn body_owner_def_id(&self) -> LocalDefId;
+
+    fn tcx(&self) -> TyCtxt<'tcx>;
+}
+
+impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
+    type TypeckResults<'a> = Ref<'a, ty::TypeckResults<'tcx>>
+    where
+        Self: 'a;
+
+    type Error = ErrorGuaranteed;
+
+    fn typeck_results(&self) -> Self::TypeckResults<'_> {
+        self.typeck_results.borrow()
+    }
+
+    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
+        self.infcx.resolve_vars_if_possible(t)
+    }
+
+    fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
+        (**self).try_structurally_resolve_type(sp, ty)
+    }
+
+    fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error {
+        self.tcx.dcx().span_delayed_bug(span, msg.to_string())
+    }
+
+    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> {
+        ty.error_reported()
+    }
+
+    fn tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
+        if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) }
+    }
+
+    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
+        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
+    }
+
+    fn body_owner_def_id(&self) -> LocalDefId {
+        self.body_id
+    }
+
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+}
+
+impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
+    type TypeckResults<'a> = &'tcx ty::TypeckResults<'tcx>
+    where
+        Self: 'a;
+
+    type Error = !;
+
+    fn typeck_results(&self) -> Self::TypeckResults<'_> {
+        self.0.maybe_typeck_results().expect("expected typeck results")
+    }
+
+    fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
+        // FIXME: Maybe need to normalize here.
+        ty
+    }
+
+    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
+        t
+    }
+
+    fn report_error(&self, span: Span, msg: impl ToString) -> ! {
+        span_bug!(span, "{}", msg.to_string())
+    }
+
+    fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), !> {
+        Ok(())
+    }
+
+    fn tainted_by_errors(&self) -> Result<(), !> {
+        Ok(())
+    }
+
+    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
+        ty.is_copy_modulo_regions(self.0.tcx, self.0.param_env)
+    }
+
+    fn body_owner_def_id(&self) -> LocalDefId {
+        self.1
+    }
+
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.0.tcx
+    }
 }
 
 /// The ExprUseVisitor type
 ///
 /// This is the code that actually walks the tree.
-pub struct ExprUseVisitor<'a, 'tcx> {
-    mc: mc::MemCategorizationContext<'a, 'tcx>,
-    body_owner: LocalDefId,
-    delegate: &'a mut dyn Delegate<'tcx>,
+pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
+    cx: Cx,
+    /// We use a `RefCell` here so that delegates can mutate themselves, but we can
+    /// still have calls to our own helper functions.
+    delegate: RefCell<D>,
+    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
 }
 
-/// If the MC results in an error, it's because the type check
-/// failed (or will fail, when the error is uncovered and reported
-/// during writeback). In this case, we just ignore this part of the
-/// code.
-///
-/// Note that this macro appears similar to try!(), but, unlike try!(),
-/// it does not propagate the error.
-macro_rules! return_if_err {
-    ($inp: expr) => {
-        match $inp {
-            Ok(v) => v,
-            Err(()) => {
-                debug!("mc reported err");
-                return;
-            }
-        }
-    };
+impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> {
+    pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self {
+        Self::new((cx, body_def_id), delegate)
+    }
 }
 
-impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
+impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
     /// Creates the ExprUseVisitor, configuring it with the various options provided:
     ///
     /// - `delegate` -- who receives the callbacks
     /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
     /// - `typeck_results` --- typeck results for the code being analyzed
-    pub fn new(
-        delegate: &'a mut (dyn Delegate<'tcx> + 'a),
-        infcx: &'a InferCtxt<'tcx>,
-        body_owner: LocalDefId,
-        param_env: ty::ParamEnv<'tcx>,
-        typeck_results: &'a ty::TypeckResults<'tcx>,
-    ) -> Self {
+    pub(crate) fn new(cx: Cx, delegate: D) -> Self {
         ExprUseVisitor {
-            mc: mc::MemCategorizationContext::new(infcx, param_env, body_owner, typeck_results),
-            body_owner,
-            delegate,
+            delegate: RefCell::new(delegate),
+            upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()),
+            cx,
         }
     }
 
-    #[instrument(skip(self), level = "debug")]
-    pub fn consume_body(&mut self, body: &hir::Body<'_>) {
+    pub fn consume_body(&self, body: &hir::Body<'_>) -> Result<(), Cx::Error> {
         for param in body.params {
-            let param_ty = return_if_err!(self.mc.pat_ty_adjusted(param.pat));
+            let param_ty = self.pat_ty_adjusted(param.pat)?;
             debug!("consume_body: param_ty = {:?}", param_ty);
 
-            let param_place = self.mc.cat_rvalue(param.hir_id, param_ty);
+            let param_place = self.cat_rvalue(param.hir_id, param_ty);
 
-            self.walk_irrefutable_pat(&param_place, param.pat);
+            self.walk_irrefutable_pat(&param_place, param.pat)?;
         }
 
-        self.consume_expr(body.value);
-    }
+        self.consume_expr(body.value)?;
 
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.mc.tcx()
+        Ok(())
     }
 
-    fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
-        delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id)
+    fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
+        debug!("delegate_consume(place_with_id={:?})", place_with_id);
+
+        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
+            self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
+        } else {
+            self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
+        }
     }
 
-    fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) {
+    fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> {
         for expr in exprs {
-            self.consume_expr(expr);
+            self.consume_expr(expr)?;
         }
+
+        Ok(())
     }
 
-    pub fn consume_expr(&mut self, expr: &hir::Expr<'_>) {
+    // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`.
+    pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
         debug!("consume_expr(expr={:?})", expr);
 
-        let place_with_id = return_if_err!(self.mc.cat_expr(expr));
-        self.delegate_consume(&place_with_id, place_with_id.hir_id);
-        self.walk_expr(expr);
+        let place_with_id = self.cat_expr(expr)?;
+        self.consume_or_copy(&place_with_id, place_with_id.hir_id);
+        self.walk_expr(expr)?;
+        Ok(())
     }
 
-    fn mutate_expr(&mut self, expr: &hir::Expr<'_>) {
-        let place_with_id = return_if_err!(self.mc.cat_expr(expr));
-        self.delegate.mutate(&place_with_id, place_with_id.hir_id);
-        self.walk_expr(expr);
+    fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
+        let place_with_id = self.cat_expr(expr)?;
+        self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id);
+        self.walk_expr(expr)?;
+        Ok(())
     }
 
-    fn borrow_expr(&mut self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) {
+    fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> {
         debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk);
 
-        let place_with_id = return_if_err!(self.mc.cat_expr(expr));
-        self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk);
-
-        self.walk_expr(expr)
-    }
-
-    fn select_from_expr(&mut self, expr: &hir::Expr<'_>) {
+        let place_with_id = self.cat_expr(expr)?;
+        self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
         self.walk_expr(expr)
     }
 
-    pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) {
+    pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
         debug!("walk_expr(expr={:?})", expr);
 
-        self.walk_adjustment(expr);
+        self.walk_adjustment(expr)?;
 
         match expr.kind {
             hir::ExprKind::Path(_) => {}
 
-            hir::ExprKind::Type(subexpr, _) => self.walk_expr(subexpr),
+            hir::ExprKind::Type(subexpr, _) => {
+                self.walk_expr(subexpr)?;
+            }
 
             hir::ExprKind::Unary(hir::UnOp::Deref, base) => {
                 // *base
-                self.select_from_expr(base);
+                self.walk_expr(base)?;
             }
 
             hir::ExprKind::Field(base, _) => {
                 // base.f
-                self.select_from_expr(base);
+                self.walk_expr(base)?;
             }
 
             hir::ExprKind::Index(lhs, rhs, _) => {
                 // lhs[rhs]
-                self.select_from_expr(lhs);
-                self.consume_expr(rhs);
+                self.walk_expr(lhs)?;
+                self.consume_expr(rhs)?;
             }
 
             hir::ExprKind::Call(callee, args) => {
                 // callee(args)
-                self.consume_expr(callee);
-                self.consume_exprs(args);
+                self.consume_expr(callee)?;
+                self.consume_exprs(args)?;
             }
 
             hir::ExprKind::MethodCall(.., receiver, args, _) => {
                 // callee.m(args)
-                self.consume_expr(receiver);
-                self.consume_exprs(args);
+                self.consume_expr(receiver)?;
+                self.consume_exprs(args)?;
             }
 
             hir::ExprKind::Struct(_, fields, ref opt_with) => {
-                self.walk_struct_expr(fields, opt_with);
+                self.walk_struct_expr(fields, opt_with)?;
             }
 
             hir::ExprKind::Tup(exprs) => {
-                self.consume_exprs(exprs);
+                self.consume_exprs(exprs)?;
             }
 
             hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) => {
-                self.consume_expr(cond_expr);
-                self.consume_expr(then_expr);
+                self.consume_expr(cond_expr)?;
+                self.consume_expr(then_expr)?;
                 if let Some(else_expr) = *opt_else_expr {
-                    self.consume_expr(else_expr);
+                    self.consume_expr(else_expr)?;
                 }
             }
 
             hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => {
-                self.walk_local(init, pat, None, |t| t.borrow_expr(init, ty::ImmBorrow))
+                self.walk_local(init, pat, None, || self.borrow_expr(init, ty::ImmBorrow))?;
             }
 
             hir::ExprKind::Match(discr, arms, _) => {
-                let discr_place = return_if_err!(self.mc.cat_expr(discr));
-                return_if_err!(self.maybe_read_scrutinee(
+                let discr_place = self.cat_expr(discr)?;
+                self.maybe_read_scrutinee(
                     discr,
                     discr_place.clone(),
                     arms.iter().map(|arm| arm.pat),
-                ));
+                )?;
 
                 // treatment of the discriminant is handled while walking the arms.
                 for arm in arms {
-                    self.walk_arm(&discr_place, arm);
+                    self.walk_arm(&discr_place, arm)?;
                 }
             }
 
             hir::ExprKind::Array(exprs) => {
-                self.consume_exprs(exprs);
+                self.consume_exprs(exprs)?;
             }
 
             hir::ExprKind::AddrOf(_, m, base) => {
@@ -272,21 +411,23 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 // make sure that the thing we are pointing out stays valid
                 // for the lifetime `scope_r` of the resulting ptr:
                 let bk = ty::BorrowKind::from_mutbl(m);
-                self.borrow_expr(base, bk);
+                self.borrow_expr(base, bk)?;
             }
 
             hir::ExprKind::InlineAsm(asm) => {
                 for (op, _op_sp) in asm.operands {
                     match op {
-                        hir::InlineAsmOperand::In { expr, .. } => self.consume_expr(expr),
+                        hir::InlineAsmOperand::In { expr, .. } => {
+                            self.consume_expr(expr)?;
+                        }
                         hir::InlineAsmOperand::Out { expr: Some(expr), .. }
                         | hir::InlineAsmOperand::InOut { expr, .. } => {
-                            self.mutate_expr(expr);
+                            self.mutate_expr(expr)?;
                         }
                         hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
-                            self.consume_expr(in_expr);
+                            self.consume_expr(in_expr)?;
                             if let Some(out_expr) = out_expr {
-                                self.mutate_expr(out_expr);
+                                self.mutate_expr(out_expr)?;
                             }
                         }
                         hir::InlineAsmOperand::Out { expr: None, .. }
@@ -294,7 +435,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         | hir::InlineAsmOperand::SymFn { .. }
                         | hir::InlineAsmOperand::SymStatic { .. } => {}
                         hir::InlineAsmOperand::Label { block } => {
-                            self.walk_block(block);
+                            self.walk_block(block)?;
                         }
                     }
                 }
@@ -307,72 +448,74 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             | hir::ExprKind::Err(_) => {}
 
             hir::ExprKind::Loop(blk, ..) => {
-                self.walk_block(blk);
+                self.walk_block(blk)?;
             }
 
             hir::ExprKind::Unary(_, lhs) => {
-                self.consume_expr(lhs);
+                self.consume_expr(lhs)?;
             }
 
             hir::ExprKind::Binary(_, lhs, rhs) => {
-                self.consume_expr(lhs);
-                self.consume_expr(rhs);
+                self.consume_expr(lhs)?;
+                self.consume_expr(rhs)?;
             }
 
             hir::ExprKind::Block(blk, _) => {
-                self.walk_block(blk);
+                self.walk_block(blk)?;
             }
 
             hir::ExprKind::Break(_, ref opt_expr) | hir::ExprKind::Ret(ref opt_expr) => {
                 if let Some(expr) = *opt_expr {
-                    self.consume_expr(expr);
+                    self.consume_expr(expr)?;
                 }
             }
 
             hir::ExprKind::Become(call) => {
-                self.consume_expr(call);
+                self.consume_expr(call)?;
             }
 
             hir::ExprKind::Assign(lhs, rhs, _) => {
-                self.mutate_expr(lhs);
-                self.consume_expr(rhs);
+                self.mutate_expr(lhs)?;
+                self.consume_expr(rhs)?;
             }
 
             hir::ExprKind::Cast(base, _) => {
-                self.consume_expr(base);
+                self.consume_expr(base)?;
             }
 
             hir::ExprKind::DropTemps(expr) => {
-                self.consume_expr(expr);
+                self.consume_expr(expr)?;
             }
 
             hir::ExprKind::AssignOp(_, lhs, rhs) => {
-                if self.mc.typeck_results.is_method_call(expr) {
-                    self.consume_expr(lhs);
+                if self.cx.typeck_results().is_method_call(expr) {
+                    self.consume_expr(lhs)?;
                 } else {
-                    self.mutate_expr(lhs);
+                    self.mutate_expr(lhs)?;
                 }
-                self.consume_expr(rhs);
+                self.consume_expr(rhs)?;
             }
 
             hir::ExprKind::Repeat(base, _) => {
-                self.consume_expr(base);
+                self.consume_expr(base)?;
             }
 
             hir::ExprKind::Closure(closure) => {
-                self.walk_captures(closure);
+                self.walk_captures(closure)?;
             }
 
             hir::ExprKind::Yield(value, _) => {
-                self.consume_expr(value);
+                self.consume_expr(value)?;
             }
         }
+
+        Ok(())
     }
 
-    fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) {
+    fn walk_stmt(&self, stmt: &hir::Stmt<'_>) -> Result<(), Cx::Error> {
         match stmt.kind {
             hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => {
-                self.walk_local(expr, pat, *els, |_| {})
+                self.walk_local(expr, pat, *els, || Ok(()))?;
             }
 
             hir::StmtKind::Let(_) => {}
@@ -383,25 +526,26 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             }
 
             hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => {
-                self.consume_expr(expr);
+                self.consume_expr(expr)?;
             }
         }
+
+        Ok(())
     }
 
     fn maybe_read_scrutinee<'t>(
-        &mut self,
+        &self,
         discr: &Expr<'_>,
         discr_place: PlaceWithHirId<'tcx>,
         pats: impl Iterator<Item = &'t hir::Pat<'t>>,
-    ) -> Result<(), ()> {
+    ) -> Result<(), Cx::Error> {
         // Matching should not always be considered a use of the place, hence
         // discr does not necessarily need to be borrowed.
         // We only want to borrow discr if the pattern contain something other
         // than wildcards.
-        let ExprUseVisitor { ref mc, body_owner: _, delegate: _ } = *self;
         let mut needs_to_be_read = false;
         for pat in pats {
-            mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
+            self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
                 match &pat.kind {
                     PatKind::Binding(.., opt_sub_pat) => {
                         // If the opt_sub_pat is None, then the binding does not count as
@@ -419,7 +563,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         // A `Path` pattern is just a name like `Foo`. This is either a
                         // named constant or else it refers to an ADT variant
 
-                        let res = self.mc.typeck_results.qpath_res(qpath, pat.hir_id);
+                        let res = self.cx.typeck_results().qpath_res(qpath, pat.hir_id);
                         match res {
                             Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {
                                 // Named constants have to be equated with the value
@@ -431,7 +575,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                             _ => {
                                 // Otherwise, this is a struct/enum variant, and so it's
                                 // only a read if we need to read the discriminant.
-                                needs_to_be_read |= is_multivariant_adt(place.place.ty());
+                                needs_to_be_read |=
+                                    self.is_multivariant_adt(place.place.ty(), pat.span);
                             }
                         }
                     }
@@ -443,7 +588,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         // perform some reads).
 
                         let place_ty = place.place.ty();
-                        needs_to_be_read |= is_multivariant_adt(place_ty);
+                        needs_to_be_read |= self.is_multivariant_adt(place_ty, pat.span);
                     }
                     PatKind::Lit(_) | PatKind::Range(..) => {
                         // If the PatKind is a Lit or a Range then we want
@@ -473,18 +618,20 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         // being examined
                     }
                 }
+
+                Ok(())
             })?
         }
 
         if needs_to_be_read {
-            self.borrow_expr(discr, ty::ImmBorrow);
+            self.borrow_expr(discr, ty::ImmBorrow)?;
         } else {
             let closure_def_id = match discr_place.place.base {
                 PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id),
                 _ => None,
             };
 
-            self.delegate.fake_read(
+            self.delegate.borrow_mut().fake_read(
                 &discr_place,
                 FakeReadCause::ForMatchedPlace(closure_def_id),
                 discr_place.hir_id,
@@ -492,90 +639,93 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
             // We always want to walk the discriminant. We want to make sure, for instance,
             // that the discriminant has been initialized.
-            self.walk_expr(discr);
+            self.walk_expr(discr)?;
         }
         Ok(())
     }
 
     fn walk_local<F>(
-        &mut self,
+        &self,
         expr: &hir::Expr<'_>,
         pat: &hir::Pat<'_>,
         els: Option<&hir::Block<'_>>,
         mut f: F,
-    ) where
-        F: FnMut(&mut Self),
+    ) -> Result<(), Cx::Error>
+    where
+        F: FnMut() -> Result<(), Cx::Error>,
     {
-        self.walk_expr(expr);
-        let expr_place = return_if_err!(self.mc.cat_expr(expr));
-        f(self);
+        self.walk_expr(expr)?;
+        let expr_place = self.cat_expr(expr)?;
+        f()?;
         if let Some(els) = els {
             // borrowing because we need to test the discriminant
-            return_if_err!(self.maybe_read_scrutinee(
-                expr,
-                expr_place.clone(),
-                from_ref(pat).iter()
-            ));
-            self.walk_block(els)
+            self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter())?;
+            self.walk_block(els)?;
         }
-        self.walk_irrefutable_pat(&expr_place, pat);
+        self.walk_irrefutable_pat(&expr_place, pat)?;
+        Ok(())
     }
 
     /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
     /// depending on its type.
-    fn walk_block(&mut self, blk: &hir::Block<'_>) {
+    fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> {
         debug!("walk_block(blk.hir_id={})", blk.hir_id);
 
         for stmt in blk.stmts {
-            self.walk_stmt(stmt);
+            self.walk_stmt(stmt)?;
         }
 
         if let Some(tail_expr) = blk.expr {
-            self.consume_expr(tail_expr);
+            self.consume_expr(tail_expr)?;
         }
+
+        Ok(())
     }
 
     fn walk_struct_expr<'hir>(
-        &mut self,
+        &self,
         fields: &[hir::ExprField<'_>],
         opt_with: &Option<&'hir hir::Expr<'_>>,
-    ) {
+    ) -> Result<(), Cx::Error> {
         // Consume the expressions supplying values for each field.
         for field in fields {
-            self.consume_expr(field.expr);
+            self.consume_expr(field.expr)?;
 
             // The struct path probably didn't resolve
-            if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() {
-                self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field");
+            if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() {
+                self.cx
+                    .tcx()
+                    .dcx()
+                    .span_delayed_bug(field.span, "couldn't resolve index for field");
             }
         }
 
         let with_expr = match *opt_with {
             Some(w) => &*w,
             None => {
-                return;
+                return Ok(());
             }
         };
 
-        let with_place = return_if_err!(self.mc.cat_expr(with_expr));
+        let with_place = self.cat_expr(with_expr)?;
 
         // Select just those fields of the `with`
         // expression that will actually be used
-        match with_place.place.ty().kind() {
+        match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
             ty::Adt(adt, args) if adt.is_struct() => {
                 // Consume those fields of the with expression that are needed.
                 for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
-                    let is_mentioned = fields
-                        .iter()
-                        .any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
+                    let is_mentioned = fields.iter().any(|f| {
+                        self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index)
+                    });
                     if !is_mentioned {
-                        let field_place = self.mc.cat_projection(
-                            &*with_expr,
+                        let field_place = self.cat_projection(
+                            with_expr.hir_id,
                             with_place.clone(),
-                            with_field.ty(self.tcx(), args),
+                            with_field.ty(self.cx.tcx(), args),
                             ProjectionKind::Field(f_index, FIRST_VARIANT),
                         );
-                        self.delegate_consume(&field_place, field_place.hir_id);
+                        self.consume_or_copy(&field_place, field_place.hir_id);
                     }
                 }
             }
@@ -584,7 +734,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 // struct; however, when EUV is run during typeck, it
                 // may not. This will generate an error earlier in typeck,
                 // so we can just ignore it.
-                if self.tcx().dcx().has_errors().is_none() {
+                if self.cx.tcx().dcx().has_errors().is_none() {
                     span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
                 }
             }
@@ -592,15 +742,18 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
         // walk the with expression so that complex expressions
         // are properly handled.
-        self.walk_expr(with_expr);
+        self.walk_expr(with_expr)?;
+
+        Ok(())
     }
 
     /// Invoke the appropriate delegate calls for anything that gets
     /// consumed or borrowed as part of the automatic adjustment
     /// process.
-    fn walk_adjustment(&mut self, expr: &hir::Expr<'_>) {
-        let adjustments = self.mc.typeck_results.expr_adjustments(expr);
-        let mut place_with_id = return_if_err!(self.mc.cat_expr_unadjusted(expr));
+    fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
+        let typeck_results = self.cx.typeck_results();
+        let adjustments = typeck_results.expr_adjustments(expr);
+        let mut place_with_id = self.cat_expr_unadjusted(expr)?;
         for adjustment in adjustments {
             debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
             match adjustment.kind {
@@ -609,7 +762,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 | adjustment::Adjust::DynStar => {
                     // Creating a closure/fn-pointer or unsizing consumes
                     // the input and stores it into the resulting rvalue.
-                    self.delegate_consume(&place_with_id, place_with_id.hir_id);
+                    self.consume_or_copy(&place_with_id, place_with_id.hir_id);
                 }
 
                 adjustment::Adjust::Deref(None) => {}
@@ -621,23 +774,24 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 // this is an autoref of `x`.
                 adjustment::Adjust::Deref(Some(ref deref)) => {
                     let bk = ty::BorrowKind::from_mutbl(deref.mutbl);
-                    self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk);
+                    self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
                 }
 
                 adjustment::Adjust::Borrow(ref autoref) => {
                     self.walk_autoref(expr, &place_with_id, autoref);
                 }
             }
-            place_with_id =
-                return_if_err!(self.mc.cat_expr_adjusted(expr, place_with_id, adjustment));
+            place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
         }
+
+        Ok(())
     }
 
     /// Walks the autoref `autoref` applied to the autoderef'd
     /// `expr`. `base_place` is the mem-categorized form of `expr`
     /// after all relevant autoderefs have occurred.
     fn walk_autoref(
-        &mut self,
+        &self,
         expr: &hir::Expr<'_>,
         base_place: &PlaceWithHirId<'tcx>,
         autoref: &adjustment::AutoBorrow<'tcx>,
@@ -649,7 +803,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
         match *autoref {
             adjustment::AutoBorrow::Ref(_, m) => {
-                self.delegate.borrow(
+                self.delegate.borrow_mut().borrow(
                     base_place,
                     base_place.hir_id,
                     ty::BorrowKind::from_mutbl(m.into()),
@@ -659,80 +813,93 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             adjustment::AutoBorrow::RawPtr(m) => {
                 debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place);
 
-                self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m));
+                self.delegate.borrow_mut().borrow(
+                    base_place,
+                    base_place.hir_id,
+                    ty::BorrowKind::from_mutbl(m),
+                );
             }
         }
     }
 
-    fn walk_arm(&mut self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) {
+    fn walk_arm(
+        &self,
+        discr_place: &PlaceWithHirId<'tcx>,
+        arm: &hir::Arm<'_>,
+    ) -> Result<(), Cx::Error> {
         let closure_def_id = match discr_place.place.base {
             PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id),
             _ => None,
         };
 
-        self.delegate.fake_read(
+        self.delegate.borrow_mut().fake_read(
             discr_place,
             FakeReadCause::ForMatchedPlace(closure_def_id),
             discr_place.hir_id,
         );
-        self.walk_pat(discr_place, arm.pat, arm.guard.is_some());
+        self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?;
 
         if let Some(ref e) = arm.guard {
-            self.consume_expr(e)
+            self.consume_expr(e)?;
         }
 
-        self.consume_expr(arm.body);
+        self.consume_expr(arm.body)?;
+        Ok(())
     }
 
     /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or
     /// let binding, and *not* a match arm or nested pat.)
-    fn walk_irrefutable_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) {
+    fn walk_irrefutable_pat(
+        &self,
+        discr_place: &PlaceWithHirId<'tcx>,
+        pat: &hir::Pat<'_>,
+    ) -> Result<(), Cx::Error> {
         let closure_def_id = match discr_place.place.base {
             PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id),
             _ => None,
         };
 
-        self.delegate.fake_read(
+        self.delegate.borrow_mut().fake_read(
             discr_place,
             FakeReadCause::ForLet(closure_def_id),
             discr_place.hir_id,
         );
-        self.walk_pat(discr_place, pat, false);
+        self.walk_pat(discr_place, pat, false)?;
+        Ok(())
     }
 
     /// The core driver for walking a pattern
     fn walk_pat(
-        &mut self,
+        &self,
         discr_place: &PlaceWithHirId<'tcx>,
         pat: &hir::Pat<'_>,
         has_guard: bool,
-    ) {
+    ) -> Result<(), Cx::Error> {
         debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard);
 
-        let tcx = self.tcx();
-        let ExprUseVisitor { ref mc, body_owner: _, ref mut delegate } = *self;
-        return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
+        let tcx = self.cx.tcx();
+        self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
             if let PatKind::Binding(_, canonical_id, ..) = pat.kind {
                 debug!("walk_pat: binding place={:?} pat={:?}", place, pat);
                 if let Some(bm) =
-                    mc.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span)
+                    self.cx.typeck_results().extract_binding_mode(tcx.sess, pat.hir_id, pat.span)
                 {
                     debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
 
                     // pat_ty: the type of the binding being produced.
-                    let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
+                    let pat_ty = self.node_ty(pat.hir_id)?;
                     debug!("walk_pat: pat_ty={:?}", pat_ty);
 
                     let def = Res::Local(canonical_id);
-                    if let Ok(ref binding_place) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) {
-                        delegate.bind(binding_place, binding_place.hir_id);
+                    if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) {
+                        self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id);
                     }
 
                     // Subtle: MIR desugaring introduces immutable borrows for each pattern
                     // binding when lowering pattern guards to ensure that the guard does not
                     // modify the scrutinee.
                     if has_guard {
-                        delegate.borrow(place, discr_place.hir_id, ImmBorrow);
+                        self.delegate.borrow_mut().borrow(place, discr_place.hir_id, ImmBorrow);
                     }
 
                     // It is also a borrow or copy/move of the value being matched.
@@ -742,11 +909,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                     match bm.0 {
                         hir::ByRef::Yes(m) => {
                             let bk = ty::BorrowKind::from_mutbl(m);
-                            delegate.borrow(place, discr_place.hir_id, bk);
+                            self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
                         }
                         hir::ByRef::No => {
                             debug!("walk_pat binding consuming pat");
-                            delegate_consume(mc, *delegate, place, discr_place.hir_id);
+                            self.consume_or_copy(place, discr_place.hir_id);
                         }
                     }
                 }
@@ -755,12 +922,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 // determines whether to borrow *at the level of the deref pattern* rather than
                 // borrowing the bound place (since that inner place is inside the temporary that
                 // stores the result of calling `deref()`/`deref_mut()` so can't be captured).
-                let mutable = mc.typeck_results.pat_has_ref_mut_binding(subpattern);
+                let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpattern);
                 let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
                 let bk = ty::BorrowKind::from_mutbl(mutability);
-                delegate.borrow(place, discr_place.hir_id, bk);
+                self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
             }
-        }));
+
+            Ok(())
+        })
     }
 
     /// Handle the case where the current body contains a closure.
@@ -782,7 +951,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     ///
     /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
     /// closure as the DefId.
-    fn walk_captures(&mut self, closure_expr: &hir::Closure<'_>) {
+    fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> {
         fn upvar_is_local_variable(
             upvars: Option<&FxIndexMap<HirId, hir::Upvar>>,
             upvar_id: HirId,
@@ -793,21 +962,21 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
         debug!("walk_captures({:?})", closure_expr);
 
-        let tcx = self.tcx();
+        let tcx = self.cx.tcx();
         let closure_def_id = closure_expr.def_id;
-        let upvars = tcx.upvars_mentioned(self.body_owner);
-
         // For purposes of this function, coroutine and closures are equivalent.
-        let body_owner_is_closure =
-            matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,);
+        let body_owner_is_closure = matches!(
+            tcx.hir().body_owner_kind(self.cx.body_owner_def_id()),
+            hir::BodyOwnerKind::Closure
+        );
 
         // If we have a nested closure, we want to include the fake reads present in the nested closure.
-        if let Some(fake_reads) = self.mc.typeck_results.closure_fake_reads.get(&closure_def_id) {
+        if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) {
             for (fake_read, cause, hir_id) in fake_reads.iter() {
                 match fake_read.base {
                     PlaceBase::Upvar(upvar_id) => {
                         if upvar_is_local_variable(
-                            upvars,
+                            self.upvars,
                             upvar_id.var_path.hir_id,
                             body_owner_is_closure,
                         ) {
@@ -837,7 +1006,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         );
                     }
                 };
-                self.delegate.fake_read(
+                self.delegate.borrow_mut().fake_read(
                     &PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id },
                     *cause,
                     *hir_id,
@@ -845,10 +1014,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             }
         }
 
-        if let Some(min_captures) = self.mc.typeck_results.closure_min_captures.get(&closure_def_id)
+        if let Some(min_captures) =
+            self.cx.typeck_results().closure_min_captures.get(&closure_def_id)
         {
             for (var_hir_id, min_list) in min_captures.iter() {
-                if upvars.map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) {
+                if self
+                    .upvars
+                    .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id))
+                {
                     // The nested closure might be capturing the current (enclosing) closure's local variables.
                     // We check if the root variable is ever mentioned within the enclosing closure, if not
                     // then for the current body (if it's a closure) these aren't captures, we will ignore them.
@@ -860,7 +1033,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
                     let place_base = if body_owner_is_closure {
                         // Mark the place to be captured by the enclosing closure
-                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner))
+                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id()))
                     } else {
                         // If the body owner isn't a closure then the variable must
                         // be a local variable
@@ -878,10 +1051,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
                     match capture_info.capture_kind {
                         ty::UpvarCapture::ByValue => {
-                            self.delegate_consume(&place_with_id, place_with_id.hir_id);
+                            self.consume_or_copy(&place_with_id, place_with_id.hir_id);
                         }
                         ty::UpvarCapture::ByRef(upvar_borrow) => {
-                            self.delegate.borrow(
+                            self.delegate.borrow_mut().borrow(
                                 &place_with_id,
                                 place_with_id.hir_id,
                                 upvar_borrow,
@@ -891,53 +1064,733 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 }
             }
         }
+
+        Ok(())
     }
 }
 
-fn copy_or_move<'a, 'tcx>(
-    mc: &mc::MemCategorizationContext<'a, 'tcx>,
-    place_with_id: &PlaceWithHirId<'tcx>,
-) -> ConsumeMode {
-    if !mc.type_is_copy_modulo_regions(place_with_id.place.ty()) {
-        ConsumeMode::Move
-    } else {
-        ConsumeMode::Copy
+/// The job of the categorization methods is to analyze an expression to
+/// determine what kind of memory is used in evaluating it (for example,
+/// where dereferences occur and what kind of pointer is dereferenced;
+/// whether the memory is mutable, etc.).
+///
+/// Categorization effectively transforms all of our expressions into
+/// expressions of the following forms (the actual enum has many more
+/// possibilities, naturally, but they are all variants of these base
+/// forms):
+/// ```ignore (not-rust)
+/// E = rvalue    // some computed rvalue
+///   | x         // address of a local variable or argument
+///   | *E        // deref of a ptr
+///   | E.comp    // access to an interior component
+/// ```
+/// Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
+/// address where the result is to be found. If Expr is a place, then this
+/// is the address of the place. If `Expr` is an rvalue, this is the address of
+/// some temporary spot in memory where the result is stored.
+///
+/// Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)`
+/// as follows:
+///
+/// - `cat`: what kind of expression was this? This is a subset of the
+///   full expression forms which only includes those that we care about
+///   for the purpose of the analysis.
+/// - `mutbl`: mutability of the address `A`.
+/// - `ty`: the type of data found at the address `A`.
+///
+/// The resulting categorization tree differs somewhat from the expressions
+/// themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is
+/// decomposed into two operations: a dereference to reach the array data and
+/// then an index to jump forward to the relevant item.
+///
+/// ## By-reference upvars
+///
+/// One part of the codegen which may be non-obvious is that we translate
+/// closure upvars into the dereference of a borrowed pointer; this more closely
+/// resembles the runtime codegen. So, for example, if we had:
+///
+///     let mut x = 3;
+///     let y = 5;
+///     let inc = || x += y;
+///
+/// Then when we categorize `x` (*within* the closure) we would yield a
+/// result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
+/// tied to `x`. The type of `x'` will be a borrowed pointer.
+impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
+    fn resolve_type_vars_or_error(
+        &self,
+        id: HirId,
+        ty: Option<Ty<'tcx>>,
+    ) -> Result<Ty<'tcx>, Cx::Error> {
+        match ty {
+            Some(ty) => {
+                let ty = self.cx.resolve_vars_if_possible(ty);
+                self.cx.error_reported_in_ty(ty)?;
+                if ty.is_ty_var() {
+                    debug!("resolve_type_vars_or_error: infer var from {:?}", ty);
+                    Err(self
+                        .cx
+                        .report_error(self.cx.tcx().hir().span(id), "encountered type variable"))
+                } else {
+                    Ok(ty)
+                }
+            }
+            None => {
+                // FIXME: We shouldn't be relying on the infcx being tainted.
+                self.cx.tainted_by_errors()?;
+                bug!(
+                    "no type for node {} in mem_categorization",
+                    self.cx.tcx().hir().node_to_string(id)
+                );
+            }
+        }
     }
-}
 
-// - If a place is used in a `ByValue` context then move it if it's not a `Copy` type.
-// - If the place that is a `Copy` type consider it an `ImmBorrow`.
-fn delegate_consume<'a, 'tcx>(
-    mc: &mc::MemCategorizationContext<'a, 'tcx>,
-    delegate: &mut (dyn Delegate<'tcx> + 'a),
-    place_with_id: &PlaceWithHirId<'tcx>,
-    diag_expr_id: HirId,
-) {
-    debug!("delegate_consume(place_with_id={:?})", place_with_id);
+    fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
+        self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
+    }
 
-    let mode = copy_or_move(mc, place_with_id);
+    fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
+        self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
+    }
 
-    match mode {
-        ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id),
-        ConsumeMode::Copy => delegate.copy(place_with_id, diag_expr_id),
+    fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
+        self.resolve_type_vars_or_error(
+            expr.hir_id,
+            self.cx.typeck_results().expr_ty_adjusted_opt(expr),
+        )
+    }
+
+    /// Returns the type of value that this pattern matches against.
+    /// Some non-obvious cases:
+    ///
+    /// - a `ref x` binding matches against a value of type `T` and gives
+    ///   `x` the type `&T`; we return `T`.
+    /// - a pattern with implicit derefs (thanks to default binding
+    ///   modes #42640) may look like `Some(x)` but in fact have
+    ///   implicit deref patterns attached (e.g., it is really
+    ///   `&Some(x)`). In that case, we return the "outermost" type
+    ///   (e.g., `&Option<T>`).
+    fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
+        // Check for implicit `&` types wrapping the pattern; note
+        // that these are never attached to binding patterns, so
+        // actually this is somewhat "disjoint" from the code below
+        // that aims to account for `ref x`.
+        if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) {
+            if let Some(first_ty) = vec.first() {
+                debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
+                return Ok(*first_ty);
+            }
+        }
+
+        self.pat_ty_unadjusted(pat)
+    }
+
+    /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns.
+    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
+        let base_ty = self.node_ty(pat.hir_id)?;
+        trace!(?base_ty);
+
+        // This code detects whether we are looking at a `ref x`,
+        // and if so, figures out what the type *being borrowed* is.
+        match pat.kind {
+            PatKind::Binding(..) => {
+                let bm = *self
+                    .cx
+                    .typeck_results()
+                    .pat_binding_modes()
+                    .get(pat.hir_id)
+                    .expect("missing binding mode");
+
+                if matches!(bm.0, hir::ByRef::Yes(_)) {
+                    // a bind-by-ref means that the base_ty will be the type of the ident itself,
+                    // but what we want here is the type of the underlying value being borrowed.
+                    // So peel off one-level, turning the &T into T.
+                    match self
+                        .cx
+                        .try_structurally_resolve_type(pat.span, base_ty)
+                        .builtin_deref(false)
+                    {
+                        Some(ty) => Ok(ty),
+                        None => {
+                            debug!("By-ref binding of non-derefable type");
+                            Err(self
+                                .cx
+                                .report_error(pat.span, "by-ref binding of non-derefable type"))
+                        }
+                    }
+                } else {
+                    Ok(base_ty)
+                }
+            }
+            _ => Ok(base_ty),
+        }
+    }
+
+    fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr))
+    }
+
+    /// This recursion helper avoids going through *too many*
+    /// adjustments, since *only* non-overloaded deref recurses.
+    fn cat_expr_(
+        &self,
+        expr: &hir::Expr<'_>,
+        adjustments: &[adjustment::Adjustment<'tcx>],
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        match adjustments.split_last() {
+            None => self.cat_expr_unadjusted(expr),
+            Some((adjustment, previous)) => {
+                self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment)
+            }
+        }
+    }
+
+    fn cat_expr_adjusted(
+        &self,
+        expr: &hir::Expr<'_>,
+        previous: PlaceWithHirId<'tcx>,
+        adjustment: &adjustment::Adjustment<'tcx>,
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
+    }
+
+    fn cat_expr_adjusted_with<F>(
+        &self,
+        expr: &hir::Expr<'_>,
+        previous: F,
+        adjustment: &adjustment::Adjustment<'tcx>,
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>
+    where
+        F: FnOnce() -> Result<PlaceWithHirId<'tcx>, Cx::Error>,
+    {
+        let target = self.cx.resolve_vars_if_possible(adjustment.target);
+        match adjustment.kind {
+            adjustment::Adjust::Deref(overloaded) => {
+                // Equivalent to *expr or something similar.
+                let base = if let Some(deref) = overloaded {
+                    let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl);
+                    self.cat_rvalue(expr.hir_id, ref_ty)
+                } else {
+                    previous()?
+                };
+                self.cat_deref(expr.hir_id, base)
+            }
+
+            adjustment::Adjust::NeverToAny
+            | adjustment::Adjust::Pointer(_)
+            | adjustment::Adjust::Borrow(_)
+            | adjustment::Adjust::DynStar => {
+                // Result is an rvalue.
+                Ok(self.cat_rvalue(expr.hir_id, target))
+            }
+        }
     }
-}
 
-fn is_multivariant_adt(ty: Ty<'_>) -> bool {
-    if let ty::Adt(def, _) = ty.kind() {
-        // Note that if a non-exhaustive SingleVariant is defined in another crate, we need
-        // to assume that more cases will be added to the variant in the future. This mean
-        // that we should handle non-exhaustive SingleVariant the same way we would handle
-        // a MultiVariant.
-        // If the variant is not local it must be defined in another crate.
-        let is_non_exhaustive = match def.adt_kind() {
-            AdtKind::Struct | AdtKind::Union => {
-                def.non_enum_variant().is_field_list_non_exhaustive()
-            }
-            AdtKind::Enum => def.is_variant_list_non_exhaustive(),
+    fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        let expr_ty = self.expr_ty(expr)?;
+        match expr.kind {
+            hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => {
+                if self.cx.typeck_results().is_method_call(expr) {
+                    self.cat_overloaded_place(expr, e_base)
+                } else {
+                    let base = self.cat_expr(e_base)?;
+                    self.cat_deref(expr.hir_id, base)
+                }
+            }
+
+            hir::ExprKind::Field(base, _) => {
+                let base = self.cat_expr(base)?;
+                debug!(?base);
+
+                let field_idx = self
+                    .cx
+                    .typeck_results()
+                    .field_indices()
+                    .get(expr.hir_id)
+                    .cloned()
+                    .expect("Field index not found");
+
+                Ok(self.cat_projection(
+                    expr.hir_id,
+                    base,
+                    expr_ty,
+                    ProjectionKind::Field(field_idx, FIRST_VARIANT),
+                ))
+            }
+
+            hir::ExprKind::Index(base, _, _) => {
+                if self.cx.typeck_results().is_method_call(expr) {
+                    // If this is an index implemented by a method call, then it
+                    // will include an implicit deref of the result.
+                    // The call to index() returns a `&T` value, which
+                    // is an rvalue. That is what we will be
+                    // dereferencing.
+                    self.cat_overloaded_place(expr, base)
+                } else {
+                    let base = self.cat_expr(base)?;
+                    Ok(self.cat_projection(expr.hir_id, base, expr_ty, ProjectionKind::Index))
+                }
+            }
+
+            hir::ExprKind::Path(ref qpath) => {
+                let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id);
+                self.cat_res(expr.hir_id, expr.span, expr_ty, res)
+            }
+
+            hir::ExprKind::Type(e, _) => self.cat_expr(e),
+
+            hir::ExprKind::AddrOf(..)
+            | hir::ExprKind::Call(..)
+            | hir::ExprKind::Assign(..)
+            | hir::ExprKind::AssignOp(..)
+            | hir::ExprKind::Closure { .. }
+            | hir::ExprKind::Ret(..)
+            | hir::ExprKind::Become(..)
+            | hir::ExprKind::Unary(..)
+            | hir::ExprKind::Yield(..)
+            | hir::ExprKind::MethodCall(..)
+            | hir::ExprKind::Cast(..)
+            | hir::ExprKind::DropTemps(..)
+            | hir::ExprKind::Array(..)
+            | hir::ExprKind::If(..)
+            | hir::ExprKind::Tup(..)
+            | hir::ExprKind::Binary(..)
+            | hir::ExprKind::Block(..)
+            | hir::ExprKind::Let(..)
+            | hir::ExprKind::Loop(..)
+            | hir::ExprKind::Match(..)
+            | hir::ExprKind::Lit(..)
+            | hir::ExprKind::ConstBlock(..)
+            | hir::ExprKind::Break(..)
+            | hir::ExprKind::Continue(..)
+            | hir::ExprKind::Struct(..)
+            | hir::ExprKind::Repeat(..)
+            | hir::ExprKind::InlineAsm(..)
+            | hir::ExprKind::OffsetOf(..)
+            | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)),
+        }
+    }
+
+    fn cat_res(
+        &self,
+        hir_id: HirId,
+        span: Span,
+        expr_ty: Ty<'tcx>,
+        res: Res,
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        match res {
+            Res::Def(
+                DefKind::Ctor(..)
+                | DefKind::Const
+                | DefKind::ConstParam
+                | DefKind::AssocConst
+                | DefKind::Fn
+                | DefKind::AssocFn,
+                _,
+            )
+            | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)),
+
+            Res::Def(DefKind::Static { .. }, _) => {
+                Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new()))
+            }
+
+            Res::Local(var_id) => {
+                if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) {
+                    self.cat_upvar(hir_id, var_id)
+                } else {
+                    Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
+                }
+            }
+
+            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def),
+        }
+    }
+
+    /// Categorize an upvar.
+    ///
+    /// Note: the actual upvar access contains invisible derefs of closure
+    /// environment and upvar reference as appropriate. Only regionck cares
+    /// about these dereferences, so we let it compute them as needed.
+    fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        let closure_expr_def_id = self.cx.body_owner_def_id();
+
+        let upvar_id = ty::UpvarId {
+            var_path: ty::UpvarPath { hir_id: var_id },
+            closure_expr_id: closure_expr_def_id,
         };
-        def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive)
-    } else {
-        false
+        let var_ty = self.node_ty(var_id)?;
+
+        Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new()))
+    }
+
+    fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> {
+        PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
+    }
+
+    fn cat_projection(
+        &self,
+        node: HirId,
+        base_place: PlaceWithHirId<'tcx>,
+        ty: Ty<'tcx>,
+        kind: ProjectionKind,
+    ) -> PlaceWithHirId<'tcx> {
+        let place_ty = base_place.place.ty();
+        let mut projections = base_place.place.projections;
+
+        let node_ty = self.cx.typeck_results().node_type(node);
+        // Opaque types can't have field projections, but we can instead convert
+        // the current place in-place (heh) to the hidden type, and then apply all
+        // follow up projections on that.
+        if node_ty != place_ty
+            && self
+                .cx
+                .try_structurally_resolve_type(
+                    self.cx.tcx().hir().span(base_place.hir_id),
+                    place_ty,
+                )
+                .is_impl_trait()
+        {
+            projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
+        }
+        projections.push(Projection { kind, ty });
+        PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
+    }
+
+    fn cat_overloaded_place(
+        &self,
+        expr: &hir::Expr<'_>,
+        base: &hir::Expr<'_>,
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        // Reconstruct the output assuming it's a reference with the
+        // same region and mutability as the receiver. This holds for
+        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
+        let place_ty = self.expr_ty(expr)?;
+        let base_ty = self.expr_ty_adjusted(base)?;
+
+        let ty::Ref(region, _, mutbl) =
+            *self.cx.try_structurally_resolve_type(base.span, base_ty).kind()
+        else {
+            span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
+        };
+        let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl);
+
+        let base = self.cat_rvalue(expr.hir_id, ref_ty);
+        self.cat_deref(expr.hir_id, base)
+    }
+
+    fn cat_deref(
+        &self,
+        node: HirId,
+        base_place: PlaceWithHirId<'tcx>,
+    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
+        let base_curr_ty = base_place.place.ty();
+        let deref_ty = match self
+            .cx
+            .try_structurally_resolve_type(
+                self.cx.tcx().hir().span(base_place.hir_id),
+                base_curr_ty,
+            )
+            .builtin_deref(true)
+        {
+            Some(ty) => ty,
+            None => {
+                debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
+                return Err(self.cx.report_error(
+                    self.cx.tcx().hir().span(node),
+                    "explicit deref of non-derefable type",
+                ));
+            }
+        };
+        let mut projections = base_place.place.projections;
+        projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty });
+
+        Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections))
+    }
+
+    /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
+    /// Here `pat_hir_id` is the HirId of the pattern itself.
+    fn variant_index_for_adt(
+        &self,
+        qpath: &hir::QPath<'_>,
+        pat_hir_id: HirId,
+        span: Span,
+    ) -> Result<VariantIdx, Cx::Error> {
+        let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
+        let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else {
+            return Err(self
+                .cx
+                .report_error(span, "struct or tuple struct pattern not applied to an ADT"));
+        };
+
+        match res {
+            Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
+            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
+                Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
+            }
+            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
+            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
+            | Res::SelfCtor(..)
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. } => {
+                // Structs and Unions have only have one variant.
+                Ok(FIRST_VARIANT)
+            }
+            _ => bug!("expected ADT path, found={:?}", res),
+        }
+    }
+
+    /// Returns the total number of fields in an ADT variant used within a pattern.
+    /// Here `pat_hir_id` is the HirId of the pattern itself.
+    fn total_fields_in_adt_variant(
+        &self,
+        pat_hir_id: HirId,
+        variant_index: VariantIdx,
+        span: Span,
+    ) -> Result<usize, Cx::Error> {
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
+        match self.cx.try_structurally_resolve_type(span, ty).kind() {
+            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
+            _ => {
+                self.cx
+                    .tcx()
+                    .dcx()
+                    .span_bug(span, "struct or tuple struct pattern not applied to an ADT");
+            }
+        }
+    }
+
+    /// Returns the total number of fields in a tuple used within a Tuple pattern.
+    /// Here `pat_hir_id` is the HirId of the pattern itself.
+    fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
+        match self.cx.try_structurally_resolve_type(span, ty).kind() {
+            ty::Tuple(args) => Ok(args.len()),
+            _ => Err(self.cx.report_error(span, "tuple pattern not applied to a tuple")),
+        }
+    }
+
+    /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
+    /// is being matched against.
+    ///
+    /// In general, the way that this works is that we walk down the pattern,
+    /// constructing a `PlaceWithHirId` that represents the path that will be taken
+    /// to reach the value being matched.
+    fn cat_pattern<F>(
+        &self,
+        mut place_with_id: PlaceWithHirId<'tcx>,
+        pat: &hir::Pat<'_>,
+        op: &mut F,
+    ) -> Result<(), Cx::Error>
+    where
+        F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>) -> Result<(), Cx::Error>,
+    {
+        // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly.
+        // `PlaceWithHirId`s are constructed differently from patterns. For example, in
+        //
+        // ```
+        // match foo {
+        //     &&Some(x, ) => { ... },
+        //     _ => { ... },
+        // }
+        // ```
+        //
+        // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the
+        // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the
+        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
+        //
+        // `&&Some(x,)` `place_foo`
+        //  `&Some(x,)` `deref { place_foo}`
+        //   `Some(x,)` `deref { deref { place_foo }}`
+        //       `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place
+        //
+        // The above example has no adjustments. If the code were instead the (after adjustments,
+        // equivalent) version
+        //
+        // ```
+        // match foo {
+        //     Some(x, ) => { ... },
+        //     _ => { ... },
+        // }
+        // ```
+        //
+        // Then we see that to get the same result, we must start with
+        // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
+        // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
+        for _ in
+            0..self.cx.typeck_results().pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len())
+        {
+            debug!("applying adjustment to place_with_id={:?}", place_with_id);
+            place_with_id = self.cat_deref(pat.hir_id, place_with_id)?;
+        }
+        let place_with_id = place_with_id; // lose mutability
+        debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id);
+
+        // Invoke the callback, but only now, after the `place_with_id` has adjusted.
+        //
+        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
+        // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We
+        // don't want to call `op` with these incompatible values. As written, what happens instead
+        // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern
+        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
+        // result in the place `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
+        // that (where the `ref` on `x` is implied).
+        op(&place_with_id, pat)?;
+
+        match pat.kind {
+            PatKind::Tuple(subpats, dots_pos) => {
+                // (p1, ..., pN)
+                let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?;
+
+                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
+                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
+                    let projection_kind =
+                        ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT);
+                    let sub_place = self.cat_projection(
+                        pat.hir_id,
+                        place_with_id.clone(),
+                        subpat_ty,
+                        projection_kind,
+                    );
+                    self.cat_pattern(sub_place, subpat, op)?;
+                }
+            }
+
+            PatKind::TupleStruct(ref qpath, subpats, dots_pos) => {
+                // S(p1, ..., pN)
+                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
+                let total_fields =
+                    self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?;
+
+                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
+                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
+                    let projection_kind =
+                        ProjectionKind::Field(FieldIdx::from_usize(i), variant_index);
+                    let sub_place = self.cat_projection(
+                        pat.hir_id,
+                        place_with_id.clone(),
+                        subpat_ty,
+                        projection_kind,
+                    );
+                    self.cat_pattern(sub_place, subpat, op)?;
+                }
+            }
+
+            PatKind::Struct(ref qpath, field_pats, _) => {
+                // S { f1: p1, ..., fN: pN }
+
+                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
+
+                for fp in field_pats {
+                    let field_ty = self.pat_ty_adjusted(fp.pat)?;
+                    let field_index = self
+                        .cx
+                        .typeck_results()
+                        .field_indices()
+                        .get(fp.hir_id)
+                        .cloned()
+                        .expect("no index for a field");
+
+                    let field_place = self.cat_projection(
+                        pat.hir_id,
+                        place_with_id.clone(),
+                        field_ty,
+                        ProjectionKind::Field(field_index, variant_index),
+                    );
+                    self.cat_pattern(field_place, fp.pat, op)?;
+                }
+            }
+
+            PatKind::Or(pats) => {
+                for pat in pats {
+                    self.cat_pattern(place_with_id.clone(), pat, op)?;
+                }
+            }
+
+            PatKind::Binding(.., Some(subpat)) => {
+                self.cat_pattern(place_with_id, subpat, op)?;
+            }
+
+            PatKind::Box(subpat) | PatKind::Ref(subpat, _) => {
+                // box p1, &p1, &mut p1. we can ignore the mutability of
+                // PatKind::Ref since that information is already contained
+                // in the type.
+                let subplace = self.cat_deref(pat.hir_id, place_with_id)?;
+                self.cat_pattern(subplace, subpat, op)?;
+            }
+            PatKind::Deref(subpat) => {
+                let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpat);
+                let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
+                let re_erased = self.cx.tcx().lifetimes.re_erased;
+                let ty = self.pat_ty_adjusted(subpat)?;
+                let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability);
+                // A deref pattern generates a temporary.
+                let place = self.cat_rvalue(pat.hir_id, ty);
+                self.cat_pattern(place, subpat, op)?;
+            }
+
+            PatKind::Slice(before, ref slice, after) => {
+                let Some(element_ty) = place_with_id.place.ty().builtin_index() else {
+                    debug!("explicit index of non-indexable type {:?}", place_with_id);
+                    return Err(self
+                        .cx
+                        .report_error(pat.span, "explicit index of non-indexable type"));
+                };
+                let elt_place = self.cat_projection(
+                    pat.hir_id,
+                    place_with_id.clone(),
+                    element_ty,
+                    ProjectionKind::Index,
+                );
+                for before_pat in before {
+                    self.cat_pattern(elt_place.clone(), before_pat, op)?;
+                }
+                if let Some(slice_pat) = *slice {
+                    let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?;
+                    let slice_place = self.cat_projection(
+                        pat.hir_id,
+                        place_with_id,
+                        slice_pat_ty,
+                        ProjectionKind::Subslice,
+                    );
+                    self.cat_pattern(slice_place, slice_pat, op)?;
+                }
+                for after_pat in after {
+                    self.cat_pattern(elt_place.clone(), after_pat, op)?;
+                }
+            }
+
+            PatKind::Path(_)
+            | PatKind::Binding(.., None)
+            | PatKind::Lit(..)
+            | PatKind::Range(..)
+            | PatKind::Never
+            | PatKind::Wild
+            | PatKind::Err(_) => {
+                // always ok
+            }
+        }
+
+        Ok(())
+    }
+
+    fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
+        if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() {
+            // Note that if a non-exhaustive SingleVariant is defined in another crate, we need
+            // to assume that more cases will be added to the variant in the future. This mean
+            // that we should handle non-exhaustive SingleVariant the same way we would handle
+            // a MultiVariant.
+            // If the variant is not local it must be defined in another crate.
+            let is_non_exhaustive = match def.adt_kind() {
+                AdtKind::Struct | AdtKind::Union => {
+                    def.non_enum_variant().is_field_list_non_exhaustive()
+                }
+                AdtKind::Enum => def.is_variant_list_non_exhaustive(),
+            };
+            def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive)
+        } else {
+            false
+        }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index f240a53a679..c79b6be6560 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -9,6 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::HirId;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
+use rustc_middle::bug;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
 use rustc_session::lint;
 use rustc_span::DUMMY_SP;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index b32cab6d3f7..6e8ef044452 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -29,6 +29,7 @@ use rustc_middle::ty::{
     self, AdtKind, CanonicalUserType, GenericParamDefKind, IsIdentity, Ty, TyCtxt, UserType,
 };
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef, UserArgs, UserSelfTy};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::hygiene::DesugaringKind;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 5fa715dc761..aea34407a2d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -36,6 +36,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
 use rustc_span::symbol::{kw, Ident};
 use rustc_span::{sym, BytePos, Span, DUMMY_SP};
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index f1b719f24c7..11f288391c3 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -25,6 +25,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::traits;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::middle::stability::EvalResult;
+use rustc_middle::span_bug;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
     self, suggest_constraining_type_params, Article, Binder, IsSuggestable, ToPredicate, Ty,
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 62711e40049..fb8863c143f 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -2,6 +2,7 @@ use hir::HirId;
 use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_index::Idx;
+use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_target::abi::{Pointer, VariantIdx};
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index e270e589505..6892da7a5e2 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -10,9 +10,6 @@
 #[macro_use]
 extern crate tracing;
 
-#[macro_use]
-extern crate rustc_middle;
-
 mod _match;
 mod autoderef;
 mod callee;
@@ -32,7 +29,6 @@ mod fallback;
 mod fn_ctxt;
 mod gather_locals;
 mod intrinsicck;
-mod mem_categorization;
 mod method;
 mod op;
 mod pat;
@@ -63,6 +59,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::config;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
deleted file mode 100644
index ae71c484f7b..00000000000
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ /dev/null
@@ -1,774 +0,0 @@
-//! # Categorization
-//!
-//! The job of the categorization module is to analyze an expression to
-//! determine what kind of memory is used in evaluating it (for example,
-//! where dereferences occur and what kind of pointer is dereferenced;
-//! whether the memory is mutable, etc.).
-//!
-//! Categorization effectively transforms all of our expressions into
-//! expressions of the following forms (the actual enum has many more
-//! possibilities, naturally, but they are all variants of these base
-//! forms):
-//! ```ignore (not-rust)
-//! E = rvalue    // some computed rvalue
-//!   | x         // address of a local variable or argument
-//!   | *E        // deref of a ptr
-//!   | E.comp    // access to an interior component
-//! ```
-//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
-//! address where the result is to be found. If Expr is a place, then this
-//! is the address of the place. If `Expr` is an rvalue, this is the address of
-//! some temporary spot in memory where the result is stored.
-//!
-//! Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)`
-//! as follows:
-//!
-//! - `cat`: what kind of expression was this? This is a subset of the
-//!   full expression forms which only includes those that we care about
-//!   for the purpose of the analysis.
-//! - `mutbl`: mutability of the address `A`.
-//! - `ty`: the type of data found at the address `A`.
-//!
-//! The resulting categorization tree differs somewhat from the expressions
-//! themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is
-//! decomposed into two operations: a dereference to reach the array data and
-//! then an index to jump forward to the relevant item.
-//!
-//! ## By-reference upvars
-//!
-//! One part of the codegen which may be non-obvious is that we translate
-//! closure upvars into the dereference of a borrowed pointer; this more closely
-//! resembles the runtime codegen. So, for example, if we had:
-//!
-//!     let mut x = 3;
-//!     let y = 5;
-//!     let inc = || x += y;
-//!
-//! Then when we categorize `x` (*within* the closure) we would yield a
-//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
-//! tied to `x`. The type of `x'` will be a borrowed pointer.
-
-use rustc_middle::hir::place::*;
-use rustc_middle::ty::adjustment;
-use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
-
-use rustc_data_structures::fx::FxIndexMap;
-use rustc_hir as hir;
-use rustc_hir::def::{CtorOf, DefKind, Res};
-use rustc_hir::def_id::LocalDefId;
-use rustc_hir::pat_util::EnumerateAndAdjustIterator;
-use rustc_hir::{HirId, PatKind};
-use rustc_infer::infer::InferCtxt;
-use rustc_span::Span;
-use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
-use rustc_trait_selection::infer::InferCtxtExt;
-
-pub(crate) trait HirNode {
-    fn hir_id(&self) -> HirId;
-}
-
-impl HirNode for hir::Expr<'_> {
-    fn hir_id(&self) -> HirId {
-        self.hir_id
-    }
-}
-
-impl HirNode for hir::Pat<'_> {
-    fn hir_id(&self) -> HirId {
-        self.hir_id
-    }
-}
-
-#[derive(Clone)]
-pub(crate) struct MemCategorizationContext<'a, 'tcx> {
-    pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>,
-    infcx: &'a InferCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    body_owner: LocalDefId,
-    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
-}
-
-pub(crate) type McResult<T> = Result<T, ()>;
-
-impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
-    /// Creates a `MemCategorizationContext`.
-    pub(crate) fn new(
-        infcx: &'a InferCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        body_owner: LocalDefId,
-        typeck_results: &'a ty::TypeckResults<'tcx>,
-    ) -> MemCategorizationContext<'a, 'tcx> {
-        MemCategorizationContext {
-            typeck_results,
-            infcx,
-            param_env,
-            body_owner,
-            upvars: infcx.tcx.upvars_mentioned(body_owner),
-        }
-    }
-
-    pub(crate) fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
-        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
-    }
-
-    fn resolve_vars_if_possible<T>(&self, value: T) -> T
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.infcx.resolve_vars_if_possible(value)
-    }
-
-    fn is_tainted_by_errors(&self) -> bool {
-        self.infcx.tainted_by_errors().is_some()
-    }
-
-    fn resolve_type_vars_or_error(&self, id: HirId, ty: Option<Ty<'tcx>>) -> McResult<Ty<'tcx>> {
-        match ty {
-            Some(ty) => {
-                let ty = self.resolve_vars_if_possible(ty);
-                if ty.references_error() || ty.is_ty_var() {
-                    debug!("resolve_type_vars_or_error: error from {:?}", ty);
-                    Err(())
-                } else {
-                    Ok(ty)
-                }
-            }
-            // FIXME
-            None if self.is_tainted_by_errors() => Err(()),
-            None => {
-                bug!(
-                    "no type for node {} in mem_categorization",
-                    self.tcx().hir().node_to_string(id)
-                );
-            }
-        }
-    }
-
-    pub(crate) fn node_ty(&self, hir_id: HirId) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id))
-    }
-
-    fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr))
-    }
-
-    pub(crate) fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr))
-    }
-
-    /// Returns the type of value that this pattern matches against.
-    /// Some non-obvious cases:
-    ///
-    /// - a `ref x` binding matches against a value of type `T` and gives
-    ///   `x` the type `&T`; we return `T`.
-    /// - a pattern with implicit derefs (thanks to default binding
-    ///   modes #42640) may look like `Some(x)` but in fact have
-    ///   implicit deref patterns attached (e.g., it is really
-    ///   `&Some(x)`). In that case, we return the "outermost" type
-    ///   (e.g., `&Option<T>`).
-    pub(crate) fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
-        // Check for implicit `&` types wrapping the pattern; note
-        // that these are never attached to binding patterns, so
-        // actually this is somewhat "disjoint" from the code below
-        // that aims to account for `ref x`.
-        if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) {
-            if let Some(first_ty) = vec.first() {
-                debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
-                return Ok(*first_ty);
-            }
-        }
-
-        self.pat_ty_unadjusted(pat)
-    }
-
-    /// Like `pat_ty`, but ignores implicit `&` patterns.
-    #[instrument(level = "debug", skip(self), ret)]
-    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
-        let base_ty = self.node_ty(pat.hir_id)?;
-        trace!(?base_ty);
-
-        // This code detects whether we are looking at a `ref x`,
-        // and if so, figures out what the type *being borrowed* is.
-        match pat.kind {
-            PatKind::Binding(..) => {
-                let bm = *self
-                    .typeck_results
-                    .pat_binding_modes()
-                    .get(pat.hir_id)
-                    .expect("missing binding mode");
-
-                if matches!(bm.0, hir::ByRef::Yes(_)) {
-                    // a bind-by-ref means that the base_ty will be the type of the ident itself,
-                    // but what we want here is the type of the underlying value being borrowed.
-                    // So peel off one-level, turning the &T into T.
-                    match base_ty.builtin_deref(false) {
-                        Some(ty) => Ok(ty),
-                        None => {
-                            debug!("By-ref binding of non-derefable type");
-                            Err(())
-                        }
-                    }
-                } else {
-                    Ok(base_ty)
-                }
-            }
-            _ => Ok(base_ty),
-        }
-    }
-
-    pub(crate) fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
-        // This recursion helper avoids going through *too many*
-        // adjustments, since *only* non-overloaded deref recurses.
-        fn helper<'a, 'tcx>(
-            mc: &MemCategorizationContext<'a, 'tcx>,
-            expr: &hir::Expr<'_>,
-            adjustments: &[adjustment::Adjustment<'tcx>],
-        ) -> McResult<PlaceWithHirId<'tcx>> {
-            match adjustments.split_last() {
-                None => mc.cat_expr_unadjusted(expr),
-                Some((adjustment, previous)) => {
-                    mc.cat_expr_adjusted_with(expr, || helper(mc, expr, previous), adjustment)
-                }
-            }
-        }
-
-        helper(self, expr, self.typeck_results.expr_adjustments(expr))
-    }
-
-    pub(crate) fn cat_expr_adjusted(
-        &self,
-        expr: &hir::Expr<'_>,
-        previous: PlaceWithHirId<'tcx>,
-        adjustment: &adjustment::Adjustment<'tcx>,
-    ) -> McResult<PlaceWithHirId<'tcx>> {
-        self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
-    }
-
-    #[instrument(level = "debug", skip(self, previous))]
-    fn cat_expr_adjusted_with<F>(
-        &self,
-        expr: &hir::Expr<'_>,
-        previous: F,
-        adjustment: &adjustment::Adjustment<'tcx>,
-    ) -> McResult<PlaceWithHirId<'tcx>>
-    where
-        F: FnOnce() -> McResult<PlaceWithHirId<'tcx>>,
-    {
-        let target = self.resolve_vars_if_possible(adjustment.target);
-        match adjustment.kind {
-            adjustment::Adjust::Deref(overloaded) => {
-                // Equivalent to *expr or something similar.
-                let base = if let Some(deref) = overloaded {
-                    let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl);
-                    self.cat_rvalue(expr.hir_id, ref_ty)
-                } else {
-                    previous()?
-                };
-                self.cat_deref(expr, base)
-            }
-
-            adjustment::Adjust::NeverToAny
-            | adjustment::Adjust::Pointer(_)
-            | adjustment::Adjust::Borrow(_)
-            | adjustment::Adjust::DynStar => {
-                // Result is an rvalue.
-                Ok(self.cat_rvalue(expr.hir_id, target))
-            }
-        }
-    }
-
-    #[instrument(level = "debug", skip(self), ret)]
-    pub(crate) fn cat_expr_unadjusted(
-        &self,
-        expr: &hir::Expr<'_>,
-    ) -> McResult<PlaceWithHirId<'tcx>> {
-        let expr_ty = self.expr_ty(expr)?;
-        match expr.kind {
-            hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => {
-                if self.typeck_results.is_method_call(expr) {
-                    self.cat_overloaded_place(expr, e_base)
-                } else {
-                    let base = self.cat_expr(e_base)?;
-                    self.cat_deref(expr, base)
-                }
-            }
-
-            hir::ExprKind::Field(base, _) => {
-                let base = self.cat_expr(base)?;
-                debug!(?base);
-
-                let field_idx = self
-                    .typeck_results
-                    .field_indices()
-                    .get(expr.hir_id)
-                    .cloned()
-                    .expect("Field index not found");
-
-                Ok(self.cat_projection(
-                    expr,
-                    base,
-                    expr_ty,
-                    ProjectionKind::Field(field_idx, FIRST_VARIANT),
-                ))
-            }
-
-            hir::ExprKind::Index(base, _, _) => {
-                if self.typeck_results.is_method_call(expr) {
-                    // If this is an index implemented by a method call, then it
-                    // will include an implicit deref of the result.
-                    // The call to index() returns a `&T` value, which
-                    // is an rvalue. That is what we will be
-                    // dereferencing.
-                    self.cat_overloaded_place(expr, base)
-                } else {
-                    let base = self.cat_expr(base)?;
-                    Ok(self.cat_projection(expr, base, expr_ty, ProjectionKind::Index))
-                }
-            }
-
-            hir::ExprKind::Path(ref qpath) => {
-                let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
-                self.cat_res(expr.hir_id, expr.span, expr_ty, res)
-            }
-
-            hir::ExprKind::Type(e, _) => self.cat_expr(e),
-
-            hir::ExprKind::AddrOf(..)
-            | hir::ExprKind::Call(..)
-            | hir::ExprKind::Assign(..)
-            | hir::ExprKind::AssignOp(..)
-            | hir::ExprKind::Closure { .. }
-            | hir::ExprKind::Ret(..)
-            | hir::ExprKind::Become(..)
-            | hir::ExprKind::Unary(..)
-            | hir::ExprKind::Yield(..)
-            | hir::ExprKind::MethodCall(..)
-            | hir::ExprKind::Cast(..)
-            | hir::ExprKind::DropTemps(..)
-            | hir::ExprKind::Array(..)
-            | hir::ExprKind::If(..)
-            | hir::ExprKind::Tup(..)
-            | hir::ExprKind::Binary(..)
-            | hir::ExprKind::Block(..)
-            | hir::ExprKind::Let(..)
-            | hir::ExprKind::Loop(..)
-            | hir::ExprKind::Match(..)
-            | hir::ExprKind::Lit(..)
-            | hir::ExprKind::ConstBlock(..)
-            | hir::ExprKind::Break(..)
-            | hir::ExprKind::Continue(..)
-            | hir::ExprKind::Struct(..)
-            | hir::ExprKind::Repeat(..)
-            | hir::ExprKind::InlineAsm(..)
-            | hir::ExprKind::OffsetOf(..)
-            | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)),
-        }
-    }
-
-    #[instrument(level = "debug", skip(self, span), ret)]
-    pub(crate) fn cat_res(
-        &self,
-        hir_id: HirId,
-        span: Span,
-        expr_ty: Ty<'tcx>,
-        res: Res,
-    ) -> McResult<PlaceWithHirId<'tcx>> {
-        match res {
-            Res::Def(
-                DefKind::Ctor(..)
-                | DefKind::Const
-                | DefKind::ConstParam
-                | DefKind::AssocConst
-                | DefKind::Fn
-                | DefKind::AssocFn,
-                _,
-            )
-            | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)),
-
-            Res::Def(DefKind::Static { .. }, _) => {
-                Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new()))
-            }
-
-            Res::Local(var_id) => {
-                if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) {
-                    self.cat_upvar(hir_id, var_id)
-                } else {
-                    Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
-                }
-            }
-
-            def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def),
-        }
-    }
-
-    /// Categorize an upvar.
-    ///
-    /// Note: the actual upvar access contains invisible derefs of closure
-    /// environment and upvar reference as appropriate. Only regionck cares
-    /// about these dereferences, so we let it compute them as needed.
-    #[instrument(level = "debug", skip(self), ret)]
-    fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult<PlaceWithHirId<'tcx>> {
-        let closure_expr_def_id = self.body_owner;
-
-        let upvar_id = ty::UpvarId {
-            var_path: ty::UpvarPath { hir_id: var_id },
-            closure_expr_id: closure_expr_def_id,
-        };
-        let var_ty = self.node_ty(var_id)?;
-
-        Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new()))
-    }
-
-    #[instrument(level = "debug", skip(self), ret)]
-    pub(crate) fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> {
-        PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
-    }
-
-    #[instrument(level = "debug", skip(self, node), ret)]
-    pub(crate) fn cat_projection<N: HirNode>(
-        &self,
-        node: &N,
-        base_place: PlaceWithHirId<'tcx>,
-        ty: Ty<'tcx>,
-        kind: ProjectionKind,
-    ) -> PlaceWithHirId<'tcx> {
-        let place_ty = base_place.place.ty();
-        let mut projections = base_place.place.projections;
-
-        let node_ty = self.typeck_results.node_type(node.hir_id());
-        // Opaque types can't have field projections, but we can instead convert
-        // the current place in-place (heh) to the hidden type, and then apply all
-        // follow up projections on that.
-        if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) {
-            projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
-        }
-        projections.push(Projection { kind, ty });
-        PlaceWithHirId::new(
-            node.hir_id(),
-            base_place.place.base_ty,
-            base_place.place.base,
-            projections,
-        )
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn cat_overloaded_place(
-        &self,
-        expr: &hir::Expr<'_>,
-        base: &hir::Expr<'_>,
-    ) -> McResult<PlaceWithHirId<'tcx>> {
-        // Reconstruct the output assuming it's a reference with the
-        // same region and mutability as the receiver. This holds for
-        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
-        let place_ty = self.expr_ty(expr)?;
-        let base_ty = self.expr_ty_adjusted(base)?;
-
-        let ty::Ref(region, _, mutbl) = *base_ty.kind() else {
-            span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
-        };
-        let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl);
-
-        let base = self.cat_rvalue(expr.hir_id, ref_ty);
-        self.cat_deref(expr, base)
-    }
-
-    #[instrument(level = "debug", skip(self, node), ret)]
-    fn cat_deref(
-        &self,
-        node: &impl HirNode,
-        base_place: PlaceWithHirId<'tcx>,
-    ) -> McResult<PlaceWithHirId<'tcx>> {
-        let base_curr_ty = base_place.place.ty();
-        let deref_ty = match base_curr_ty.builtin_deref(true) {
-            Some(pointee_ty) => pointee_ty,
-            None => {
-                debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
-                return Err(());
-            }
-        };
-        let mut projections = base_place.place.projections;
-        projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty });
-
-        Ok(PlaceWithHirId::new(
-            node.hir_id(),
-            base_place.place.base_ty,
-            base_place.place.base,
-            projections,
-        ))
-    }
-
-    pub(crate) fn cat_pattern<F>(
-        &self,
-        place: PlaceWithHirId<'tcx>,
-        pat: &hir::Pat<'_>,
-        mut op: F,
-    ) -> McResult<()>
-    where
-        F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>),
-    {
-        self.cat_pattern_(place, pat, &mut op)
-    }
-
-    /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
-    /// Here `pat_hir_id` is the HirId of the pattern itself.
-    fn variant_index_for_adt(
-        &self,
-        qpath: &hir::QPath<'_>,
-        pat_hir_id: HirId,
-        span: Span,
-    ) -> McResult<VariantIdx> {
-        let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
-        let ty = self.typeck_results.node_type(pat_hir_id);
-        let ty::Adt(adt_def, _) = ty.kind() else {
-            self.tcx()
-                .dcx()
-                .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT");
-            return Err(());
-        };
-
-        match res {
-            Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
-            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
-                Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
-            }
-            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
-            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
-            | Res::SelfCtor(..)
-            | Res::SelfTyParam { .. }
-            | Res::SelfTyAlias { .. } => {
-                // Structs and Unions have only have one variant.
-                Ok(FIRST_VARIANT)
-            }
-            _ => bug!("expected ADT path, found={:?}", res),
-        }
-    }
-
-    /// Returns the total number of fields in an ADT variant used within a pattern.
-    /// Here `pat_hir_id` is the HirId of the pattern itself.
-    fn total_fields_in_adt_variant(
-        &self,
-        pat_hir_id: HirId,
-        variant_index: VariantIdx,
-        span: Span,
-    ) -> McResult<usize> {
-        let ty = self.typeck_results.node_type(pat_hir_id);
-        match ty.kind() {
-            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
-            _ => {
-                self.tcx()
-                    .dcx()
-                    .span_bug(span, "struct or tuple struct pattern not applied to an ADT");
-            }
-        }
-    }
-
-    /// Returns the total number of fields in a tuple used within a Tuple pattern.
-    /// Here `pat_hir_id` is the HirId of the pattern itself.
-    fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult<usize> {
-        let ty = self.typeck_results.node_type(pat_hir_id);
-        match ty.kind() {
-            ty::Tuple(args) => Ok(args.len()),
-            _ => {
-                self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple");
-                Err(())
-            }
-        }
-    }
-
-    /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
-    /// is being matched against.
-    ///
-    /// In general, the way that this works is that we walk down the pattern,
-    /// constructing a `PlaceWithHirId` that represents the path that will be taken
-    /// to reach the value being matched.
-    #[instrument(skip(self, op), ret, level = "debug")]
-    fn cat_pattern_<F>(
-        &self,
-        mut place_with_id: PlaceWithHirId<'tcx>,
-        pat: &hir::Pat<'_>,
-        op: &mut F,
-    ) -> McResult<()>
-    where
-        F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>),
-    {
-        // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly.
-        // `PlaceWithHirId`s are constructed differently from patterns. For example, in
-        //
-        // ```
-        // match foo {
-        //     &&Some(x, ) => { ... },
-        //     _ => { ... },
-        // }
-        // ```
-        //
-        // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the
-        // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the
-        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
-        //
-        // `&&Some(x,)` `place_foo`
-        //  `&Some(x,)` `deref { place_foo}`
-        //   `Some(x,)` `deref { deref { place_foo }}`
-        //       `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place
-        //
-        // The above example has no adjustments. If the code were instead the (after adjustments,
-        // equivalent) version
-        //
-        // ```
-        // match foo {
-        //     Some(x, ) => { ... },
-        //     _ => { ... },
-        // }
-        // ```
-        //
-        // Then we see that to get the same result, we must start with
-        // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
-        // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
-        for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) {
-            debug!("applying adjustment to place_with_id={:?}", place_with_id);
-            place_with_id = self.cat_deref(pat, place_with_id)?;
-        }
-        let place_with_id = place_with_id; // lose mutability
-        debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id);
-
-        // Invoke the callback, but only now, after the `place_with_id` has adjusted.
-        //
-        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
-        // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We
-        // don't want to call `op` with these incompatible values. As written, what happens instead
-        // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern
-        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
-        // result in the place `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
-        // that (where the `ref` on `x` is implied).
-        op(&place_with_id, pat);
-
-        match pat.kind {
-            PatKind::Tuple(subpats, dots_pos) => {
-                // (p1, ..., pN)
-                let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?;
-
-                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
-                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
-                    let projection_kind =
-                        ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT);
-                    let sub_place =
-                        self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
-                    self.cat_pattern_(sub_place, subpat, op)?;
-                }
-            }
-
-            PatKind::TupleStruct(ref qpath, subpats, dots_pos) => {
-                // S(p1, ..., pN)
-                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
-                let total_fields =
-                    self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?;
-
-                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
-                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
-                    let projection_kind =
-                        ProjectionKind::Field(FieldIdx::from_usize(i), variant_index);
-                    let sub_place =
-                        self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
-                    self.cat_pattern_(sub_place, subpat, op)?;
-                }
-            }
-
-            PatKind::Struct(ref qpath, field_pats, _) => {
-                // S { f1: p1, ..., fN: pN }
-
-                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
-
-                for fp in field_pats {
-                    let field_ty = self.pat_ty_adjusted(fp.pat)?;
-                    let field_index = self
-                        .typeck_results
-                        .field_indices()
-                        .get(fp.hir_id)
-                        .cloned()
-                        .expect("no index for a field");
-
-                    let field_place = self.cat_projection(
-                        pat,
-                        place_with_id.clone(),
-                        field_ty,
-                        ProjectionKind::Field(field_index, variant_index),
-                    );
-                    self.cat_pattern_(field_place, fp.pat, op)?;
-                }
-            }
-
-            PatKind::Or(pats) => {
-                for pat in pats {
-                    self.cat_pattern_(place_with_id.clone(), pat, op)?;
-                }
-            }
-
-            PatKind::Binding(.., Some(subpat)) => {
-                self.cat_pattern_(place_with_id, subpat, op)?;
-            }
-
-            PatKind::Box(subpat) | PatKind::Ref(subpat, _) => {
-                // box p1, &p1, &mut p1. we can ignore the mutability of
-                // PatKind::Ref since that information is already contained
-                // in the type.
-                let subplace = self.cat_deref(pat, place_with_id)?;
-                self.cat_pattern_(subplace, subpat, op)?;
-            }
-            PatKind::Deref(subpat) => {
-                let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat);
-                let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
-                let re_erased = self.tcx().lifetimes.re_erased;
-                let ty = self.pat_ty_adjusted(subpat)?;
-                let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability);
-                // A deref pattern generates a temporary.
-                let place = self.cat_rvalue(pat.hir_id, ty);
-                self.cat_pattern_(place, subpat, op)?;
-            }
-
-            PatKind::Slice(before, ref slice, after) => {
-                let Some(element_ty) = place_with_id.place.ty().builtin_index() else {
-                    debug!("explicit index of non-indexable type {:?}", place_with_id);
-                    return Err(());
-                };
-                let elt_place = self.cat_projection(
-                    pat,
-                    place_with_id.clone(),
-                    element_ty,
-                    ProjectionKind::Index,
-                );
-                for before_pat in before {
-                    self.cat_pattern_(elt_place.clone(), before_pat, op)?;
-                }
-                if let Some(slice_pat) = *slice {
-                    let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?;
-                    let slice_place = self.cat_projection(
-                        pat,
-                        place_with_id,
-                        slice_pat_ty,
-                        ProjectionKind::Subslice,
-                    );
-                    self.cat_pattern_(slice_place, slice_pat, op)?;
-                }
-                for after_pat in after {
-                    self.cat_pattern_(elt_place.clone(), after_pat, op)?;
-                }
-            }
-
-            PatKind::Path(_)
-            | PatKind::Binding(.., None)
-            | PatKind::Lit(..)
-            | PatKind::Range(..)
-            | PatKind::Never
-            | PatKind::Wild
-            | PatKind::Err(_) => {
-                // always ok
-            }
-        }
-
-        Ok(())
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 007ec7ff378..74254058534 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -16,6 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{
     self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, UserArgs, UserType,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::traits;
 
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index ec613f3d14e..f82182fa058 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -20,6 +20,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
index 305aaf3b8dd..a305461344d 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
@@ -7,6 +7,7 @@ use hir::HirId;
 use hir::ItemKind;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
 use rustc_span::symbol::kw::{Empty, Underscore};
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index e9446b862fa..81e179c9090 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -24,6 +24,7 @@ use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::def_id::DefId;
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 0483bd03576..e8a15eb0ca3 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -23,6 +23,7 @@ use rustc_hir::PatKind::Binding;
 use rustc_hir::PathSegment;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::{self, RegionVariableOrigin};
+use rustc_middle::bug;
 use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
 use rustc_middle::ty::print::{
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index dca1cda0694..e371775be0a 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Ident};
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 259336f438d..b9b220d5af8 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -11,6 +11,7 @@ use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind
 use rustc_infer::infer;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::hygiene::DesugaringKind;
@@ -73,21 +74,23 @@ struct TopInfo<'tcx> {
     ///              found type `std::result::Result<_, _>`
     /// ```
     span: Option<Span>,
+    /// The [`HirId`] of the top-level pattern.
+    hir_id: HirId,
 }
 
 #[derive(Copy, Clone)]
 struct PatInfo<'tcx, 'a> {
     binding_mode: ByRef,
     max_ref_mutbl: MutblCap,
-    top_info: TopInfo<'tcx>,
-    decl_origin: Option<DeclOrigin<'a>>,
+    top_info: &'a TopInfo<'tcx>,
+    decl_origin: Option<DeclOrigin<'tcx>>,
 
     /// The depth of current pattern
     current_depth: u32,
 }
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
-    fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
+    fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
         let code = ObligationCauseCode::Pattern {
             span: ti.span,
             root_ty: ti.expected,
@@ -101,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         cause_span: Span,
         expected: Ty<'tcx>,
         actual: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) -> Option<Diag<'tcx>> {
         let mut diag =
             self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?;
@@ -118,7 +121,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         cause_span: Span,
         expected: Ty<'tcx>,
         actual: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) {
         if let Some(err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) {
             err.emit();
@@ -199,11 +202,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         origin_expr: Option<&'tcx hir::Expr<'tcx>>,
         decl_origin: Option<DeclOrigin<'tcx>>,
     ) {
-        let info = TopInfo { expected, origin_expr, span };
+        let info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id };
         let pat_info = PatInfo {
             binding_mode: ByRef::No,
             max_ref_mutbl: MutblCap::Mut,
-            top_info: info,
+            top_info: &info,
             decl_origin,
             current_depth: 0,
         };
@@ -463,7 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         lt: &hir::Expr<'tcx>,
         expected: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         // We've already computed the type above (when checking for a non-ref pat),
         // so avoid computing it again.
@@ -533,7 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lhs: Option<&'tcx hir::Expr<'tcx>>,
         rhs: Option<&'tcx hir::Expr<'tcx>>,
         expected: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr {
             None => None,
@@ -671,18 +674,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Determine the binding mode...
         let bm = match user_bind_annot {
+            // `mut` resets binding mode on edition <= 2021
             BindingMode(ByRef::No, Mutability::Mut)
                 if !(pat.span.at_least_rust_2024()
                     && self.tcx.features().mut_preserve_binding_mode_2024)
                     && matches!(def_br, ByRef::Yes(_)) =>
             {
-                // `mut x` resets the binding mode in edition <= 2021.
-                self.tcx.emit_node_span_lint(
-                    rustc_lint::builtin::DEREFERENCING_MUT_BINDING,
-                    pat.hir_id,
-                    pat.span,
-                    errors::DereferencingMutBinding { span: pat.span },
-                );
+                self.typeck_results
+                    .borrow_mut()
+                    .rust_2024_migration_desugared_pats_mut()
+                    .insert(pat_info.top_info.hir_id);
                 BindingMode(ByRef::No, Mutability::Mut)
             }
             BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
@@ -754,7 +755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         var_id: HirId,
         ty: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) {
         let var_ty = self.local_ty(span, var_id);
         if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
@@ -996,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &hir::QPath<'_>,
         path_resolution: (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]),
         expected: Ty<'tcx>,
-        ti: TopInfo<'tcx>,
+        ti: &TopInfo<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
 
@@ -2178,8 +2179,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Reset binding mode on old editions
-            pat_info.binding_mode = ByRef::No;
-            pat_info.max_ref_mutbl = MutblCap::Mut
+
+            if pat_info.binding_mode != ByRef::No {
+                pat_info.binding_mode = ByRef::No;
+
+                self.typeck_results
+                    .borrow_mut()
+                    .rust_2024_migration_desugared_pats_mut()
+                    .insert(pat_info.top_info.hir_id);
+            }
+
+            pat_info.max_ref_mutbl = MutblCap::Mut;
         }
 
         let tcx = self.tcx;
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index 374279722ba..515e1b5ed0e 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir_analysis::autoderef::Autoderef;
 use rustc_infer::infer::InferOk;
+use rustc_middle::span_bug;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion};
 use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
index 34ce0ab1f8b..805f36d9b97 100644
--- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
+++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
@@ -2,6 +2,7 @@ use super::FnCtxt;
 use hir::def_id::DefId;
 use hir::Node;
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::middle::region::{RvalueCandidateType, Scope, ScopeTree};
 use rustc_middle::ty::RvalueScopes;
 
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index 31ce271a5fc..19d6481cc1b 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -5,6 +5,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{HirId, HirIdMap};
 use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
+use rustc_middle::span_bug;
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefIdMap;
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 2bf4f51a803..d313c0eafe1 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -47,6 +47,7 @@ use rustc_middle::ty::{
     self, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, UpvarArgs,
     UpvarCapture,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_span::sym;
 use rustc_span::{BytePos, Pos, Span, Symbol};
@@ -252,12 +253,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        euv::ExprUseVisitor::new(
+        let _ = euv::ExprUseVisitor::new(
+            &FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id),
             &mut delegate,
-            &self.infcx,
-            closure_def_id,
-            self.param_env,
-            &self.typeck_results.borrow(),
         )
         .consume_body(body);
 
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 0a40ffb0d5a..f798deea207 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -9,6 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
+use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
@@ -346,6 +347,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
             _ => {}
         };
 
+        self.visit_rust_2024_migration_desugared_pats(p.hir_id);
         self.visit_skipped_ref_pats(p.hir_id);
         self.visit_pat_adjustments(p.span, p.hir_id);
 
@@ -655,6 +657,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
+    #[instrument(skip(self), level = "debug")]
+    fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
+        if self
+            .fcx
+            .typeck_results
+            .borrow_mut()
+            .rust_2024_migration_desugared_pats_mut()
+            .remove(hir_id)
+        {
+            debug!(
+                "node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
+            );
+            self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
+        }
+    }
+
     #[instrument(skip(self, span), level = "debug")]
     fn visit_pat_adjustments(&mut self, span: Span, hir_id: HirId) {
         let adjustment = self.fcx.typeck_results.borrow_mut().pat_adjustments_mut().remove(hir_id);
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index c7f07ebed97..f0b336ca046 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -1,6 +1,7 @@
 use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::nice_region_error::find_anon_type;
 use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
+use rustc_middle::bug;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::kw, Span};
 
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 0f21d3966c4..57b58006e23 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -27,6 +27,7 @@
 
 use super::*;
 
+use rustc_middle::bug;
 use rustc_middle::ty::relate::{Relate, TypeRelation};
 use rustc_middle::ty::{Const, ImplSubject};
 
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 4d712e9ffd3..27b06c4b73e 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -9,6 +9,7 @@ use crate::infer::canonical::{
     Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, OriginalQueryValues,
 };
 use crate::infer::InferCtxt;
+use rustc_middle::bug;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::GenericArg;
 use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
index f95cc13623c..de0e15ef3de 100644
--- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs
+++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
@@ -8,6 +8,7 @@
 
 use crate::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_macros::extension;
+use rustc_middle::bug;
 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/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index b948067e750..1732913e191 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -25,6 +25,7 @@ use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, BoundVar, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArg, GenericArgKind};
+use rustc_middle::{bug, span_bug};
 use std::fmt::Debug;
 use std::iter;
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 3488517a4ef..4cb0bf83aac 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -69,6 +69,7 @@ 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::bug;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
 use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 415f0eee8c5..b4decbf14a2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -11,6 +11,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource};
+use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
index fdfce7f8f73..45dce0a0e33 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
@@ -13,6 +13,7 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
+use rustc_middle::bug;
 use rustc_middle::ty::TypeVisitor;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index 31d45133eb0..8859772848f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_errors::{Diag, IntoDiagArg};
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
+use rustc_middle::bug;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
 use rustc_middle::ty::GenericArgsRef;
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index ef9c407acef..b2d89523ea8 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -32,6 +32,7 @@
 //! inferencer knows "so far".
 use super::InferCtxt;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::bug;
 use rustc_middle::infer::unify_key::ToType;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt};
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 5ae7f8bf504..72944c9c7de 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -20,6 +20,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ReBound, RePlaceholder, ReVar};
 use rustc_middle::ty::{ReEarlyParam, ReErased, ReError, ReLateParam, ReStatic};
 use rustc_middle::ty::{Region, RegionVid};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 use std::fmt;
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index ce82296a8aa..efd883d0d83 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -44,6 +44,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
 use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
 use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use snapshot::undo_log::InferCtxtUndoLogs;
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index a7ddf475436..e07d181e4e0 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -1,4 +1,5 @@
 use rustc_data_structures::undo_log::UndoLogs;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
 
 use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index f8dbfdde30c..c44a5082f68 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -3,6 +3,7 @@ use crate::infer::GenericKind;
 use crate::traits::query::OutlivesBound;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, Region};
 
 use super::explicit_outlives_bounds;
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index e0d23d7629f..32c790523b6 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -67,6 +67,7 @@ use crate::infer::snapshot::undo_log::UndoLog;
 use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_data_structures::undo_log::UndoLogs;
+use rustc_middle::bug;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::{
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 6e8efa3e7c1..255ca52d3e9 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -3,6 +3,7 @@ use crate::infer::snapshot::CombinedSnapshot;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::graph::{scc::Sccs, vec_graph::VecGraph};
 use rustc_index::Idx;
+use rustc_middle::span_bug;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::RelateResult;
 
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 223e6e3d344..6f755e07ff1 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -17,6 +17,7 @@ use rustc_middle::ty::ReStatic;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ReBound, ReVar};
 use rustc_middle::ty::{Region, RegionVid};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 
 use std::ops::Range;
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 8a3125f9ded..c1baadfa8df 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -24,6 +24,7 @@ use super::type_relating::TypeRelating;
 use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligations};
+use rustc_middle::bug;
 use rustc_middle::infer::canonical::OriginalQueryValues;
 use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 5880ca788bc..104c16eac02 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -6,6 +6,7 @@ use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin};
 use rustc_data_structures::sso::SsoHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::DefId;
+use rustc_middle::bug;
 use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 758aac004dc..61b13dd9a54 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -1,4 +1,5 @@
 use super::{FixupError, FixupResult, InferCtxt};
+use rustc_middle::bug;
 use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 96afa257ebb..b56b39e61f0 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -1,6 +1,7 @@
 use rustc_data_structures::undo_log::Rollback;
 use rustc_hir::def_id::DefId;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, Ty, TyVid};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 0299af61d45..28d908abf83 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -31,8 +31,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 mod errors;
 pub mod infer;
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 2b147e052ae..8866b2be078 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -677,6 +677,33 @@ trait UnusedDelimLint {
         }
 
         // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
+        //
+        // FIXME: https://github.com/rust-lang/rust/issues/119426
+        // The syntax tree in this code is from after macro expansion, so the
+        // current implementation has both false negatives and false positives
+        // related to expressions containing macros.
+        //
+        //     macro_rules! m1 {
+        //         () => {
+        //             1
+        //         };
+        //     }
+        //
+        //     fn f1() -> u8 {
+        //         // Lint says parens are not needed, but they are.
+        //         (m1! {} + 1)
+        //     }
+        //
+        //     macro_rules! m2 {
+        //         () => {
+        //             loop { break 1; }
+        //         };
+        //     }
+        //
+        //     fn f2() -> u8 {
+        //         // Lint says parens are needed, but they are not.
+        //         (m2!() + 1)
+        //     }
         {
             let mut innermost = inner;
             loop {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index eea3ca44c48..53694545772 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -38,7 +38,6 @@ declare_lint_pass! {
         DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
         DEPRECATED_IN_FUTURE,
         DEPRECATED_WHERE_CLAUSE_LOCATION,
-        DEREFERENCING_MUT_BINDING,
         DUPLICATE_MACRO_ATTRIBUTES,
         ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
         ELIDED_LIFETIMES_IN_PATHS,
@@ -90,6 +89,7 @@ declare_lint_pass! {
         RUST_2021_INCOMPATIBLE_OR_PATTERNS,
         RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
         RUST_2021_PRELUDE_COLLISIONS,
+        RUST_2024_INCOMPATIBLE_PAT,
         SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
         SINGLE_USE_LIFETIMES,
         SOFT_UNSTABLE,
@@ -1630,34 +1630,34 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode,
-    /// as this behavior will change in rust 2024.
+    /// The `rust_2024_incompatible_pat` lint
+    /// detects patterns whose meaning will change in the Rust 2024 edition.
     ///
     /// ### Example
     ///
-    /// ```rust
-    /// # #![warn(dereferencing_mut_binding)]
-    /// let x = Some(123u32);
-    /// let _y = match &x {
-    ///     Some(mut x) => {
-    ///         x += 1;
-    ///         x
-    ///     }
-    ///     None => 0,
-    /// };
+    /// ```rust,edition2021
+    /// #![feature(ref_pat_eat_one_layer_2024)]
+    /// #![warn(rust_2024_incompatible_pat)]
+    ///
+    /// if let Some(&a) = &Some(&0u8) {
+    ///     let _: u8 = a;
+    /// }
+    /// if let Some(mut _a) = &mut Some(0u8) {
+    ///     _a = 7u8;
+    /// }
     /// ```
     ///
     /// {{produces}}
     ///
     /// ### Explanation
     ///
-    /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type
-    /// `u32`, which was deemed surprising. After edition 2024, adding `mut` will not change the
-    /// type of `x`. This lint warns users of editions before 2024 to update their code.
-    pub DEREFERENCING_MUT_BINDING,
+    /// In Rust 2024 and above, the `mut` keyword does not reset the pattern binding mode,
+    /// and nor do `&` or `&mut` patterns. The lint will suggest code that
+    /// has the same meaning in all editions.
+    pub RUST_2024_INCOMPATIBLE_PAT,
     Allow,
-    "detects `mut x` bindings that change the type of `x`",
-    @feature_gate = sym::mut_preserve_binding_mode_2024;
+    "detects patterns whose meaning will change in Rust 2024",
+    @feature_gate = sym::ref_pat_eat_one_layer_2024;
     // FIXME uncomment below upon stabilization
     /*@future_incompatible = FutureIncompatibleInfo {
         reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 888c2427d8f..e3205fc1d30 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -16,6 +16,7 @@ use rustc_fs_util::try_canonicalize;
 use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
 use rustc_session::config::{self, CrateType, ExternLocation};
 use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index 4d1bd455412..99181f9c860 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -59,6 +59,7 @@ use crate::errors::{
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::CrateNum;
+use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::CrateType;
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index c8162a1f0ee..99584845e49 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -20,9 +20,6 @@
 extern crate proc_macro;
 
 #[macro_use]
-extern crate rustc_middle;
-
-#[macro_use]
 extern crate tracing;
 
 pub use rmeta::provide;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 2a33088513b..bb68c6eaf09 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -21,6 +21,7 @@ use rustc_middle::middle::lib_features::LibFeatures;
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::ty::codec::TyDecoder;
 use rustc_middle::ty::Visibility;
+use rustc_middle::{bug, implement_ty_decoder};
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::{Decodable, Decoder};
 use rustc_session::cstore::{CrateSource, ExternCrate};
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 531b2e05411..c783149a695 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -11,6 +11,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_middle::arena::ArenaAllocatable;
+use rustc_middle::bug;
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::middle::stability::DeprecationEntry;
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7c96a6fa9a9..db0dc6d9064 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -20,6 +20,7 @@ use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, TreatParams};
 use rustc_middle::ty::{AssocItemContainer, SymbolName};
 use rustc_middle::util::common::to_readable_str;
+use rustc_middle::{bug, span_bug};
 use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
 use rustc_session::config::{CrateType, OptLevel};
 use rustc_span::hygiene::HygieneEncodeContext;
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index c9cb2f5a240..79e4ff81093 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -24,6 +24,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
 use rustc_middle::mir;
+use rustc_middle::trivially_parameterized_over_tcx;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams};
 use rustc_middle::ty::{DeducedParamAttrs, ParameterizedOverTcx, TyCtxt};
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 38cb1d5f9a0..20afe52c1f3 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -8,11 +8,13 @@ macro_rules! err_unsup {
         )
     };
 }
+pub use err_unsup;
 
 #[macro_export]
 macro_rules! err_unsup_format {
-    ($($tt:tt)*) => { err_unsup!(Unsupported(format!($($tt)*))) };
+    ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) };
 }
+pub use err_unsup_format;
 
 #[macro_export]
 macro_rules! err_inval {
@@ -22,6 +24,7 @@ macro_rules! err_inval {
         )
     };
 }
+pub use err_inval;
 
 #[macro_export]
 macro_rules! err_ub {
@@ -31,11 +34,13 @@ macro_rules! err_ub {
         )
     };
 }
+pub use err_ub;
 
 #[macro_export]
 macro_rules! err_ub_format {
     ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) };
 }
+pub use err_ub_format;
 
 #[macro_export]
 macro_rules! err_exhaust {
@@ -45,6 +50,7 @@ macro_rules! err_exhaust {
         )
     };
 }
+pub use err_exhaust;
 
 #[macro_export]
 macro_rules! err_machine_stop {
@@ -52,42 +58,50 @@ macro_rules! err_machine_stop {
         $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*))
     };
 }
+pub use err_machine_stop;
 
 // In the `throw_*` macros, avoid `return` to make them work with `try {}`.
 #[macro_export]
 macro_rules! throw_unsup {
-    ($($tt:tt)*) => { do yeet err_unsup!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) };
 }
+pub use throw_unsup;
 
 #[macro_export]
 macro_rules! throw_unsup_format {
-    ($($tt:tt)*) => { throw_unsup!(Unsupported(format!($($tt)*))) };
+    ($($tt:tt)*) => { $crate::throw_unsup!(Unsupported(format!($($tt)*))) };
 }
+pub use throw_unsup_format;
 
 #[macro_export]
 macro_rules! throw_inval {
-    ($($tt:tt)*) => { do yeet err_inval!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) };
 }
+pub use throw_inval;
 
 #[macro_export]
 macro_rules! throw_ub {
-    ($($tt:tt)*) => { do yeet err_ub!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) };
 }
+pub use throw_ub;
 
 #[macro_export]
 macro_rules! throw_ub_format {
-    ($($tt:tt)*) => { throw_ub!(Ub(format!($($tt)*))) };
+    ($($tt:tt)*) => { $crate::throw_ub!(Ub(format!($($tt)*))) };
 }
+pub use throw_ub_format;
 
 #[macro_export]
 macro_rules! throw_exhaust {
-    ($($tt:tt)*) => { do yeet err_exhaust!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) };
 }
+pub use throw_exhaust;
 
 #[macro_export]
 macro_rules! throw_machine_stop {
-    ($($tt:tt)*) => { do yeet err_machine_stop!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) };
 }
+pub use throw_machine_stop;
 
 #[macro_export]
 macro_rules! err_ub_custom {
@@ -95,8 +109,8 @@ macro_rules! err_ub_custom {
         $(
             let ($($name,)*) = ($($value,)*);
         )?
-        err_ub!(Custom(
-            rustc_middle::error::CustomSubdiagnostic {
+        $crate::err_ub!(Custom(
+            $crate::error::CustomSubdiagnostic {
                 msg: || $msg,
                 add_args: Box::new(move |mut set_arg| {
                     $($(
@@ -107,11 +121,13 @@ macro_rules! err_ub_custom {
         ))
     }};
 }
+pub use err_ub_custom;
 
 #[macro_export]
 macro_rules! throw_ub_custom {
-    ($($tt:tt)*) => { do yeet err_ub_custom!($($tt)*) };
+    ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) };
 }
+pub use throw_ub_custom;
 
 mod allocation;
 mod error;
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 41f417dfd4b..24e3e623ff2 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -79,6 +79,10 @@ pub struct TypeckResults<'tcx> {
     /// Stores the actual binding mode for all instances of [`BindingMode`].
     pat_binding_modes: ItemLocalMap<BindingMode>,
 
+    /// Top-level patterns whose match ergonomics need to be desugared
+    /// by the Rust 2021 -> 2024 migration lint.
+    rust_2024_migration_desugared_pats: ItemLocalSet,
+
     /// Stores the types which were implicitly dereferenced in pattern binding modes
     /// for later usage in THIR lowering. For example,
     ///
@@ -229,6 +233,7 @@ impl<'tcx> TypeckResults<'tcx> {
             adjustments: Default::default(),
             pat_binding_modes: Default::default(),
             pat_adjustments: Default::default(),
+            rust_2024_migration_desugared_pats: Default::default(),
             skipped_ref_pats: Default::default(),
             closure_kind_origins: Default::default(),
             liberated_fn_sigs: Default::default(),
@@ -432,6 +437,20 @@ impl<'tcx> TypeckResults<'tcx> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
     }
 
+    pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
+        LocalSetInContext {
+            hir_owner: self.hir_owner,
+            data: &self.rust_2024_migration_desugared_pats,
+        }
+    }
+
+    pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
+        LocalSetInContextMut {
+            hir_owner: self.hir_owner,
+            data: &mut self.rust_2024_migration_desugared_pats,
+        }
+    }
+
     pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
         LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
     }
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
index 6618e4f5a00..77f27236437 100644
--- a/compiler/rustc_mir_build/Cargo.toml
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -16,6 +16,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
+rustc_lint = { path = "../rustc_lint" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 34440c60cf3..0bb44dbb870 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -267,6 +267,8 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
 
 mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
 
+mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
+
 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
     .attributes = no other attributes may be applied
     .not_box = `#[rustc_box]` may only be applied to a `Box::new()` call
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 00e99f330f7..6ae98e15946 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -1,6 +1,7 @@
 use crate::build::ForGuard::OutsideGuard;
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
 use rustc_middle::middle::region::Scope;
+use rustc_middle::span_bug;
 use rustc_middle::thir::*;
 use rustc_middle::{mir::*, ty};
 use rustc_span::Span;
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
index 566dba460d4..9cfb25e663d 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
@@ -1,5 +1,6 @@
 use std::collections::VecDeque;
 
+use rustc_middle::bug;
 use rustc_middle::mir::coverage::{
     BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan,
 };
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 30877e38318..a0a512a2eff 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -24,6 +24,7 @@ use rustc_hir::HirId;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::{
     mir::*,
+    span_bug,
     thir::*,
     ty::{ParamEnv, Ty, TyCtxt},
 };
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index a557f61b016..817f5f787b1 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -9,6 +9,7 @@ use rustc_middle::thir::*;
 use rustc_middle::ty::{
     self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::Size;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 060b328ef48..9963629fc52 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -4,6 +4,7 @@ use crate::build::expr::category::Category;
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap};
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::bug;
 use rustc_middle::hir::place::Projection as HirProjection;
 use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
 use rustc_middle::middle::region;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 260ab058e60..0b2248d049a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -9,6 +9,7 @@ use crate::build::expr::as_place::PlaceBase;
 use crate::build::expr::category::{Category, RvalueFunc};
 use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary};
 use rustc_hir::lang_items::LangItem;
+use rustc_middle::bug;
 use rustc_middle::middle::region;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index c8360b6a5fd..f8c91073045 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::thir::*;
 use rustc_middle::ty::CanonicalUserTypeAnnotation;
 use rustc_span::source_map::Spanned;
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 7cf4fac731b..3fc719394bf 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -12,6 +12,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
 use rustc_data_structures::{fx::FxIndexMap, stack::ensure_sufficient_stack};
 use rustc_hir::{BindingMode, ByRef};
+use rustc_middle::bug;
 use rustc_middle::middle::region;
 use rustc_middle::mir::{self, *};
 use rustc_middle::thir::{self, *};
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 7f65697fa4b..f3faeb4158e 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -13,6 +13,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::GenericArg;
 use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Symbol};
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 794e7ebb7b4..92cd7f75d62 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -20,6 +20,7 @@ use rustc_middle::mir::*;
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_span::Symbol;
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 2d31e84aba7..be32363fec5 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -90,6 +90,7 @@ use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::middle::region;
 use rustc_middle::mir::*;
 use rustc_middle::thir::{ExprId, LintLevel};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::Level;
 use rustc_span::source_map::Spanned;
 use rustc_span::{Span, DUMMY_SP};
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 227d19c3e43..b9990d65ec7 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -4,6 +4,7 @@ use crate::errors::*;
 use rustc_errors::DiagArgValue;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
 use rustc_middle::mir::BorrowKind;
+use rustc_middle::span_bug;
 use rustc_middle::thir::visit::Visitor;
 use rustc_middle::thir::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index f67113afd6d..e2a28467b84 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -950,3 +950,30 @@ pub enum RustcBoxAttrReason {
     #[note(mir_build_missing_box)]
     MissingBox,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(mir_build_rust_2024_incompatible_pat)]
+pub struct Rust2024IncompatiblePat {
+    #[subdiagnostic]
+    pub sugg: Rust2024IncompatiblePatSugg,
+}
+
+pub struct Rust2024IncompatiblePatSugg {
+    pub suggestion: Vec<(Span, String)>,
+}
+
+impl Subdiagnostic for Rust2024IncompatiblePatSugg {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        _f: &F,
+    ) {
+        let applicability =
+            if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
+                Applicability::MachineApplicable
+            } else {
+                Applicability::MaybeIncorrect
+            };
+        diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability);
+    }
+}
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index e79e3b887fb..2e1cb0e1b5e 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -12,8 +12,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 mod build;
 mod check_unsafety;
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 65cc13286af..03c7c1fd6ec 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -1,4 +1,5 @@
 use rustc_ast as ast;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index c697e16217b..b7766666960 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -21,6 +21,7 @@ use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{
     self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_span::source_map::Spanned;
 use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 79738b54035..d1d21f88aef 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::HirId;
 use rustc_hir::Node;
+use rustc_middle::bug;
 use rustc_middle::middle::region;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
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 25ab9046706..592f0dcf4ef 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -1,9 +1,3 @@
-use rustc_pattern_analysis::errors::Uncovered;
-use rustc_pattern_analysis::rustc::{
-    Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport,
-    WitnessPat,
-};
-
 use crate::errors::*;
 
 use rustc_arena::{DroplessArena, TypedArena};
@@ -14,11 +8,17 @@ use rustc_errors::{codes::*, struct_span_code_err, Applicability, ErrorGuarantee
 use rustc_hir::def::*;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
+use rustc_middle::bug;
 use rustc_middle::middle::limits::get_limit_size;
 use rustc_middle::thir::visit::Visitor;
 use rustc_middle::thir::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
+use rustc_pattern_analysis::errors::Uncovered;
+use rustc_pattern_analysis::rustc::{
+    Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport,
+    WitnessPat,
+};
 use rustc_session::lint::builtin::{
     BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
 };
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 65c53be8ddd..c6f81c3cb99 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -4,6 +4,7 @@ use rustc_index::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::Obligation;
 use rustc_middle::mir;
+use rustc_middle::span_bug;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
 use rustc_session::lint;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 5c016682d8d..dc845b3d4ac 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -11,8 +11,9 @@ use crate::thir::util::UserAnnotatedTyHelpers;
 use rustc_errors::codes::*;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
-use rustc_hir::{self as hir, RangeEnd};
+use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd};
 use rustc_index::Idx;
+use rustc_lint as lint;
 use rustc_middle::mir::interpret::{ErrorHandled, GlobalId, LitToConstError, LitToConstInput};
 use rustc_middle::mir::{self, Const};
 use rustc_middle::thir::{
@@ -20,6 +21,7 @@ use rustc_middle::thir::{
 };
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_target::abi::{FieldIdx, Integer};
@@ -30,6 +32,9 @@ struct PatCtxt<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     typeck_results: &'a ty::TypeckResults<'tcx>,
+
+    /// Used by the Rust 2024 migration lint.
+    rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg>,
 }
 
 pub(super) fn pat_from_hir<'a, 'tcx>(
@@ -38,9 +43,25 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
     typeck_results: &'a ty::TypeckResults<'tcx>,
     pat: &'tcx hir::Pat<'tcx>,
 ) -> Box<Pat<'tcx>> {
-    let mut pcx = PatCtxt { tcx, param_env, typeck_results };
+    let mut pcx = PatCtxt {
+        tcx,
+        param_env,
+        typeck_results,
+        rust_2024_migration_suggestion: typeck_results
+            .rust_2024_migration_desugared_pats()
+            .contains(pat.hir_id)
+            .then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
+    };
     let result = pcx.lower_pattern(pat);
     debug!("pat_from_hir({:?}) = {:?}", pat, result);
+    if let Some(sugg) = pcx.rust_2024_migration_suggestion {
+        tcx.emit_node_span_lint(
+            lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
+            pat.hir_id,
+            pat.span,
+            Rust2024IncompatiblePat { sugg },
+        );
+    }
     result
 }
 
@@ -73,17 +94,38 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             }
             _ => self.lower_pattern_unadjusted(pat),
         };
-        self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
-            unadjusted_pat,
-            |pat: Box<_>, ref_ty| {
-                debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
-                Box::new(Pat {
-                    span: pat.span,
-                    ty: *ref_ty,
-                    kind: PatKind::Deref { subpattern: pat },
+
+        let adjustments: &[Ty<'tcx>] =
+            self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
+        let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| {
+            debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty);
+            Box::new(Pat {
+                span: thir_pat.span,
+                ty: *ref_ty,
+                kind: PatKind::Deref { subpattern: thir_pat },
+            })
+        });
+
+        if let Some(s) = &mut self.rust_2024_migration_suggestion
+            && !adjustments.is_empty()
+        {
+            let suggestion_str: String = adjustments
+                .iter()
+                .map(|ref_ty| {
+                    let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
+                        span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
+                    };
+
+                    match mutbl {
+                        ty::Mutability::Not => "&",
+                        ty::Mutability::Mut => "&mut ",
+                    }
                 })
-            },
-        )
+                .collect();
+            s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
+        };
+
+        adjusted_pat
     }
 
     fn lower_pattern_range_endpoint(
@@ -272,7 +314,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
             }
 
-            hir::PatKind::Slice(prefix, ref slice, suffix) => {
+            hir::PatKind::Slice(prefix, slice, suffix) => {
                 self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix)
             }
 
@@ -284,7 +326,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 PatKind::Leaf { subpatterns }
             }
 
-            hir::PatKind::Binding(_, id, ident, ref sub) => {
+            hir::PatKind::Binding(explicit_ba, id, ident, sub) => {
                 if let Some(ident_span) = ident.span.find_ancestor_inside(span) {
                     span = span.with_hi(ident_span.hi());
                 }
@@ -295,6 +337,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     .get(pat.hir_id)
                     .expect("missing binding mode");
 
+                if let Some(s) = &mut self.rust_2024_migration_suggestion
+                    && explicit_ba.0 == ByRef::No
+                    && let ByRef::Yes(mutbl) = mode.0
+                {
+                    let sugg_str = match mutbl {
+                        Mutability::Not => "ref ",
+                        Mutability::Mut => "ref mut ",
+                    };
+                    s.suggestion.push((
+                        pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
+                        sugg_str.to_owned(),
+                    ))
+                }
+
                 // A ref x pattern is the same node used for x, and as such it has
                 // x's type, which is &T, where we want T (the type being matched).
                 let var_ty = ty;
@@ -366,10 +422,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         pats.iter().map(|p| self.lower_pattern(p)).collect()
     }
 
-    fn lower_opt_pattern(
-        &mut self,
-        pat: &'tcx Option<&'tcx hir::Pat<'tcx>>,
-    ) -> Option<Box<Pat<'tcx>>> {
+    fn lower_opt_pattern(&mut self, pat: Option<&'tcx hir::Pat<'tcx>>) -> Option<Box<Pat<'tcx>>> {
         pat.map(|p| self.lower_pattern(p))
     }
 
@@ -378,7 +431,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         span: Span,
         ty: Ty<'tcx>,
         prefix: &'tcx [hir::Pat<'tcx>],
-        slice: &'tcx Option<&'tcx hir::Pat<'tcx>>,
+        slice: Option<&'tcx hir::Pat<'tcx>>,
         suffix: &'tcx [hir::Pat<'tcx>],
     ) -> PatKind<'tcx> {
         let prefix = self.lower_patterns(prefix);
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index 52c9cf14ac8..340eb3c2eea 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -1,4 +1,5 @@
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType};
 
 pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index ba70a4453d6..d43fca3dc7e 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -1,5 +1,6 @@
 use rustc_ast::InlineAsmOptions;
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::ty::layout;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_target::spec::abi::Abi;
diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs
index a405ed6088d..5f67bd75c48 100644
--- a/compiler/rustc_mir_transform/src/check_packed_ref.rs
+++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs
@@ -1,5 +1,6 @@
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, TyCtxt};
 
 use crate::MirLint;
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 3008016863e..a3e6e5a5a91 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -70,6 +70,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::CoroutineArgs;
 use rustc_middle::ty::InstanceDef;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
 };
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 3d6c1a95204..10c0567eb4b 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -71,6 +71,7 @@
 
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::hir::place::{Projection, ProjectionKind};
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::{self, dump_mir, MirPass};
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 6e73a476421..b98554ec00f 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
 
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops};
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 1895735ab35..fd74a2a97e2 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::graph::dominators::{self, Dominators};
 use rustc_data_structures::graph::{self, DirectedGraph, StartNode};
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind};
 
 use std::cmp::Ordering;
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index a0570c45f96..f2f76ac70c2 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,3 +1,4 @@
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_span::{BytePos, Span};
 
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 4ce37b5defc..d1727a94a35 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::bug;
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::{
     self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index cf1a2b399f9..ca64688e6b8 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -30,6 +30,7 @@ use super::graph::{self, BasicCoverageBlock};
 use itertools::Itertools;
 use rustc_data_structures::graph::{DirectedGraph, Successors};
 use rustc_index::{Idx, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty;
 use rustc_span::{BytePos, Pos, Span, DUMMY_SP};
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 3019b275fb2..a42d64f86be 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -6,6 +6,7 @@ use rustc_const_eval::const_eval::{throw_machine_stop_str, DummyMachine};
 use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::DefKind;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index e6317e5469c..08dba1de500 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -13,6 +13,7 @@
 //!
 
 use crate::util::is_within_packed;
+use rustc_middle::bug;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 10fea09531a..1bc383fccc7 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -135,6 +135,7 @@ use crate::MirPass;
 use rustc_data_structures::fx::{FxIndexMap, IndexEntry, IndexOccupiedEntry};
 use rustc_index::bit_set::BitSet;
 use rustc_index::interval::SparseIntervalMatrix;
+use rustc_middle::bug;
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::HasLocalDecls;
 use rustc_middle::mir::{dump_mir, PassWhere};
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index 318674f24e7..d955b96d06a 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -6,6 +6,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::*;
+use rustc_middle::span_bug;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_target::abi::FieldIdx;
 
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 0970c4de19f..5e3cd853675 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -4,6 +4,7 @@ use rustc_middle::query::LocalCrate;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::FFI_UNWIND_CALLS;
 use rustc_target::spec::abi::Abi;
 use rustc_target::spec::PanicStrategy;
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 342d1a1cd5b..123166a764d 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -91,6 +91,7 @@ use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
 use rustc_index::newtype_index;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::GlobalAlloc;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 7a3b08f82f6..401056cd496 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -6,6 +6,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
 use rustc_index::Idx;
+use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index fd768cc96ae..f1adeab3f88 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -2,6 +2,7 @@
 
 use crate::simplify::simplify_duplicate_switch_targets;
 use rustc_ast::attr;
+use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout;
 use rustc_middle::ty::layout::ValidityRequirement;
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index a458297210d..ae807655b68 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -41,6 +41,7 @@ use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable}
 use rustc_data_structures::fx::FxHashSet;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 90c1c7ba63b..d0a5a6cada8 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -14,6 +14,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::HirId;
 use rustc_index::{bit_set::BitSet, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index e69c5da757e..9af48f0bad2 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -16,8 +16,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 use hir::ConstContext;
 use required_consts::RequiredConstsVisitor;
@@ -38,6 +36,7 @@ use rustc_middle::mir::{
 use rustc_middle::query;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_middle::util::Providers;
+use rustc_middle::{bug, span_bug};
 use rustc_span::{source_map::Spanned, sym, DUMMY_SP};
 use rustc_trait_selection::traits;
 
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index da63fcf23d9..43d8c45bb2d 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -2,6 +2,7 @@
 
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
 
 pub struct LowerIntrinsics;
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index 232c290e0fb..885dbd5f339 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -2,6 +2,7 @@
 
 use rustc_hir::Mutability;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::bug;
 use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{self, BasicBlock, Local, Location};
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 689a547689a..b3116c002d3 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -20,6 +20,7 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis
 use rustc_middle::mir::*;
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 
 use rustc_index::{Idx, IndexSlice, IndexVec};
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index 044ae32c1d4..801ef14c9cd 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -1,6 +1,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 1c85a604053..cd8a43d6e6c 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -5,6 +5,7 @@ use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
 
 use rustc_index::{Idx, IndexVec};
diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
index 80eadb9abdc..0d023c62683 100644
--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
@@ -14,6 +14,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::util::Discr;
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::source_map::respan;
 use rustc_span::{Span, Symbol};
 use rustc_target::abi::{FieldIdx, VariantIdx};
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index 1a8cfc41178..03907babf2b 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -2,6 +2,7 @@ use std::iter;
 
 use super::MirPass;
 use rustc_middle::{
+    bug,
     mir::{
         interpret::Scalar, BasicBlock, BinOp, Body, Operand, Place, Rvalue, Statement,
         StatementKind, SwitchTargets, TerminatorKind,
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 06d5e17fdd6..cdf3305b560 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -1,6 +1,7 @@
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_index::bit_set::{BitSet, GrowableBitSet};
 use rustc_index::IndexVec;
+use rustc_middle::bug;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index 55fed7d9da2..fb870425f6e 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -9,6 +9,7 @@
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_index::bit_set::BitSet;
 use rustc_index::{IndexSlice, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::middle::resolve_bound_vars::Set1;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
index 66b6235eb93..1404a45f4d2 100644
--- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
@@ -2,6 +2,7 @@
 
 use crate::MirPass;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::bug;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::{
     BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind,
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index 8ad7bc394c5..a6c3c3b189e 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -3,6 +3,7 @@
 //! post-order traversal of the blocks.
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 577003e94fb..441aa5b0806 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -497,8 +497,7 @@ impl<'a> Parser<'a> {
 
     /// Checks if this expression is a successfully parsed statement.
     fn expr_is_complete(&self, e: &Expr) -> bool {
-        self.restrictions.contains(Restrictions::STMT_EXPR)
-            && !classify::expr_requires_semi_to_be_stmt(e)
+        self.restrictions.contains(Restrictions::STMT_EXPR) && classify::expr_is_complete(e)
     }
 
     /// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
@@ -2691,8 +2690,33 @@ impl<'a> Parser<'a> {
             let first_tok_span = self.token.span;
             match self.parse_expr() {
                 Ok(cond)
-                // If it's not a free-standing expression, and is followed by a block,
-                // then it's very likely the condition to an `else if`.
+                // Try to guess the difference between a "condition-like" vs
+                // "statement-like" expression.
+                //
+                // We are seeing the following code, in which $cond is neither
+                // ExprKind::Block nor ExprKind::If (the 2 cases wherein this
+                // would be valid syntax).
+                //
+                //     if ... {
+                //     } else $cond
+                //
+                // If $cond is "condition-like" such as ExprKind::Binary, we
+                // want to suggest inserting `if`.
+                //
+                //     if ... {
+                //     } else if a == b {
+                //            ^^
+                //     }
+                //
+                // If $cond is "statement-like" such as ExprKind::While then we
+                // want to suggest wrapping in braces.
+                //
+                //     if ... {
+                //     } else {
+                //            ^
+                //         while true {}
+                //     }
+                //     ^
                     if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
                         && classify::expr_requires_semi_to_be_stmt(&cond) =>
                 {
@@ -3136,7 +3160,7 @@ impl<'a> Parser<'a> {
                         err
                     })?;
 
-                let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
+                let require_comma = !classify::expr_is_complete(&expr)
                     && this.token != token::CloseDelim(Delimiter::Brace);
 
                 if !require_comma {
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 914481d712e..85f55553af3 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -8,9 +8,6 @@
 #![allow(rustc::potential_query_instability, unused_parens)]
 #![allow(internal_features)]
 
-#[macro_use]
-extern crate rustc_middle;
-
 use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green};
 use crate::profiling_support::QueryKeyStringCache;
 use field_offset::offset_of;
@@ -222,4 +219,4 @@ pub fn query_system<'tcx>(
     }
 }
 
-rustc_query_append! { define_queries! }
+rustc_middle::rustc_query_append! { define_queries! }
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index a7696b1fbaf..86531bd9590 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -7,8 +7,8 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
 use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::DiagInner;
-
 use rustc_index::Idx;
+use rustc_middle::bug;
 use rustc_middle::dep_graph::dep_kinds;
 use rustc_middle::dep_graph::{
     self, DepContext, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
@@ -781,6 +781,7 @@ macro_rules! define_queries {
         #[allow(nonstandard_style)]
         mod query_callbacks {
             use super::*;
+            use rustc_middle::bug;
             use rustc_query_system::dep_graph::FingerprintStyle;
 
             // We use this for most things when incr. comp. is turned off.
@@ -849,7 +850,7 @@ macro_rules! define_queries {
         }
 
         pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
-            arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
+            arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(query_callbacks))
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index f1f03b810a9..521e4ef0c9e 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -30,8 +30,6 @@
 
 #[macro_use]
 extern crate tracing;
-#[macro_use]
-extern crate rustc_middle;
 
 pub mod errors;
 pub mod infer;
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index f2c441dcbed..e079809aecc 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -20,7 +20,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
 use rustc_middle::ty;
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn compute_alias_relate_goal(
         &mut self,
         goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>,
@@ -50,7 +50,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         self.try_evaluate_added_goals()?;
         let lhs = self.resolve_vars_if_possible(lhs);
         let rhs = self.resolve_vars_if_possible(rhs);
-        debug!(?lhs, ?rhs);
+        trace!(?lhs, ?rhs);
 
         let variance = match direction {
             ty::AliasRelationDirection::Equate => ty::Variance::Invariant,
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index f2ca42a0be9..9a027d7f937 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -4,6 +4,7 @@ use crate::solve::GoalSource;
 use crate::solve::{inspect, EvalCtxt, SolverMode};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
+use rustc_middle::bug;
 use rustc_middle::traits::solve::inspect::ProbeKind;
 use rustc_middle::traits::solve::{
     CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult,
@@ -331,7 +332,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty))
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_non_blanket_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -447,7 +448,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_blanket_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -470,7 +471,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_builtin_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -544,7 +545,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_param_env_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -561,7 +562,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_alias_bound_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -665,7 +666,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -756,7 +757,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ///
     /// To do so we add an ambiguous candidate in case such an unknown impl could
     /// apply to the current goal.
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "trace", skip_all)]
     fn assemble_coherence_unknowable_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
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 a8b1a182d3c..f1115c3504e 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -5,6 +5,7 @@ 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::bug;
 use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::{
     self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
@@ -17,7 +18,7 @@ use crate::solve::EvalCtxt;
 //
 // For types with an "existential" binder, i.e. coroutine witnesses, we also
 // instantiate the binder with placeholders eagerly.
-#[instrument(level = "debug", skip(ecx), ret)]
+#[instrument(level = "trace", skip(ecx), ret)]
 pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
@@ -96,7 +97,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
     }
 }
 
-#[instrument(level = "debug", skip(ecx), ret)]
+#[instrument(level = "trace", skip(ecx), ret)]
 pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
@@ -160,7 +161,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
     }
 }
 
-#[instrument(level = "debug", skip(ecx), ret)]
+#[instrument(level = "trace", skip(ecx), ret)]
 pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
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 d6010242e4c..2058650f288 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -22,6 +22,7 @@ use rustc_infer::infer::resolve::EagerResolver;
 use rustc_infer::infer::RegionVariableOrigin;
 use rustc_infer::infer::{InferCtxt, InferOk};
 use rustc_infer::traits::solve::NestedNormalizationGoals;
+use rustc_middle::bug;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
@@ -83,7 +84,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ///   the values inferred while solving the instantiated goal.
     /// - `external_constraints`: additional constraints which aren't expressible
     ///   using simple unification of inference variables.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
         &mut self,
         certainty: Certainty,
@@ -166,7 +167,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// external constraints do not need to record that opaque, since if it is
     /// further constrained by inference, that will be passed back in the var
     /// values.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn compute_external_query_constraints(
         &self,
         normalization_nested_goals: NestedNormalizationGoals<'tcx>,
@@ -174,7 +175,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         // We only check for leaks from universes which were entered inside
         // of the query.
         self.infcx.leak_check(self.max_input_universe, None).map_err(|e| {
-            debug!(?e, "failed the leak check");
+            trace!(?e, "failed the leak check");
             NoSolution
         })?;
 
@@ -334,7 +335,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// whether an alias is rigid by using the trait solver. When instantiating a response
     /// from the solver we assume that the solver correctly handled aliases and therefore
     /// always relate them structurally here.
-    #[instrument(level = "debug", skip(infcx))]
+    #[instrument(level = "trace", skip(infcx))]
     fn unify_query_var_values(
         infcx: &InferCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -407,7 +408,7 @@ pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>
 /// 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.
-#[instrument(level = "debug", skip(infcx, span, param_env))]
+#[instrument(level = "trace", skip(infcx, span, param_env))]
 pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     infcx: &InferCtxt<'tcx>,
     span: Span,
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 9cd1841051d..144197b0bec 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::traits::query::NoSolution;
 use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals};
 use rustc_infer::traits::ObligationCause;
 use rustc_macros::{extension, HashStable};
+use rustc_middle::bug;
 use rustc_middle::infer::canonical::CanonicalVarInfos;
 use rustc_middle::traits::solve::inspect;
 use rustc_middle::traits::solve::{
@@ -458,7 +459,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", 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);
@@ -472,7 +473,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 
     // Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning
     // the certainty of all the goals.
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     pub(super) fn try_evaluate_added_goals(&mut self) -> Result<Certainty, NoSolution> {
         self.inspect.start_evaluate_added_goals();
         let mut response = Ok(Certainty::overflow(false));
@@ -526,7 +527,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 unconstrained_goal,
             )?;
             // Add the nested goals from normalization to our own nested goals.
-            debug!(?nested_goals);
+            trace!(?nested_goals);
             goals.goals.extend(nested_goals);
 
             // Finally, equate the goal's RHS with the unconstrained var.
@@ -622,7 +623,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ///
     /// This is the case if the `term` does not occur in any other part of the predicate
     /// and is able to name all other placeholder and inference variables.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn term_is_fully_unconstrained(
         &self,
         goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
@@ -718,7 +719,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             && goal.param_env.visit_with(&mut visitor).is_continue()
     }
 
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     pub(super) fn eq<T: ToTrace<'tcx>>(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -733,7 +734,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
             .map_err(|e| {
-                debug!(?e, "failed to equate");
+                trace!(?e, "failed to equate");
                 NoSolution
             })
     }
@@ -743,7 +744,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// Normally we emit a nested `AliasRelate` when equating an inference
     /// variable and an alias. This causes us to instead constrain the inference
     /// variable to the alias without emitting a nested alias relate goals.
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     pub(super) fn relate_rigid_alias_non_alias(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -781,7 +782,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// This sohuld only be used when we're either instantiating a previously
     /// unconstrained "return value" or when we're sure that all aliases in
     /// the types are rigid.
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     pub(super) fn eq_structurally_relating_aliases<T: ToTrace<'tcx>>(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -798,7 +799,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         Ok(())
     }
 
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     pub(super) fn sub<T: ToTrace<'tcx>>(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -813,12 +814,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
             .map_err(|e| {
-                debug!(?e, "failed to subtype");
+                trace!(?e, "failed to subtype");
                 NoSolution
             })
     }
 
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     pub(super) fn relate<T: ToTrace<'tcx>>(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -834,7 +835,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
             .map_err(|e| {
-                debug!(?e, "failed to relate");
+                trace!(?e, "failed to relate");
                 NoSolution
             })
     }
@@ -859,7 +860,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 obligations.into_iter().map(|o| o.into()).collect()
             })
             .map_err(|e| {
-                debug!(?e, "failed to equate");
+                trace!(?e, "failed to equate");
                 NoSolution
             })
     }
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 ee23f49939b..47109c8ad5d 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
@@ -58,6 +58,7 @@ impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F>
 where
     F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>,
 {
+    #[instrument(level = "debug", skip_all, fields(source = ?self.source))]
     pub(in crate::solve) fn enter(
         self,
         f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
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 7efc951135b..6fda5f4af25 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -8,6 +8,7 @@ use rustc_infer::traits::{
     PolyTraitObligation, Selection, SelectionError, SelectionResult,
 };
 use rustc_macros::extension;
+use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 
 use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 4cc041fca8c..3323f1bbf39 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -9,6 +9,7 @@ use rustc_infer::traits::{
     self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation,
     ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine,
 };
+use rustc_middle::bug;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::sym;
@@ -119,7 +120,7 @@ impl<'tcx> FulfillmentCtxt<'tcx> {
 }
 
 impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
-    #[instrument(level = "debug", skip(self, infcx))]
+    #[instrument(level = "trace", skip(self, infcx))]
     fn register_predicate_obligation(
         &mut self,
         infcx: &InferCtxt<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
index 3c5505055a4..9dd681f09e7 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
@@ -6,6 +6,7 @@
 use std::mem;
 
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::bug;
 use rustc_middle::infer::canonical::CanonicalVarValues;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index b2b076e28e6..6c912db975a 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -17,6 +17,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::bug;
 use rustc_middle::infer::canonical::CanonicalVarInfos;
 use rustc_middle::traits::solve::{
     CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, QueryResult, Response,
@@ -82,7 +83,7 @@ impl<'tcx> Canonical<'tcx, Response<'tcx>> {
 }
 
 impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_type_outlives_goal(
         &mut self,
         goal: Goal<'tcx, TypeOutlivesPredicate<'tcx>>,
@@ -92,7 +93,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_region_outlives_goal(
         &mut self,
         goal: Goal<'tcx, RegionOutlivesPredicate<'tcx>>,
@@ -102,7 +103,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_coerce_goal(
         &mut self,
         goal: Goal<'tcx, CoercePredicate<'tcx>>,
@@ -117,7 +118,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         })
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_subtype_goal(
         &mut self,
         goal: Goal<'tcx, SubtypePredicate<'tcx>>,
@@ -138,7 +139,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_well_formed_goal(
         &mut self,
         goal: Goal<'tcx, ty::GenericArg<'tcx>>,
@@ -152,7 +153,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn compute_const_evaluatable_goal(
         &mut self,
         Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>,
@@ -189,7 +190,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn compute_const_arg_has_type_goal(
         &mut self,
         goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>,
@@ -201,7 +202,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self, goals))]
+    #[instrument(level = "trace", skip(self, goals))]
     fn add_goals(
         &mut self,
         source: GoalSource,
@@ -215,7 +216,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// Try to merge multiple possible ways to prove a goal, if that is not possible returns `None`.
     ///
     /// In this case we tend to flounder and return ambiguity by calling `[EvalCtxt::flounder]`.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn try_merge_responses(
         &mut self,
         responses: &[CanonicalResponse<'tcx>],
@@ -241,7 +242,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     }
 
     /// If we fail to merge responses we flounder and return overflow or ambiguity.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn flounder(&mut self, responses: &[CanonicalResponse<'tcx>]) -> QueryResult<'tcx> {
         if responses.is_empty() {
             return Err(NoSolution);
@@ -263,7 +264,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// This function is necessary in nearly all cases before matching on a type.
     /// Not doing so is likely to be incomplete and therefore unsound during
     /// coherence.
-    #[instrument(level = "debug", skip(self, param_env), ret)]
+    #[instrument(level = "trace", skip(self, param_env), ret)]
     fn structurally_normalize_ty(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index cd1add9e0fa..1ac1827bf1c 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -162,7 +162,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
         Ok(t)
     }
 
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
         let infcx = self.at.infcx;
         debug_assert_eq!(ty, infcx.shallow_resolve(ty));
@@ -189,7 +189,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
         let infcx = self.at.infcx;
         debug_assert_eq!(ct, infcx.shallow_resolve_const(ct));
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
index 37d56452893..94e078f5615 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
@@ -3,7 +3,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
 use rustc_middle::ty;
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn normalize_anon_const(
         &mut self,
         goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
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 454c7a5f00f..906cf149750 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -17,6 +17,7 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::NormalizesTo;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
 
 mod anon_const;
@@ -25,7 +26,7 @@ mod opaque_types;
 mod weak_types;
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn compute_normalizes_to_goal(
         &mut self,
         goal: Goal<'tcx, NormalizesTo<'tcx>>,
@@ -59,7 +60,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     /// Normalize the given alias by at least one step. If the alias is rigid, this
     /// returns `NoSolution`.
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     fn normalize_at_least_one_step(
         &mut self,
         goal: Goal<'tcx, NormalizesTo<'tcx>>,
@@ -897,7 +898,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 ///
 /// FIXME: We should merge these 3 implementations as it's likely that they otherwise
 /// diverge.
-#[instrument(level = "debug", skip(ecx, param_env), ret)]
+#[instrument(level = "trace", skip(ecx, param_env), ret)]
 fn fetch_eligible_assoc_item_def<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
@@ -920,7 +921,7 @@ fn fetch_eligible_assoc_item_def<'tcx>(
             let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref);
             !poly_trait_ref.still_further_specializable()
         } else {
-            debug!(?node_item.item.def_id, "not eligible due to default");
+            trace!(?node_item.item.def_id, "not eligible due to default");
             false
         }
     };
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 30ae385a8a0..74b3db71e78 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -5,7 +5,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
 use rustc_middle::ty::{self, ProjectionPredicate};
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
-    #[instrument(level = "debug", skip(self), ret)]
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn compute_projection_goal(
         &mut self,
         goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs
index a48b2f2478b..60362aa01da 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs
@@ -130,7 +130,7 @@ impl<'tcx> SearchGraph<'tcx> {
     }
 
     /// Update the stack and reached depths on cache hits.
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) {
         let reached_depth = self.stack.next_index().plus(additional_depth);
         if let Some(last) = self.stack.raw.last_mut() {
@@ -296,6 +296,7 @@ impl<'tcx> SearchGraph<'tcx> {
             }
 
             self.on_cache_hit(reached_depth, encountered_overflow);
+            debug!("global cache hit");
             return result;
         }
 
@@ -315,6 +316,7 @@ impl<'tcx> SearchGraph<'tcx> {
                     .filter(|p| !Self::stack_coinductive_from(tcx, &self.stack, p.head))
             })
         {
+            debug!("provisional cache hit");
             // We have a nested goal which is already in the provisional cache, use
             // its result. We do not provide any usage kind as that should have been
             // already set correctly while computing the cache entry.
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 083cc0aa3c2..1cafa970b68 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -10,6 +10,7 @@ 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::bug;
 use rustc_middle::traits::solve::inspect::ProbeKind;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
 use rustc_middle::traits::{BuiltinImplSource, Reveal};
@@ -1130,7 +1131,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     },
                 );
                 if let Some(def_id) = disqualifying_impl {
-                    debug!(?def_id, ?goal, "disqualified auto-trait implementation");
+                    trace!(?def_id, ?goal, "disqualified auto-trait implementation");
                     // No need to actually consider the candidate here,
                     // since we do that in `consider_impl_candidate`.
                     return Some(Err(NoSolution));
@@ -1171,7 +1172,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         })
     }
 
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     pub(super) fn compute_trait_goal(
         &mut self,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 59725ce9de0..2cc972cb98e 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -20,6 +20,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::{util, FulfillmentErrorCode};
+use rustc_middle::bug;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index a8be5627fed..8348482386f 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -11,6 +11,7 @@
 
 use rustc_hir::def::DefKind;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
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 040ce450aaf..7fc94b31b3b 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
@@ -10,6 +10,7 @@ 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::bug;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
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 ea1752a6e98..f1088626f5b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -34,6 +34,7 @@ use rustc_middle::ty::{
     InferTy, IsSuggestable, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeVisitableExt, TypeckResults,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
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 08ffe37b8b4..4092022d531 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
@@ -45,6 +45,7 @@ use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
     TypeVisitable, TypeVisitableExt,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_session::config::DumpSolverProofTree;
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index e3497c646db..bb4067804aa 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -8,6 +8,7 @@ use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProce
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::traits::ProjectionCacheKey;
 use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 56f8b4b9cdb..4b42496c2e2 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -31,6 +31,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_errors::ErrorGuaranteed;
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFolder, TypeSuperVisitable};
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 1dd2ada3356..1dc2ebfaa7a 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -5,6 +5,7 @@ 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::span_bug;
 use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
 
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index f092f42dacf..d2ffd13cba4 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -17,6 +17,7 @@ use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::traits::ImplSource;
 use rustc_middle::traits::ImplSourceUserDefinedData;
+use rustc_middle::{bug, span_bug};
 
 use crate::errors::InherentProjectionNormalizationOverflow;
 use crate::infer::{BoundRegionConversionTime, InferOk};
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 87d240cf8ac..692feee7395 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -1,4 +1,5 @@
 use rustc_macros::extension;
+use rustc_middle::span_bug;
 
 use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferCtxt;
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 40d206b92b8..a0260324da0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -16,6 +16,7 @@ use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
+use rustc_middle::{bug, span_bug};
 
 use crate::traits;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 69d11b45e60..24c6951a014 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -17,6 +17,7 @@ use rustc_middle::ty::{
     self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
     TraitPredicate, Ty, TyCtxt,
 };
+use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
 
 use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7aa2aabed7f..3cf47e0f98e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -36,6 +36,7 @@ use rustc_infer::infer::BoundRegionConversionTime;
 use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType;
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::traits::TraitObligation;
+use rustc_middle::bug;
 use rustc_middle::dep_graph::dep_kinds;
 use rustc_middle::dep_graph::DepNodeIndex;
 use rustc_middle::mir::interpret::ErrorHandled;
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index fe3f66f3a3f..826bb706f48 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -23,6 +23,7 @@ use crate::traits::{
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee};
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::bug;
 use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
 use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
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 b6c2fcb46eb..90f2c7ad213 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -4,6 +4,7 @@ use crate::traits;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_macros::extension;
+use rustc_middle::bug;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 6778ac81aea..d4535db951e 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::bug;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use std::ops::ControlFlow;
 
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index b2ba7854f18..83edddb9a96 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -6,6 +6,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Diag;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_middle::bug;
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable};
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index 3f1ba80acd3..8fd9889b4ea 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -4,6 +4,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::traits::util::PredicateSet;
 use rustc_infer::traits::ImplSource;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::visit::TypeVisitableExt;
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 562a82cc73d..31eae3926ee 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -3,6 +3,7 @@ use crate::traits;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::traits::ObligationCauseCode;
+use rustc_middle::bug;
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index c6b83628506..fd7e2fec389 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -1,5 +1,6 @@
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{
     fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout,
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index d3fe8291e03..4395eb57cd6 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -5,6 +5,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::kw;
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index acbcc3918b2..fec02f515ca 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -1,6 +1,7 @@
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::bug;
 use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::query::Providers;
 use rustc_middle::thir::visit;
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 862fb2e1663..e87058f9ba4 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index d0aa4eb2e71..41f482d8a70 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -1,6 +1,7 @@
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError};
 use rustc_middle::ty::GenericArgsRef;
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index f78a28d16fd..1ef22497a8f 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -2,6 +2,7 @@ use hir::def_id::DefId;
 use rustc_hir as hir;
 use rustc_index::bit_set::BitSet;
 use rustc_index::{IndexSlice, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{
diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
index 6332c614a90..ab7d1be226b 100644
--- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs
+++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
@@ -1,3 +1,4 @@
+use rustc_middle::bug;
 use rustc_middle::ty::{
     layout::{LayoutCx, TyAndLayout},
     TyCtxt,
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index fd392d11e83..e8c5c54d3a0 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -17,8 +17,6 @@
 #![feature(never_type)]
 
 #[macro_use]
-extern crate rustc_middle;
-#[macro_use]
 extern crate tracing;
 
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index ee930a78e77..4e23fb30383 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -2,6 +2,7 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop};
 use rustc_middle::ty::GenericArgsRef;
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index d7d31a88c9b..be227ec8b9a 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{def::DefKind, def_id::LocalDefId};
 use rustc_hir::{intravisit, CRATE_HIR_ID};
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
 use rustc_middle::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs
index 446f16b4125..0ffb7f62496 100644
--- a/compiler/rustc_ty_utils/src/representability.rs
+++ b/compiler/rustc_ty_utils/src/representability.rs
@@ -1,5 +1,6 @@
 use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Representability, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 19c092c5ddf..2d8c78267d9 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -4,6 +4,7 @@
 use rustc_ast_ir::try_visit;
 use rustc_ast_ir::visit::VisitorResult;
 use rustc_hir::{def::DefKind, def_id::LocalDefId};
+use rustc_middle::span_bug;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Span;
 use rustc_type_ir::visit::TypeVisitable;
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index fa1085c7cd7..d98b46dfb93 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -3,6 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::LangItem;
 use rustc_index::bit_set::BitSet;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt, TypeVisitor};
 use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable};
diff --git a/config.example.toml b/config.example.toml
index 3b76952504f..224d079b206 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -213,17 +213,17 @@
 # the root of the repository.
 #build-dir = "build"
 
-# Instead of downloading the src/stage0.json version of Cargo specified, use
+# Instead of downloading the src/stage0 version of Cargo specified, use
 # this Cargo binary instead to build all Rust code
 # If you set this, you likely want to set `rustc` as well.
 #cargo = "/path/to/cargo"
 
-# Instead of downloading the src/stage0.json version of the compiler
+# Instead of downloading the src/stage0 version of the compiler
 # specified, use this rustc binary instead as the stage0 snapshot compiler.
 # If you set this, you likely want to set `cargo` as well.
 #rustc = "/path/to/rustc"
 
-# Instead of downloading the src/stage0.json version of rustfmt specified,
+# Instead of downloading the src/stage0 version of rustfmt specified,
 # use this rustfmt binary instead as the stage0 snapshot rustfmt.
 #rustfmt = "/path/to/rustfmt"
 
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index d7dc6ae6694..ae44cab8131 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -630,7 +630,9 @@ pub fn format(args: Arguments<'_>) -> string::String {
     fn format_inner(args: Arguments<'_>) -> string::String {
         let capacity = args.estimated_capacity();
         let mut output = string::String::with_capacity(capacity);
-        output.write_fmt(args).expect("a formatting trait implementation returned an error");
+        output
+            .write_fmt(args)
+            .expect("a formatting trait implementation returned an error when the underlying stream did not");
         output
     }
 
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index d8597369b9b..8283fdc459b 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1467,8 +1467,9 @@ mod prim_usize {}
 /// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API
 /// boundary, the following invariants must generally be upheld:
 ///
+/// * `t` is non-null
 /// * `t` is aligned to `align_of_val(t)`
-/// * `t` is dereferenceable for `size_of_val(t)` many bytes
+/// * if `size_of_val(t) > 0`, then `t` is dereferenceable for `size_of_val(t)` many bytes
 ///
 /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range
 /// `[a, a + N)` is all contained within a single [allocated object].
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index af055152cbe..5c6e7b7bd50 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1839,7 +1839,11 @@ pub trait Write {
                 if output.error.is_err() {
                     output.error
                 } else {
-                    Err(error::const_io_error!(ErrorKind::Uncategorized, "formatter error"))
+                    // This shouldn't happen: the underlying stream did not error, but somehow
+                    // the formatter still errored?
+                    panic!(
+                        "a formatting trait implementation returned an error when the underlying stream did not"
+                    );
                 }
             }
         }
diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs
index 9938c0bac25..993bf55edcf 100644
--- a/library/std/src/sys/pal/unix/alloc.rs
+++ b/library/std/src/sys/pal/unix/alloc.rs
@@ -61,9 +61,7 @@ unsafe impl GlobalAlloc for System {
 cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "android",
-        target_os = "illumos",
         target_os = "redox",
-        target_os = "solaris",
         target_os = "espidf",
         target_os = "horizon",
         target_os = "vita",
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index e464e444fea..e60e8f0aa1f 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -3,7 +3,6 @@ import argparse
 import contextlib
 import datetime
 import hashlib
-import json
 import os
 import re
 import shutil
@@ -52,7 +51,7 @@ def get(base, url, path, checksums, verbose=False):
 
     try:
         if url not in checksums:
-            raise RuntimeError(("src/stage0.json doesn't contain a checksum for {}. "
+            raise RuntimeError(("src/stage0 doesn't contain a checksum for {}. "
                                 "Pre-built artifacts might not be available for this "
                                 "target at this time, see https://doc.rust-lang.org/nightly"
                                 "/rustc/platform-support.html for more information.")
@@ -421,9 +420,9 @@ def output(filepath):
 
 
 class Stage0Toolchain:
-    def __init__(self, stage0_payload):
-        self.date = stage0_payload["date"]
-        self.version = stage0_payload["version"]
+    def __init__(self, date, version):
+        self.date = date
+        self.version = version
 
     def channel(self):
         return self.version + "-" + self.date
@@ -439,7 +438,7 @@ class DownloadInfo:
         bin_root,
         tarball_path,
         tarball_suffix,
-        checksums_sha256,
+        stage0_data,
         pattern,
         verbose,
     ):
@@ -448,7 +447,7 @@ class DownloadInfo:
         self.bin_root = bin_root
         self.tarball_path = tarball_path
         self.tarball_suffix = tarball_suffix
-        self.checksums_sha256 = checksums_sha256
+        self.stage0_data = stage0_data
         self.pattern = pattern
         self.verbose = verbose
 
@@ -458,7 +457,7 @@ def download_component(download_info):
             download_info.base_download_url,
             download_info.download_path,
             download_info.tarball_path,
-            download_info.checksums_sha256,
+            download_info.stage0_data,
             verbose=download_info.verbose,
         )
 
@@ -510,11 +509,12 @@ class RustBuild(object):
         build_dir = args.build_dir or self.get_toml('build-dir', 'build') or 'build'
         self.build_dir = os.path.abspath(build_dir)
 
-        with open(os.path.join(self.rust_root, "src", "stage0.json")) as f:
-            data = json.load(f)
-        self.checksums_sha256 = data["checksums_sha256"]
-        self.stage0_compiler = Stage0Toolchain(data["compiler"])
-        self.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"]
+        self.stage0_data = parse_stage0_file(os.path.join(self.rust_root, "src", "stage0"))
+        self.stage0_compiler = Stage0Toolchain(
+            self.stage0_data["compiler_date"],
+            self.stage0_data["compiler_version"]
+        )
+        self.download_url = os.getenv("RUSTUP_DIST_SERVER") or self.stage0_data["dist_server"]
 
         self.build = args.build or self.build_triple()
 
@@ -581,7 +581,7 @@ class RustBuild(object):
                     bin_root=self.bin_root(),
                     tarball_path=os.path.join(rustc_cache, filename),
                     tarball_suffix=tarball_suffix,
-                    checksums_sha256=self.checksums_sha256,
+                    stage0_data=self.stage0_data,
                     pattern=pattern,
                     verbose=self.verbose,
                 )
@@ -1071,6 +1071,16 @@ def parse_args(args):
 
     return parser.parse_known_args(args)[0]
 
+def parse_stage0_file(path):
+    result = {}
+    with open(path, 'r') as file:
+        for line in file:
+            line = line.strip()
+            if line and not line.startswith('#'):
+                key, value = line.split('=', 1)
+                result[key.strip()] = value.strip()
+    return result
+
 def bootstrap(args):
     """Configure, fetch, build and run the initial bootstrap"""
     rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 0167c51fc7e..bb51433a3dc 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -181,7 +181,7 @@ pub struct Config {
     pub test_compare_mode: bool,
     pub color: Color,
     pub patch_binaries_for_nix: Option<bool>,
-    pub stage0_metadata: Stage0Metadata,
+    pub stage0_metadata: build_helper::stage0_parser::Stage0,
     pub android_ndk: Option<PathBuf>,
     /// Whether to use the `c` feature of the `compiler_builtins` crate.
     pub optimized_compiler_builtins: bool,
@@ -351,34 +351,6 @@ pub struct Config {
     pub paths: Vec<PathBuf>,
 }
 
-#[derive(Default, Deserialize, Clone)]
-pub struct Stage0Metadata {
-    pub compiler: CompilerMetadata,
-    pub config: Stage0Config,
-    pub checksums_sha256: HashMap<String, String>,
-    pub rustfmt: Option<RustfmtMetadata>,
-}
-#[derive(Default, Deserialize, Clone)]
-pub struct CompilerMetadata {
-    pub date: String,
-    pub version: String,
-}
-
-#[derive(Default, Deserialize, Clone)]
-pub struct Stage0Config {
-    pub dist_server: String,
-    pub artifacts_server: String,
-    pub artifacts_with_llvm_assertions_server: String,
-    pub git_merge_commit_email: String,
-    pub git_repository: String,
-    pub nightly_branch: String,
-}
-#[derive(Default, Deserialize, Clone)]
-pub struct RustfmtMetadata {
-    pub date: String,
-    pub version: String,
-}
-
 #[derive(Clone, Debug, Default)]
 pub enum RustfmtState {
     SystemToolchain(PathBuf),
@@ -1298,13 +1270,13 @@ impl Config {
                 Some(p) => PathBuf::from(p),
                 None => git_root,
             };
-            // If this doesn't have at least `stage0.json`, we guessed wrong. This can happen when,
+            // If this doesn't have at least `stage0`, we guessed wrong. This can happen when,
             // for example, the build directory is inside of another unrelated git directory.
             // In that case keep the original `CARGO_MANIFEST_DIR` handling.
             //
             // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
             // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
-            if git_root.join("src").join("stage0.json").exists() {
+            if git_root.join("src").join("stage0").exists() {
                 config.src = git_root;
             }
         } else {
@@ -1322,9 +1294,7 @@ impl Config {
             .to_path_buf();
         }
 
-        let stage0_json = t!(std::fs::read(config.src.join("src").join("stage0.json")));
-
-        config.stage0_metadata = t!(serde_json::from_slice::<Stage0Metadata>(&stage0_json));
+        config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file();
 
         // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory.
         let toml_path = flags
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 75e0f646da6..a074d53aa36 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -9,9 +9,9 @@ use std::{
 };
 
 use build_helper::ci::CiEnv;
+use build_helper::stage0_parser::VersionMetadata;
 use xz2::bufread::XzDecoder;
 
-use crate::core::config::RustfmtMetadata;
 use crate::utils::helpers::{check_run, exe, program_out_of_date};
 use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
 use crate::{t, Config};
@@ -408,7 +408,7 @@ impl Config {
     /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
     /// reuse target directories or artifacts
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
-        let RustfmtMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
+        let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
         let channel = format!("{version}-{date}");
 
         let host = self.build;
@@ -606,7 +606,7 @@ impl Config {
             DownloadSource::Dist => {
                 let dist_server = env::var("RUSTUP_DIST_SERVER")
                     .unwrap_or(self.stage0_metadata.config.dist_server.to_string());
-                // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0.json
+                // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0
                 (dist_server, format!("dist/{key}/{filename}"), true)
             }
         };
@@ -616,7 +616,7 @@ impl Config {
         // this on each and every nightly ...
         let checksum = if should_verify {
             let error = format!(
-                "src/stage0.json doesn't contain a checksum for {url}. \
+                "src/stage0 doesn't contain a checksum for {url}. \
                 Pre-built artifacts might not be available for this \
                 target at this time, see https://doc.rust-lang.org/nightly\
                 /rustc/platform-support.html for more information."
diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md
index 822f341b370..69fb7e3313f 100644
--- a/src/doc/rustdoc/src/command-line-arguments.md
+++ b/src/doc/rustdoc/src/command-line-arguments.md
@@ -273,7 +273,7 @@ will be added.
 
 When rendering Rust files, this flag is ignored.
 
-## `--html-in-header`: include more HTML in <head>
+## `--html-in-header`: include more HTML in `<head>`
 
 Using this flag looks like this:
 
diff --git a/src/stage0 b/src/stage0
new file mode 100644
index 00000000000..5ec8f5b715e
--- /dev/null
+++ b/src/stage0
@@ -0,0 +1,447 @@
+dist_server=https://static.rust-lang.org
+artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds
+artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt
+git_merge_commit_email=bors@rust-lang.org
+git_repository=rust-lang/rust
+nightly_branch=master
+
+# The configuration above this comment is editable, and can be changed
+# by forks of the repository if they have alternate values.
+#
+# The section below is generated by `./x.py run src/tools/bump-stage0`,
+# run that command again to update the bootstrap compiler.
+#
+# All changes below this comment will be overridden the next time the
+# tool is executed.
+            
+compiler_date=2024-04-29
+compiler_version=beta
+rustfmt_date=2024-04-29
+rustfmt_version=nightly
+
+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
\ No newline at end of file
diff --git a/src/stage0.json b/src/stage0.json
deleted file mode 100644
index a9a53a7528f..00000000000
--- a/src/stage0.json
+++ /dev/null
@@ -1,456 +0,0 @@
-{
-  "config": {
-    "dist_server": "https://static.rust-lang.org",
-    "artifacts_server": "https://ci-artifacts.rust-lang.org/rustc-builds",
-    "artifacts_with_llvm_assertions_server": "https://ci-artifacts.rust-lang.org/rustc-builds-alt",
-    "git_merge_commit_email": "bors@rust-lang.org",
-    "git_repository": "rust-lang/rust",
-    "nightly_branch": "master"
-  },
-  "__comments": [
-    "The configuration above this comment is editable, and can be changed",
-    "by forks of the repository if they have alternate values.",
-    "",
-    "The section below is generated by `./x.py run src/tools/bump-stage0`,",
-    "run that command again to update the bootstrap compiler.",
-    "",
-    "All changes below this comment will be overridden the next time the",
-    "tool is executed."
-  ],
-  "compiler": {
-    "date": "2024-04-29",
-    "version": "beta"
-  },
-  "rustfmt": {
-    "date": "2024-04-29",
-    "version": "nightly"
-  },
-  "checksums_sha256": {
-    "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/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs
index 575f3677155..6a4e86eb1df 100644
--- a/src/tools/build_helper/src/lib.rs
+++ b/src/tools/build_helper/src/lib.rs
@@ -2,3 +2,4 @@ pub mod ci;
 pub mod git;
 pub mod metrics;
 pub mod util;
+pub mod stage0_parser;
diff --git a/src/tools/build_helper/src/stage0_parser.rs b/src/tools/build_helper/src/stage0_parser.rs
new file mode 100644
index 00000000000..ff05b116989
--- /dev/null
+++ b/src/tools/build_helper/src/stage0_parser.rs
@@ -0,0 +1,76 @@
+use std::collections::BTreeMap;
+
+#[derive(Default, Clone)]
+pub struct Stage0 {
+    pub compiler: VersionMetadata,
+    pub rustfmt: Option<VersionMetadata>,
+    pub config: Stage0Config,
+    pub checksums_sha256: BTreeMap<String, String>,
+}
+
+#[derive(Default, Clone)]
+pub struct VersionMetadata {
+    pub date: String,
+    pub version: String,
+}
+
+#[derive(Default, Clone)]
+pub struct Stage0Config {
+    pub dist_server: String,
+    pub artifacts_server: String,
+    pub artifacts_with_llvm_assertions_server: String,
+    pub git_merge_commit_email: String,
+    pub git_repository: String,
+    pub nightly_branch: String,
+}
+
+pub fn parse_stage0_file() -> Stage0 {
+    let stage0_content = include_str!("../../../stage0");
+
+    let mut stage0 = Stage0::default();
+    for line in stage0_content.lines() {
+        let line = line.trim();
+
+        if line.is_empty() {
+            continue;
+        }
+
+        // Ignore comments
+        if line.starts_with('#') {
+            continue;
+        }
+
+        let (key, value) = line.split_once('=').unwrap();
+
+        match key {
+            "dist_server" => stage0.config.dist_server = value.to_owned(),
+            "artifacts_server" => stage0.config.artifacts_server = value.to_owned(),
+            "artifacts_with_llvm_assertions_server" => {
+                stage0.config.artifacts_with_llvm_assertions_server = value.to_owned()
+            }
+            "git_merge_commit_email" => stage0.config.git_merge_commit_email = value.to_owned(),
+            "git_repository" => stage0.config.git_repository = value.to_owned(),
+            "nightly_branch" => stage0.config.nightly_branch = value.to_owned(),
+
+            "compiler_date" => stage0.compiler.date = value.to_owned(),
+            "compiler_version" => stage0.compiler.version = value.to_owned(),
+
+            "rustfmt_date" => {
+                stage0.rustfmt.get_or_insert(VersionMetadata::default()).date = value.to_owned();
+            }
+            "rustfmt_version" => {
+                stage0.rustfmt.get_or_insert(VersionMetadata::default()).version = value.to_owned();
+            }
+
+            dist if dist.starts_with("dist") => {
+                stage0.checksums_sha256.insert(key.to_owned(), value.to_owned());
+            }
+
+            unsupported => {
+                println!("'{unsupported}' field is not supported.");
+            }
+        }
+    }
+
+    stage0
+}
diff --git a/src/tools/bump-stage0/Cargo.toml b/src/tools/bump-stage0/Cargo.toml
index 4680a7ab661..de5d821133d 100644
--- a/src/tools/bump-stage0/Cargo.toml
+++ b/src/tools/bump-stage0/Cargo.toml
@@ -7,8 +7,8 @@ edition = "2021"
 
 [dependencies]
 anyhow = "1.0.34"
+build_helper = { path = "../build_helper" }
 curl = "0.4.38"
 indexmap = { version = "2.0.0", features = ["serde"] }
 serde = { version = "1.0.125", features = ["derive"] }
-serde_json = { version = "1.0.59", features = ["preserve_order"] }
 toml = "0.5.7"
diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs
index bd97b4eaa3e..bb06e113c0e 100644
--- a/src/tools/bump-stage0/src/main.rs
+++ b/src/tools/bump-stage0/src/main.rs
@@ -1,15 +1,17 @@
+#![deny(unused_variables)]
+
 use anyhow::{Context, Error};
+use build_helper::stage0_parser::{parse_stage0_file, Stage0Config, VersionMetadata};
 use curl::easy::Easy;
 use indexmap::IndexMap;
 use std::collections::HashMap;
 
-const PATH: &str = "src/stage0.json";
+const PATH: &str = "src/stage0";
 const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo", "clippy-preview"];
 const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview", "rustc"];
 
 struct Tool {
-    config: Config,
-    comments: Vec<String>,
+    config: Stage0Config,
 
     channel: Channel,
     date: Option<String>,
@@ -35,37 +37,64 @@ impl Tool {
             .try_into()
             .map_err(|_| anyhow::anyhow!("failed to parse version"))?;
 
-        let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?;
+        let existing = parse_stage0_file();
 
-        Ok(Self {
-            channel,
-            version,
-            date,
-            config: existing.config,
-            comments: existing.comments,
-            checksums: IndexMap::new(),
-        })
+        Ok(Self { channel, version, date, config: existing.config, checksums: IndexMap::new() })
     }
 
-    fn update_json(mut self) -> Result<(), Error> {
-        std::fs::write(
-            PATH,
-            format!(
-                "{}\n",
-                serde_json::to_string_pretty(&Stage0 {
-                    compiler: self.detect_compiler()?,
-                    rustfmt: self.detect_rustfmt()?,
-                    checksums_sha256: {
-                        // Keys are sorted here instead of beforehand because values in this map
-                        // are added while filling the other struct fields just above this block.
-                        self.checksums.sort_keys();
-                        self.checksums
-                    },
-                    config: self.config,
-                    comments: self.comments,
-                })?
-            ),
-        )?;
+    fn update_stage0_file(mut self) -> Result<(), Error> {
+        const COMMENTS: &str = r#"# The configuration above this comment is editable, and can be changed
+# by forks of the repository if they have alternate values.
+#
+# The section below is generated by `./x.py run src/tools/bump-stage0`,
+# run that command again to update the bootstrap compiler.
+#
+# All changes below this comment will be overridden the next time the
+# tool is executed.
+            "#;
+
+        let mut file_content = String::new();
+
+        // Destructure `Stage0Config` here to ensure the stage0 file is synced with any new
+        // fields when they are added.
+        let Stage0Config {
+            dist_server,
+            artifacts_server,
+            artifacts_with_llvm_assertions_server,
+            git_merge_commit_email,
+            git_repository,
+            nightly_branch,
+        } = &self.config;
+
+        file_content.push_str(&format!("dist_server={}", dist_server));
+        file_content.push_str(&format!("\nartifacts_server={}", artifacts_server));
+        file_content.push_str(&format!(
+            "\nartifacts_with_llvm_assertions_server={}",
+            artifacts_with_llvm_assertions_server
+        ));
+        file_content.push_str(&format!("\ngit_merge_commit_email={}", git_merge_commit_email));
+        file_content.push_str(&format!("\ngit_repository={}", git_repository));
+        file_content.push_str(&format!("\nnightly_branch={}", nightly_branch));
+
+        file_content.push_str("\n\n");
+        file_content.push_str(COMMENTS);
+
+        let compiler = self.detect_compiler()?;
+        file_content.push_str(&format!("\ncompiler_date={}", compiler.date));
+        file_content.push_str(&format!("\ncompiler_version={}", compiler.version));
+
+        if let Some(rustfmt) = self.detect_rustfmt()? {
+            file_content.push_str(&format!("\nrustfmt_date={}", rustfmt.date));
+            file_content.push_str(&format!("\nrustfmt_version={}", rustfmt.version));
+        }
+
+        file_content.push_str("\n");
+
+        for (key, value) in self.checksums {
+            file_content.push_str(&format!("\n{}={}", key, value));
+        }
+
+        std::fs::write(PATH, file_content)?;
         Ok(())
     }
 
@@ -76,7 +105,7 @@ impl Tool {
     // On the master branch the compiler version is configured to `beta` whereas if you're looking
     // at the beta or stable channel you'll likely see `1.x.0` as the version, with the previous
     // release's version number.
-    fn detect_compiler(&mut self) -> Result<Stage0Toolchain, Error> {
+    fn detect_compiler(&mut self) -> Result<VersionMetadata, Error> {
         let channel = match self.channel {
             Channel::Stable | Channel::Beta => {
                 // The 1.XX manifest points to the latest point release of that minor release.
@@ -87,7 +116,7 @@ impl Tool {
 
         let manifest = fetch_manifest(&self.config, &channel, self.date.as_deref())?;
         self.collect_checksums(&manifest, COMPILER_COMPONENTS)?;
-        Ok(Stage0Toolchain {
+        Ok(VersionMetadata {
             date: manifest.date,
             version: if self.channel == Channel::Nightly {
                 "beta".to_string()
@@ -106,14 +135,14 @@ impl Tool {
     /// We use a nightly rustfmt to format the source because it solves some bootstrapping issues
     /// with use of new syntax in this repo. For the beta/stable channels rustfmt is not provided,
     /// as we don't want to depend on rustfmt from nightly there.
-    fn detect_rustfmt(&mut self) -> Result<Option<Stage0Toolchain>, Error> {
+    fn detect_rustfmt(&mut self) -> Result<Option<VersionMetadata>, Error> {
         if self.channel != Channel::Nightly {
             return Ok(None);
         }
 
         let manifest = fetch_manifest(&self.config, "nightly", self.date.as_deref())?;
         self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?;
-        Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() }))
+        Ok(Some(VersionMetadata { date: manifest.date, version: "nightly".into() }))
     }
 
     fn collect_checksums(&mut self, manifest: &Manifest, components: &[&str]) -> Result<(), Error> {
@@ -143,11 +172,15 @@ impl Tool {
 
 fn main() -> Result<(), Error> {
     let tool = Tool::new(std::env::args().nth(1))?;
-    tool.update_json()?;
+    tool.update_stage0_file()?;
     Ok(())
 }
 
-fn fetch_manifest(config: &Config, channel: &str, date: Option<&str>) -> Result<Manifest, Error> {
+fn fetch_manifest(
+    config: &Stage0Config,
+    channel: &str,
+    date: Option<&str>,
+) -> Result<Manifest, Error> {
     let url = if let Some(date) = date {
         format!("{}/dist/{}/channel-rust-{}.toml", config.dist_server, date, channel)
     } else {
@@ -181,42 +214,6 @@ enum Channel {
 }
 
 #[derive(Debug, serde::Serialize, serde::Deserialize)]
-struct Stage0 {
-    config: Config,
-    // Comments are explicitly below the config, do not move them above.
-    //
-    // Downstream forks of the compiler codebase can change the configuration values defined above,
-    // but doing so would risk merge conflicts whenever they import new changes that include a
-    // bootstrap compiler bump.
-    //
-    // To lessen the pain, a big block of comments is placed between the configuration and the
-    // auto-generated parts of the file, preventing git diffs of the config to include parts of the
-    // auto-generated content and vice versa. This should prevent merge conflicts.
-    #[serde(rename = "__comments")]
-    comments: Vec<String>,
-    compiler: Stage0Toolchain,
-    rustfmt: Option<Stage0Toolchain>,
-    checksums_sha256: IndexMap<String, String>,
-}
-
-#[derive(Debug, serde::Serialize, serde::Deserialize)]
-struct Config {
-    dist_server: String,
-    // There are other fields in the configuration, which will be read by src/bootstrap or other
-    // tools consuming stage0.json. To avoid the need to update bump-stage0 every time a new field
-    // is added, we collect all the fields in an untyped Value and serialize them back with the
-    // same order and structure they were deserialized in.
-    #[serde(flatten)]
-    other: serde_json::Value,
-}
-
-#[derive(Debug, serde::Serialize, serde::Deserialize)]
-struct Stage0Toolchain {
-    date: String,
-    version: String,
-}
-
-#[derive(Debug, serde::Serialize, serde::Deserialize)]
 struct Manifest {
     date: String,
     pkg: HashMap<String, ManifestPackage>,
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 386d4c3c317..6715de52649 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir;
 use rustc_hir::{intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::layout::LayoutOf;
@@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
             too_large_for_stack: self.too_large_for_stack,
         };
 
-        let infcx = cx.tcx.infer_ctxt().build();
-        ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
+        ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v).consume_body(body).into_ok();
 
         for node in v.set {
             span_lint_hir(
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 2c44c3881aa..a8bfbbdd9ec 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(never_type)]
 #![feature(rustc_private)]
 #![feature(stmt_expr_attributes)]
+#![feature(unwrap_infallible)]
 #![recursion_limit = "512"]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 #![allow(
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index 5047092192f..6b9ecf5f141 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -4,7 +4,6 @@ use clippy_utils::{get_enclosing_block, higher, path_to_local};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty;
@@ -61,15 +60,12 @@ fn check_for_mutation(
         span_low: None,
         span_high: None,
     };
-    let infcx = cx.tcx.infer_ctxt().build();
-    ExprUseVisitor::new(
-        &mut delegate,
-        &infcx,
+    ExprUseVisitor::for_clippy(
+        cx,
         body.hir_id.owner.def_id,
-        cx.param_env,
-        cx.typeck_results(),
+        &mut delegate,
     )
-    .walk_expr(body);
+    .walk_expr(body).into_ok();
 
     delegate.mutation_span()
 }
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 deac159457a..a52d38790a2 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
@@ -9,7 +9,6 @@ use rustc_lint::LateContext;
 use rustc_middle::mir::{FakeReadCause, Mutability};
 use rustc_middle::ty::{self, BorrowKind};
 use rustc_span::sym;
-use rustc_trait_selection::infer::TyCtxtInferExt;
 
 use super::ITER_OVEREAGER_CLONED;
 use crate::redundant_clone::REDUNDANT_CLONE;
@@ -69,16 +68,13 @@ pub(super) fn check<'tcx>(
             let mut delegate = MoveDelegate {
                 used_move: HirIdSet::default(),
             };
-            let infcx = cx.tcx.infer_ctxt().build();
 
-            ExprUseVisitor::new(
+            ExprUseVisitor::for_clippy(
+                cx,
+                closure.def_id,
                 &mut delegate,
-                &infcx,
-                closure.body.hir_id.owner.def_id,
-                cx.param_env,
-                cx.typeck_results(),
             )
-            .consume_body(body);
+            .consume_body(body).into_ok();
 
             let mut to_be_discarded = false;
 
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 9e47c3ad0b7..9b852f52ea1 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
@@ -11,7 +11,6 @@ use rustc_hir::{
     PatKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
-use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};
@@ -102,7 +101,6 @@ fn should_skip<'tcx>(
 fn check_closures<'tcx>(
     ctx: &mut MutablyUsedVariablesCtxt<'tcx>,
     cx: &LateContext<'tcx>,
-    infcx: &InferCtxt<'tcx>,
     checked_closures: &mut FxHashSet<LocalDefId>,
     closures: FxHashSet<LocalDefId>,
 ) {
@@ -119,7 +117,7 @@ fn check_closures<'tcx>(
             .associated_body()
             .map(|(_, body_id)| hir.body(body_id))
         {
-            euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);
+            euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx).consume_body(body).into_ok();
         }
     }
 }
@@ -196,8 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                 async_closures: FxHashSet::default(),
                 tcx: cx.tcx,
             };
-            let infcx = cx.tcx.infer_ctxt().build();
-            euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
+            euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok();
 
             let mut checked_closures = FxHashSet::default();
 
@@ -210,13 +207,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                 }
                 ControlFlow::<()>::Continue(())
             });
-            check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
+            check_closures(&mut ctx, cx, &mut checked_closures, closures);
 
             if is_async {
                 while !ctx.async_closures.is_empty() {
                     let async_closures = ctx.async_closures.clone();
                     ctx.async_closures.clear();
-                    check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures);
+                    check_closures(&mut ctx, cx, &mut checked_closures, async_closures);
                 }
             }
             ctx.generate_mutably_used_ids_from_aliases()
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 39d374d0d27..0986571d0f2 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
@@ -13,7 +13,6 @@ use rustc_hir::{
     TyKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
@@ -134,8 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
         // function body.
         let MovedVariablesCtxt { moved_vars } = {
             let mut ctx = MovedVariablesCtxt::default();
-            let infcx = cx.tcx.infer_ctxt().build();
-            euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
+            euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok();
             ctx
         };
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index 435eb9048f5..910e584a7a0 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -11,7 +11,6 @@ use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, Pl
 use rustc_lint::LateContext;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::BorrowKind;
-use rustc_trait_selection::infer::TyCtxtInferExt;
 
 use super::ASSIGN_OP_PATTERN;
 
@@ -119,15 +118,8 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {
     }
 
     let mut s = S(HirIdSet::default());
-    let infcx = cx.tcx.infer_ctxt().build();
-    let mut v = ExprUseVisitor::new(
-        &mut s,
-        &infcx,
-        cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
-        cx.param_env,
-        cx.typeck_results(),
-    );
-    v.consume_expr(e);
+    let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s);
+    v.consume_expr(e).into_ok();
     s.0
 }
 
@@ -151,14 +143,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {
     }
 
     let mut s = S(HirIdSet::default());
-    let infcx = cx.tcx.infer_ctxt().build();
-    let mut v = ExprUseVisitor::new(
-        &mut s,
-        &infcx,
-        cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
-        cx.param_env,
-        cx.typeck_results(),
-    );
-    v.consume_expr(e);
+    let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s);
+    v.consume_expr(e).into_ok();
     s.0
 }
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index 2622abd59cb..5b2841dcd83 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::in_external_macro;
@@ -252,16 +251,13 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
                 local_id: unwrap_info.local_id,
             };
 
-            let infcx = self.cx.tcx.infer_ctxt().build();
-            let mut vis = ExprUseVisitor::new(
-                &mut delegate,
-                &infcx,
+            let vis = ExprUseVisitor::for_clippy(
+                self.cx,
                 cond.hir_id.owner.def_id,
-                self.cx.param_env,
-                self.cx.typeck_results(),
+                &mut delegate,
             );
-            vis.walk_expr(cond);
-            vis.walk_expr(branch);
+            vis.walk_expr(cond).into_ok();
+            vis.walk_expr(branch).into_ok();
 
             if delegate.is_mutated {
                 // if the variable is mutated, we don't know whether it can be unwrapped.
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index a49414a058b..99d7aba2f7a 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -7,6 +7,7 @@
 #![feature(never_type)]
 #![feature(rustc_private)]
 #![feature(assert_matches)]
+#![feature(unwrap_infallible)]
 #![recursion_limit = "512"]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 #![allow(
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 8d6057272c4..bf03c6c1601 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -11,7 +11,6 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{EarlyContext, LateContext, LintContext};
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::{FakeReadCause, Mutability};
@@ -831,8 +830,9 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti
             applicability: Applicability::MachineApplicable,
         };
 
-        let infcx = cx.tcx.infer_ctxt().build();
-        ExprUseVisitor::new(&mut visitor, &infcx, def_id, cx.param_env, cx.typeck_results()).consume_body(closure_body);
+        ExprUseVisitor::for_clippy(cx, def_id, &mut visitor)
+            .consume_body(closure_body)
+            .into_ok();
 
         if !visitor.suggestion_start.is_empty() {
             return Some(DerefClosure {
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index a145920aa85..9abb4ef9b8d 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -5,7 +5,6 @@ use hir::def::Res;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, Expr, ExprKind, HirId, HirIdSet};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceBase, PlaceWithHirId};
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::FakeReadCause;
@@ -17,15 +16,13 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
         used_mutably: HirIdSet::default(),
         skip: false,
     };
-    let infcx = cx.tcx.infer_ctxt().build();
-    ExprUseVisitor::new(
-        &mut delegate,
-        &infcx,
+    ExprUseVisitor::for_clippy(
+        cx,
         expr.hir_id.owner.def_id,
-        cx.param_env,
-        cx.typeck_results(),
+        &mut delegate,
     )
-    .walk_expr(expr);
+    .walk_expr(expr)
+    .into_ok();
 
     if delegate.skip {
         return None;
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 9888ca2d1ed..cc81d23a8ff 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -54,6 +54,15 @@ pub fn static_lib(name: &str) -> PathBuf {
     tmp_dir().join(static_lib_name(name))
 }
 
+pub fn python_command() -> Command {
+    let python_path = std::env::var("PYTHON").expect("PYTHON environment variable does not exist");
+    Command::new(python_path)
+}
+
+pub fn source_path() -> PathBuf {
+    std::env::var("S").expect("S variable does not exist").into()
+}
+
 /// Construct the static library name based on the platform.
 pub fn static_lib_name(name: &str) -> String {
     // See tools.mk (irrelevant lines omitted):
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index de773d688ef..1671a01860a 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -1,5 +1,5 @@
 use std::env;
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
 use std::io::Write;
 use std::path::Path;
 use std::process::{Command, Output, Stdio};
@@ -176,6 +176,13 @@ impl Rustc {
         self
     }
 
+    /// Specify the crate name.
+    pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
+        self.cmd.arg("--crate-name");
+        self.cmd.arg(name.as_ref());
+        self
+    }
+
     /// Get the [`Output`][::std::process::Output] of the finished process.
     #[track_caller]
     pub fn command_output(&mut self) -> ::std::process::Output {
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
index aa3c7dcf0e3..75ca1fc2974 100644
--- a/src/tools/run-make-support/src/rustdoc.rs
+++ b/src/tools/run-make-support/src/rustdoc.rs
@@ -1,4 +1,5 @@
 use std::env;
+use std::ffi::OsStr;
 use std::io::Write;
 use std::path::Path;
 use std::process::{Command, Output, Stdio};
@@ -45,6 +46,21 @@ impl Rustdoc {
         Self { cmd, stdin: None }
     }
 
+    /// Specify where an external library is located.
+    pub fn extern_<P: AsRef<Path>>(&mut self, crate_name: &str, path: P) -> &mut Self {
+        assert!(
+            !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'),
+            "crate name cannot contain whitespace or path separators"
+        );
+
+        let path = path.as_ref().to_string_lossy();
+
+        self.cmd.arg("--extern");
+        self.cmd.arg(format!("{crate_name}={path}"));
+
+        self
+    }
+
     /// Specify path to the input file.
     pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
         self.cmd.arg(path.as_ref());
@@ -107,6 +123,20 @@ impl Rustdoc {
         self
     }
 
+    /// Specify the crate type.
+    pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
+        self.cmd.arg("--crate-type");
+        self.cmd.arg(crate_type);
+        self
+    }
+
+    /// Specify the crate name.
+    pub fn crate_name<S: AsRef<OsStr>>(&mut self, name: S) -> &mut Self {
+        self.cmd.arg("--crate-name");
+        self.cmd.arg(name.as_ref());
+        self
+    }
+
     #[track_caller]
     pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
         let caller_location = std::panic::Location::caller();
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 74592424337..d7423682920 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -248,7 +248,6 @@ run-make/rustdoc-io-error/Makefile
 run-make/rustdoc-scrape-examples-invalid-expr/Makefile
 run-make/rustdoc-scrape-examples-macros/Makefile
 run-make/rustdoc-scrape-examples-multiple/Makefile
-run-make/rustdoc-scrape-examples-ordering/Makefile
 run-make/rustdoc-scrape-examples-remap/Makefile
 run-make/rustdoc-scrape-examples-test/Makefile
 run-make/rustdoc-scrape-examples-whitespace/Makefile
diff --git a/tests/codegen-units/partitioning/extern-drop-glue.rs b/tests/codegen-units/partitioning/extern-drop-glue.rs
index 84eb802f264..d3bce7b4223 100644
--- a/tests/codegen-units/partitioning/extern-drop-glue.rs
+++ b/tests/codegen-units/partitioning/extern-drop-glue.rs
@@ -1,7 +1,4 @@
-//
-
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
diff --git a/tests/codegen-units/partitioning/extern-generic.rs b/tests/codegen-units/partitioning/extern-generic.rs
index abd3918094d..0e4b6a37f71 100644
--- a/tests/codegen-units/partitioning/extern-generic.rs
+++ b/tests/codegen-units/partitioning/extern-generic.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y
 
diff --git a/tests/codegen-units/partitioning/incremental-merging.rs b/tests/codegen-units/partitioning/incremental-merging.rs
index b44090c866a..6834bb2bebf 100644
--- a/tests/codegen-units/partitioning/incremental-merging.rs
+++ b/tests/codegen-units/partitioning/incremental-merging.rs
@@ -1,5 +1,4 @@
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Ccodegen-units=3
diff --git a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs
index 74734d3cf38..d021f467f1f 100644
--- a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs
+++ b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Zinline-in-all-cgus
diff --git a/tests/codegen-units/partitioning/local-drop-glue.rs b/tests/codegen-units/partitioning/local-drop-glue.rs
index 0974187ade0..5fa1df95cbc 100644
--- a/tests/codegen-units/partitioning/local-drop-glue.rs
+++ b/tests/codegen-units/partitioning/local-drop-glue.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
diff --git a/tests/codegen-units/partitioning/local-generic.rs b/tests/codegen-units/partitioning/local-generic.rs
index 2cfdc27ccb1..06f46b23db6 100644
--- a/tests/codegen-units/partitioning/local-generic.rs
+++ b/tests/codegen-units/partitioning/local-generic.rs
@@ -1,5 +1,4 @@
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=eager
 
diff --git a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs
index 49a2ce7c5d9..2f9cbe83f1d 100644
--- a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs
+++ b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Zinline-in-all-cgus=no
diff --git a/tests/codegen-units/partitioning/local-inlining.rs b/tests/codegen-units/partitioning/local-inlining.rs
index 726cf2b87d2..2329a876c96 100644
--- a/tests/codegen-units/partitioning/local-inlining.rs
+++ b/tests/codegen-units/partitioning/local-inlining.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Zinline-in-all-cgus
diff --git a/tests/codegen-units/partitioning/local-transitive-inlining.rs b/tests/codegen-units/partitioning/local-transitive-inlining.rs
index 355eb6cf395..4ccc53aea1d 100644
--- a/tests/codegen-units/partitioning/local-transitive-inlining.rs
+++ b/tests/codegen-units/partitioning/local-transitive-inlining.rs
@@ -1,6 +1,4 @@
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Zinline-in-all-cgus
diff --git a/tests/codegen-units/partitioning/methods-are-with-self-type.rs b/tests/codegen-units/partitioning/methods-are-with-self-type.rs
index 2e54725ff28..3ba53334cc9 100644
--- a/tests/codegen-units/partitioning/methods-are-with-self-type.rs
+++ b/tests/codegen-units/partitioning/methods-are-with-self-type.rs
@@ -3,9 +3,7 @@
 // much sense at the moment.
 //@ ignore-test
 
-//
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 
diff --git a/tests/codegen-units/partitioning/regular-modules.rs b/tests/codegen-units/partitioning/regular-modules.rs
index 0eb0848e454..68601975d06 100644
--- a/tests/codegen-units/partitioning/regular-modules.rs
+++ b/tests/codegen-units/partitioning/regular-modules.rs
@@ -1,5 +1,4 @@
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=eager
 
diff --git a/tests/codegen-units/partitioning/shared-generics.rs b/tests/codegen-units/partitioning/shared-generics.rs
index 25ea7fab735..5b78794316c 100644
--- a/tests/codegen-units/partitioning/shared-generics.rs
+++ b/tests/codegen-units/partitioning/shared-generics.rs
@@ -1,4 +1,3 @@
-//
 //@ no-prefer-dynamic
 // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
 //       prevent drop-glue from participating in share-generics.
diff --git a/tests/codegen-units/partitioning/statics.rs b/tests/codegen-units/partitioning/statics.rs
index 9503a91b0ab..c7eef1f3789 100644
--- a/tests/codegen-units/partitioning/statics.rs
+++ b/tests/codegen-units/partitioning/statics.rs
@@ -1,5 +1,4 @@
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 
diff --git a/tests/codegen-units/partitioning/vtable-through-const.rs b/tests/codegen-units/partitioning/vtable-through-const.rs
index 111b4fa1b9a..ca4d3822b54 100644
--- a/tests/codegen-units/partitioning/vtable-through-const.rs
+++ b/tests/codegen-units/partitioning/vtable-through-const.rs
@@ -1,7 +1,4 @@
-//
-
-// We specify incremental here because we want to test the partitioning for
-//@ incremental compilation
+// We specify incremental here because we want to test the partitioning for incremental compilation
 //@ incremental
 //@ compile-flags:-Zprint-mono-items=lazy
 //@ compile-flags:-Zinline-in-all-cgus
diff --git a/tests/crashes/123901.rs b/tests/crashes/123901.rs
deleted file mode 100644
index 06722f0bf29..00000000000
--- a/tests/crashes/123901.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #123901
-//@ edition:2021
-
-pub fn test(test: &u64, temp: &u64) {
-    async |check, a, b| {
-        temp.abs_diff(12);
-    };
-}
diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile b/tests/run-make/rustdoc-scrape-examples-ordering/Makefile
deleted file mode 100644
index bf45b8148c0..00000000000
--- a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-deps := ex1 ex2
-
-include ../rustdoc-scrape-examples-multiple/scrape.mk
-
-all: scrape
diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs
new file mode 100644
index 00000000000..edcf3406d47
--- /dev/null
+++ b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs
@@ -0,0 +1,55 @@
+use run_make_support::{python_command, rustc, rustdoc, source_path, tmp_dir};
+use std::fs::read_dir;
+use std::path::Path;
+
+fn main() {
+    let lib_dir = tmp_dir();
+    let out_dir = tmp_dir().join("rustdoc");
+    let crate_name = "foobar";
+    let deps = read_dir("examples")
+        .unwrap()
+        .filter_map(|entry| entry.ok().map(|e| e.path()))
+        .filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs"))
+        .collect::<Vec<_>>();
+
+    rustc().input("src/lib.rs").crate_name(crate_name).crate_type("lib").emit("metadata").run();
+
+    let mut out_deps = Vec::with_capacity(deps.len());
+    for dep in deps {
+        let dep_stem = dep.file_stem().unwrap();
+        let out_example = out_dir.join(format!("{}.calls", dep_stem.to_str().unwrap()));
+        rustdoc()
+            .input(&dep)
+            .crate_name(&dep_stem)
+            .crate_type("bin")
+            .output(&out_dir)
+            .extern_(crate_name, lib_dir.join(format!("lib{crate_name}.rmeta")))
+            .arg("-Zunstable-options")
+            .arg("--scrape-examples-output-path")
+            .arg(&out_example)
+            .arg("--scrape-examples-target-crate")
+            .arg(crate_name)
+            .run();
+        out_deps.push(out_example);
+    }
+
+    let mut rustdoc = rustdoc();
+    rustdoc
+        .input("src/lib.rs")
+        .output(&out_dir)
+        .crate_name(crate_name)
+        .crate_type("lib")
+        .arg("-Zunstable-options");
+    for dep in out_deps {
+        rustdoc.arg("--with-examples").arg(dep);
+    }
+    rustdoc.run();
+
+    python_command()
+        .arg(source_path().join("/src/etc/htmldocck.py"))
+        .arg(out_dir)
+        .arg("src/lib.rs")
+        .status()
+        .unwrap()
+        .success();
+}
diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.rs b/tests/ui/async-await/async-closures/ambiguous-arg.rs
new file mode 100644
index 00000000000..d76a1cf953e
--- /dev/null
+++ b/tests/ui/async-await/async-closures/ambiguous-arg.rs
@@ -0,0 +1,15 @@
+//@ edition:2021
+
+// Regression test for #123901. We previously ICE'd as we silently
+// swallowed an in the `ExprUseVisitor`.
+
+#![feature(async_closure)]
+
+pub fn test(test: &u64, temp: &u64) {
+    async |check, a, b| {
+        //~^ ERROR type annotations needed
+        temp.abs_diff(12);
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.stderr b/tests/ui/async-await/async-closures/ambiguous-arg.stderr
new file mode 100644
index 00000000000..01f72e94ecc
--- /dev/null
+++ b/tests/ui/async-await/async-closures/ambiguous-arg.stderr
@@ -0,0 +1,13 @@
+error[E0282]: type annotations needed
+  --> $DIR/ambiguous-arg.rs:9:25
+   |
+LL |       async |check, a, b| {
+   |  _________________________^
+LL | |
+LL | |         temp.abs_diff(12);
+LL | |     };
+   | |_____^ cannot infer type
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/lint/lint-unnecessary-parens.fixed b/tests/ui/lint/lint-unnecessary-parens.fixed
index 973bbd70f25..760897c5143 100644
--- a/tests/ui/lint/lint-unnecessary-parens.fixed
+++ b/tests/ui/lint/lint-unnecessary-parens.fixed
@@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 {
 macro_rules! baz {
     ($($foo:expr),+) => {
         ($($foo),*)
+    };
+}
+
+macro_rules! unit {
+    () => {
+        ()
+    };
+}
+
+struct One;
+
+impl std::ops::Sub<One> for () {
+    type Output = i32;
+    fn sub(self, _: One) -> Self::Output {
+        -1
+    }
+}
+
+impl std::ops::Neg for One {
+    type Output = i32;
+    fn neg(self) -> Self::Output {
+        -1
     }
 }
 
@@ -94,4 +116,13 @@ fn main() {
 
     let _a = baz!(3, 4);
     let _b = baz!(3);
+
+    let _ = {
+        unit!() - One //~ ERROR unnecessary parentheses around block return value
+    } + {
+        unit![] - One //~ ERROR unnecessary parentheses around block return value
+    } + {
+        // FIXME: false positive. This parenthesis is required.
+        unit! {} - One //~ ERROR unnecessary parentheses around block return value
+    };
 }
diff --git a/tests/ui/lint/lint-unnecessary-parens.rs b/tests/ui/lint/lint-unnecessary-parens.rs
index 40cd61fcc2c..7cbaac8ae54 100644
--- a/tests/ui/lint/lint-unnecessary-parens.rs
+++ b/tests/ui/lint/lint-unnecessary-parens.rs
@@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 {
 macro_rules! baz {
     ($($foo:expr),+) => {
         ($($foo),*)
+    };
+}
+
+macro_rules! unit {
+    () => {
+        ()
+    };
+}
+
+struct One;
+
+impl std::ops::Sub<One> for () {
+    type Output = i32;
+    fn sub(self, _: One) -> Self::Output {
+        -1
+    }
+}
+
+impl std::ops::Neg for One {
+    type Output = i32;
+    fn neg(self) -> Self::Output {
+        -1
     }
 }
 
@@ -94,4 +116,13 @@ fn main() {
 
     let _a = baz!(3, 4);
     let _b = baz!(3);
+
+    let _ = {
+        (unit!() - One) //~ ERROR unnecessary parentheses around block return value
+    } + {
+        (unit![] - One) //~ ERROR unnecessary parentheses around block return value
+    } + {
+        // FIXME: false positive. This parenthesis is required.
+        (unit! {} - One) //~ ERROR unnecessary parentheses around block return value
+    };
 }
diff --git a/tests/ui/lint/lint-unnecessary-parens.stderr b/tests/ui/lint/lint-unnecessary-parens.stderr
index ba7a78b8da1..755dd5fc309 100644
--- a/tests/ui/lint/lint-unnecessary-parens.stderr
+++ b/tests/ui/lint/lint-unnecessary-parens.stderr
@@ -124,7 +124,7 @@ LL +     return 1;
    |
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:52:31
+  --> $DIR/lint-unnecessary-parens.rs:74:31
    |
 LL | pub const CONST_ITEM: usize = (10);
    |                               ^  ^
@@ -136,7 +136,7 @@ LL + pub const CONST_ITEM: usize = 10;
    |
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:53:33
+  --> $DIR/lint-unnecessary-parens.rs:75:33
    |
 LL | pub static STATIC_ITEM: usize = (10);
    |                                 ^  ^
@@ -148,7 +148,7 @@ LL + pub static STATIC_ITEM: usize = 10;
    |
 
 error: unnecessary parentheses around function argument
-  --> $DIR/lint-unnecessary-parens.rs:57:9
+  --> $DIR/lint-unnecessary-parens.rs:79:9
    |
 LL |     bar((true));
    |         ^    ^
@@ -160,7 +160,7 @@ LL +     bar(true);
    |
 
 error: unnecessary parentheses around `if` condition
-  --> $DIR/lint-unnecessary-parens.rs:59:8
+  --> $DIR/lint-unnecessary-parens.rs:81:8
    |
 LL |     if (true) {}
    |        ^    ^
@@ -172,7 +172,7 @@ LL +     if true {}
    |
 
 error: unnecessary parentheses around `while` condition
-  --> $DIR/lint-unnecessary-parens.rs:60:11
+  --> $DIR/lint-unnecessary-parens.rs:82:11
    |
 LL |     while (true) {}
    |           ^    ^
@@ -184,7 +184,7 @@ LL +     while true {}
    |
 
 error: unnecessary parentheses around `match` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:61:11
+  --> $DIR/lint-unnecessary-parens.rs:83:11
    |
 LL |     match (true) {
    |           ^    ^
@@ -196,7 +196,7 @@ LL +     match true {
    |
 
 error: unnecessary parentheses around `let` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:64:16
+  --> $DIR/lint-unnecessary-parens.rs:86:16
    |
 LL |     if let 1 = (1) {}
    |                ^ ^
@@ -208,7 +208,7 @@ LL +     if let 1 = 1 {}
    |
 
 error: unnecessary parentheses around `let` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:65:19
+  --> $DIR/lint-unnecessary-parens.rs:87:19
    |
 LL |     while let 1 = (2) {}
    |                   ^ ^
@@ -220,7 +220,7 @@ LL +     while let 1 = 2 {}
    |
 
 error: unnecessary parentheses around method argument
-  --> $DIR/lint-unnecessary-parens.rs:81:24
+  --> $DIR/lint-unnecessary-parens.rs:103:24
    |
 LL |     X { y: false }.foo((true));
    |                        ^    ^
@@ -232,7 +232,7 @@ LL +     X { y: false }.foo(true);
    |
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:83:18
+  --> $DIR/lint-unnecessary-parens.rs:105:18
    |
 LL |     let mut _a = (0);
    |                  ^ ^
@@ -244,7 +244,7 @@ LL +     let mut _a = 0;
    |
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:84:10
+  --> $DIR/lint-unnecessary-parens.rs:106:10
    |
 LL |     _a = (0);
    |          ^ ^
@@ -256,7 +256,7 @@ LL +     _a = 0;
    |
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:85:11
+  --> $DIR/lint-unnecessary-parens.rs:107:11
    |
 LL |     _a += (1);
    |           ^ ^
@@ -268,7 +268,7 @@ LL +     _a += 1;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:87:8
+  --> $DIR/lint-unnecessary-parens.rs:109:8
    |
 LL |     let(mut _a) = 3;
    |        ^      ^
@@ -280,7 +280,7 @@ LL +     let mut _a = 3;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:88:9
+  --> $DIR/lint-unnecessary-parens.rs:110:9
    |
 LL |     let (mut _a) = 3;
    |         ^      ^
@@ -292,7 +292,7 @@ LL +     let mut _a = 3;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:89:8
+  --> $DIR/lint-unnecessary-parens.rs:111:8
    |
 LL |     let( mut _a) = 3;
    |        ^^      ^
@@ -304,7 +304,7 @@ LL +     let mut _a = 3;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:91:8
+  --> $DIR/lint-unnecessary-parens.rs:113:8
    |
 LL |     let(_a) = 3;
    |        ^  ^
@@ -316,7 +316,7 @@ LL +     let _a = 3;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:92:9
+  --> $DIR/lint-unnecessary-parens.rs:114:9
    |
 LL |     let (_a) = 3;
    |         ^  ^
@@ -328,7 +328,7 @@ LL +     let _a = 3;
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/lint-unnecessary-parens.rs:93:8
+  --> $DIR/lint-unnecessary-parens.rs:115:8
    |
 LL |     let( _a) = 3;
    |        ^^  ^
@@ -339,5 +339,41 @@ LL -     let( _a) = 3;
 LL +     let _a = 3;
    |
 
-error: aborting due to 28 previous errors
+error: unnecessary parentheses around block return value
+  --> $DIR/lint-unnecessary-parens.rs:121:9
+   |
+LL |         (unit!() - One)
+   |         ^             ^
+   |
+help: remove these parentheses
+   |
+LL -         (unit!() - One)
+LL +         unit!() - One
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/lint-unnecessary-parens.rs:123:9
+   |
+LL |         (unit![] - One)
+   |         ^             ^
+   |
+help: remove these parentheses
+   |
+LL -         (unit![] - One)
+LL +         unit![] - One
+   |
+
+error: unnecessary parentheses around block return value
+  --> $DIR/lint-unnecessary-parens.rs:126:9
+   |
+LL |         (unit! {} - One)
+   |         ^              ^
+   |
+help: remove these parentheses
+   |
+LL -         (unit! {} - One)
+LL +         unit! {} - One
+   |
+
+error: aborting due to 31 previous errors
 
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index 492bd2450b1..6b215ba525d 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -213,6 +213,21 @@ fn test_expr() {
         "match () { _ => ({ 1 }) - 1, }",
         "match () { _ => { 1 } - 1 }",
     );
+    c2_match_arm!(
+        [ m!() - 1 ],
+        "match () { _ => m!() - 1, }",
+        "match () { _ => m!() - 1 }",
+    );
+    c2_match_arm!(
+        [ m![] - 1 ],
+        "match () { _ => m![] - 1, }",
+        "match () { _ => m![] - 1 }",
+    );
+    c2_match_arm!(
+        [ m! {} - 1 ],
+        "match () { _ => m! {} - 1, }",
+        "match () { _ => m! {} - 1 }",
+    );
 
     // ExprKind::Closure
     c1!(expr, [ || {} ], "|| {}");
@@ -660,6 +675,11 @@ fn test_stmt() {
         "let (a, b): (u32, u32) = (1, 2);",
         "let (a, b): (u32, u32) = (1, 2)"
     );
+    c2!(stmt,
+        [ let _ = f() else { return; } ],
+        "let _ = f() else { return; };",
+        "let _ = f() else { return; }",
+    );
     macro_rules! c2_let_expr_minus_one {
         ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => {
             c2!(stmt, [ let _ = $expr - 1 ], $stmt_expected, $tokens_expected);
@@ -670,6 +690,16 @@ fn test_stmt() {
         "let _ = match void {} - 1;",
         "let _ = match void {} - 1",
     );
+    macro_rules! c2_let_expr_else_return {
+        ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => {
+            c2!(stmt, [ let _ = $expr else { return; } ], $stmt_expected, $tokens_expected);
+        };
+    }
+    c2_let_expr_else_return!(
+        [ f() ],
+        "let _ = f() else { return; };",
+        "let _ = f() else { return; }",
+    );
 
     // StmtKind::Item
     c1!(stmt, [ struct S; ], "struct S;");
@@ -720,6 +750,21 @@ fn test_stmt() {
         "(loop { break 1; }) - 1;",
         "loop { break 1; } - 1",
     );
+    c2_minus_one!(
+        [ m!() ],
+        "m!() - 1;",
+        "m!() - 1"
+    );
+    c2_minus_one!(
+        [ m![] ],
+        "m![] - 1;",
+        "m![] - 1"
+    );
+    c2_minus_one!(
+        [ m! {} ],
+        "(m! {}) - 1;",
+        "m! {} - 1"
+    );
 
     // StmtKind::Empty
     c1!(stmt, [ ; ], ";");
diff --git a/tests/ui/parser/else-no-if.rs b/tests/ui/parser/else-no-if.rs
index f0b40ecde66..ad5262cd2cc 100644
--- a/tests/ui/parser/else-no-if.rs
+++ b/tests/ui/parser/else-no-if.rs
@@ -1,3 +1,7 @@
+macro_rules! falsy {
+    () => { false };
+}
+
 fn foo() {
     if true {
     } else false {
@@ -25,6 +29,32 @@ fn foo4() {
     {}
 }
 
+fn foo5() {
+    if true {
+    } else falsy!() {
+    //~^ ERROR expected `{`, found `falsy`
+    }
+}
+
+fn foo6() {
+    if true {
+    } else falsy!();
+    //~^ ERROR expected `{`, found `falsy`
+}
+
+fn foo7() {
+    if true {
+    } else falsy! {} {
+    //~^ ERROR expected `{`, found `falsy`
+    }
+}
+
+fn foo8() {
+    if true {
+    } else falsy! {};
+    //~^ ERROR expected `{`, found `falsy`
+}
+
 fn falsy() -> bool {
     false
 }
diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr
index b9c1a75276c..2e3e8f6b50e 100644
--- a/tests/ui/parser/else-no-if.stderr
+++ b/tests/ui/parser/else-no-if.stderr
@@ -1,5 +1,5 @@
 error: expected `{`, found keyword `false`
-  --> $DIR/else-no-if.rs:3:12
+  --> $DIR/else-no-if.rs:7:12
    |
 LL |     } else false {
    |       ---- ^^^^^
@@ -12,7 +12,7 @@ LL |     } else if false {
    |            ++
 
 error: expected `{`, found `falsy`
-  --> $DIR/else-no-if.rs:10:12
+  --> $DIR/else-no-if.rs:14:12
    |
 LL |     } else falsy() {
    |       ---- ^^^^^
@@ -25,7 +25,7 @@ LL |     } else if falsy() {
    |            ++
 
 error: expected `{`, found `falsy`
-  --> $DIR/else-no-if.rs:17:12
+  --> $DIR/else-no-if.rs:21:12
    |
 LL |     } else falsy();
    |            ^^^^^ expected `{`
@@ -36,7 +36,7 @@ LL |     } else { falsy() };
    |            +         +
 
 error: expected `{`, found keyword `loop`
-  --> $DIR/else-no-if.rs:23:12
+  --> $DIR/else-no-if.rs:27:12
    |
 LL |     } else loop{}
    |            ^^^^ expected `{`
@@ -46,5 +46,51 @@ help: try placing this code inside a block
 LL |     } else { loop{} }
    |            +        +
 
-error: aborting due to 4 previous errors
+error: expected `{`, found `falsy`
+  --> $DIR/else-no-if.rs:34:12
+   |
+LL |     } else falsy!() {
+   |       ---- ^^^^^
+   |       |
+   |       expected an `if` or a block after this `else`
+   |
+help: add an `if` if this is the condition of a chained `else if` statement
+   |
+LL |     } else if falsy!() {
+   |            ++
+
+error: expected `{`, found `falsy`
+  --> $DIR/else-no-if.rs:41:12
+   |
+LL |     } else falsy!();
+   |            ^^^^^ expected `{`
+   |
+help: try placing this code inside a block
+   |
+LL |     } else { falsy!() };
+   |            +          +
+
+error: expected `{`, found `falsy`
+  --> $DIR/else-no-if.rs:47:12
+   |
+LL |     } else falsy! {} {
+   |            ^^^^^ expected `{`
+   |
+help: try placing this code inside a block
+   |
+LL |     } else { falsy! {} } {
+   |            +           +
+
+error: expected `{`, found `falsy`
+  --> $DIR/else-no-if.rs:54:12
+   |
+LL |     } else falsy! {};
+   |            ^^^^^ expected `{`
+   |
+help: try placing this code inside a block
+   |
+LL |     } else { falsy! {} };
+   |            +           +
+
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/parser/macro/statement-boundaries.rs b/tests/ui/parser/macro/statement-boundaries.rs
new file mode 100644
index 00000000000..67a6aa30f0c
--- /dev/null
+++ b/tests/ui/parser/macro/statement-boundaries.rs
@@ -0,0 +1,104 @@
+//@ run-pass
+//@ edition:2021
+
+// This is a test of several uses of rustc_ast::util::classify::expr_requires_semi_to_be_stmt
+// by the Rust parser, which relates to the insertion of statement boundaries
+// after certain kinds of expressions if they appear at the head of a statement.
+
+#![allow(unused_braces, unused_unsafe)]
+
+macro_rules! unit {
+    () => {
+        { () }
+    };
+}
+
+#[derive(Copy, Clone)]
+struct X;
+
+fn main() {
+    let x = X;
+
+    // There is a statement boundary before `|x| x`, so it's a closure.
+    let _: fn(X) -> X = { if true {} |x| x };
+    let _: fn(X) -> X = { if true {} else {} |x| x };
+    let _: fn(X) -> X = { match () { () => {} } |x| x };
+    let _: fn(X) -> X = { { () } |x| x };
+    let _: fn(X) -> X = { unsafe {} |x| x };
+    let _: fn(X) -> X = { while false {} |x| x };
+    let _: fn(X) -> X = { loop { break; } |x| x };
+    let _: fn(X) -> X = { for _ in 0..0 {} |x| x };
+    let _: fn(X) -> X = { const {} |x| x };
+    let _: fn(X) -> X = { unit! {} |x| x };
+
+    // No statement boundary, so `|x| x` is 2× BitOr operation.
+    () = { "" |x| x };
+    () = { ("") |x| x };
+    () = { [""] |x| x };
+    () = { unit!() |x| x };
+    () = { unit![] |x| x };
+
+    // All the same cases, but as a match arm.
+    () = match x {
+        // Statement boundary before `| X`, which becomes a new arm with leading vert.
+        X if false => if true {} | X if false => {}
+        X if false => if true {} else {} | X if false => {}
+        X if false => match () { () => {} } | X if false => {}
+        X if false => { () } | X if false => {}
+        X if false => unsafe {} | X if false => {}
+        X if false => while false {} | X if false => {}
+        X if false => loop { break; } | X if false => {}
+        X if false => for _ in 0..0 {} | X if false => {}
+        X if false => const {} | X if false => {}
+
+        // No statement boundary, so `| X` is BitOr.
+        X if false => "" | X,
+        X if false => ("") | X,
+        X if false => [""] | X,
+        X if false => unit! {} | X, // !! inconsistent with braced mac call in statement position
+        X if false => unit!() | X,
+        X if false => unit![] | X,
+
+        X => {}
+    };
+
+    // Test how the statement boundary logic interacts with macro metavariables /
+    // "invisible delimiters".
+    macro_rules! assert_statement_boundary {
+        ($expr:expr) => {
+            let _: fn(X) -> X = { $expr |x| x };
+
+            () = match X {
+                X if false => $expr | X if false => {}
+                X => {}
+            };
+        };
+    }
+    macro_rules! assert_no_statement_boundary {
+        ($expr:expr) => {
+            () = { $expr |x| x };
+
+            () = match x {
+                X if false => $expr | X,
+                X => {}
+            };
+        };
+    }
+    assert_statement_boundary!(if true {});
+    assert_no_statement_boundary!("");
+}
+
+impl std::ops::BitOr<X> for () {
+    type Output = ();
+    fn bitor(self, _: X) {}
+}
+
+impl std::ops::BitOr<X> for &str {
+    type Output = ();
+    fn bitor(self, _: X) {}
+}
+
+impl<T, const N: usize> std::ops::BitOr<X> for [T; N] {
+    type Output = ();
+    fn bitor(self, _: X) {}
+}
diff --git a/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs
new file mode 100644
index 00000000000..0b70e4404ab
--- /dev/null
+++ b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs
@@ -0,0 +1,12 @@
+//@ edition: 2024
+//@ compile-flags: -Z unstable-options
+
+// This contains a binding in edition 2024, so if matched with a reference binding mode it will end
+// up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with
+// mixed editions.
+#[macro_export]
+macro_rules! mixed_edition_pat {
+    ($foo:ident) => {
+        Some(mut $foo)
+    };
+}
diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/match_ergonomics_2024.fixed
new file mode 100644
index 00000000000..d8dbcb217c0
--- /dev/null
+++ b/tests/ui/pattern/match_ergonomics_2024.fixed
@@ -0,0 +1,57 @@
+//@ edition: 2021
+//@ run-rustfix
+//@ rustfix-only-machine-applicable
+//@ aux-build:match_ergonomics_2024_macros.rs
+#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
+#![allow(incomplete_features, unused)]
+#![deny(rust_2024_incompatible_pat)]
+
+extern crate match_ergonomics_2024_macros;
+
+struct Foo(u8);
+
+fn main() {
+    let &Foo(mut a) = &Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    a = 42;
+
+    let &mut Foo(mut a) = &mut Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    a = 42;
+
+    if let &&&&&Some(&_) = &&&&&Some(&0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    struct Struct {
+        a: u32,
+        b: u32,
+        c: u32,
+    }
+    let s = Struct { a: 0, b: 0, c: 0 };
+    let &Struct { ref a, mut b, ref c } = &s;
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    #[warn(rust_2024_incompatible_pat)]
+    match &(Some(0), Some(0)) {
+        // The two patterns are the same syntactically, but because they're defined in different
+        // editions they don't mean the same thing.
+        (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
+            //~^ WARN: the semantics of this pattern will change in edition 2024
+            _x = 4;
+            _y = &7;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/match_ergonomics_2024.rs
new file mode 100644
index 00000000000..38dc0c8bebb
--- /dev/null
+++ b/tests/ui/pattern/match_ergonomics_2024.rs
@@ -0,0 +1,57 @@
+//@ edition: 2021
+//@ run-rustfix
+//@ rustfix-only-machine-applicable
+//@ aux-build:match_ergonomics_2024_macros.rs
+#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
+#![allow(incomplete_features, unused)]
+#![deny(rust_2024_incompatible_pat)]
+
+extern crate match_ergonomics_2024_macros;
+
+struct Foo(u8);
+
+fn main() {
+    let Foo(mut a) = &Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    a = 42;
+
+    let Foo(mut a) = &mut Foo(0);
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+    a = 42;
+
+    if let Some(&_) = &&&&&Some(&0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let Some(&_) = &&&&&mut Some(&0u8) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    struct Struct {
+        a: u32,
+        b: u32,
+        c: u32,
+    }
+    let s = Struct { a: 0, b: 0, c: 0 };
+    let Struct { a, mut b, c } = &s;
+    //~^ ERROR: the semantics of this pattern will change in edition 2024
+
+    #[warn(rust_2024_incompatible_pat)]
+    match &(Some(0), Some(0)) {
+        // The two patterns are the same syntactically, but because they're defined in different
+        // editions they don't mean the same thing.
+        (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
+            //~^ WARN: the semantics of this pattern will change in edition 2024
+            _x = 4;
+            _y = &7;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/pattern/match_ergonomics_2024.stderr b/tests/ui/pattern/match_ergonomics_2024.stderr
new file mode 100644
index 00000000000..11844434ad2
--- /dev/null
+++ b/tests/ui/pattern/match_ergonomics_2024.stderr
@@ -0,0 +1,97 @@
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:14:9
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |         -^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&`
+   |
+note: the lint level is defined here
+  --> $DIR/match_ergonomics_2024.rs:7:9
+   |
+LL | #![deny(rust_2024_incompatible_pat)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:18:9
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |         -^^^^^^^^^
+   |         |
+   |         help: desugar the match ergonomics: `&mut`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:22:12
+   |
+LL |     if let Some(&_) = &&&&&Some(&0u8) {}
+   |            -^^^^^^^
+   |            |
+   |            help: desugar the match ergonomics: `&&&&&`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:25:12
+   |
+LL |     if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
+   |            -^^^^^^^^^^^
+   |            |
+   |            help: desugar the match ergonomics: `&&&&&`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:28:12
+   |
+LL |     if let Some(&_) = &&&&&mut Some(&0u8) {}
+   |            -^^^^^^^
+   |            |
+   |            help: desugar the match ergonomics: `&&&&&mut`
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:31:12
+   |
+LL |     if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: desugar the match ergonomics
+   |
+LL |     if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+   |            ++++                ++++
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:34:12
+   |
+LL |     if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: desugar the match ergonomics
+   |
+LL |     if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
+   |            ++++                ++++      +++++++
+
+error: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:43:9
+   |
+LL |     let Struct { a, mut b, c } = &s;
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: desugar the match ergonomics
+   |
+LL |     let &Struct { ref a, mut b, ref c } = &s;
+   |         +         +++           +++
+
+warning: the semantics of this pattern will change in edition 2024
+  --> $DIR/match_ergonomics_2024.rs:50:9
+   |
+LL |         (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/match_ergonomics_2024.rs:46:12
+   |
+LL |     #[warn(rust_2024_incompatible_pat)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: desugar the match ergonomics
+   |
+LL |         &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
+   |         +                                                                +++
+
+error: aborting due to 8 previous errors; 1 warning emitted
+
diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs
deleted file mode 100644
index 249f251d2cd..00000000000
--- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ edition: 2021
-#![feature(mut_preserve_binding_mode_2024)]
-#![allow(incomplete_features, unused)]
-#![forbid(dereferencing_mut_binding)]
-
-struct Foo(u8);
-
-fn main() {
-    let Foo(mut a) = &Foo(0);
-    //~^ ERROR: dereferencing `mut` binding
-    a = 42;
-
-    let Foo(mut a) = &mut Foo(0);
-    //~^ ERROR: dereferencing `mut` binding
-    a = 42;
-}
diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr
deleted file mode 100644
index e8d11acd83e..00000000000
--- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error: dereferencing `mut` binding
-  --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ^^^^^ `mut` dereferences the type of this binding
-   |
-help: this will change in edition 2024
-  --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ^^^^^
-note: the lint level is defined here
-  --> $DIR/mut_preserve_binding_mode_2024_lint.rs:4:11
-   |
-LL | #![forbid(dereferencing_mut_binding)]
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: dereferencing `mut` binding
-  --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ^^^^^ `mut` dereferences the type of this binding
-   |
-help: this will change in edition 2024
-  --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs
new file mode 100644
index 00000000000..6567f275240
--- /dev/null
+++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs
@@ -0,0 +1,19 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Fixes a regression in icu_provider_adaptors where we weren't normalizing the
+// return type of a function type before performing a `Ty::builtin_deref` call,
+// leading to an ICE.
+
+struct Struct {
+    field: i32,
+}
+
+fn hello(f: impl Fn() -> &'static Box<[i32]>, f2: impl Fn() -> &'static Struct) {
+    let cl = || {
+        let x = &f()[0];
+        let y = &f2().field;
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/unpretty/pretty-let-else.rs b/tests/ui/unpretty/let-else-hir.rs
index 9c231189659..9c231189659 100644
--- a/tests/ui/unpretty/pretty-let-else.rs
+++ b/tests/ui/unpretty/let-else-hir.rs
diff --git a/tests/ui/unpretty/pretty-let-else.stdout b/tests/ui/unpretty/let-else-hir.stdout
index ed55f293876..ed55f293876 100644
--- a/tests/ui/unpretty/pretty-let-else.stdout
+++ b/tests/ui/unpretty/let-else-hir.stdout
diff --git a/tests/ui/unpretty/let-else.rs b/tests/ui/unpretty/let-else.rs
new file mode 100644
index 00000000000..4db6eca99b1
--- /dev/null
+++ b/tests/ui/unpretty/let-else.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: -Zunpretty=expanded
+//@ check-pass
+
+macro_rules! expr {
+    ($e:expr) => { $e };
+}
+
+fn main() {
+    let _ = expr!(1 + 1) else { return; };
+    let _ = expr!(loop {}) else { return; };
+}
diff --git a/tests/ui/unpretty/let-else.stdout b/tests/ui/unpretty/let-else.stdout
new file mode 100644
index 00000000000..4bc4d9e085f
--- /dev/null
+++ b/tests/ui/unpretty/let-else.stdout
@@ -0,0 +1,15 @@
+#![feature(prelude_import)]
+#![no_std]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ compile-flags: -Zunpretty=expanded
+//@ check-pass
+
+macro_rules! expr { ($e:expr) => { $e }; }
+
+fn main() {
+    let _ = 1 + 1 else { return; };
+    let _ = (loop {}) else { return; };
+}
diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs
index f194e25b556..1dafb9a784b 100644
--- a/tests/ui/write-fmt-errors.rs
+++ b/tests/ui/write-fmt-errors.rs
@@ -1,9 +1,11 @@
 //@ run-pass
+//@ needs-unwind
 
 #![feature(io_error_uncategorized)]
 
 use std::fmt;
 use std::io::{self, Error, Write, sink};
+use std::panic::catch_unwind;
 
 struct ErrorDisplay;
 
@@ -15,7 +17,6 @@ impl fmt::Display for ErrorDisplay {
 
 struct ErrorWriter;
 
-const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Uncategorized;
 const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected;
 
 impl Write for ErrorWriter {
@@ -27,22 +28,28 @@ impl Write for ErrorWriter {
 }
 
 fn main() {
-    // Test that the error from the formatter is propagated.
-    let res = write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar");
-    assert!(res.is_err(), "formatter error did not propagate");
-    assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR);
-
     // Test that an underlying error is propagated
     let res = write!(ErrorWriter, "abc");
     assert!(res.is_err(), "writer error did not propagate");
 
-    // Writer error
+    // Test that the error from the formatter is detected.
+    let res = catch_unwind(|| write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar"));
+    let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap();
+    assert!(
+        err.contains("formatting trait implementation returned an error"),
+        "unexpected panic: {}", err
+    );
+
+    // Writer error when there's some string before the first `{}`
     let res = write!(ErrorWriter, "abc {}", ErrorDisplay);
     assert!(res.is_err(), "writer error did not propagate");
     assert_eq!(res.unwrap_err().kind(), WRITER_ERROR);
 
-    // Formatter error
-    let res = write!(ErrorWriter, "{} abc", ErrorDisplay);
-    assert!(res.is_err(), "formatter error did not propagate");
-    assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR);
+    // Formatter error when the `{}` comes first
+    let res = catch_unwind(|| write!(ErrorWriter, "{} abc", ErrorDisplay));
+    let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap();
+    assert!(
+        err.contains("formatting trait implementation returned an error"),
+        "unexpected panic: {}", err
+    );
 }
diff --git a/triagebot.toml b/triagebot.toml
index 3dbc60279ef..3d22da56f7c 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -310,7 +310,7 @@ trigger_files = [
     "configure",
     "Cargo.toml",
     "config.example.toml",
-    "src/stage0.json",
+    "src/stage0",
     "src/tools/compiletest",
     "src/tools/tidy",
     "src/tools/rustdoc-gui-test",
@@ -370,7 +370,7 @@ trigger_files = [
 [autolabel."T-release"]
 trigger_files = [
     "RELEASES.md",
-    "src/stage0.json",
+    "src/stage0",
     "src/version"
 ]
 
@@ -1049,7 +1049,7 @@ project-exploit-mitigations = [
 "/src/librustdoc" =                                      ["rustdoc"]
 "/src/llvm-project" =                                    ["@cuviper"]
 "/src/rustdoc-json-types" =                              ["rustdoc"]
-"/src/stage0.json" =                                     ["bootstrap"]
+"/src/stage0" =                                          ["bootstrap"]
 "/tests/run-make" =                                      ["@jieyouxu"]
 "/tests/ui" =                                            ["compiler"]
 "/src/tools/cargo" =                                     ["@ehuss"]